Raspberry Pi でブラウザから操作できるラジコン戦車を作る! – WebIOPi から DC モーターを制御する –


■WebIOPi から DC モーターを制御する

Raspberry Pi で

・ブラウザから操作できるラジコン戦車

を作るシリーズ第五回目。

前回の段階で、ようやく

・Raspberry Pi で DC モーターを制御できるようにする

ということが実現できた。

しかしながら、このままだと、

・SSH で remote login してコマンドラインから操作

といった、パソコン経由での操作しかできない。
*というか、でないと難しい。

これでは、ラジコンというにはほど遠いものになってしまう。

よって、遠隔からより簡単に操作できるようにする必要がある。

これを実現するために、通常のラジコンであれば、

コントローラーが付属している。

が、これを一から作るのは大変だし、面倒。

ということで、ここでは、

・ブラウザからラジコン戦車を操作する

ということを目指している。

これであれば、スマホなどからも簡単に操作できる。

こういったことを実現するためには、

・遠隔から Raspberry Pi の GIPO を操作する

ということができないといけない。

これを実現してくれる方法の一つに、

WebIOPi というのが存在する。

よって今回は、

・WebIOPi から DC モーターを制御する

ということにチャレンジする。

手順は以下のとおり。

では、各々について記載していく。



■WebIOPi をインストールする

WebIOPi とはなんぞや?とか、

インストール方法については、

すでに

WebIOPi による遠隔操作(インストール編)

で述べている。

よってこちらを見ていただいてもよい。

ただ、root 権限での操作について記載していたり、

patch 当てを含めたスムーズなインストール方法には

なっていない部分もあるため、以下に再度整理しておく。

・WebIOPi のダウンロードと展開

まずは WebIOPi をダウンロードしてくる。

WebIOPi のダウンロードサイト
http://webiopi.trouch.com/DOWNLOADS.html

にアクセスし、以下の青枠部分をクリックして、

WebIOPi-0.7.1.tar.gz

をダウンロードする。

以下の通り、wget で取得してもよい。

pi@raspberry:~$ wget http://sourceforge.net/projects/webiopi/files/WebIOPi-0.7.1.tar.gz/download

続いて、取得した file を展開する。

ブラウザから tar.gz ファイルを取得した場合は、

pi@raspberry:~$ tar zxvf WebIOPi-0.7.1.tar.gz

で tar.gz ファイルを展開する。

wget で download というファイルを取得した場合は、

pi@raspberry:~$ tar zxvf download

で展開できる。

展開すると、

WebIOPi-0.7.1

というディレクトリが作成されるため、そこに移動する。

pi@raspberry:~$ cd ./WebIOPi-0.7.1/

これで、WebIOPi そのものはインストール可能な状態となる。

・Raspberry Pi 2/3 向けパッチの適用

このままインストールしてもよいのだが、

WebIOPi は 2018 年 4 月現在、

GPIO が 26 pin しかなかった、

初代の Raspberry Pi 向けの対応となっている。

このため、ダウンロードして即インストールすると、

40 ピンある Raspberry Pi 2 及び 3 では、

WebIOPi でコントロール出来ないピンが出来てしまう。

ということで、Raspberry Pi 2 及び 3 向けのパッチを適用する。

まずは wget コマンドで、以下の通り、パッチを取得する。

      pi@raspberry:~/WebIOPi-0.7.1$ wget https://raw.githubusercontent.com/neuralassembly/raspi2/master/webiopi-pi2bplus.patch

続いて patch コマンドで取得したパッチを当てる。

      pi@raspberry:~/WebIOPi-0.7.1$ sudo patch -p1 -i webiopi-pi2bplus.patch

これでパッチは適切に当てられるはずである。

・パッチ適用済み WebIOPi のインストール

パッチが当たれば、いよいよ WebIOPi をインストールしていく。

インストール自体は簡単で、

先ほど展開した WebIOPi-0.7.1 ディレクトリ直下にある、

setup.sh

を root 権限で実行すればよい。

具体的には以下の通り。

      pi@raspberry:~/WebIOPi-0.7.1$ sudo ./setup.sh

インストールが進むと、

      Do you want to access WebIOPi over Internet? [y/n]

と聞かれる。

今後遠隔操作を実現する際に、

y にして試してみたいが、今回は n を選択。

そうするとすぐにインストールが終わる。

この後、起動用のファイルを適切な位置に置く必要があるため、

