Edited at

ミニドローン Parrot MAMBO を Node.js で飛ばす(Windows 編)

More than 1 year has passed since last update.


目的

Node.js (JavaScript) でドローン(Parrot のミニドローン)を飛ばします。

既に Mac による例Raspberry Pi による例を拝見していたので、Windows でもやってみました。Windows では他の環境に比べて少しトリッキーでしたので、自分のメモの意味も含め、まとめておきます。


環境・機材


ハードウェア


ソフトウェア


環境構築


Node.js のインストール


  • 通常どおりインストーラでインストール


    • 私は C:\nodejs にインストールしました




windows-build-tools のインストール



  • 各種の Node モジュールを Windows ネイティブでコンパイルするための環境一式で、以下を一括でインストール・各種設定できます(こちらをご参考)。なお、既に VisualStudio 、C++ Build Tools、Python がインストールされている環境でも「conflict-free」だそうです。


    • Visual C++ Build Tools 2015

    • Python 2.7.11


      • C:\Users\(ユーザ名)\.windows-build-tools\python27 にインストールされる





  • コマンドプロンプト(cmd.exe)を「管理者として実行」して、以下のコマンドを実行


npm install --global windows-build-tools


  • インストールが終わるまで気長に待ちます


node-rolling-spider のインストール


  • Parrot のミニドローンと Bluetooth でやりとりできるモジュールです

  • これからアプリケーションを作るフォルダを適当に作成


    • 例 C:\Users\(ユーザ名)\drone



  • コマンドプロンプトでそのフォルダに移動

  • 以下のコマンドを実行

npm install rolling-spider


  • 黄色い文字で「WARN」がいくつか出てくると思いますが、たいてい大丈夫です

  • 赤い文字で「ERROR」の場合はネイティブコンパイル等に失敗しているので、windows-build-tools をインストールし直したり、エラーメッセージをもとに試行錯誤してください


Bluetooth アダプタの設定


  • Bluetooth アダプタをパソコンの USB ポートにさします


    • Windows 10 の場合、普通に使う場合はドライバ不要(自動インストール)だそうです(させば、デバイスマネージャーで Bluetooth デバイスとして認識されます)が…



  • 上記 node-rolling-spider が依存している node-bluetooth-hci-socket というモジュールを通じて使う場合は、「WinUSB」というドライバに書き換える必要があります(こちらに記載)。

  • Zadig というドライバ書き換えツールをこちらからダウンロードします

  • zadig-2.3.exe をダブルクリックで実行します

  • Options メニュー -> List All Devices を選択するとデバイスの一覧が出ます

zadig.PNG


  • デバイスの一覧から Bluetooth アダプタ(今回の場合は「CSR8510 A10」)を選ぶと、左側に現在のドライバが出ます(私の場合は以前に東芝のスタックを入れていたので tosrfusb と表示されています)

  • これを「WinUSB」に書き換えるため、「Replace Driver」をクリックします

zadig2.PNG


  • 「The driver was installed successfully.」と出れば成功です。

zadig3.PNG


  • するとこれまで「デバイスマネージャー」で「Bluetooth」として認識されていたアダプタが、「ユニバーサル シリアル バス デバイス」として認識されるようになります。こうなれば OK です。

※ Bluetooth アダプタのドライバを元に戻す方法は後述します


ようやく飛ばします

既に標準のスマホ/タブレットアプリを使って当該ドローンの操作はひととおり理解していることを前提とします。

以下のコードは rolling-spider モジュール内の eg フォルダにある「keyboard.js」をベースにして、モジュールのサイトを参考に書き換えつつ、コメントを加えています。間違いがあればコメントいただけましたら幸いです。


コーディング

以下のコードをテキストエディタで入力し、さきほど rolling-spider をインストールしたフォルダ(例 C:\(ユーザ名)\drone)内に「app.js」として保存します。


app.js

'use strict';                             // 厳格モードにする

