プロポのジョイスティックをマイクロサーボで操作する
概要(Summary)
これまで電動台車や車椅子、電動ウィンチなんかを自律制御する時は、いつも人間が指で制御するインターフェイス(タッチパネルやボタン、ジョイスティック)を外部からサーボモーターで操作するというハッキング方法を取ってきた。通常ハッキングというと、一度外装を外して中の基盤を見てどういうシグナルがどこにいってどう動くかを把握して内部から電気信号を与えて制御するような方法だと思うけど、何が起こってるか分かりにくいし、デバッグもしにくい、そして私の技術力のなさもあいまって外部操作する方法でずっとやってきた。ので、今回もその方法を採用する。
その他の詳しい事は前回ポストで。
研究事例との一致(先行研究)
前回の記事で行った事前調査では、ChatGPTが以下のような研究事例を提示してくれた。
- SDKが存在しない場合
- 大学・研究機関でも同様の物理操作手法が採用されている
- 「古典的手法」とされるほど定番
参考論文
Development of a Remote-Controlled Drone System by Using Only Eye Movements
Design of a Control Screen Considering Operability and Microsaccade J-STAGE
https://www.jstage.jst.go.jp/article/jrobomech/33/2/33_301/_pdf
特定のポジションでサーボを固定できる治具を設計出力
使用サーボ
-
MG92B マイクロサーボ
-
選定理由:
- 応答速度が速い
- サイズに対して十分なトルク
- 秋月電子で安定入手可能
🔗 https://akizukidenshi.com/catalog/g/g113228/
サーボ固定治具(3Dプリント)
設計ポイント
- SketchUpでモデリング
- 特定の位置・高さでサーボを固定
- 結束バンド固定用の溝を追加
- ボルト固定用の穴を設計
- L字型サポートでプロポ上面高さに合わせる
ジョイスティック構成
-
左スティック:
- 上下移動
- 左右回転
-
右スティック:
- 前後左右移動
-
合計サーボ数:4個
🔗 SketchUp
https://sketchup.trimble.com/
サーボホーン拡張パーツ
仕様
- ジョイスティックを通すための長穴構造
- デフォルトで付いてるスティック(M2ネジ穴)ではスペース不足
- M2 × 15mm ボルトを使用して拡張パーツを固定
出力
- すべてのモデルを STL形式でエクスポート
- 3Dプリンタで出力
サーボ4個をPCからシリアル制御
全体構成
(ドローンのセンサー値)
↓ Wi-Fi
PC
↓
Max/MSP
↓ USBシリアル
XIAO ESP32 C3
↓
サーボ × 4
XIAO ESP32 C3(Arduino)側コード
- 過去の書いたコードを流用
- AIで整理・簡略化
- エラーが起きにくい構成に修正
#include <ESP32Servo.h>
// サーボピン設定
const int srvPinL1 = D7;
const int srvPinL2 = D8;
const int srvPinR1 = D2;
const int srvPinR2 = D3;
Servo srvL1, srvL2, srvR1, srvR2;
void setup() {
Serial.begin(9600); // Max側と同じbaud
srvL1.attach(srvPinL1);
srvL2.attach(srvPinL2);
srvR1.attach(srvPinR1);
srvR2.attach(srvPinR2);
// 初期位置
srvL1.write(90);
srvL2.write(90);
srvR1.write(90);
srvR2.write(90);
Serial.println("System Ready: Send format 'ID Angle' (e.g., L1 90)");
}
void loop() {
if (Serial.available() > 0) {
String id = Serial.readStringUntil(' ');
int angle = Serial.parseInt();
while (Serial.available() > 0 &&
(Serial.peek() == '\n' || Serial.peek() == '\r')) {
Serial.read();
}
if (id == "L1") srvL1.write(angle);
else if (id == "L2") srvL2.write(angle);
else if (id == "R1") srvR1.write(angle);
else if (id == "R2") srvR2.write(angle);
}
}
Max/MSP 側インターフェイス
- キーボード入力でテスト可能な簡易パッチ
- シリアル経由でサーボ角度を送信





