2016年6月15日水曜日

ルータがPPPoEで取得しているIPアドレスが変わったらRoute 53のレコードを更新するスクリプト

リモートから自宅のネットワークに接続できるようにしている方も多いと思いますが、ウチも出先からリモートアクセスしたりしています。

これまで外部の Dynamic DNS サービスに頼っていたのですが、利用していたサービスに変更があったのをきっかけに自前の仕組みに置き換えました。今回は、その仕組みについて紹介します。

私の自宅では RTX1100 が上流ネットワークとの PPPoE 接続を行っており、 pp 1 インターフェイスが外側のアドレスを持っています。このインターフェイスのアドレスを、自分が Amazon Web Services の Route 53 上で管理するゾーンのAレコードとして登録します。

ちょっと面倒だったのが RTX1100 の外側 IP アドレスの取得をどうするか、です。最初は 「SNMP クライアントでつっつけば出てくるじゃろ?」と適当に snmpwalk してみたのですが、よくわからなかったので、結局 telnet で調べるローテクで実装しています。

使っているコードのうち自宅依存部分を取り除いたものを https://github.com/hasegaw/route53update に Push してあります。


この中には3つのファイルが含まれています。

  • rtx1x00_show_status_pp_1.exp …… RTX1100 と telnet して IP アドレスを取得する
  • route53update.py …… 取得したアドレスを R53 に反映する
  • run.sh …… 実行方法

rtx1x00_show_status_pp_1.exp

RTX1100 に telnet して IP アドレスを取得します。このスクリプトは実際には RTX1100 と通信して、その内容を標準出力に書き出すまでです。実行には expect が必要です。引数としてホスト名とパスワードをとります。



route53update.py

上記 Except スクリプトを実行し、ルータからの出力を実際にパースし、 Route 53 のレコード内容と比較してみて、必要なら反映するのがこちらのスクリプトです。ファイル内にいくつか設定項目があります。(レコード名、 ゾーン名、ルータのホスト名とパスワードなど)
おまけで Slack にも対応しています。


 run.sh

route53update.py を実行する方法の例です。 AWS の API キーを設定しスクリプトを叩いています。手元ではこのスクリプトを cron に仕掛けています。


定期的にこのしくみが実行されることにより、Route 53 上の A レコードが常に自宅のルータに向くようになります。また、 Slack に新しい IP アドレスが通知されるため、ネットワークの不調に気づきやすかったり、などのメリットがあるかもしれません。

2016年5月6日金曜日

Oculus Rift CV1 をスムーズに迎え入れるためのポイント

ゴールデンウイーク突入早々に Oculus Rift CV1 が届いたのですが、実際に動かせるようになるまで、思った以上に時間がかかりました。

というわけで、自分が Oculus Rift CV1 を入手して色々試した上で、「Oculus Rift CV1 到着前に知っていたら良かったかも」と思ったことをいくつかまとめてみます。

GPU のドライバを最新にアップデートしておく

GeForce や Radeon など GPU のドライバを最新のアップデートしておきましょう。そうしないと Oculus Rift のセットアップが途中で「アップデートするように」と注意されてしまいます。

ドライブの容量をあけておく

Oculus Rift のランタイムをセットアップする際、インストール先のパスを指定します。ここで指定されたパスの下に、今後インストールする Oculus 対応アプリケーションも保存されていきます。このため、 Oculus Rift のランタイムのインストール先は容量に余裕をみておく必要があります。

ランタイム自体が 1.2GB 、さらにゲームタイトルをロードするスペースが必要です(たとえば一作 20GB など)。つまりは100GB程度空きあれば、とりあえずは安心です。別に、足りないならば、コマンドプロンプトでジャンクションきってもいいですけど。

おまけ。私の環境は C: (SSD 50GB空き / 256GB), D: (HDD 1TB空き / 2TB), K: (ioDrive2 200GB空き / 1.2TB) という構成だったのですが、なぜか K: にしかインストールさせてくれませんでした。おそらくインストーラのバグだと思います。
ランタイムのインストーラが、可能なドライブしか表示してくれませんが、そこでなぜか本当に K: しか出てきませんでした。 K: のドライブレターを外したらインストール可能なドライブがひとつも見つからずにセットアップできず、です。なので、私の環境では ioDrive2 に Oculus および関連ファイルがインストールされています...。


CV1 が届く前にランタイムのダウンロードを済ませておく

Oculus Rift ランタイムのセットアップは oculus.com/setup からファイルをダウンロードして実行します(と、ハードウェアとともに届く説明書に書いてあります。)。
このアドレスから入手したインストーラが 800MB 近くのファイルをダウンロードするので、そこでもけっこうな時間待ちがあります。 Oculus Rift 自体がなくてもソフトウェアのセットアップ(ダウンロードおよびインストール)は可能なので、先に済ませておきましょう。

ソフトウェアをインストールした後に Oculus Rift 、センサ、コントローラの設定を行う必要がありますが、そこは実機がないと進めないと思います。

XBox 360 ワイヤレスコントローラがあるなら、 PC に接続しておこう

Oculus Rift CV1 には Xbox One コントローラが付属していますが、これは日本国内だと無線で利用できず、配線が邪魔になります。 XBox 360 用のワイヤレスコントローラとレシーバがお持ちでしたら、そちらを PC に接続して利用すると快適です

Steam を準備しておこう

Oculus 向けのアプリケーションは Oculus のアプリストアである Oculus Store から購入可能になります。同時に VALVE が運営する Steam でも VR 対応アプリケーションが購入できます。

「どうして Oculus Store ではなく Steam を使うの?」 一部のゲームは Oculus Store で Oculus Rift 専用として独占販売されるようですが、見た感じ Oculus Store と Steam で扱われているタイトルも複数ありました。タイミングによるでしょうが、為替の都合同じタイトルが Steam のほうが安くなっていたりするケースもあります。

