単体動作
ROSなどのミドルウェア(MW)経由での動作も可能ですが、動作確認をするためには必要最小限のスクリプトを用意しておくと問題の切り分けが簡単になります。また、モータ部にある程度の自由のある制御が出来れば、各種の性能試験も可能になります。ここではゲームコントローラで前後・左右に移動させるスクリプトを記述します。
- 構成
- ゲームコントローラ
ロボに命令を与える手段として、ゲームコントローラを使います。BTタイプなので無線制御がお手軽に実現できます。 ロボの制御に使うゲームコントローラは気に入ったものを使えば良いと思いますが、RasPiのディストリによっては、そのゲームコントローラに使われているBTを認識できない場合があります。Web-Masterが試してみたコントローラは以下になります。一部使えないものがありました。全て購入して試したので、ヒトバシラーですね。念のために申し上げますが、動作を保証するものでありません。以下の条件で選択しました。
- スマホやタブレットが取り付けられるもの
今後はロボ側に様々なWebアプリを動作させます。その表示用としてスマホを使うのでスマホ取り付けを要件に入れました。
- アナログジョイスティックが並列しているもの
クローラの動作がしやすくなるので、並列タイプを選択しました。
- スマホやタブレットが取り付けられるもの
- 試したもの
Controller
RasPi
Note
3B, 3B+
良好。Trustをかけておくとそのまま使える。Pocket-PCとの組み合わせが可能なので、PCをコントローラとすればsshでのログインも含めてすべて制御が可能になります。
3B, 3B+
良好。Trustをかけておくとそのまま使える。タブレットとの組み合わせが可能なので、ロボット側のWebアプリを強化したケースには使いやすいと思います。
3B, 3B+
良好。Trustをかけておくとそのまま使える。振動機能もありますし、価格も手頃なので最初の一台に良いでしょう。
3B, 3B+
良好。Trustをかけておくとそのまま使える。非常に小型です。コントローラの大きさを優先する場合はこちらもおすすめです。
3B, 3B+
当初は問題なく接続できたが、しばらくぶりに使ってみるとアドバタイズしなくなって使えなくなってしまった。
3B
3B+では利用できず。
- python script
構成をpython scriptに実装します。ゲームコントローラの読み取りはevent-libraryを使います。以下にscriptを掲載します。ここではゲームコントローラのスティックの読み取り値(0-255)をそのまま逓倍して、最小値/最大値に収めてからGroovy-PIDの速度設定を行いモータを駆動します。事前の準備として、以下のライブラリをインストールします。
12pip install evdevpip install pyserial1234567891011121314151617181920212223242526272829303132333435363738394041424344454647import requestsfrom evdev import InputDevice, categorize, ecodesimport serialfrom time import sleepmotor_speedL = 0motor_speedR = 0#creates object gamepadgamepad = InputDevice('/dev/input/event0')#prints out device info at startprint(gamepad)ser = serial.Serial('/dev/ttyACM0', 57600, timeout=1)print (ser)#display codesfor event in gamepad.read_loop():#Buttonsif event.type == ecodes.EV_KEY:print(event)#Analog gamepadelif event.type == ecodes.EV_ABS:absevent = categorize(event)# print ecodes.bytype[absevent.event.type][absevent.event.code], absevent.event.valueif ecodes.bytype[absevent.event.type][absevent.event.code] == 'ABS_Y':jLeft = absevent.event.valuemotor_speedL = (jLeft - 128) * 8if (motor_speedL < -1023):motor_speedL = -1023elif ecodes.bytype[absevent.event.type][absevent.event.code] == 'ABS_RZ':jRight = absevent.event.valuemotor_speedR = -(jRight - 128) * 8if (motor_speedR > 1023):motor_speedR = 1023motorSpeed = ('s 2 %d %d\r\n' % (motor_speedL, motor_speedR))sleep(0.01)ser.write(motorSpeed)print (motorSpeed)print("End script")