Edited at
IBM CloudDay 12

Node-REDで動く段ボール製の人工知能ロボットTJBotを作る

More than 1 year has passed since last update.

今回は、Node-REDで動作する手作り段ボールロボットTJBotを組み立ててみます。以下の様にOpenCVで顔を認識すると手を振って反応してくれる動作をTJBotにさせてみます。

tjbot.png


TJBotとは

GitHub上でレーザカットや3Dプリンタ用のデータが公開されているロボットです。中にラズパイを載せて、接続したカメラ、LED、モータ等をNode-REDで制御できます。手軽に人工知能ロボットを作れるため、世界中で面白い開発例が公開されています。

tjbot2.png


TJBotでできること

TJBotは接続した部品によって、以下の機能を利用できます。


  • 右目のカメラで撮影する

    camera.jpg

    中に入っているカメラの画像を、画像認識APIへ投げることができます。

     


  • 頭のLEDを光らせる

    led.jpg

    赤や青など様々な色でLEDを光らせ、警告やロボットの感情を表すことができます。

     


  • 左手のモータを動かし手を振る

    wave.jpg

    サーボモータに接続した左手を前後に動かせます。

     


  • スピーカから音声を出す

    speaker.jpg

    後ろに積んだスピーカを使い、音声合成で作成した音声や、音楽ファイルを再生できます。

     


  • マイクから音声を拾う

    mic.png

    下側に接続したUSBマイクで拾った音声を、音声認識APIに渡すことができます。

     


  • Cognitive Services、Watson、OpenCVによる画像や音声の認識

    nodes.png

    TJBotの中身はラズパイであるため、Node-REDで扱える人工知能API、認識エンジン(OpenCV等)をノンプログラミングで動かすことができます。



組み立てで必要なもの

※組み立てで必要な道具、周辺機器


  • カッター

  • セロハンテープ

  • プラスの精密ドライバ

  • HDMIで接続できるディスプレイ

  • USB接続のマウス、キーボード

段ボールをレーザカッターで切断すると、以下の写真の様になります。プラモデルみたいでワクワクしますね!

IMG-1370.JPG


組み立て手順

レーザカットで切断した段ボールは、以下の動画を見て組み立ててください。

https://www.youtube.com/watch?v=bLt3Cf2Ui3o

assembly.jpg

組み立てのポイントは以下の通りです。


  • パーツを外す際は、切断箇所の表と裏をカッターで切ると綺麗に外せる。
    IMG-1485.JPG
     

  • 段ボールは一度折ると外側が破れ、反対方向に折り直しできないため、折る方向に注意する。
     

  • 段ボールの外側を破れにくくするため、折り目から1mm程度離れた部分を爪で潰す。
    cardboard_1.png
     

  • 段ボールが破れてしまった際や、上手く固定できない際は、セロハンテープで補強する。
    IMG-1512.JPG
     

  • 頭のパーツの中に中身のパーツが入らない時は、段ボールを折り返す部分を以下の通りカッターで切断する。
    IMG-1727.jpg
     

  • LEDは接続を間違えると焦げるので以下の様に正しい配線になるよう注意する(LEDの一番長い足がGNDです)。
    led_motor.jpg
     

  • サーボモータに腕を付ける際は、逆向きにならないように一度waveノードで動きを確認してからネジで固定する。


ラズパイのセットアップ手順

(1) ラズパイにRaspbianをインストール

PC上でマイクロSDカードをFAT32形式でフォーマットし、RaspbianのOSイメージを書き込みます。その後、マイクロSDカードをラズパイに差して起動し、OSをインストールします。

(2) カメラを有効にする

ラズパイ上でカメラを使えるように設定します。メニューの「設定」->「Raspberry Piの設定」を選択し「インターフェース」タブ内のカメラ設定を有効にします。

screenshot_settings.png

(3) 最新のNode-REDにアップデート

ラズパイのターミナル上で以下のコマンドを実行し、最新のNode-REDにアップデートします。

update-nodejs-and-nodered

本コマンドを実行すると、同時にnpmコマンドも使えるようになります。

(4) Node-REDのノードをインストール

以下のコマンドを実行し、カメラ撮影、音声再生、LEDやモータ制御などを行うノードをインストールします。

sudo apt-get update

sudo apt-get install libopencv-dev libasound2-dev git scons swig
sudo npm -g install git+https://github.com/jeancarl/node-red-contrib-tjbot
sudo npm --unsafe-perm -g install node-red-node-watson node-red-dashboard node-red-contrib-camerapi node-red-contrib-cognitive-services node-red-contrib-play-audio node-red-contrib-micropi node-red-node-pi-neopixel node-red-contrib-speakerpi node-red-contrib-opencv node-red-node-base64
git clone https://github.com/jgarff/rpi_ws281x.git
cd rpi_ws281x
scons
cd python
sudo python setup.py install