また、 Oculus Store で購入したソフトウェアが HTC Vive など他の VR ヘッドセットで使えるのか良くわかりませんが、 Steam で購入したソフトは、対応していればどちらでも使えそうです。また、 Steam では Virtual Desktop など、 Oculus Store に無いけども便利なアプリケーションなどもあります。 Oculus Store にあるものは Oculus Store から買ったほうが楽だとは思いますが、 Steam も準備しておくと色々ナイスです。

 Oculus Rift が届く前に済ませておくべき事は下記4点です。
  • Steam のアカウントを持っていなければ、作成する
  • Steam クライアントソフトウェアを Oculus Rift のホストとなる PC にインストールする
  • Steam クライアントから、Steam VR をインストールする
  • 購入を決意しているタイトルがあるのなら、事前に購入してインストールを済ませることも可能
Oculus Rift が到着し、 Rift のセットアップを済ませたら、下記の作業ができるようになります。
  • Steam VR のコンフィグレーションを済ませる(そうしなければ、 SteamVR が起動に失敗します)
  • Oculus の設定画面で「Unknown Source」を有効にし、 Oculus Store 以外から入手したソフトウェアも実行できるようにする

それでは、よい VR ライフを。

Oculus Rift と組み合わせて無線式のコントローラを使う

ついにコンシューマ向けの Oculus Rift が発売開始され、日本の予約者の方々のところにも続々と届いているようです。

ただ、日本のユーザにとっては、日本でのみ(?)残念な点として、本来 Oculus Rift に同梱されている XBox One コントローラのレシーバーが省かれ、代わりに USB ケーブルが付いてきています。それでも価格据え置きなのはちょっと残念ですが、まあそれはおいておいて。

XBox One のワイヤレスレシーバは、日本国内で利用できない周波数を使うため、並行輸入品を購入して利用していると、知っているか知らないかに関わらず電波法違反になります。もちろん技適も通っていません。手元で動くかどうかはともかく「使っちゃダメ」、というわけで、 Oculus Rift のパッケージからは日本向けのパッケージに限ってレシーバーが除かれています。

とはいえ、Oculus Rift 本体からは HDMI および USB3.0 のケーブルが出ているほか、 XBox One コントローラを手元にまで引っ張ってくると、ケーブルが増えて邪魔です。 Rift 本体のケーブルはどうにもなりませんが、とりあえずコントローラは無線化することにしました。



これを....



こうじゃ!



写真を見て判る人はもう判ったと思いますが....  Oculus Rift 付属の XBox One コントローラを使わずに、XBox 360 の無線式コントローラを接続して使っているだけです。以前 XBox 360 用の 2 台目のコントローラを買うときに、 Windows マシンにも接続できるよう、 Windows マシン用のレシーバーが付属しているパッケージを購入していました。 いままで一度も Windows でこのコントローラを使ったことはないのですが、 Oculus Rift と組み合わせて使うために、今回はじめてレシーバーを Windows 10 マシンに接続してみました。さすが Windows と XBox 360 レシーバーです。レシーバーのペアリングボタンを長押しし、コントローラもペアリングモードにして、あっさりと接続できました。

XBox 360 コントローラとワイヤレスレシーバのセット商品は、いまでも市中在庫があるようです。これからコントローラとセットで買いたいかたはこちらを購入すればいいのではないかと思います。



もし XBox 360 コントローラをすでにお持ちで、コントローラを購入する必要のない方は、下記のレシーバーを購入すれば、たぶん手持ちのコントローラを Oculus Rift との組み合わせに転用できます。



「ところで、 Rift 付属の XBox One コントローラを使わなくても大丈夫なの?」という疑問をお持ちのかたへ。ちょっと調べてみたところ、 Rift 向けのソフトウェア開発では XBox 360 コントローラはよく使われているそうです。 Windows の仕組み的には XBox 360 / XBox One のコントローラは特に区別もしていないようですし、ボタンの数とかも一緒のはずなので、 XBox 360 用コントローラを使っても問題は無いはずです。

よい VR ライフを。

2016年2月16日火曜日

ZFS (on OpenIndiana VM on ESXi) のディスク交換

先日 ZFS の RAID-Z1 アレイがデグレードした。デグレードしたアレイは下記の構成。
  • WD RED 4TB X5、パリティ一発の構成
  • メンバディスクは2014年頃に購入してからこれまでは安定
  • たびたび自宅のブレーカー断 が発生。その仮定でディスクに損傷がおきている可能性はありそう
  • ESXi に SATA ポート経由で接続し、 RAW デバイスマッピングを介して OpenIndiana VM に接続

はじめに現れた症状

VMware 上の OpenIndiana で動く ZFS ストレージをその ESXi 自体で NFS データストアとしてマウントしているが、そこで動く BIND が落ちて自宅のネットワークが不調になった。原因なんだろうなーと思ったが、どうやら ZFS アレイのデグレが原因の模様。

 root@vm230:~# zpool status
  pool: array3
 state: DEGRADED
status: One or more devices has experienced an unrecoverable error.  An
        attempt was made to correct the error.  Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
        using 'zpool clear' or replace the device with 'zpool replace'.
   see: http://illumos.org/msg/ZFS-8000-9P
  scan: scrub repaired 523M in 22h40m with 0 errors on Sun Feb 14 07:48:45 2016
config:

        NAME        STATE     READ WRITE CKSUM
        array3      DEGRADED     0     0     0
          raidz1-0  DEGRADED     0     0     0
            c3t1d0  ONLINE       0     0     0
            c3t5d0  ONLINE       0     0     0
            c3t4d0  DEGRADED     0     0 8.15K  too many errors
            c3t2d0  ONLINE       0     0     0
            c3t3d0  DEGRADED     0     0 1.36K  too many errors
        logs
          c3t8d0    ONLINE       0     0     0
        cache
          c3t9d0    ONLINE       0     0     0
