見出し画像

Maker Faire Tokyo 2019での無線対策


Maker Faire Tokyo 2019では、AIカーでRCカーを走らせよう! コミュニティで、ブースを運営を手伝う予定です。

DonkeyCarは、RaspberryPi3ベースで、2.4GHz帯の無線を用いて、SSHでログインしてコマンドを実行します。また、DonkeyCarの車体の操作には、F710というWireless Joystickを用います。

抱えている問題

RaspberryPi3の2.4GHz帯WiFiと、F710のWireless通信がMaker Faire Tokyo 2019の会場では不安定になるため、この部分の対策が必要です。

2.4GHz帯WiFi問題の対策案

RaspberryPi3へのログインは、PCとDirectにEthernetで接続します。

画像1

Macユーザは、Bonjourがはいっているので、この方法で、Host名でDonkeyCarを発見できます。

ssh pi@donkeypi.local

Windowsユーザは、iTunesをインストールすると、Bonjourも一緒にインストールされ、DonkeyCarをHost名検索できるようです。

次に、DonkeyCarの起動時には、コマンドの最後に&をつけてプロセスをバックグランド起動すると、Ethernetケーブルを取り外しても、プロセスが残るので問題なく走行できるようになります。

python manage.py drive --js  &

プロセスを切るには、pkillコマンドを使うと楽にプロセスを落とせます。

pkill -f manage.py

F710のWireless通信の対策案

F710は、 Unifyingという独自のプロトコルで、USBドングルとJoystick間でネットワークを構築します。DonkeyCar界隈では、すぐ接続して、操作性もわるくないという事で、支持されているJoystickです。その一方で、Maker Faire Tokyoでは、F710が不安定になると思われます。これは、Unifyingのプロトコルの問題であり、対処方法が存在していない感じです。

そこで、今回は、プロポとプロポのレシーバーの先に、Arduino Microをつなぎ、Arduino MicroでHIDプロトコルを用いてF710をエミュレートするハードウェアを作成しました。

画像2

車体には、マジックテープで貼り付けます。

画像3

これでDonkeyCar本体は一切改造せずに、プロポから操作できるようになります。

画像4

プロポは、3ch以上に対応したプロポを選びます。左右、前後、学習済みモデルを呼び出すために用います。

機種名                          メーカー   プロトコル       チャンネル数     本体価格
T10J                           Futaba         T-FSHH           10ch                   38,000円
3PV                            Futaba         T-FSHH           3ch                     13,800円
エクスペックGT-I    Tamiya          FSHH               3ch                     12,800円
MX-6                         SANWA        FH-E                3ch                      11,800円

Arduino Microは、HIDに対応しているので、下記ライブラリを使用します。

Arduinoのスケッチは以下の通りです。

#include <Joystick.h>

#define NUM_BUTTON  32

#define PIN_X         0
#define PIN_Y         1
#define PIN_AI        2

#define BUTTON_ESTOP  1
#define BUTTON_ERASE  3
#define BUTTON_AI     9
#define BUTTON_MODE  10

Joystick_ Joystick = Joystick_(
 0x03,                    // reportid
 JOYSTICK_TYPE_GAMEPAD,   // type
 NUM_BUTTON,              // button count
 0,                       // hat switch count
 true, false, false,      // left x,y,z axis enable
 false, true, false,      // right x,y,zaxis enable
 false,                   // rudder enable
 false,                   // throttle enable
 false,                   // accelerator enable
 false,                   // brake enable
 false                    // steering enable
 );

byte PWM_PIN[5] = {A0, A1, A2, A3, A4};
int value[5] = {0,0,0,0,0};
int base[5] = {0,0,0,0,0};
boolean toggle_num[NUM_BUTTON];
int WIDTH = 410;
float joystick[5] = {0,0,0,0,0};

boolean DEBUG = true;
boolean SUCCESS = false;

void setup() {
 // Serial for DEBUG.
 Serial.begin(9600);
 
 // setup pin mode.
 pinMode(13, OUTPUT);
 pinMode(PWM_PIN[PIN_X], INPUT);
 pinMode(PWM_PIN[PIN_Y], INPUT);
 pinMode(PWM_PIN[PIN_AI], INPUT);

 delay(100);

 // Initialize joystick.
 Joystick.begin();
 Joystick.setXAxisRange(0, 100);
 Joystick.setRyAxisRange(0, 100);

 // Initialize button.
 for(int i = 0; i < NUM_BUTTON; i++) {
   Joystick.setButton(i, false);
   toggle_num[i] = false;
 }

 // Get base value.
 for(int i = 0; i < sizeof(PWM_PIN); i++) {
   base[i] = pulseIn(PWM_PIN[i], HIGH, 29412);
 }

 // Check servo signal.
 if(base[0] > 100) {
   digitalWrite(13, HIGH);
   SUCCESS = true;
 }
}

void loop() {

 for(int i = 0; i < sizeof(PWM_PIN); i++) {
   
   // Get pwm values.
   value[i] = pulseIn(PWM_PIN[i], HIGH, 29412);
   // Map for button
   if(i >= 2) {
     joystick[i] = map(value[i], long(base[i]), long(base[i] + WIDTH * 2), 0, 100);
   } 
   // Map for axis
   else {
    joystick[i] = map(value[i], long(base[i] - WIDTH), long(base[i] + WIDTH), 0, 100);
   }
   
   if(DEBUG) {
     Serial.print(joystick[i]);
     Serial.print(",");
   }
 }

 if(DEBUG) Serial.println();
 
 // F710 emulation.
 //
 // F710  Arduino Micro
 // XAxis XAxis
 // YAxis RyAxis
 //
 // F710  Arduino Micro
 // E-stop                    1
 // erase                     3
 // ai launcher               9
 // mode                     10
 // constant_throttle        11
 //

 if(SUCCESS) {
   // XAxis
   Joystick.setXAxis(joystick[PIN_X]);
   // YAxis
   Joystick.setRyAxis(joystick[PIN_Y]);
   // Button
   check_button(PIN_AI, BUTTON_MODE);
 }
}

void check_button(int pin_num, int button_num) {
 if(joystick[pin_num]>50){
   if(!toggle_num[button_num]) {
     toggle_num[button_num] = true;
     Joystick.pressButton(button_num);
   }
 } else {
   if(toggle_num[button_num]) {
     toggle_num[button_num] = false;
     Joystick.releaseButton(button_num);
   }
 }
}

PlanBの必要性

PlanAは用意できましたが、PlanBも案だけ考えています。2.4GHz帯がまったく使いものにならない場合、SubGHz帯に逃げるというプランもあります。これがPlanBです。

PlanBはLoRa Moduleを用いて通信します。SubGHz帯なので、2.4GHz帯で抱えている問題の根本的な解決につながります。

画像5

HSPの車体に付属しているプロポの通信関連基板をとりはずし、LoRa基板に取り替えます。これで、LoRaプロポのできあがり。

画像6

PlanC

PlanAもPlanBもだめな場合は、最終手段の有線接続です。F710もプロポもLoRaも諦めて、有線JoystickのF310で操作します。DonkeyCarを追いかけて人間も一緒に走り回らないといけないので、本当に最終手段です。

最後に

Maker Faire Tokyo 2019のAIカーでRCカーを走らせよう! ブースでは、日本中からAIカーに魅了されたフルスタックエンジニアが集結します。AIカートーナメントや子供 vs AI、JetBotデモ走行をおこなう予定です。皆様のご来場をお待ちしております。


この記事が気に入ったらサポートをしてみませんか?