ラズベリーパイ(Raspberry Pi Zero WH)でロボットをラジコン操作しよう

raspi-robot

前回の『ラズベリーパイ(Raspberry Pi Zero WH)でScratch ロボットと遊ぼう!』で紹介したロボットを、今度はPythonJavascriptで動かしてみたいと思います。

さらにロボットの前につけたカメラで、ロボットがみている風景を見ながら操作できるようにします。

WebIOPiMJPG-StreamerSVGを組み合わせて、スマホでラジコン操作に挑戦です。

準備するもの・配線方法

準備するもの配線方法は前回と同じなので、こちらの記事をみてください。

 

一つ追加になるのがこちらのカメラです。

 

 

写真にもありますが、透明のアクリルのケースホルダーがついていて、簡単にカメラを固定することができます。

このホルダーの組み立ては、こちらのYoutubeの動画を参考にしたら簡単でした。しかも、組み立て用のミニドライバーまでついているので驚きです。

画像・画質も十分ですし、ラズベリーパイ(Raspberry Pi Zero WH)に接続するコードも付属されています。

コスパ◎で、とってもおすすめです。

カメラを有効にする

まずは、ラズベリーパイのカメラの設定を有効にします。

raspi-configを起動します。

$ sudo raspi-config

 

[Interfaces Options] を選択します。

raspi-config

 

[Camera]を選択します。

raspi-config

 

enabled? で[はい] を選びます。

raspi-config

再起動します。

ちゃんとカメラが検出されているか、確認します。

vcgencmd get_camera

supported=1 detected=1

detectedが1であれば、カメラが検出されているのでOKということです。

このあと出てくるストリーミングの取得が、なかなかうまくいかなくて、試行錯誤している途中、ためしにこのコマンドでチェックしてみたら、「detected=0」になっていてびっくり!

いつの間にかケーブルが抜けてしまっていました。一つ一つのチェックが大切ですね。

 

操作画面

こちらのような操作画面を作りたいと思います。

Raspberry Pi Zero WHでロボット操作

右側のストリーミング画像を見ながら操作します。

[スクロールON]ボタンをクリックすると、スクロールON/OFFが切り替わります。

スクロールONの状態で、スマホで操作する際、アドレスバーを非表示にしたり、ズームで表示サイズを調整したりします。

左下の円にタッチしてロボットを操作をする場合は、スクロールOFFにして画面が動かないようにします。

 

画面を表示した最初の3秒間は、「前進」「後退」といったガイドの文字列を表示させます。

Raspberry Pi Zero WHでロボット操作

円の上の方をクリックすると前進、下の方をクリックすると後退します。

外側の色が濃い部分をクリックするとより速く動きます。左右も同様です。

 

そして、パソコンの大きな画面でもスマホの小さな画面でも操作できるように、レスポンシブ対応にしたいと思います。

どう実装するのか本やネットでみてみると、クリックしたX・Yの座標と図形の座標を比較して、どこをクリックしたか算出する方法が多く見つかりました。

レスポンシブ対応にするには、さらに表示幅によって拡大・縮小させ、座標を自分で設定しなおさなくてはいけないようです。

処理が難しそうですし、もっと画像をオブジェクトとして扱える簡単な方法はないのかいろいろ調べてみて、いちばん簡単そうなSVGを使うことにしました。

SVG

SVGとは(Scalable Vector Graphics)の略で、JPEGやPNGのような点々で表現した画像(ビットマップデータ)ではなく、点の座標とそれを結ぶ線を計算式で表したベクターデータです。

拡大・縮小すると計算しなおして描画するので、ギザギザにもなりませんし、レスポンシブ対応も簡単です。

外部の画像ファイルを読み込むこともできますし、HTMLの中にSVGを直接記述することもでき、さらにJavascriptで操作することもできます。

SVGのコマンド

例えば、円や四角を描画する場合、このようにSVGで記述します。

// 円を描画

<circle id="maru" cx = "100" cy = "100" r = "50" stroke = "black" fill = "#fff" stroke-width = "2" />

 

// 四角を描画

<rect id="shikaku" x="0" y="0" width="100" height="100" stroke="black" fill="#fff" stroke-width="1" />

 

そして、描いた図形をidで指定して、JQueryで処理を書くことができます。

$("#shikaku").click("処理");

 

SVGでコントローラー作成

このSVGで円のコントローラーを描いていきます。

このコントローラーは扇形を組み合わせて作っています。

例えば「前進」の部分は、3つの大きさの扇形を重ねて、3段階の速さを選択できるようにしました。

前進のコントローラー

SVGで扇形を描画

SVGで扇形を描く場合は、「パス描画」というコマンドで記述します。

M150 330 L44 224 A150 150 0 0 1 256 224 Z

SVGで扇形を描画

コマンドの意味を解説します。

① M(Move to) x y : 円の中心点の座標(150,330)移動します

② L(Line to) x y :座標(44,224)まで線を引きます

③ A(arc) rx ry x-axis-rotation large-arc-flag sweep-flag x y:指定したパラメータで円弧を描きます 

  rx:x軸の半径 (150)

  ry:y軸の半径 (150)

  x-axis-rotation:円弧の回転度 (0)

  large-arc-flag:中心角が180度以上なら1、未満なら0 (0)

  sweep-flag:時計回りで円弧を描く場合1、反時計回りなら0 (1)

  x y: 円弧を描き終える座標(256,224)

④ Z(Close path):最初の座標(150,330)まで線を引いて閉じます

円弧の座標を取得

ここで円弧を描き始める座標(L x yの部分)と描き終える座標(最後の x yの部分)を算出するために、三角関数を使います。

