Donkey Car操作を従来のジョイスティックを、RCカーのプロポでの操作をするための手順を、「その1 ハードウェア編」、「その2 ソフトウェア編」、そして「その3 セットアップ編」に分けて説明しましたが、今回はそのTIPS編を書いてみます。
その1 https://qiita.com/arigadget/items/2c465915b5fbde07196e
その2 https://qiita.com/arigadget/items/51bf75e19cd395ac9b2f
その3 https://qiita.com/arigadget/items/9396451d6837bbbed79d
エクスポーネンシャルカーブ
柏の葉のAIロボカーシンポジウムにて、スロットルをリニアではなく、エクスポーネンシャルカーブで変化させると操作しやすくなるとのプレゼンがありました。後日調べてみると、ボリューム(可変抵抗)のAカーブに相当するもので、エレキギターやベースのボリュームに使われていて、人間の耳の特性に合っているとのことで、ジョイスティック操作にも当てはまるので不思議な気がします。
紹介されたプロポ(Jumper T16)には、スロットル値を変える機能があるとのことですが、自分は中間にいるArduinoにそのカーブをエミュレーションさせました。以下のスケッチは、アナログポート2番に接続されたボリュームの値を読んで、カーブの曲がり具合を変更できるようにしています。
if(channel_length[1] > base_value[1]){
exponent = (float)analogRead(2);
if(exponent > 10.0) {
throttle_fvalue = fmap((float)throttle_range, (float)base_value[1], (float)THROTTLE_FORWARD_PWM, 0.0, 1.0);
throttle_evalue = (pow(exponent, throttle_fvalue)-1.0) / (double)(exponent - 1.0);
throttle_value = (int)(throttle_evalue * 32767.0);
} else { // forward linear line
throttle_value = map(throttle_range, base_value[1], THROTTLE_FORWARD_PWM, 0, MAX_VALUE16);
}
} else { // backward linear line
throttle_value = map(throttle_range, THROTTLE_REVERSE_PWM, base_value[1], MIN_VALUE16, 0);
}
ジョイスティックとRaspberry Piの構成においては、Donkey Car本体側を修正する方法を、mituhiromatuuraさんが以下に公開されており、自分も参考にさせていただきました。
DonkeyCar ジョイスティックのステアリングをエクスポネンシャル化
ニュートラル時のデータ未採取のご利益
PCINTによるハードウェア割込みを使った場合、PWMの幅の測定誤差が4μsと非常に精度がいいため、ニュートラルの時にThrottle値が0になります。
ジョイスティックだと、なかなかニュートラル値にならないため、ずっとデータを取り続けています。学習データを取り終わって、机まで運んでいる映像まで取っているようなこともあるある。
controller.pyにこんなコメントが。
def on_throttle_changes(self):
'''
turn on recording when non zero throttle in the user mode.
'''
if self.auto_record_on_throttle:
self.recording = (abs(self.throttle) > self.dead_zone and self.mode == 'user')
おわりに
プロポの記事はアドベントカレンダー始まる前に書いてしまい、ちょっとショボイ内容になってしましましたが、ぜひ最初の記事からお読みください。