まずは以下の通り wget で webiopi.service という

設定用ファイルを取得する。

      pi@raspberry:~/WebIOPi-0.7.1$ wget https://raw.githubusercontent.com/neuralassembly/raspi/master/webiopi.service

次に、取得したファイルを

/etc/systemd/system/

以下に移動させておく。

      pi@raspberry:~/WebIOPi-0.7.1$ mv webiopi.service /etc/systemd/system/

これでインストールは完了。

・WebIOPi の起動

インストールが完了すれば、次はいよいよ起動する。

以下のコマンドを実行することで、デバッグモードで起動出来る。

      pi@raspberry:~/WebIOPi-0.7.1$ sudo webiopi -d

その後、ブラウザを立ち上げ、URL 部分に

http://<IP address>:8000

を入力、実行する。

この際、以下の通りログインが要求される。

ログイン ID とパスワードは各々以下の通り。

ログイン ID : webiopi
パスワード : raspberry

無事ログイン出来れば、以下のような画面が現れる。

ここで、GPIO Header をクリックすると、

次のような画面になる。

この画面上で、IN を OUT にし、PIN をクリックすると、

該当 PIN に High が出力される。

このような形で、ブラウザからラズパイの GPIO を操作可能となる。

なお、ラジコンとして GPIO を操作するためには、

DC モーターを同時に操作する必要があるため、

この画面は使わない。

これに関しては、具体的な方法を後述する。

最後に、ラズベリーパイが起動すると同時に、

WebIOPi も自動的に起動するようにしておく。

具体的には、

      pi@raspberry:~$ sudo systemctl enable webiopi

を実行すればよい。

ちなみに、自動起動を解除したい場合は、

      pi@raspberry:~$ sudo systemctl disable webiopi

を実行すればよい。

これにより、WebIOPi が利用可能な状態になったはずである。



■操作用プログラムを作る

WebIOPi が起動できるようになれば、

お次は WebIOPi 経由で DC モーターを制御するための

python コードを作成する。

今回の場合、以下のようなコードを作成した。


	import webiopi
	import pigpio

	GPIO = webiopi.GPIO
	pi = pigpio.pi()

	# ラジコン戦車用パラメータ設定
	tank_left_f = 9
	tank_left_b = 11
	tank_right_f = 23
	tank_right_b = 22

	def setup():
	# ラジコン戦車用 GPIO ピン設定
	pi.set_mode(tank_right_f, pigpio.OUTPUT)  
	pi.set_mode(tank_right_b, pigpio.OUTPUT)  
	pi.set_mode(tank_left_f, pigpio.OUTPUT)  
	pi.set_mode(tank_left_b, pigpio.OUTPUT)  

	def loop():
	webiopi.sleep(0.5)

	# ラジコン戦車用マクロ関数
	@webiopi.macro
	def tfront():
	#前進
	pi.write(tank_right_f, 1)
	pi.write(tank_right_b, 0)
	pi.write(tank_left_f, 1)
	pi.write(tank_left_b, 0)
  
	@webiopi.macro
	def tback():
	#後退
	pi.write(tank_right_f, 0)
	pi.write(tank_right_b, 1)
	pi.write(tank_left_f, 0)
	pi.write(tank_left_b, 1)
  
	@webiopi.macro
	def tright():
	#右旋回
	pi.write(tank_right_f, 0)
	pi.write(tank_right_b, 1)
	pi.write(tank_left_f, 1)
	pi.write(tank_left_b, 0)
  
	@webiopi.macro
	def tleft():
	#左旋回
	pi.write(tank_right_f, 1)
	pi.write(tank_right_b, 0)
	pi.write(tank_left_f, 0)
	pi.write(tank_left_b, 1)
  
	@webiopi.macro
	def tstop():
	#停止
	pi.write(tank_right_f, 1)
	pi.write(tank_right_b, 1)
	pi.write(tank_left_f, 1)
	pi.write(tank_left_b, 1)
      

以下、先頭から順に解説していく。


	import webiopi
	import pigpio
      

GPIO を操作するための python ライブラリとして、

webiopi

pigpio

を使えるようにしている。

本来であれば、webiopi にある関数だけで

動かせるはず。

しかしながら、私の環境独自の問題なのか、

webiopi の関数を利用しても思った通りに

GPIO を操作することができなかった。

このため、代替策として、

pigpio

にある関数を利用して DC モーターの操作を実現する。


	GPIO = webiopi.GPIO
	pi = pigpio.pi()
      

