自転車のホイールにお絵描きした

まえがき

なぜ作ったか

 私の通う大学には1年間かけてグループで何かを作る「プロジェクト」というものがあり、私は「自転車をスマートに!」というテーマのプロジェクトに参加しました。
 他のメンバーは、自転車にウインカーを付けたり、自動変速機(開発担当の記事へのリンク)を付けたり。私もそれらを手伝う予定だったのですが、急に思いついてしまったので残像ディスプレイというものを考案しました。残像ディスプレイと言うのは私が名付けたのですが、簡単に言うと、数十個のledの列が回転しながら点滅して残像で絵や文字を表示するものです。既にそのような製品は割とあるので、ご存知の方は多いかもしれません。

f:id:takumus:20161223234036j:plain

既にあるのになぜ作ったか

 既にある製品は、自転車のタイヤに絵を描画するためにsdカードなどのメディアを経由するものが多く、車輪を一時的に停止する必要があります。(後日調べたらbluetoothで転送するタイプの物がありました。まじで悔しいです)
 そこで、スマートフォンなどで描いた絵や文字をリアルタイムで転送する仕組みを取り入れたらもっと面白くなるのでは!と思い制作しました。

プロジェクト発表会での展示

お絵描き体験

www.youtube.com スローはこちら
 PCに表示したQRコードを読み取り、スマートフォンで描いた絵がタイヤに反映されているのがわかります。プロジェクト発表会は、それぞれのブースに見学者が見にくる形式なので、自分のスマホで描いた絵をタイヤに送信できるという体験をして貰うことにしました。

具体的な説明

写真

全体像です。 f:id:takumus:20161221142546p:plain ラズベリーパイとモバイルバッテリーが積んであります。 f:id:takumus:20161221142923j:plain シフトレジスタとLEDを付けた基板です。 f:id:takumus:20161221142910j:plain 半田頑張りました。 f:id:takumus:20161221142935j:plain 基板からのケーブルはラズベリーパイに刺せるようにしています。 f:id:takumus:20161223112515j:plain タイヤから外した全体像です。 f:id:takumus:20161223112600j:plain ※ケーブルの色が違いますが、写真を撮った時期が違うのです。

ハード面

 LED表示部分の基盤はシフトレジスタを大量に使用し、5本位の線で制御しています。またリードスイッチと磁石を組み合わせる事で回転数を取得し、LED点灯のタイミングを制御しているので、低速でも高速でも乱れる事なく表示ができます。
 ラズベリーパイにつながっているケーブルはリードスイッチとLED制御線のみで、開発においてはハード面よりもソフトウェア面の方が大変でした。

ソフトウェア面

 今回、展示用にQRコードを読み取ってもらい、ブラウザから絵が描けるという体験を実現させました。ブラウザからタイヤにデータを送るのに、そこそこ多くのレイヤーを挟んでいます。

お絵描きツールと、お絵かきサーバー

f:id:takumus:20161221154608p:plain  見学者にすぐ絵を描いてもらうためには、ブラウザという選択肢一択でした。canvasは直接触るのは大変なので、PIXI.jsを使ってお絵描きツールを作りました。このお絵かきツールは描いた線の座標情報をサーバーに送信する機能しかありません。座標情報は、node.jsで立てたhttpサーバーに送られ、そこから動画右下に置かれたPCに送られます。
 線を描くごとに(タッチリリース時に)データ送信をしているのですが、時々失敗するので一応送信ボタンもあります。ちなみにこのお絵かきツールの自転車のホイールイラストはスクリプトで描いています笑

 今回展示用という事でたくさんの人がQRコードを読み取り絵を描きます。しかしこの仕様だと、例えば体験を終えて部屋の外に出た後もそのURLから絵を送信する事ができてしまうので、いろいろと問題になります。 今回それらを徹底的に対策しました。
 QRコードで取得できるURLを、http://~~.com/?hogehogeこうしました。最後にハッシュ値を加えています。そして見学者が入れ替わるごとにハッシュ値を更新し、QRコードを再生成します。クライアントは送信時にこのハッシュ値をサーバーに送り照合します。サーバーはそのハッシュ値が最新のものでないと絵の受信を拒否する仕組みにしました。これで問題は解決です。 f:id:takumus:20161221155141p:plain

お絵かきデータの変換

 お絵描きサーバーから送られた座標データは動画右下に置かれたPCで残像ディスプレイ用データに変換されます。この変換ソフトはAS3で書き、AIRアプリケーションとして動作しています。変換には、やや重い処理が必要になるのでWorker(スレッド)を立てて処理しています。
 変換自体もサーバーでやりたかったのですが、時間がなかったので自分が得意なAS3で実装することになりました。それ以外にも色々な理由はありますが!
 変換されたデータはいよいよラズベリーパイへ送ります。ラズベリーパイはPCと同じネットワークにつながっているのでローカルネットワーク上でデータをやり取りしています。

LED制御

 PCが送信したデータはラズベリーパイ上で走るnode.jsサーバーが受信します。サーバーはchildprocessとしてC++で書いたled制御プログラムを走らせていて、受信したデータをchildprocessへ標準入力で渡します。
 C++で書いたled制御プログラムは、複数スレッドで構成されています。データ受信スレッド、回転数検知用スレッド、led点灯用スレッドが主なスレッドです。なので回転しながらスムーズにデータを受信したり、回転数にあわせてledを点灯する事ができます。回転数に合わせてledを制御する細かいロジックについて解説すると、とても長くなってしまうので省略させていただきます。最後に貼ったソースをご覧ください。

さいごに

ソース

github.com 終盤追い込みで開発したので、ソースや設計が汚いのと、階層がぐだぐだなので許してください。
一応少し大まかに階層を分けておくので、興味のある方はご覧ください。

ラズベリーパイ側のC++とnode.js部分

/server/src

PCで絵を変換する部分

/client

お絵描き用のWebページ部分

/web_client

お絵描き用のサーバー部分

/web_server

お礼

 ここまでお読みいただきありがとうございました。質問などございましたら、me(あっ)takumus.ioまたは@takumusまで。