三角関数

描きたい扇形の角度の x' y' の座標を、次の式で求めることができます。

x' = cx + r * sin θ

y' = cy + r * cos θ

 

Javascriptで計算する場合、Math.sin(x)、Math.cos(x)を使用しますが、xには弧度法を指定します。

45°・60°といった度数法に、(π/180)を掛けて弧度法に変換します。

度数法を弧度法に変換

SVGコマンド取得Javascript

扇形の座標の計算方法が分かったので、前・後・左・右 各3サイズの扇形を描くコマンドをJavascriptで取得します。

このプログラムで取得した扇形を描くSVGコマンドをindex.htmlに埋め込んでいきます。

扇形を描くのにこちらのサイトを参考にさせていただきました。ありがとうございます。

SVGで円グラフを描く

三角関数と弧度法についてはこちらのサイトで分かりやすく解説されています。

三角関数の基礎知識。sinθ cosθ tanθ の覚え方・弧度法・三角比の表まとめ

 

MJPG-Streamer

次にカメラで撮影したストリーミング画像を画面に表示させたいと思います。

今回は、Raspberry Pi でよく使われているライブカメラ用ソフト「MJPG-Streamer」を使うことにしました。

MJPG-Streamerのインストール

ネット上にも、いろいろな方法が紹介されていますが、うまく起動してくれなかったり、思うようにPathが通せなかったりして、はまってしまいました。

結局、こちらのラズベリーパイのバイブル『Raspberry Piで学ぶ電子工作』に載ってる方法でインストールしたら、すんなり起動しました。やっぱりすごいです。

 

こちらの本は、ほんとにすばらしいです。初心者の人にもやさしく基礎から解説されていて、ラズベリーパイをさわる方は最初に読んだ方がいいと思います。

MJPG-Streamerのインストール

$ sudo apt-get update

$ sudo apt-get install libjpeg8-dev cmake

$ git clone https://github.com/jacksonliam/mjpg-streamer.git

$ cd mjpg-streamer/mjpg-streamer-experimental

$ make

$ cd

$ sudo mv mjpg-streamer/mjpg-streamer-experimental /opt/mjpg-streamer

MJPG-Streamerの起動

本の中では自動起動させるシェルが紹介されていますが、忘れてしまいそうなので少し変えた次のコマンドを手動で起動させています。

$ LD_LIBRARY_PATH=/opt/mjpg-streamer/ /opt/mjpg-streamer/mjpg_streamer -i "input_raspicam.so -fps 15 -q 50" -o "output_http.so -p 9000 -w /opt/mjpg-streamer/www"

オプションは、デフォルトから変更したいものだけを指定します。
-r 解像度 (def.640x480)
-f レームレート(def.5)
-q PEGのクオリティ(1-100)
-p ポート(def.8080)
-w wwwフォルダのパス

MJPG-Streamerの動作確認

http:/raspberrypi.local:9000/ にアクセスして、こちらの画面が表示されたら成功です!

MJPG-Streamer

 

「http:/raspberrypi.local:9000/?action=stream」で、モーションJPEG形式の動画を取り出せます。

Motion-JPEGとは、画像の圧縮方式であるJPEGを応用して動画データを生成する圧縮・記録方式のことである。圧縮されたJPEG画像を各コマに配置して、アニメーションのように再生する。

引用元:IT用語辞典バイナリ

 

プログラム

前回の「ラズベリーパイ(Raspberry Pi Zero WH)をスマホから操作する方法(WebIOPi)」と同じ要領でプログラムを作っていきます。

WebIOPiをベースに、SVGを使ってMotion-JPEGのストリーミングを取り込みます。

/home/pi/webiopi/test/に、以下のindex.htmlscript.pyを保存します。

index.html

パソコンからはクリックで、スマホからはタッチ操作で動かすようにしました。

処理内容の詳細は、コメントを見てください。

JavascriptやCSS(スタイルシート)などは、別のファイルにした方がいいのですが、ここでは内容を追いやすいように1つのファイルにまとめています。

script.py

前回とだいたい同じですが、Pythonのプログラムファイルです。

動作確認

WebIOPiとMJPG-Streamerを起動し、パソコンやスマホのブラウザからアクセスして動作を確認します。

$ sudo systemctl start webiopi

 

$ LD_LIBRARY_PATH=/opt/mjpg-streamer/ /opt/mjpg-streamer/mjpg_streamer -i "input_raspicam.so -fps 15 -q 50" -o "output_http.so -p 9000 -w /opt/mjpg-streamer/www"

 

パソコンからアクセス

パソコンのブラウザから http://raspberrypi.local:8000/test/ にアクセスして、操作画面が表示されればOKです。

Raspberry Pi Zero WHでロボット操作

スマホからアクセス

スマホからは名前解決ができないので、IPアドレスを調べて「http://192.168.0.xx:8000/test/」のようにアクセスします。

*ラズベリーパイ(Raspberry Pi Zero WH)のIPアドレスは、ターミナルで「ip addr show」と入力して確認します。

ラジコン操作している動画

スマホでラジコン操作している動画です。ロボットの視界を確認しながら操作しています。

 

まとめ

WebIOPi + MJPG-Streamer + SVG を組み合わせることで、簡単にスマホからロボットを操作することができました。

すごい技術がたくさんあって、ほんと楽しいですよね。

このロボットが3輪なこともあると思いますが、結構 操作が難しいですし、スマホでロボット視点のストリーミングを見ながら動かすのがとってもおもしろいです。

いろいろ拡張できると思いますので、さらに手を加えていきたいと思います。

Posted by ままあちゃん