この部分は、単に、

GPIO と書けば、webiopi.GPIO の略ですよ、

pi と書けば、pigpio.pi() の略ですよ、

ぐらいの認識でよいと思う。


	# ラジコン戦車用パラメータ設定
	tank_left_f = 9
	tank_left_b = 11
	tank_right_f = 23
	tank_right_b = 22
      

ここはパラメータ設定。

以下の処理において、GPIO ピンに対する

各種操作をしていくのだが、その際、

pin 番号を直接設定してしまうと、

・この pin 番号は何用の GPIO ピンだっけ?

となることが多々ある。

また、後々 pin を差し替えたりした場合、

コード中の該当 pin 番号をすべて書き換えねばならず、

バグの元にもなる。

よって、操作したい GPIO ピンの番号を

変数として宣言している、というのがこの部分。

変数名は好きに設定すればよく、

ここでは、該当する GPIO のピン番号を変数に格納している。

例えば、tank_left_f = 9 の部分は、

ラジコン戦車左車輪の前進に相当する DC モーター用信号を

制御するための GPIO ピン名を tank_left_f という

変数として宣言し、ピン番号である 9 という値を格納している

ということを意味している。

よって、もし当サイトとは異なる GPIO ピンを

利用している場合には、ここを自分が利用しているピン番号に

変更する必要があることにご注意頂きたい。

ちなみに、変数名の最後につけている、

f は forword で前進用、

b は back で後退用、

として宣言している。

次は、GPIO ピンの初期設定。


	def setup():
	# ラジコン戦車用 GPIO ピン設定
	pi.set_mode(tank_right_f, pigpio.OUTPUT)  
	pi.set_mode(tank_right_b, pigpio.OUTPUT)  
	pi.set_mode(tank_left_f, pigpio.OUTPUT)  
	pi.set_mode(tank_left_b, pigpio.OUTPUT)  
      

setup() 関数として、各ピンの設定を行う関数を宣言。

具体的には、左右車輪の前進、後退を制御するための

各ピンを、信号出力用ピンとして設定している。

次は何もしないときの処理。


	def loop():
	webiopi.sleep(0.5)
      

何も処理がないときは待つと言う処理をしているだけ。

で、いよいよ車輪の DC モーターを

制御するための関数部分。


	# ラジコン戦車用マクロ関数
	@webiopi.macro
	def tfront():
	#前進
	pi.write(tank_right_f, 1)
	pi.write(tank_right_b, 0)
	pi.write(tank_left_f, 1)
	pi.write(tank_left_b, 0)
      

ここでは、前進用の関数を定義している。

まず最初の、


	@webiopi.macro
      

で、WebIOPi を利用する際、ブラウザ(html)側から

呼び出せる関数であることを宣言する。

で、次の


	def tfront():
      

が関数名。

この名前で html 側から呼び出す。

その後は関数の処理内容。

ラジコン戦車を前進させるためには、

左右の車輪を同時に前転させる必要がある。

よって、pi.write() 関数で値を書き込むのだが、

tank_right_f, tank_left_f には 1 を、

tank_right_b, tank_left_b には 0 を、

各々書き込んでいる。


	@webiopi.macro
	def tback():
	#後退
	pi.write(tank_right_f, 0)
	pi.write(tank_right_b, 1)
	pi.write(tank_left_f, 0)
	pi.write(tank_left_b, 1)
      

後退の場合は前進と逆で、b 側を 1 に、

f 側を 0 に設定すればよい。


	@webiopi.macro
	def tright():
	#右旋回
	pi.write(tank_right_f, 0)
	pi.write(tank_right_b, 1)
	pi.write(tank_left_f, 1)
	pi.write(tank_left_b, 0)
      

右折させるためには、

・右側車輪を後退方向に
・左側車輪を前進方向に

各々回転させればよい。

よってそのような設定をしている。


	@webiopi.macro
	def tleft():
	#左旋回
	pi.write(tank_right_f, 1)
	pi.write(tank_right_b, 0)
	pi.write(tank_left_f, 0)
	pi.write(tank_left_b, 1)
      

左折は右折の逆。


	@webiopi.macro
	def tstop():
	#停止
	pi.write(tank_right_f, 1)
	pi.write(tank_right_b, 1)
	pi.write(tank_left_f, 1)
	pi.write(tank_left_b, 1)
      