// モジュールの読み込み
const Drone = require('rolling-spider'); // rolling-spider モジュールを使う
const keypress = require('keypress'); // キーボード操作を取得する keypress モジュールを使う(rolling-spider と同時にインストールされる)

// 変数の設定
let ACTIVE = true; // ドローンがアクティブ状態か否か
const STEPS = 2; // 一度のキー操作で命令を出す回数(動かすステップ数、0-100)

// rolling-spider のインスタンスを作る
const d = new Drone();
// ドローンの初期設定
d.connect( () => { // BLE でドローンに接続し、接続できたらコールバック
d.setup( () => { // ドローンを初期設定してサービスや特徴を取得、その後コールバック
d.flatTrim(); // トリムをリセット
d.startPing(); // 不明
d.flatTrim(); // なぜ二回呼ぶのかは不明
ACTIVE = true; // ドローンを ACTIVE 状態とする
console.log(d.name, 'is ready!'); // 準備OKなことをコンソール出力
});
});

// キー操作でイベントを発生させる
keypress(process.stdin); // 標準入力に keypress イベントを発生させる
process.stdin.setRawMode(true); // raw mode(修飾を伴わない)で標準入力を受け付ける
process.stdin.resume(); // keypress イベントをリッスン

// キー操作後に少しのあいだ入力を受け付けないようにする関数
function cooldown() {
ACTIVE = false; // いったん ACTIVE 状態でなくしておいて
setTimeout( () => { // 一定時間後に
ACTIVE = true; // ACTIVE に戻す
}, STEPS * 12); // この例では 24 ms
}

// キーボードからの入力による操作
process.stdin.on('keypress', (ch, key) => { // keypress イベントが発生したら
if (ACTIVE && key) { // ドローンが ACTIVE で key があれば
// 緊急停止
if (key.name === 'm') { // m キー
d.emergency(); // 緊急停止(モーターを即時停止)
setTimeout( () => { // 3秒後にプログラム終了
process.exit();
}, 3000);

// 離陸(t; take-off)
} else if (key.name === 't') { // t キー
console.log('takeoff'); // コンソール出力
d.takeOff(); // 離陸

// w/s/a/d キー(前後左右の移動)
} else if (key.name === 'w') { // w キー
d.forward({ steps: STEPS }); // 前進(前ピッチ)
cooldown(); // 少しの間キー操作を受け付けない
} else if (key.name === 's') { // s キー
d.backward({ steps: STEPS }); // 後退(後ピッチ)
cooldown(); // 少しの間キー操作を受け付けない
} else if (key.name === 'a') { // a キー
d.tiltLeft({ steps: STEPS }); // 左水平移動(左ロール)
cooldown(); // 少しの間キー操作を受け付けない
} else if (key.name === 'd') { // d キー
d.tiltRight({ steps: STEPS }); // 右水平移動(右ロール)
cooldown(); // 少しの間キー操作を受け付けない

// カーソルキー(上下と左右スピン)
} else if (key.name === 'left') { // 左カーソルキー
d.turnLeft({ steps: STEPS }); // 左旋回(左スピン(ヨー))
cooldown(); // 少しの間キー操作を受け付けない
} else if (key.name === 'right') { // 右カーソルキー
d.turnRight({ steps: STEPS }); // 右旋回(右スピン(ヨー))
cooldown(); // 少しの間キー操作を受け付けない
} else if (key.name === 'up') { // 上カーソルキー
d.up({ steps: STEPS * 2.5 }); // 上昇
cooldown(); // 少しの間キー操作を受け付けない
} else if (key.name === 'down') { // 下カーソルキー
d.down({ steps: STEPS * 2.5 }); // 下降
cooldown(); // 少しの間キー操作を受け付けない

// i/j/k/l キー(アクロバット)
} else if (key.name === 'i') { // i キー
d.frontFlip({ steps: STEPS }); // 前に宙返り
cooldown(); // 少しの間キー操作を受け付けない
} else if (key.name === 'k') { // k キー
d.backFlip({ steps: STEPS }); // 後ろに宙返り
cooldown(); // 少しの間キー操作を受け付けない
} else if (key.name === 'j') { // j キー
d.leftFlip({ steps: STEPS }); // 左に宙返り
cooldown(); // 少しの間キー操作を受け付けない
} else if (key.name === 'l') { // l キー
d.rightFlip({ steps: STEPS }); // 右に宙返り
cooldown(); // 少しの間キー操作を受け付けない

// 着陸(q; quit)
} else if (key.name === 'q') { // q キー
console.log('landing...'); // コンソール出力
d.land(); // 着陸
}
}

// プログラム終了(ctrl + c)
if (key && key.ctrl && key.name === 'c') { // ctrl + c なら
process.stdin.pause(); // 標準入力を一時停止
process.exit(); // プログラム終了
}
});



