TDUPRESS公式ブログ

コラムやエッセイなどをゆる〜く発信中。

「PROJECT TSUKUYOMi」とは何だったのか(ハードウェア、ネットワーク編)

PROJECT TSUKUYOMi(以下、月詠)のUnityで作られた投票画面カッコよかったですよね。宇宙空間をバックに玉が発射される様子は圧巻でした。

さて、そんな月詠ですが目立つ部分のみで構成されていた訳ではありません。月詠を支える技術にはハードウェアやネットワークも含まれます。本記事はそんな部分についてザックリと触れていこうかと思います。

月詠を支えたローカルネットワーク

写真が展示されていた展示パネルの裏側ではノートパソコンが2台、常時起動していました。1台目のPC(以下PC1)はプロジェクタと接続され、そこではUnityで作成した投票ソフトが起動していました。一方で、もう1台のPC(以下PC2)では以下の3つのプログラムが常時起動されていました。

  • ①WebSocketサーバ+APIサーバ
  • ②MQTTサブスクライバ
  • ③シリアル経由で送られてきたArduinoからのデータを処理するスクリプト

各プログラムについて説明する前に、月詠のシステム図を以下に示します。

f:id:dendai_tarou:20161208123125p:plain

②、③に関しては後ほど説明します。図の通り、2台のPCはイーサネットケーブルを用いて相互に接続されLANが構築されています。ここで、PC2で建てられていたWebSocketサーバとPC1の投票ソフトはWebSocketを用いて常にコネクションが貼り続けられていました。つまり、投票ソフトはWebSocketクライアントになっていました。

どの様な流れで投票ソフトへ投票情報が送られていたかを以下に示します。

(1) 展示会場の投票ボタン、もしくは投票サイトの投票ボタンが押される
(2) ②及び③で投票情報を処理し、APIサーバへ投票情報を含めたリクエストを送信する。
(3) WebSocketサーバとAPIサーバは同スクリプト内にて記述されており、APIサーバに飛んできたリクエストから投票情報を取得し、WebSocketサーバとコネクションを貼っているクライアントに対して投票情報をブロードキャストする。
(4) 投票ソフトは送られてきた投票情報を元に、適切な写真へ玉を飛ばす。

以上が投票までの流れになります。APIサーバへは、投票された写真の番号をクエリパラメータにて指定し、GETリクエストを送信する事で投票情報を送信する様にしていました。
余談ですが、1000リクエスト/1sみたいな事をローカルで行ってもシステムはダウンすること無く正常に動いていましたが投票ソフトでは流石にフレームレートが落ち、玉が消えました。

②MQTTブローカ について

まず始めにMQTTについてですが、この場ではパブ・サブモデルを持つ軽量なプロトコルという説明に留めておきます。
今回はMQTTプロトコルの持つ利点を利用したというよりかは、外部ブローカサーバ(今回はMQTT as a Serviceのsangoの無料プランで運用しました)とサブスクライバがコネクションを張り続ける事でポートなどを開けずとも、外部からのメッセージを受けられるので採用しました。と、同時に以前paho-mqttというPythonのモジュールでMQTTを触った事があったのでその時に利用したスクリプトを再利用できるかもと思ったのも理由の一つです。

月詠は展示会場に設置されたスイッチからの投票の他、特設投票サイトからの投票にも対応していました。この投票サイトから投票された事を大学内部のPCに伝える方法としてMQTTは最適でした。投票サイトはPaaSのHeroku上に建っており、投票サイトがパブリッシャとなってサブスクライバへ情報を伝えていました。

sangoの無料プランでは、月間最大メッセージ数が10万件とホビーユースでは十二分なメッセージ数ですが同時接続数が10件までという制約があります。この部分に関して若干不安がありましたが、幸か不幸か本番では同時接続数が10を超える事はありませんでした。

③シリアル経由で送られてきたArduinoからのデータを処理するスクリプト について

展示会場の全てのボタンはArduinoに接続されていました。投票ボタンは長押し非対応であり、チャタリングをソフトウェア側で除去しました。チャタリング除去に関しては「Bounce2」というライブラリを用いて行った為非常に簡単に実装する事ができました。
また利用した投票ボタンは以下の物です。

LED付き押しボタンスイッチ(白・赤色LED) MP86A1W1H−G: パーツ一般 秋月電子通商 電子部品 ネット通販

このボタンが若干クセ者であり、LEDは付いているのですがLEDとスイッチ回路は完全に独立しており単純に接続するだけではスイッチを押した時にLEDが光るという回路は実現できません。そこでArduinoのdigitalReadが反応する最小の電流を考え、ディジタルピンとスイッチの間にLEDと抵抗を挟み回路を作成しました。

ArduinoとパソコンはUSBケーブルで接続されており、シリアル通信をしていますがPythonでシリアルポートを監視するためにPySerialモジュールを用いました。

さて、

長々と書きましたが、月詠のバックには以上の様なシステムが隠れていました。冗長構成等は考えず、多分動くだろみたいな感じでシステムを作りましたが旭祭の2日間特に何の問題も無く(?)動いてくれたので満足です。