停止させるには、全部に 1 を出力させてやればよい。

これでひとまず最低限の操作ができる

python コードが作成できたことになる。

この内容を、例えば

・Remote_Controller.py

とでもしてファイルに保存しておく。

なお、python はコードの各行におけるインデントとして、

Tab かスペースかのいずれか一方だけ

にする必要がある。

これが混じってしまうと、エラーとなって

WebIOPi も起動しなくなってしまうので注意が必要。



■操作用画面を作る

DC モーターを制御するためのプログラムが完成すれば、

次はブラウザから操作できるよう、

操作用画面を作成していく。

ここで作成する画面はこういったもの。

もちろん、自分の好きなデザインにして頂ければ結構。

ただ、私の場合、自分がイメージしていたのと

かなり近いものを、すでに作られていた方が居られたため、

かなりの部分で参考にさせていただいた。

1ban.yoka.to
http://1ban.yoka.to/?p=48

こちらでご提示頂いている html を参考に、

まずは以下のような html ソースを作成し、

index.html として保存する。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>
<title>Raspberry Pi ラジコン戦車コントローラー</title>
<script type=”text/javascript” src=”/webiopi.js”></script>
<script type=”text/javascript”>
webiopi().ready(function(){
var callBack = function(macro, args, response){
}
<!– 戦車操作用ボタン –>
var BtnTS = webiopi().createButton(“tank-s”, “停止”, function(){
webiopi().callMacro(“tstop”,[], callBack);
});
$(“#tank-s”).append(BtnTS);

var BtnTR = webiopi().createButton(“tank-r”, “右折”, function(){
webiopi().callMacro(“tright”,[], callBack);
});
$(“#tank-r”).append(BtnTR);

var BtnTL = webiopi().createButton(“tank-l”, “左折”, function(){
webiopi().callMacro(“tleft”,[], callBack);
});
$(“#tank-l”).append(BtnTL);

var BtnTF = webiopi().createButton(“tank-f”, “前進”, function(){
webiopi().callMacro(“tfront”,[], callBack);
});
$(“#tank-f”).append(BtnTF);

var BtnTB = webiopi().createButton(“tank-b”, “後退”, function(){
webiopi().callMacro(“tback”,[],callBack);
});
$(“#tank-b”).append(BtnTB);
webiopi().refreshGPIO(true);
});
</script>
<style type=”text/css”>
button {
display: block;
margin: 5px 5px 5px 5px;
width: 150px;
height: 100px;
font-size: 24pt;
font-weight: bold;
color: white;
}
</style>
</head>
<body>
<div align=”center”>
<table>
<tr>
<td>
<table border=0 cellspacing=”10″ cellpadding=”0″>
<tbody>
<tr>
<td>&nbsp;</td>
<td><div id=”tank-f”></div></td>
<td>&nbsp;</td>
</tr>
<tr>
<td><div id=”tank-l”></div></td>
<td><div id=”tank-s”></div></td>
<td><div id=”tank-r”></div></td>
</tr>
<tr>
<td>&nbsp;</td>
<td><div id=”tank-b”></div></td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
</div>
</body>
</html>

基本的にはそのまま張り付ければ動くと思う。



■動作を確認する

ここまで出来たら、後はファイルを設定して動作を確認するだけ。

まずは先ほど作った python コードと index.html を

格納するためのフォルダを作る。

正直何でもよいが、ここでは pi ユーザのホームディレクトリ以下に

iot というディレクトリを作り、さらにその下に

python/, html/ というディレクトリを作ることにする。

      pi@raspberry:~$ mkdir iot
      pi@raspberry:~$ mkdir iot/python
      pi@raspberry:~$ mkdir iot/html

続いて、先ほど作成した python コードである

Remote_Controller.py と、index.html を

各々作成したディレクトリに格納する。

      pi@raspberry:~$ mv Remote_Controller.py ./iot/python/
      pi@raspberry:~$ mv index.html ./iot/html/

最後に、WebIOPi がこれらのファイルを読み込めるよう、

WebIOPi の諸々設定ファイルである、

/etc/webiopi/config

に、必要なパスを書き込んでおく。

まず、/etc/webiopi/config をエディタ等で開く。

最初に、プログラムの位置を教えてあげるため、

25 行目の # を外し、以下のような形で path を設定する。

具体的には、

      [SCRIPTS]
      # Load custom scripts syntax :
      # name = sourcefile
      #   each sourcefile may have setup, loop and destroy functions and macros
      #myscript = /home/pi/webiopi/examples/scripts/macros/script.py

における myscript = の部分を

[SCRIPTS]
      # Load custom scripts syntax :
      # name = sourcefile
      #   each sourcefile may have setup, loop and destroy functions and macros
      myscript = /root/iot/python/Remote_Controller.py

と、# を外すとともに、さっき作ったプログラムへのパスに変える。

続いて、42 行目の

      # Use doc-root to change default HTML and resource files location
      #doc-root = /home/pi/webiopi/examples/scripts/macros

      # Use doc-root to change default HTML and resource files location
      doc-root = /home/pi/iot/html

と、こちらも # を外すとともに、今度は html ディレクトリへのパスに変える。

これで、設定自体は完了。

よって起動して動作を確認したいのだが、

この際に注意して欲しいのは、python コードで

pigpio を利用していること。

これを利用するためには、

pigpiod

が起動している必要がある。

よって、まずは以下の通り pigpiod を起動させる。

      pi@raspberry:~$ sudo pigpiod

なお、pigpiod は raspberry pi を起動させる度に、

毎回起動させないといけない。

これはラズパイ戦車として動かす上で、

かなり致命的な障壁になってしまうので、

root 権限で /etc/rc.local を編集し、

最終行の exit0 の前に、

pigpiod

と一行記載しておく必要がある。

その後、WebIOPi を、

先ほど変更した設定ファイルを読み込む形

で起動する。

      pi@raspberry:~$ sudo webiopi -d -c /etc/webiopi/config

-d はデバッグモードでの起動を、

-c はその後に続くファイルを設定ファイルとして読み込む、という指定。

この際、先ほど起動していた WebIOPi が起動したままだと、

      pi@raspberry:~$ sudo webiopi -d -c /etc/webiopi/config
      OSError: [Errno 98] Address already in use

というエラーがでるため、

      pi@raspberry:~$ sudo /etc/init.d/webiopi stop

等で一旦 WebIOPi を停止した上で、再度起動すればよい。

この辺の操作手順がややこしければ、

・設定ファイルの記載を上述の通り終える
・WebIOPi の自動起動設定をしておく
・/etc/rc.local に pigpiod を記載しておく

という作業をやった上で、reboot するのが早いと思う。

で、reboot 後に

http://<IP address>:8000

にアクセスし、

ID : webiopi
PW : raspberry

としてログインした結果、最初に示した画面が出てくれば、

まずは WebIOPi の自動起動や python コードの

構文エラーは出ていないということになる。
*python にエラーがあると WebIOPi は起動に失敗するので。

その後、

【モバイルバッテリーの電源を入れた後で】

画面上のボタンを押してみて、

意図どおりにモーターが動けば OK。

この時、モーターの回転方向までは分かりにくいが、

これはギアボックスに組み込んで車輪をつければわかるので、

この段階では、

・ボタンを押せばモーターが動く、止まる

という動作をしていることが確認できれば OK だろう。



■まとめ

前回の、

・Raspberry Pi から DC モーターを制御する

に加え、今回は WebIOPi を利用することで、

・ブラウザから DC モーターを制御する

ということが出来るようになる。

ここまで出来れば、ラジコン戦車は完成したに等しい。

ということで、ひとまずここまでの作業をまとめておく。

ここまでの Point!・WebIOPi をインストールしよう!
・操作用の python コードと操作用画面の html を作成しよう!
・WebIOPi の設定ファイルに、作ったコードと html の在り処を指定しよう!
・pigpiod の自動起動設定も忘れずに!
・全部できたら、reboot して動作を確認しよう!

なお、今回はブラウザから操作するために、

・WebIOPi

という既存のフレームワークを利用した。

しかしながら、ブラウザから操作するだけであれば、

・ラジコン戦車本体上で Web サーバーを立ち上げる
・php を動かせるようにしておく
・exec() 等でラジコン戦車本体のラズパイを操作する

という形にすることで、WebIOPi を使わずとも、

ブラウザから DC モーターを制御出来ると思われる。

この方法に関しては、今後余裕があればチャレンジしてみたい。

さて、次回以降はいよいよ車体を作っていき、

ラジコン戦車の完成形に近づけていきたいと思う。




Copyright (c) 2017 Webmaster of this site All Rights Reserved.
カテゴリー: ラズパイで電子工作 タグ: , パーマリンク

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください