ヘルニアクソ野郎エンジニアblog

~ヘルニアでHell near~

RaspberryPiで作る2足歩行ロボ「ApacheでCGIを使ってブラウザからpythonでサーボモーターを制御」

calendar

以前にもブラウザで操作できるRaspberryPiの2足歩行ロボットを作成しましたが、「webiopi」というWEBサーバーを使ったものでした。↓

 

これはこれで良いのですが、webiopiはラズパイ専用に用意されたモジュールであり、他に使える場面が無く導入も少し面倒だったり(極端に言えば無駄な知識になり得る)、更新も結構前で止まっているので、いつ使えなくか分かりません。

そういった事を加味し、今回はオープンソースのWEBサーバーで有名な「Apache」を導入し、CGIを使ってブラウザからpythonでサーボモーターを制御するRaspberryPi2足歩行ロボを作成いたしました。

当初は、pythonの簡易WEBサーバーであるhttp serverでの作成を考えておりましたが、jsからcgi(python)へデータをpostする際のタイムラグが無視できないレベルだったので、Apacheを使う事にしました。

webiopiからの変更点はApacheに変更しただけでなく、以下の改善点も追加いたしました。

・操作ボタンを押している間だけ歩行し、離すと止まる

今回はこのロボットの作成方法についてまとめようと思います。

 

スポンサーリンク

初めに

全体的な構成

おおまかな構成自体はwebiopi使用時とほとんど変わりはないので、過去記事のリンクを張っておきます。↓

 

プログラムからサーボモータを制御する一連の流れとしましては、

ブラウザ(html)→javascript→CGI(python)→PCA9685→サーボモーター

となります。

 

Apacheの導入と各種設定

インストール

それではまず、Apacheをインストールします。

Apacheがインストールされれば自動的にWEBサーバーが立ち上がるので、ラズパイからはローカルホスト(127.0.0.1)、他のデバイスからはラズパイのIPをブラウザで指定してやれば、デフォルトのApacheのWEBページが表示されます。

初期のルートディレクトリは、

/var/www/html/

になっていますので、その配下のindex.htmlを差し替えてやれば、WEBページを変更できます。

ちなみに、Apacheインストール後は、ラズパイの電源が投入された段階でWEBサーバーが立ち上がる仕様になっていますので、変更したい場合は別途設定の変更が必要です。また、ラズパイのIPは固定した方が便利ですが、その辺についての説明は今回割愛します。

CGIの設定

CGIを使ってpythonスクリプトを動作させるための設定を行います。

まず、CGIのシンボリックリンク(ショートカットのようなもの)を貼ります。

続いて、pythonでCGIが実効出来るように、.pyを追加します。

続いて、CGIのディレクトリ場所を指定します。

今回、ルートディレクトリ配下にファイル一式を格納しますので、上記のようにしています。変更前が/var/www/html/cgi-bin/なら、変更は不要です。

もちろん、他の任意の場所に指定する事も可能です。(その場合はルートディレクトリも変更する事をおすすめします。)

 

Apacheからi2cを制御するための設定

ハマりどころでした。。これをしなくとも、とりあえずCGIは動くのですが、例えばpythonスクリプトにPCA9685の専用ライブラリをインポートしていると「エラー500」のサーバーエラーを吐きます。つまり、i2cデバイスを制御するならば、以下のようなi2cにアクセスできる設定が必要になります。

これでApacheの導入と設定はひと段落なので、設定反映のためにApacheを再起動しておきます。

次は、ルートディレクトリに必要なファイルを作成していきます。

 

html,css,javascript,python

構成

図のように、ルートディレクトリの/var/www/html/配下に必要なファイルを作成していきます。

 

html

操作画面になります。jsからpythonへデータをpostする為に非同期通信が必要なので、Ajaxは必須です。

 

css

スタイリングしているだけですが、1つ重要な部分があります。body{}に記述しているwebkitです。

ここもハマりどころでしたが、というのも、今回後述するjsで「スマホでボタンを押している間イベント発火」としているのですが、そうするとボタンのtextが「コピーする」などのテキスト修正モードに入ってしまうのです。

ベタな解決方法として「user-select: none;」がありますが、これが効かない。。

調べた結果、どうもアンドロイド端末だと「webkit…」が必要になるみたいです。

 

javascript

少し長ったらしいですが、このjsに関してはほぼ同じ内容の事を過去記事でまとめていますので、そちらを参照ください。↓

 

追加になっている部分だけ説明しておきます。

ボタンを連続でタップした際に、同じ動作のイベント発火情報がCGIにpostされていたので、その際にサーボモーターが狂った動作を起こしていました。

これを回避する為に、jsからイベント発火のデータがpythonに送られた場合、一連のサーボモーターの動作が終了するまでは追加のイベント発火は受け付けないようにしました。

具体的には、イベントはmotor変数が「STOP」の場合(1度ボタンを上げた状態)でボタンを押すと発火するようになっているので、ボタンを上げても、CGIのpythonからの応答がない限りSTOPにはならないようにしました。

done(function(data) { でCGIからサーボモータのー動作終了の合図が返ってくるので、その時にchange_motor2関数を呼び出し、motor変数にSTOPを代入しています。

 

python

先頭にシェバンを記述しています。CGIなのでjsからこのファイルのURL宛てにpostされたデータがあれば、都度このファイルが実効されます。

postされてきたデータにあわせて歩く動作を決めています。各動作の終了時に、print()でjsに値を返しています。つまりこれがサーボモーターの動作が終了した合図になります。

 

完成

完成すると、こんな感じで動いてくれます。↓

この記事をシェアする

コメント

コメントはありません。

down コメントを残す