VMware ESXi 側で仮想マシンの仮想ディスクのレイテンシを確認すると最悪値が 10 秒に達している仮想ディスク(c3t4d0)があり、ハードウェアレベルの障害と確証を持った。OpenIndiana カーネル側には下記のようなメッセージが出力されていた。ディスクがエラーを起こしているときに出しているようだ。
Feb 16 10:26:55 vm230 scsi: [ID 107833 kern.warning] WARNING: /pci@0,0/pci15ad,1976@10/sd@3,0 (sd4):
Feb 16 10:26:55 vm230   disk not responding to selection

この状態における zpool scrub の必要性

色々試してみてわかったんだけど、ディスクを交換するつもりなら事前に scrub する必要はなかった。
まず、DEGRADED となっているメンバはドライブ障害が発生している旨フラグが立っているものの、まだ ZFS が見捨てたわけではなく、稼働中だということを示している。ここが UNAVAIL もしくは REMOVED だとドライブがそもそも応答しないかパス障害になっているので、もうひとつドライブが見えなくなった時点でこの ZFS プールはオフラインになるだろう。だが今回は DEGRADED ステートになりつつも、障害が起きているドライブ2台はまだ辛うじてオンラインのまま。
ここで zpool scrub を行えばアレイ全体を検査と自動修復を行えるけども、のちに実行する zpool replace コマンド中でも事実上スクラブ相当の処理が行われる。一時的にディスクが UNAVAIL になったためアレイセットのなかで置いて行かれた状態などであれば scrub する意味があるだろうけど、今回は辛うじて全ドライブがオンラインのままだし、ディスク交換前に scrub を繰り返してとどめを刺しても仕方ないので、結果論としてスクラブを試す強い理由はなかった。せいぜいディスクのエラーカウンタをリセットした後にスクラブしてみて不良かを再判断できる程度。

交換用ディスクを調達、 VM に接続

今回は東芝製MD04ACA6 (6TB)をメンバディスクとして使ってみる。RAID-Zなので不具合が出たディスクだけ6TBのディスクにしなくとも、4TB前後で十分なのだが、これから数年後に4TBクラスのディスクが大量に転がっているのは避けたいし。 先の zpool status の状況からディスク2台に障害がおきていると想定し、交換用のディスクは2台準備した。
問題のディスクは SUPERMICRO 社製 X9SRA の SATA ポートに接続されている。残念ながら SATA ポート自体は ZFS プールのメンバ群などで埋まっているので、相手いる SAS ポートに今回用意した SATA ディスクを接続して復旧作業を進める。(一般的にSASポートはSATAディスクも扱える)
横着だがマシンが稼働した状態のまま SATA ケーブルでシステムボードの SAS ポートとMD04ACA6を接続し、SATA電源ケーブルを慎重にプラグし活性接続。ディスクトラブルが起きているときはマシンの電源を切りたくないし、可能ならマウント(インポート)している仮想マシンの電源も落としたくない。 vSphere Client を介して VMware ESXi に対しストレージのリスキャンをかけると接続したディスクが認識されていたので ESXi の再起動なしに先に進めそう。
ESXi 上で ls -l /vmfs/devices/ を実行してみると、新しく接続したディスクが naa.50000396aba018c8 として認識されていたので、このディスクを RAW マッピングする VMDK ファイルを生成する。
/vmfs/volumes/(snip)/vm230b # vmkfstools -z \
    /vmfs/devices/disks/naa.50000396aba018c8 \
    array3f_50000396aba018c8.vmdk
残念ながら仮想マシンを止めないと OpenIndiana に対して仮想ディスクを追加できない(と思う)。 ZFS プールは DEGRADED 状態だがメンバが足りていないわけではないし、仮想マシンを起動しなおした時点で今みえている仮想ディスクが見えなくなることも考えづらい。 DEGRADED 状態でも辛うじて I/O はできているようなので、なんとかなるだろうと判断(でもこわい。慎重を期すならここで別のファイルシステムにバックアップをとったほうがいい)。再起動後もきちんと戻ってくると信じて VM シャットダウン、仮想ディスクを追加して OI 再起動。
root@vm230:~# format
Searching for disks...done

c3t6d0: configured with capacity of 5589.03GB


AVAILABLE DISK SELECTIONS:
       0. c3t0d0 <VMware-Virtualdisk-1.0 cyl 2085 alt 2 hd 255 sec 63>
          /pci@0,0/pci15ad,1976@10/sd@0,0
       1. c3t1d0 <VMware-Virtual disk-1.0-3.64TB>
          /pci@0,0/pci15ad,1976@10/sd@1,0
       2. c3t2d0 <VMware-Virtual disk-1.0-3.64TB>
          /pci@0,0/pci15ad,1976@10/sd@2,0
       3. c3t3d0 <VMware-Virtual disk-1.0-3.64TB>
          /pci@0,0/pci15ad,1976@10/sd@3,0
       4. c3t4d0 <VMware-Virtual disk-1.0-3.64TB>
          /pci@0,0/pci15ad,1976@10/sd@4,0
       5. c3t5d0 <VMware-Virtual disk-1.0-3.64TB>
          /pci@0,0/pci15ad,1976@10/sd@5,0
       6. c3t6d0 <ATA-TOSHIBA MD04ACA6-FS2A-5.46TB>
          /pci@0,0/pci15ad,1976@10/sd@6,0
       7. c3t8d0 <VMware-Virtual disk-1.0-1.00GB>
          /pci@0,0/pci15ad,1976@10/sd@8,0
       8. c3t9d0 <VMware-Virtual disk-1.0-200.00GB>
          /pci@0,0/pci15ad,1976@10/sd@9,0