(5) Node-REDを再起動

以下のコマンドを実行してNode-REDの停止と開始を行います。

node-red-stop

node-red-start


顔を見つけると手を振るフローを作る

Node-REDはラズパイ端末のポート1880番で動作しており、http://<ラズパイのIPアドレス>:1880/へアクセスするとフローエディタへ入ることができます。Node-RED上で以下のフローを作成します。

flow.png

各ノードのプロパティ設定は以下の通りです。

(1) injectノード

Node-RED起動時に処理を開始するよう「Node-RED起動時に実行」のチェックボックスをオンにします。

inject.png

(2) Camera Piノード

ラズパイに接続したカメラで撮影を行います。撮影した画像を次のノードへバイナリデータとして渡すため、File Modeとして「Buffermode」を選択します。画像サイズは小さい方が処理が軽いため「320x240」を選択します。

camerapi.png

(3) OpenCVノード

OpenCVを用いてバイナリデータに対して画像認識を行います。ここでは認識対象を顔にするため、Detectのプルダウンメニューから「Face」を選択します。認識結果の出力形式を指定するOutputのプルダウンメニューは「JSON」を選択します。

opencv.png

画像認識が終った時に繰り返し次の画像を撮影と画像認識を行うため、OpenCVの出力端子はCamera Piの入力端子とワイヤーで接続されています。

(4) switchノード

OpenCVノードが画像認識結果として出力したJSONデータに顔の座標が含まれているか否かをSwitchノードを用いて判定します。画像に顔が含まれているとmsg.payloadの配列が1以上になるため、switchノードを用いてmsg.payload.0がnullでないかを判定します。

switch.png

(5) waveノード

最後にTJBotの左手を振るwaveノードを接続します。プロパティ設定では、動作としてMotionの「wave」を選択します。初めてTJBotノードを使う際は、Botの右側にある鉛筆マークをクリックし、TJBotノードの共通設定を登録します。

wave.png

今回はサーボモータを使うため、共通設定にてServoのチェックボックスをオンにします。

tjbotconfig.png

それでは、実際にTJBotを動かしてみます。写真なので伝わりにくいですが、TJBotを顔の正面に置きしばらく待つとジジッ、ジジッと手が動き挨拶してくれます。

waving_tjbot.png


最後に

TJBotを用いることで流行りの(?)Google Homeの様な、家電の制御や音楽再生などを行う端末も簡単に自作できます。例えば、以下のサイトには、TJBotの応用例が紹介されています。

https://github.com/johnwalicki/TJBot-Node-RED/blob/master/README.md

皆さんも様々な人工知能APIを上手に組み合わせて、ぜひ手作り人工知能ロボットを作ってみてください。

※今回作成したNode-REDのフロー

[{"id":"bad7df11.d4849","type":"tjbot-wave","z":"5c37695.9db9898","botId":"3d8dec20.5048b4","motion":"wave","name":"","x":570,"y":160,"wires":[]},{"id":"a9ea1147.86387","type":"switch","z":"5c37695.9db9898","name":"","property":"payload.0","propertyType":"msg","rules":[{"t":"nnull"}],"checkall":"true","outputs":1,"x":450,"y":160,"wires":[["bad7df11.d4849"]]},{"id":"2c15dd9e.b62742","type":"opencv","z":"5c37695.9db9898","detect":"FACE_CASCADE","output":"json","name":"","x":300,"y":160,"wires":[["a9ea1147.86387","b143102b.fcab7"]]},{"id":"b143102b.fcab7","type":"camerapi-takephoto","z":"5c37695.9db9898","filemode":"0","filename":"","filedefpath":"1","filepath":"","fileformat":"jpeg","resolution":"1","rotation":"0","fliph":"0","flipv":"0","brightness":"50","contrast":"0","sharpness":"0","imageeffect":"none","name":"","x":350,"y":60,"wires":[["2c15dd9e.b62742"]]},{"id":"aef3dd74.6f4c5","type":"inject","z":"5c37695.9db9898","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"x":130,"y":60,"wires":[["b143102b.fcab7"]]},{"id":"3d8dec20.5048b4","type":"tjbot-config","z":"","name":"","hasServo":true,"hasLED":true,"hasSpeaker":true,"hasMicrophone":true,"hasCamera":true,"speakerDeviceId":"plughw:0,0"}]

※ 引用した画像のソース

https://www.youtube.com/watch?v=8htZriltJuc

https://www.youtube.com/watch?v=uE8pvLttipU

https://www.youtube.com/watch?v=KU8DNzZNdBY

https://www.youtube.com/watch?v=Wvnh7ie3D6o

http://www.instructables.com/id/Build-TJ-Bot-Out-of-Cardboard/