動作確認


  • ミニドローンにバッテリーを装着し、電源を ON にします


    • Parrot MAMBO の目が緑色に点滅します(ペアリングモード?)



  • コマンドプロンプトで、上記の app.js があるディレクトリ(例 C:\(ユーザ名)\drone)に移動し、以下を実行します

node app.js

コンソールに以下のように表示され、MAMBO の目が緑色の「点灯」になったら準備OKです(xxxxxxは個体の番号)。

Mambo_xxxxxx is ready!


操縦方法(キーアサイン)

キー
動作
メソッド

m
緊急停止(即座にプロペラ停止)
emergency()

t
離陸
takeOff()

w
前進(前ピッチ)
forward()

s
後退(後ピッチ)
backward()

a
左水平移動(左ロール)
tiltLeft()

d
右水平移動(右ロール)
tiltRight()

↑ カーソル
上昇
up()

↓ カーソル
下降
down()

← カーソル
左旋回(左スピン(ヨー))
turnLeft()

→ カーソル
右旋回(右スピン(ヨー))
turnRight()

i
前方宙返り
frontFlip()

k
後方宙返り
backFlip()

j
左に宙返り
leftFlip()

l
右に宙返り
rightFlip()

q
着陸
land()

ctrl + c
プログラム終了
-


まとめ

node-rolling-spider モジュールを使って Windows でミニドローンを飛ばすポイントは以下です。

これらのうち1点目は今回の内容に限ったことではありませんが、これまで手動では設定しており、他のモジュールはうまくビルドされていたのに、今回つまずきました。windows-build-tools を再インストールしたらうまくいきました。手動設定で、なにか足りていなかったようです。

2点目と3点目については、node-rolling-spider の依存モジュールの readme までちゃんと読まずに試していて、つまずきました。また、一般的な Bluetooth アダプタのように「スタック」を使わずに(スタックをバイパスして)通信するというのが当初は理解できず、手間取りました。

このあたり、事前に Raspberry Pi で試した時は何も考えなくてもすんなり動いて、Windows でぜんっぜん動かなくて、心が折れかけでした。業務の都合上(?)、Windows マシンだけで済むと楽なので、少し手間取りはしましたが、動いてよかったです。


付録


Bluetooth アダプタのドライバの戻し方


  • デバイスマネージャーで WinUSB ドライバで書き換えていた Bluetooth アダプタを右クリックし、「ドライバーの更新」を選択

zadig4.PNG


  • 「コンピューターを参照してドライバーソフトウェアを検索」を選択

  • 「コンピューター上の利用可能なドライバーの一覧から選択します」を選択

  • 「Generic Bluetooth Radio」(当初に認識されていたデバイス名)を選択し、「次へ」でドライバをインストール

  • デバイスマネージャーで当該のアダプタが「Bluetooth」として認識されていれば OK です

  • 念のため zadig-2.3.exe を実行し、「List All Device」して、当該アダプタを選択して、もとのドライバになっていることを確認します