新しく接続したディスクは c3t6d0 として認識されている。なお、仮想ディスクの構成はこうなっていた(ずっと前に適当に構築したので完全に忘れていた)
  • c3t0d0 (SCSi 0:0): OSイメージ
  • c3t1d0 (SCSi 0:1): データ用ZFSプールのメンバディスク 1
  • c3t2d0 (SCSi 0:2): データ用ZFSプールのメンバディスク 2
  • c3t3d0 (SCSi 0:3): データ用ZFSプールのメンバディスク 3 (エラーが発生)
  • c3t4d0 (SCSi 0:4): データ用ZFSプールのメンバディスク 4 (エラーが多く発生)
  • c3t5d0 (SCSi 0:5): データ用ZFSプールのメンバディスク 5
  • c3t8d0 (SCSi 0:8): データ用ZFSプールのslog
  • c3t9d0 (SCSi 0:9): データ用ZFSプールのL2ARC
ここに下記デバイスを追加した。
  • c3t6d0 (SCSi 0:6): データ用ZFSプールの交換用メンバデバイス

いざリプレース

zpool replace でエラーが多数発生しているメンバディスクを新ディスクに置き換える。
root@vm230:~# zpool replace array3 c3t4d0 c3t6d0
root@vm230:~# zpool status
  pool: array3
 state: DEGRADED
status: One or more devices is currently being resilvered.  The pool will
        continue to function, possibly in a degraded state.
action: Wait for the resilver to complete.
  scan: resilver in progress since Mon Feb 15 06:14:01 2016
    51.9M scanned out of 17.4T at 5.76M/s, (scan is slow, no estimated time)
    9.94M resilvered, 0.00% done
config:

        NAME             STATE     READ WRITE CKSUM
        array3           DEGRADED     0     0     0
          raidz1-0       DEGRADED     0     0     0
            c3t1d0       ONLINE       0     0     0
            c3t5d0       ONLINE       0     0     0
            replacing-2  DEGRADED     0     0     0
              c3t4d0     DEGRADED     0     0     0  too many errors
              c3t6d0     ONLINE       0     0     0  (resilvering)
            c3t2d0       ONLINE       0     0     0
            c3t3d0       DEGRADED     0     0     0  too many errors
        logs
          c3t8d0         ONLINE       0     0     0
        cache
          c3t9d0         ONLINE       0     0     0

errors: No known data errors

約21時間後に zpool replace が完了。死んだディスクをリプレースしたディスクで置き換えたが、現在接続されている SAS ポートから SATA ポートへ新ディスクを移動させると VMware の RAW マッピングがきれる事が想定される。このため一度 zpool export した状態で VM を停止する。
SAS ポートに接続していた新ドライブを死んだドライブの位置に移動し ESXi でデバイススキャンをかけると vmfs/devices/disks/t10.ATA_____TOSHIBA_MD04ACA600__(snip)Y5C7K3SERIAL というパスで認識された。やっぱりパスが変わった。SERIAL の部分は実際にはディスクのシリアル番号が入っている。先に作成した RAW デバイスマッピングを削除して作り直し。
# rm array3f_50000396aba018c8*
# vmkfstools -z \
    /vmfs/devices/disks/t10.ATA_____TOSHIBA_MD04ACA600__(snip)Y5C7K3SERIAL 
    \ array3f_Y5C7K3SERIAL.vmdk


仮想マシンの構成変更。リプレースされて不要になった c3td40 = SCSI 0:4 およびパスが変わってしまった c3t6d0 = SCSI0:6 を VM から削除。新たに作成した array3f_Y5C7K3SERIAL.vmdk を SCSI 0:4 として追加。
VM を起動し zpool import array3 する。これで1台目の重傷ドライブが交換完了となりアレイのステータスは ONLINE に。
ただ、重傷だったオリジナルの c3t4d0 のほかに c3t3d0 でもエラーが出ていた。
重傷ドライブのせいで同時にデグレったかのように見えたのかも??と思いつつも、とりあえず軽傷なほうも zpool replace してみることにする。やることはさっきと同じ。 SAS ポートに次のドライブを接続して RAW デバイスマッピングを作成し、 SCSI 0:6 として追加して、 zpool replace で c3t3d0 から置き換える。
しばらくは順調だったけども、 resilver が 20% 越えたあたりからチェックサムエラーが出たり dmesg に下記メッセージがでたので、このディスクもやっぱりハードウェアレベルで異常があることは間違いなさそう。
Feb 16 10:26:55 vm230 scsi: [ID 107833 kern.warning] WARNING: /pci@0,0/pci15ad,1976@10/sd@3,0 (sd4):
Feb 16 10:26:55 vm230   disk not responding to selection

24時間もたてば replace は終わっているだろう。そうしたらいったん zpool export して VM を落としておき、古い c3t3d0 を取り外して、 SAS ポートに接続されている新ディスクを c3t3d0 として改めて追加し zpool import しなおせばディスク交換終了の見込み。

2016年1月13日水曜日

スプラソン用キット、稼働開始 #splathon

週末に開催された第二回スプラソンにて、パブリックビューイングシステムを導入しテストしてみました。今回は機材の都合上4画面のみの投影となりましたが、なかなか会場を盛り上げてくれたんじゃないかと思います。

