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

~ヘルニアでHell near~

Bluetoothリモコンでロボット操作「PS3のジョイコントローラーでRaspberry Piを制御」python

calendar

前回、PS3のBluetoothジョイコンをRaspberry Pi にペアリングする方法についてまとめました。

今回は、ジョイコンのBluetooth信号を受け取り、サーボモーターを駆動させてロボットを操作するプログラムを作りたいと思います。

ロボットにつきましては、過去記事でまとめましたものをベースに使いたいと思います。↓

 

動作の流れとしては、

python(raspberry pi)→i2c→pca9685→サーボモーター

となります。

ブラウザで制御する時よりもプログラムの数がはるかに少ないので(1つでOk)、その面ではスマートで良いなと思いました。

はじめに、ハマった所をまとめておこうと思います。

 

 

スポンサーリンク

ボタンの入力待ちが発生するのでwhileでボタン長押し判定ができない

threadで改善

ボタン入力の値受け取りをループで回せば、下のような例で ボタン長押し判定が 可能です。

while True:

 if a == fw:

  while a == fw:

   サーボ駆動のプログラム

   a = ボタン入力を受け取るプログラム

 elif….

 a = ボタン入力を受け取るプログラム

 

しかし、厄介な事にボタン入力を受け取るプログラムの時に「待ち」が発生してしまうようで、 連続した動作が出来ないようになっていました。

これを解決してくれたのが「threading」のライブラリでした。

threadingは、名前の通り並列処理が可能になりますので、つまり「ボタン入力用のループ」と「サーボ駆動用のループ」を同時に走らせる事が出来ます。

したがって、ボタン入力の待ちが発生しようが、一度ボタンの値をglobalの変数に格納してしまえば、それの通りにサーボ駆動用のループで動き続けてくれます。

 

 

入力値について

各ボタンの入力値は下記サイトに詳しく乗っています。↓

ラズパイでラジコン(3):Pythonでdualshock3の入力を読み取る

しかし、ボタンを表す識別「num」の値が、私の場合は異なりました。理由は分かりませんが、一概にみんな上記サイトと同じ値にはならないかもしれません。

自分で調べて、値を確認する事が重要です。

 

 

プログラム

python

/dev/input/js0 にボタンの入力値が入ります。device.read(EVENT_SIZE で入力された値を読み取り、struct.unpack(EVENT_FORMAT, event) で各変数に値の種別ごとに割り振って格納しています。

後は前途した通り、上段のループでボタン入力値を受け取り、下段のループでは上段のループで得た値を利用してサーボモーターを駆動させています。

threading.Threadの引数、target=〇〇のように、〇〇の部分に関数を埋め込んでやれば、それが並列処理されます。

 

 

動作確認

とりあえず十字キーだけですが、うまく動いてくれました。

近いうちに、アナログコントローラーでメカナムホイール操作もやってみようかと思います。