DonkeyCar シミュレータ／SDL2でゲームパッドを使う方法（macOS）

## 自動運転には興味があったが、、、

自動運転(ADAS: Advanced Driver-Assistance Systems)を業務的に調査していた時があって、本物のクルマ業界の取り組みとその進展の速さはすごいなと。振り返って、子どもたちの教育用、いつまでもライントレースでキコキコ走ってる場合じゃないよなぁと、ずっと思っていました。とは言えSLAMは重いとか大げさなことを考えてしまい、とりあえず棚上げに。

![Screen Shot 2021-03-02 at 23.55.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/c4cd11a4-a736-9347-976a-666c5723b191.png)

## Donkey Carに出会った

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/9d1751e7-7d2a-44d3-0d51-c66bc1bd8af5.png" width="360">

まだ調査中で、ど素人なのですが、、
Donkey Carというプロジェクトがあります。（もうひとつの注目はRumiCarです。AWS DeepRacerは、ガチ過ぎ？）
すでに4年ぐらい歴史があり、Qiitaにも、たくさん記事があります。

ラズパイとカメラを乗っけて、Pythonが走って、改造ラジコンカーが走る。

ホームページのタグラインは、こんな感じ。

**An opensource DIY self driving platform for small scale cars.
RC CAR  +  Raspberry Pi + Python (tornado, keras, tensorflow, opencv, ....)**

すべてPythonで書かれており、深層学習による画像認識で自動運転します。ラズパイとPythonという部分で、かなり興味を惹かれました。もちろん、オープンソースです。

<a href="https://github.com/autorope/donkeycar"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/autorope/donkeycar.png" width="460px"></a>

インプットされる情報は、目標とするラインが視界のどこにあるか、だけ。
まぁ、確かに考えてみれば、出力も結局の所、前進/後進の加速量、ステアリング角度のふたつだけ。

それにしても、リアルタイムで制御できるのは、すごいな。
https://www.donkeycar.com/examples

大きい1台は暴走気味ですが、小さな2台は追い越しの作法も学習して（？）、ちゃんと走ってます。右が進行方向、追い越し始めのシーンです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/55108f0a-e615-72c4-5c81-1a8c725463bf.png" width="480">


### シミュレーターもある

![donkeycarsim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/a5528762-7017-d405-2283-7f59e3f6bf32.gif)

Unityによるシミュレーター（Ubuntu / macOS / Windows用）もあり、手動で学習データを蓄積、自動走行できます。
（注意：このリンク、日本語翻訳のサイトになっていますが、内容が非常に古いです。）
https://coolerking.github.io/donkeycar_jpdocs/guide/simulator/

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/9341a82b-ffce-47a7-838a-6410b31297b8.png" width="320">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/9f3f92d4-ff58-f2d8-793c-9831e6255c25.png" width="320"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/58f25d6b-ab3b-90b0-9324-c8d5202c8165.png" width="320">

これだけでも、ゲームとしてちょっと楽しめるレベル。。。

と思ったら、なんとこれは、超初期のアルファバージョンv0.2aだった。逆によく動いたな!!

最新版は、11日前にリリースのv21.02.20だ。進化してる。ゲームパッドのアサインが前進／後進と左右ステアリングが同じジョイスティックにアサインされていて、良いような悪いような。きれいなコースがたくさん増えていました。
https://github.com/tawnkramer/gym-donkeycar/releases

![Screen Shot 2021-03-03 at 0.27.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5412/f3eeb799-747a-90ed-ba43-b0156d745056.png)


### ゲームパッド、あるいはジョイスティック（SDL用語）も使える
学習用に手動運転する際、キーボードで操作するとステアリング操作が0/100になってしまうので、いまいち。Linuxはゲームパッドを使えるようになっていてガイドもあるが、Mac用がない。

ようやく本題。

## MacのSDL2でゲームパッドを使う方法
Pygameでも使っている、SDL2のjoystickクラスを使っています。IDごとにキーマップを持っていて、切り替える機構があるのですね。知らなかった。Scratch/Pygameでゲームパッドを使えるようにした時に、ものによってマッピングが違うので困っていました。

### jstestを準備、ゲームパッドのIDを調べる

```
git clone --recursive https://github.com/Grumbel/sdl-jstest
cd sdl-jstest
mkdir build
cd build
cmake ..
make install

./sdl2-jstest -l

```

うまくsdl2-jstestツールをmakeできると、こんな反応が返ってきます。必要なのは、Joystick GUID:の`030000004c0500006802000000010000`の部分です。

```
Joystick Name:     'SHANWAN PS3 GamePad'
Joystick GUID:     030000004c0500006802000000010000
Joystick Number:    0
Number of Axes:     4
Number of Buttons: 19
Number of Hats:     0
Number of Balls:    0
GameControllerConfig:
  Name:    'PS3 Controller'
  Mapping: '030000004c0500006802000000010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,'
```

makeがうまく通らない場合、以下のものが足りないはずです。私の環境ではすべて入っていました。libsdl1.2-dev、libsdl2-dev、libncurses5-dev

sdlとsdl2をbrewインストールすると良いと思います。これは、結構いろいろなものを入れちゃうので、ラズパイなどササッと使える人は、そちらでツールのmakeをしたほうが良いかもしれません。Joystick GUIDを知りたいだけなので。

brewでPython3など入れ直されると厄介。なので、reinstallはオススメしません。

```
brew install sdl sdl2
```

### ゲットしたJoystick GUIDを環境変数にセット


```
export SDL_GAMECONTROLLERCONFIG="030000004c0500006802000000010000"
```

これで、シミュレーター使用時にゲームパッドが認識されて使用可能になりました。


### 再起動時も有効になるようにする

```
echo 'export SDL_GAMECONTROLLERCONFIG="030000004c0500006802000000010000"' >> ~/.bash_profile
```

Donkey Carの本体の方もこれから調べていこうと思っています。DIYの自動運転がこんなに盛り上がっていたとは。