第二回Splathonを開催したぞ(42日ぶり2回目の #splathon )
第二回Splathon@Speee(IT企業対抗スプラトゥーン大会) まとめ #splathon


第一回スプラソンの際に特定のプレイヤーの行動のみが大型スクリーンに投影されており、できれば両チームの視点からプレイを見たい、と思ったので、色々と検討していました。

一番簡単?なのは WiiU の出力を全部ひとつひとつ大型テレビなどに投影し、並べて見ることです。しかし、大型テレビが8台も沸いてくるようなリッチな環境は滅多にありません。また、プレイ画面とPV画面を別にするとスプリッタの準備も必要です。あわよくば、そこまでするなら、各プレイヤーの動きを録画したり、解析したら面白そうです。

各プレイヤーの動きを録画したり解析するには、たぶんPCにHDMIキャプチャで入力してIkaLogもしくは相当野ツールで処理するのがよいでしょう。しかし、そうするとHDMIキャプチャデバイスを最大8個準備する必要があります。ヘビーです。

で、色々考えていたのですが、スプラトゥーンは 4対4 なので、画面を半分に縮小して 4-in-1 したらいいのではないかと思ったわけです。

4-in-1 しようとすると、通常はお高い機械が必要です。たとえば BlackMagic Design の MultiView を使えば最大16画面をひとつにまとめてスクリーンに投影できたりしますが、メーカーさんなどが悪いわけではありませんが、スプラトゥーン遊ぶのに 16 万円の機械を導入するのは流石に無理です。

「まてよ? HDMI 信号を FPGA で受信してミックスすればいいのでは?」

なんか変なことを考え始めて色々と検討をはじめました。

そんなこともあろうかと自宅には ZYBO (ARM搭載FPGA)



ハードウェアが得意なわけでもないのでかなり無謀

あとは4チャンネル同時に信号を受けるようにして(FPGAや回路はソフトウェアと違い並列に並べること自体は容易)、受け取ったデータを一度DRAMに書き込んで(DDR2メモリの性能ならまあ適当に作ってもなんとかなるだろう)、その結果をHDMIもしくはRGBとして出力すればOK、、、というところで、いくつか問題が浮上してきました。

ひとつ目の問題は FPGA 上に載っている PLL ブロックの数に限りがある、ということです。開発に利用していた ZYBO の Zynq-7000 には MMCM という PLL 的なものがふたつしか載っていません。しかし HDMI はピクセルクロックで同期しつつその10倍の速度でシリアルデータが送られてくる仕様になっていて、最大 1.5GHz でデータがパタパタ流れ込んできます。 ZYBO 自体でこのクロックを作るのはかなり無理ですし HDMI のピクセルクロックを元に必要なクロックを生成するのが現実的ですが、その回路がふたつしかないのえす。ひとつを入力、もうひとつを出力を使ったらもうありません。どうやって残りの3チャンネルを受ければいいんだ。

手元にあるもうひとつの FPGA 評価ボード NEXYS 4 には MMCM が 6 ありようなのでここで勝利を確信します。しかし、トレーニングボードのネットリストを見てみると PMOD に差動信号ペアとして使えるピンが全然でてないじゃないですかーやだー。ふざけんなよなんでこんなデザインになってるんだよ。俺は差動信号を12ペアぐらい突っ込みたいんだよ。

ここでひとつの悟りをひらきました。まず私が想定している回路はFPGAで作ることは可能です。ただ問題として、HDMIの1.5GHzクロックで流れ込んでくる信号をきれいにさばくには基板の設計を数回繰り返す必要があります。さらに、私の手元にはHDMIの信号を同時に4つ受けられるようなFPGAボードがないのでそこから制作するとなると、何百ものピンが出ているFPGAパッケージとHDMIコネクタを正しく接続したボードを作って、そこに諭吉さんクラスのFPGAを購入し業者に万単位のカネを払ってチップマウントして貰わないと作れないということが現実的にわかってきました。もちろん私が一発で成功させられるわけがないのでそれを繰り返すことになりかねません。

そこまでは難しいので、どうにか外部インターフェイス部分だけの製作で済ませようとするとこういうFPGAボードが載せられる基板をつくる手があるのですが、そもそもこのFPGAボードが10万スタートでかなりハードルが高いです。

BlackMagic Design の MultiView が安く見えてきました。

が、世界の工場で作られた「とりあえず 4-in-1 が可能なハードウェア」を入手することに成功しました!

というわけで、今回のスプラソンに投入してみたわけです。





このシステムはスプラトゥーンをプレイする人々(別にほかのゲームでもいいですが)のためにお貸し出しできるように揃えています。仲間うちでプレイしたい、みんなでプレイするときにこの機材が使いたい、という方は是非ご連絡ください。

イニシャルがけっこうかかっていますので無料というのはきついですが、場合によっては一ヶ月分の給料に相当する程度の機材を気軽に利用してもらえるように準備しています。

2015年12月24日木曜日

スプラソン機材セットをつくりました



この記事は Splatoon Advent Calendar 2015 の 23 日目の記事です。(空きがあったので登録してみたものの.... 遅れてすみません)
前の記事:ギア交換所とS+に上がるための3つの戦略
次の記事:

私は別にスプラトゥーンで何か語れるほどプレイしていませんし、今回はスプラトゥーンのみんなで楽しくアソブための機材を調達した紹介をします。

スプラトゥーンは4対4のチーム戦が基本です。いわゆる野良マッチであれば世界のどこかのプレイヤーとチームを組んで戦いに臨むことになります、場合によっては仲間内で集まってタッグ同士のマッチに参戦したり、知り合い同士でプライベートマッチを開き対戦することも可能です。

最近知ったのですが、みんなで一カ所に WiiU を持ち寄ってプレイすることを”スプラソン”というのだそうです。最近スプラソンが Speee で開催されたので遊んできたのですが、それが面白く、自分たちでもなにかやりたいな、と思っていたら、気づくとスプラソンの際に便利そうな映像機器をいろいろ調達していました。こんなことができます。



このビデオではひとつの WiiU の画面を複数表示していますが、実際には複数の WiiU からの入力を同時に表示できます。


どうやっているか、ですが、4つのHDMI信号をひとつのHDMI信号にまとめてくれる機器とスプリッタを組み合わせてプレイ用テレビ/ディスプレイとチーム画面などへの同時出力を実現しています。




実現にあたって、主な装備として下記のデバイスを準備しました。

  • WiiU 4台からのビデオ信号を受け取り、ひとつのモニタ/プロジェクタに表示するHDMI スイッチ ×2
  • WiiU のバスパワーで動く 1:4 HDMI スプリッター ×9
  • 上記を配線するための HDMI ケーブル (20本ぐらい)

このうちHDMI信号のミックスができるスイッチはちゃんとしたメーカーのものを買おうとすると1台20万円もしくはそれ以上になってしまいます。そこまでの製品ではありませ、、が、4〜8人でスプラトゥーンをあそぶのに使える程度の機材を勢いとポケットマネーでゲットしました。
 まだ8画面処理は試したことがないのですが、先日某所にて有志の方々に WiiU を持ち寄ってもらい試したところ、ひとつのテレビで4画面同時表示や録画が可能なことが確認できました。

スプラトゥーン大会を開いても楽しいですし、気合いがはいった?使い方としては強化合宿でプレイ録画をしておきあとで全員でレビューする、なんてのもできそうですね。試してみて改めて感じたのですが、キャプチャデバイスひとつで4人分の録画ができるのはとても便利です。



この機材は、スプラトゥーンを楽しむ皆さんで活用してもらえればと思っており、ベストエフォートながらどんどん貸し出し等を行いたいと思います。

ただ、それなりに初期投資として持ち出しているほか、今後の機材故障での買い直しや海外への修理品輸送などが発生するとまたおカネがかかりますので、申し訳ありませんが
参加者ひとりあたりワンコイン程度を目安にレンタル料を設定するつもりでいます。ご興味おありの方は Twitter で @hasegaw までご連絡ください。

1月でスプラトゥーンの大幅アップデートは一段落ということですが、まだまだこのゲームは盛り上がると思っています。今回紹介したスプラソンキットは関係なく、楽しく遊びましょう。

ちょっと宣伝じみて恐縮ですが、みんなでたのしく遊びましょう。


この記事は Splatoon Advent Calendar 2015 の 23 日目の記事です。
前の記事:ギア交換所とS+に上がるための3つの戦略
次の記事:



2015年12月15日火曜日

Fluent-bit と XBee で作るセンサーネットワーク

この記事は Treasure Data Advent Calendar 2015 の 15日目です。
前々日の記事:Jupyter から見た Treasure Data の使い方
前日の記事:
翌日の記事:


6月に開催された LinuxCon 2015 Tokyo で Treasure Data のエンジニアが Fluent-bit を紹介していました。 Fluent-bit とは、 Fluentd のデザインを継承した、組み込み用途向けの情報収集ツールだそうです。

http://fluentbit.io/


ただ、その時点では利用できる Input プラグインが限られており、そのノードのシステム情報などの取得が中心でした。 XBee 対応もモック状態でしたので、適当にいじって動くようにしてみました。今回は in_xbee がどんな感じに動くかを紹介します。いま Fluent-bit で実現できるすべての入力を紹介します。


1. Fluent-bit + XBee でできること


Fluent-bit は、 Treasure Data 社が作っている、組み込み Linux 向けの IOT データコレクタで、各種センサからの値を取り込むためのツールです。取り込んだデータは、 Fluentd へ送信したり、もしくは Treasure Data 社のサービスへ送り蓄積できます。インプット/アウトプットのモジュールはプラグイン型となっているため、新たなインプットやアウトプットに対応することも可能です。以下は Fluent-bit プレゼンテーションで示されている概要です。

 

XBee は Digi International 社による無線モジュールで、 ZigBee (802.15.3) や WiFi(802.11) など様々なタイプのものがあります。特に、 ZigBee 規格はセンサネットワークを構築する用途に向いています。Fluent-bit から XBee を実際に扱えるような Pull Request をマージしてもらいましたので、いまだと XBee をデータソースとして使えます。



 

XBee にはいくつかの種類がありますが、どのモデルでも下記の入力が扱えます。
  • デジタル/アナログ信号を一定間隔、もしくは変化があったときに送信
  • 接続されたコンピュータ(マイコンやPC)からのシリアル通信内容により送信
今回は、 Fluent-bit と XBee を使ってデータを収集するしくみを作る例、マイコン(Arduino)からFluent-bitにデータを送信する方法を紹介したいと考えています。


2. Raspberry Pi 2 で Fluent-bit を動かす


 XBee との連携について説明する前に、 Raspberry Pi 2 上の Raspbian で Fluent-bit を動かすための最低限の方法について説明したいと思います。

Fluent-bit を GitHub からクローンしてきます。本記事の公開時点では最もあたらしいリリースである v0.5.1 がよいでしょう(私は maser を使いました)。 Fluent-bit をコンパイルするには下記の要領で作業します。


 コンパイルが成功したら下記の要領で動作確認が可能です。

または、下記要領で Fluentd へのログ送信も確認できます。 Fluentd へは "fluent_bit" タグで送信されますので、 Fluentd の設定を済ませておいてください。


3. はじめての XBee


では、 Fluent-bit で XBee を使って情報を集約するために必要なモジュール、部品を揃えていきたいと思います。今回は秋月電子で揃えられる部品で実装しますが、同等品などでも構いません。



今回はXBee Series 2 モデルを 2 台準備しました。

備考:
  • XBee用シリアルインターフェイスは利用前にハンダ付け作業が必要です。
  • XBee用シリアルインターフェイスは最低1個あれば本記事の作業を行えますが、初めてXBeeを扱う場合など、疎通を確認する段階で2個あると便利です。
  • 本稿執筆時に使用したXBeeモジュールはSeries 2、もしくはXBeeZBと呼ばれるモデルですが、XBee Series 1, XBee WiFiなども(たいして変更なく)利用可能と思われます。
  • 相互通信のためには同じシリーズを利用する必要があります。たとえばXBee S1とXBee WiFi, またXBee S2の間は相互通信できません。
  • XBeeのアンテナタイプには外付け、アンテナ付きタイプ、PCBアンテナ(基板に内蔵)タイプがあります。アンテナ付き、もしくはPCB対応がよいでしょう。


エンドポイント側 XBee の設定 


エンドポイント(センサデバイス)側として使用する XBee モジュールを USB インターフェイスボードに装着し、 USB ケーブルで作業用 PC に接続します。設定は XCTU と呼ばれるツールを使用します。 XCTU は Digi International 社のサイトから入手してください。紹介するスクリーンショットは OS X 版のものです。

XCTU Software - Product Detail - Digi International
http://www.digi.com/support/productdetail?pid=3352

XCTU で XBee モジュールに End Device API のファームウェアをロードし、下記設定値をプログラムします。




 


 

 


コーディネータ側 XBee の設定


同様に、コーディネータ(Raspberry Pi 2)側として使用する XBee モジュールも、先と同じ要領で設定を行います。こちらのファームウェアは Choordinator API のファームウェアをロードし、下記の設定値をプログラムします。








この時点でエンドポイント用 XBee の電源がオンであれば、5秒毎にデータが送られてきているはずです。ターミナルのアイコンでコーディネータ側 XBee のシリアルポートに接続すると、エンドポイント側から送られてきた IO Data Sample RX Indicator というパケットが見えるはずです。




エンドポイント側からのパケットが届いていることが確認できたら、XCTUを終了し、 USB ケーブルを抜きます。


4. Fluent-bit とコーディネータ側 XBee の接続 


コーディネータ用XBeeをRaspberry Pi 2に接続します。 USB ケーブルで Raspberry Pi 2 に接続すると、 /dev/ttyUSB0 もしくは相当のデバイス名で認識されるはずです。 FTDI の USB Serial ドライバがないとダメですのでカーネルモジュールを削ってしまっている場合はビルドしてロードしてください。


Fluent-bit 設定ファイルの作成


設定ファイル xbee.conf を作成します。



※ XBeeLogLevel を設定した場合は、 XBee の通信に関する細かなログが表示されるようになりますので、うまく動作しない場合にはコメントアウトを解除して試してみてください。


Fluent-bit の起動と XBee パケット 受信確認


Fluent-bit を起動し、実際に XBee のパケットが拾えるか確認してみます。特に設定をしない限り、/dev/ttyUSB0 は root:dialout の権限になっていますので、 sudo を使って root 権限で動作させます(お使いのユーザを dialout グループに所属させてもよいでしょう)。


起動後、XBee エンドポイント側からの定期送信パケットが表示されれば、ここまでは OK です。もしうまく表示されない場合は、 XBeeLogLevel のコメントアウトを解除して、 XBee の受信処理などのメッセージが出力されるか等から、表示がされない原因を切り分けます。


エンドポイント側 XBee からデジタル信号を入力する




 GND ピンと DIO1 ピンをショートさせる "DIO1" として 0 が送られてきます。 DIO1 ピンに 3.3V かけると 1 が送られてきます。たとえば、以下のようなデータが Fluent-bit に出力されます。5秒おきのポーリング結果に加えて、ピン状態が変化したタイミングに特定ピンへのデータが届いているためこのような表示になります。

実際にはドアのスイッチを接続したりすることになるでしょう。たとえばトイレ個室のドア開閉状況を Fluentd で収集し Kibana などに投げてやればトイレのビジー率などをグラフ化できるでしょう。


エンドポイント側 XBee からアナログ信号を入力する


次にアナログピンの実験をしてみましょう。 XBee には、 0V 〜 3.3V の範囲で、どれぐらいの電圧がアナログピンにかかっているかを検出する ADC 機能があります。アナログタイプの照度センサなどのデバイスを使えば、状態を電圧として XBee のアナログピンに入力することができます。

3.3V 端子と AD0 端子を繋ぎ、 Fluent-bit の出力をみると AD0 が 1023 になっています。逆に、 GND 端子を AD0 端子に繋いでみます。すると、今度は AD0 が 0 に近い値になります。 AD0 に 3.3V をあらためてかけると、また AD0 の値が 1023 に戻ります。 実際には日照センサなどを接続することになるでしょう。


入力したデータの取り扱い


Fluent-bitでデータが入力できたら、 Fluentd によって Treasure Data Serivce 、もしくは Fluentd を介してお好きなミドルウェアに集約することができます。


5. XBee meets MCU


ここまでは、 XBee 自体の機能だけを使い、デジタル/アナログピンの状態をを収集しました。しかし、実際には、センサを動かすためにマイコンが必要であったり、またはセンサからの入力値を送信する過程でマイコンで処理をしなければならない場合も多いでしょう。今回は、そのような状況を想定し、 Arduino を使って情報を収集し、 XBee モジュールを介して Fluent-bit に送信するセンサノードを試作してみます。

今回使用する Arduino Duemilanove は 2010 年頃に流通していたモデルで現在は見かけませんが、現在の Arduino UNO R3 相当品だとお考えください。


in_xbee プラグインが受け取れる MessagePack フォーマット


in_xbee プラグインは、以下の形式で MessagePack でシリアライズされたペイロードを受け取れます。
  • [ time, { key => val, ... } ]
  • { key => val, ... }

タイムスタンプがついていない MessagePack ペイロードの場合 Fluent-bit が受信した時刻がそのペイロードの時刻となります。センサノードやマイコンには、現在の時間を扱うリアルタイムクロック(RTC)が搭載されていないこともしばしばです。時刻が分からないノードの場合は Fluent-bit 側でタイムスタンプを付加させることができます。


サンプルの概要


Arduino と XBee 、そして温湿度センサを使って、 MessagePack でシリアライズしたデータを送信し、 Fluent-bit で受け取るサンプルを作ってみます。
  1. Arduino は I2C バスを介して温度センサ AM2320 から温度、湿度情報を読み取ります。
  2. Arudino は 温度、湿度情報を MessagePack でシリアライズします。
  3. Arudino はシリアライズしたデータを XBee でブロードキャストします。
  4. Fluent-bit で先の MessagePack を受信します。
Arduino から I2C デバイスを制御するには wire という標準ライブラリがありますが、 AM2320 をコントロールするには不十分だったため SoftI2CMaster と呼ばれる別のライブラリを利用しています。取り込んだ値は下記構造で MessagePack でシリアライズします。

{ "degC" => 23.0f, "humidity" => 40.0f }

ワンチップマイコンでは 16bit どころか 8bit アーキテクチャのものも多数あり、またモノによっては POSIX どころか malloc() すら標準提供されていないものも多くあります。また、マイコンによっては浮動小数点フォーマットが IEEE754 ではないとかの機種依存事項もあります。このため msgpack-c のようなライブラリを MCU で使うには、いくらかハードルがあります。

このような環境を想定した MessagePack 実装として、ワンチップマイコン向けの msgpack-mcu を試作しました。 msgpack-mcu は GNU C コンパイラやマイコン向けのベンダ製コンパイラでなんとなくコンパイルでき、各種マイコンで利用できることを想定しており、別に性能もコードもすごくありませんのであしからず。

MessagePack でシリアライズされたデータは XBee を介してコーディネータに送信します。今回は Aruduino スケッチは XBee の API モードでデータをブロードキャストする最低限の実装となっています。


Arduino への XBee, 温度センサの取り付け


Arduino と温湿度センサ、XBeeをArduinoに接続していきましょう。ブレットボードを使えば、半田付け作業なしで回路の試作が可能です。今回はブレットボード上に温湿度センサとXBeeを載せます。下記の要領で SDA/SCL を AM2320 へ、 Arduino の TX を XBee の TX に接続します。



Arduino は 5V でデジタル信号を扱いますが、 XBee は 3.3V のデジタル信号を扱います。 XBee に Arduino の信号をそのまま入力すると死んでしまいますので、5V ←→ 3.3V のレベル変換が必要です。今回は Arduino (5V) → XBee (3.3V) ですのでレベル変換 IC などは使わずに抵抗を利用した分圧で済ませます。 5V を 3V に落とすため、抵抗の比率を1:2にします。

 


スケッチをArduinoへアップロード


以下に AM2320 から I2C で値を読み出して MessagePack でシリアライズし、 XBee API を使ってブロードキャストするサンプルを示します(SoftI2CMasterおよびmsgpack-mcuが必要です)。


このスケッチを Arduino にプログラムしてシリアルポートを見ていると、この配線をした状態であれば Arduino の起動から2秒後に { "i2c_init": 1 } という出力が見えるはずです。すべてがうまく行っていれば温度情報が数秒ごとに MessagePack over XBee API でブロードキャストされます。




Fluent-bitでの受け取り確認


先の Arduino から送られてきた MessagePack ペイロードが Fluent-bit の in_xbee に入力されると、次のようになります。


この表示が得られれば、 XBee を介して Fluent-bit が MessagePack のデータを受信できているはずです。あとは、お手元の Fluentd の Forward ポートへ転送してあげるだけです(もちろん Treasure Data Service に送るのもよいでしょう!)。


セキュリティ上の注意


今回の記事では、データの暗号化を行っていません。実際の利用にあたってはデータの暗号化、また XBee モジュールの無線出力の調整などが必要になるかと思われます。 XBee モジュールは AES による暗号化機能を搭載していますので活用してください。


(おまけ) TWE-Lite


参考までに、 XBee は無線モジュールであり、全モデルに共通して”しっかりしたマイコン”は付いていません。このため何かしようとするとすぐにマイコンを併用することになります。そうなると部品点数が増えますし配線も面倒です。

ここで TWE-Lite がちょっと便利です。モノワイヤレス(株)が販売する TWE-Lite は XBee の別メーカー版のようなかんじで、 ZigBee ベースでメッシュネットワーク ToCoNet が構成できる上に 32 ビットのマイコンも搭載されており、エンドポイントでちょっとしたプログラムを走らせるのに向きます。ZigBee と 32bit マイコンがワンパッケージに収まっていて 2000 円以下で入手できますので、安くセンサネットワークを作るにはアリだと思います。ちょっとした試作であれば TWE-Lite DIP を使うとブレットボード上で作業できます。



当然 TWE-Lite は XBee の API をしゃべるわけではありません。そこで、わたしは個人的に、”ホストからみると TWE-Lite が XBee API を話すような”プログラムをコーディネータ相当の TWE-Lite に書き込んでいます。これを使うと Fluent-bit + in_xbee で ToCoStick (TWE-Lite + USB インターフェイス)が受信した ToCoNet のペイロードをあたかも XBee のネットワークで送られてきたかのように振る舞います。

一方、センサノード側の TWE-Lite DIP には先の msgpack-mcu などを組み合わせて温度センサなどから集めた情報を MessagePack にシリアライズし、 ToCoNet を介してコーディネータに送りつけるようプログラムしてあります。

上記2点のプログラムを組み合わせることで、少ない部品代と部品点数で XBee もどきノードを作り、データを収集して Fluentd + Kibana を動かしてみたのが下のスクリーンショットです。





 



6. まとめ 


今回は Fluent-bit と XBee ネットワークを通じて情報を収集する方法を紹介しました。本記事を通じて、 Fluent-bit どのような事ができるのか、また Treasure Data Service もしくは Fluentd を使ったデータ集約にあたって、Fluent-bit をどのように活用できるのか、イメージを掴んでいただけたのではないかと思います。

Fluent-bitの登場により、Linuxが動作するコンピュータと、数千円で用意できるセンサノードを組み合わせて、(ほとんど)ソフトウェアを書かずにセンサーデータが集約できるようになりました。空間の環境情報、ドアの動きのモニタリングなど、皆さんのまわりで物理的な情報を集約する必要が出てきた場合には、 Fluent-bit の利用を検討してみてはいかがでしょうか。


この記事は Treasure Data Advent Calendar 2015 の 15日目です。
前々日の記事:Jupyter から見た Treasure Data の使い方
前日の記事:
翌日の記事: