#はじめに
Donkey Car を学習走行させる方法はブラウザ経由またはゲームコントローラーから操縦する方法が用意されています。
しかし、普通のラジコンの操作に慣れている人の場合、これらの方法は操縦しにくいので、プロポで操作したくなります。
受信機からの一般的な信号であるPWM信号を読み取る方法もありますが、ここではFutaba受信機のS.BUS信号を読み取る方法を紹介します。
PWM信号の読み取りはチャンネル毎に配線が必要ですが、S.BUSは配線が一組で済むというメリットがあります。(一方、S.BUS対応受信機しか使えないというデメリットがあります。)
#方針
S.BUSは信号レベルが反転した100kbpsのUARTです。反転回路さえあれば、シリアル入力から読み取れます。
vJoySerialFeederを使うと、S.BUS信号を仮想ジョイスティックデバイスとして見えるようにすることができます。今回はこれを使用します。
#ハードウェア
UARTはRaspberry PiのUARTを利用しようと思いましたが、なぜか失敗したので、USBシリアル変換モジュールを使います。
私は入手性から FT234X 超小型USBシリアル変換モジュール を使いました。
反転回路はトランジスタを用いた回路を組んでみたのですが、実はFT234Xには反転回路が搭載されているので、これを使います。Windows上でFT_PROGというアプリを使って、反転回路を有効にします。
反転回路の有効化
この作業だけ Windows PC が必要です。
FTDIのサイト から FT_PROG をダウンロードします。
インストールはNextボタンなどを数クリックするだけです。
Windows PC に FT234X を接続し、FT_PROGを起動します。
DEVICE -> Scan and Parse
をすると Device Tree に一覧が表示されます。
このツリーから Invert RS232 Signals
を選択し、右ペインの Invert RXD
のチェックボックスをONにします。
DEVICE -> Program
で設定を書き込みます。
下記ダイアログで Program
クリック
以上で反転回路の有効化が完了です。
##配線
外付けの反転回路が不要になったので、配線は簡単です。
受信機 | 色 | FT234X |
---|---|---|
+5V | 赤 | +5V |
GND | 黒 | GND |
- | - | TxD |
Signal | 白 | RxD |
受信機側のコネクタは、ラジコンショップなどで入手できるサーボ延長ケーブルを流用するといいでしょう。
電子工作的な作業はこれだけです。
受信機との接続のしかたは、受信機依存です。典型的な受信機では、S.BUSを有効にすると、一番最後のチャンネルがS.BUS出力になるようです。S.BUS専用コネクタが存在する受信機もあるようです。
USBケーブルは、Type A側(Raspberry Pi側)がL字になっているものを使うといいでしょう。(ストレートコネクタだと、前に出すぎてカメラに映りこんでしまいます。)
#vJoySerialFeederのインストール
vJoySerialFeederはC#で書かれたGUIアプリです。そのため、先だって Mono環境(.NET Framework互換環境)と、PIXEL環境(RaspbianのDesktop環境)のインストールが必要です。
##Mono環境のインストール
Monoのダウンロードページ を見て mono-complete
パッケージをインストールしてください。
一応、簡単に解説すると、パッケージリポジトリの追加をして、apt install するだけです。
パッケージリポジトリの追加
Raspbian buster の場合は
sudo apt install apt-transport-https dirmngr gnupg ca-certificates
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb https://download.mono-project.com/repo/debian stable-raspbianbuster main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list
sudo apt update
Raspbian stretch の場合は
sudo apt install apt-transport-https dirmngr gnupg ca-certificates
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb https://download.mono-project.com/repo/debian stable-raspbianstretch main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list
sudo apt update
で、その後、
sudo apt install mono-complete
です。
(パッケージてんこ盛りで10分ぐらいかかります・・・)
##PIXEL環境のインストール
PIXEL環境をapt install します。
sudo apt install raspberrypi-ui-mods
(これもパッケージてんこ盛りで10分ぐらいかかります・・・)
sudo raspi-config
で、
- 起動時にCLIでなくGUIが立ち上がるようにする
- VNC Server の有効化
も行いましょう。
メニューの場所は、それぞれ
- 3 Boot Options -> B1 Desktop / CLI -> B4 Desktop Autologin
- 5 Interfacing Options -> P3 VNC
です。
(またまたVNC関連パッケージのインストールで10分ぐらいかかります・・・)
VNCサーバーはラズパイに直接ディスプレイ・キーボードを接続して操作するなら不要ですが、まあ、リモートでつないだ方が楽ですよね?
VNCクライアントは何でもいいのですが、自分は Real VNC を使用しています。
##vJoySerialFeeder本体のインストール
https://github.com/Cleric-K/vJoySerialFeeder/releases から、vJoySerialFeeder_Linux_v1.5.zip をダウンロードして展開するだけです。
展開先は適当にお願いします。
##デバイスパーミッションの設定
シリアルポートをpi
ユーザーから使えるようにするため、次のコマンドを実行します。
sudo gpasswd -a pi dialout
/dev/uinput
をpi
ユーザーから使えるようにするため、uinput
グループを用意して適切に設定します。
uinput
グループの作成と pi
ユーザーのグループへの追加
sudo groupadd -f uinput
sudo gpasswd -a pi uinput
/dev/uinput
をuinput
グループから使えるようにするには、/etc/udev/rules.d/99-input.rules
ファイルを作って次の内容を書き込みます。
SUBSYSTEM=="misc", KERNEL=="uinput", MODE="0660", GROUP="uinput"
これでいいはずなんですが、手元のRaspbian buster 環境ではうまくいきませんでした。
いろいろ試行錯誤してみたところ、/etc/modules
の最後に uinput
を追記したらうまくいきました。
ここで再起動しましょう。
(パーミッションの設定が面倒とかうまくいかない場合は、後で出てくる mono vJoySerialFeeder.exe
の起動を sudo
でやっちゃいましょう。)
##vJoySerialFeederの設定
vJoySerialFeeder を
mono vJoySerialFeeder.exe
で起動します。あ、VNCで接続して、Terminalを開いたうえで起動してください。
(sshセッションから起動するとディスプレイが見つからない旨のエラーが出ます)
Cannot open assembly 'vJoySerialFeeder.exe': No such file or directory.
というエラーが出る場合は、vJoySerialFeederの展開先ディレクトリにcd
するか、引数にパスを含めて起動しましょう。
起動したら、Protocol
で SBUS を選択、 Port
で ttyUSB0 を選択し、Connect
をクリックします。
libevdev_uinput_create_from_device() failed
っていうエラーが出る場合は、/dev/uinput
のパーミッションの設定がミスってます。
Port
に ttyUSB0 が無い場合は・・・、接続してないですね。っていうか接続してくださいという話をし忘れてますね。
先に作ったUSBシリアル変換ケーブルをラズパイに差して、反対側はラジコン受信機に接続してください。
Refresh
ボタンをクリックすると、ttyUSB0が選べるようになると思います。
Connectできたら、Add Axis
を2回クリックしてください。
正しく接続できていれば、 Input が 1500前後、Output が 50%前後の表示になります。
送信機のステアリングを操作すると、Input Output がそれぞれ変化します。
反応が無い場合は、次の項目を確認してみてください。
- 配線は間違っていないか
- USBシリアルの反転設定がされているか
- 送信機の電源は入っているか
- 送信機と受信機のバインド(ペアリング)がされているか
- 受信機をSBUSモードにしているか
- 3ピンコネクタがSBUS出力のところに接続されているか
次に、各チャンネルの詳細設定をしてまいります。
なんでYじゃなくてRyなのかというと、他のジョイスティックでの設定と同じにするためです。
それぞれのチャンネルのキャリブレーションをします。
- の
Setup
をクリックします。
Calibrate
をクリックします。
ここでCenter(ニュートラル)が決まります。
次に、Next
をクリックします。
左右のエンドポイントを決めるところです。
一旦、グラフが平たんになります。
送信機のステアリングを左右目いっぱいそれぞれ操作してください。
グラフがまた右上がりになると思います。
その状態で Done
をクリックしてキャリブレーション完了です。
Ch2(スロットル)も同様にキャリブレーションしましょう。
お好みで、Deadband
や Expo
も設定してみましょう。
スロットルのDeadband
を 1~2%程度にするのがオススメです。学習走行時に、余計な記録がされないようになります。
Expo
はエクスポーネンシャルカーブの話なんですが、ここでの説明は割愛します。(各自おググり下さいませ)
あと、スロットルは Invert
のチェックボックスをOnにしてください。
Invert
は、操作方向を逆転するものです。正負の方向の解釈がプロポメーカーによってイロイロなのですが、ここではS.BUS互換、つまりフタバ互換が前提なので、スロットルだけ逆転するのが正解です。(万が一前進後進が逆とか、左右が逆などの現象が出たら、反転してみてください。)
設定が完了したら、Profile
のところに適当な名前を入力し、Save
をクリックしましょう。次回のvJoySerialFeeder起動時は、最後に使用したプロファイルが読み込まれます。
#Donkey Car から vJoySerialFeeder を使う設定
項目を立てましたが、vJoySerialFeederの設定をジョイスティック互換になるようにしたので、特に myconfig.py
などの編集は不要です。おそらくどのジョイスティック設定でも使えると思いますが、私は CONTROLLER_TYPE='F710'
としています。
他のジョイスティックが既に存在すると /dev/input/js0
がすでに出来上がってて、vJoySerialFeeder が /dev/input/js1
などになってしまうので、 ジョイスティックを外した状態で vJoySerialFeeder を起動しましょう。
念のため、js1が存在しないことを確認してください。
$ ls /dev/input
event0 js0 mice
更に念のため、送信機を操作すると js0 にデータが出力されることを確認しましょう。
$ hexdump /dev/input/js0
0000000 93da 0032 0000 0081 93da 0032 0000 0181
0000010 93da 0032 0000 0281 93da 0032 0000 0381
0000020 93da 0032 0000 0481 93da 0032 0000 0581
0000030 93da 0032 0000 0681 93da 0032 0000 0781
...
あとは、いつものように
cd ~/mycar
python manage.py drive --js
で学習走行させてみましょう!
次回走行時は、mono vJoySerialFeeder.exe
で起動することと、Connect
ボタンをクリックすることが必要です。
#おわりに
USBシリアル変換チップと、vJoySerialFeeder を用いて、S.BUS受信機を仮想ジョイスティックに見せる方法を紹介しました。
vJoySerialFeeder はmonoとGUI環境を必要とし、大げさなことと、OS再起動後にアプリの起動とConnectのクリックが必要なので、もうちょっと軽いドライバがあるといいなと思います。(だれか作ってー!)
追記:vJoySerialFeeder を使わない方法について書きました → Donkey Car をS.BUS対応ラジコン受信機経由で操作する ~controller.py 改造版~