Altair Module Systemというロボコン用のモジュールシステムを作りました
はじめに
ロボットを自作するとき、モータ、サーボ、電磁弁などのアクチュエータが増えるにつれて、「配線がスパゲッティ状態になる」「PCのUSBポートが足りない」「マイコンごとに通信プロトコルがバラバラで管理が大変」「回路を新しくつくのが面倒」という問題に直面したことはありませんか?
これらの課題を解決するため、すべての回路モジュールをCANバス(1 Mbps)で統一し、ROS2 PCやブラウザからシームレスに一括制御できるシステム「Altair Module System」を開発しました。
本記事では、このシステムのアーキテクチャや各モジュールの設計、そして開発の過程で得られた知見について紹介します。
1. システムの全体像(アーキテクチャ)
本システムは、上位系(ROS2 PCやGUIツール)からUSB-to-CANアダプタを介し、共通のCANバスを通じて各種モジュールを制御する構成になっています。
USBtoCANについては以下記事をご覧ください
┌──────────────┐ USB-to-CAN CAN Bus (1 Mbps)
│ ROS2 PC │◄──────────────►═══════════════════════════
│ (GUI/制御) │ ║ ║ ║
└──────────────┘ ▼ ▼ ▼
┌────────┐ ┌───────┐ ┌──────────┐
│ MDD │ │ Servo │ │ Solenoid │
│ 4ch DC │ │ 6ch │ │ 12ch │
│ Motor │ │ PWM │ │ Valve │
└────────┘ └───────┘ └──────────┘
メインマイコンには、十分なタイマ数とCANコントローラを内蔵し、入手性の良いSTM32F446を採用しました。
通信仕様(CAN IDマップ)
帯域を最大限に活かすため、通信速度は 1 Mbps に固定。各モジュールへのコマンドやフィードバックは、以下のようにクリアにID設計を行っています。
| CAN ID | 方向 | モジュール | 内容 |
|---|---|---|---|
0x100 |
PC → MCU | Servo | 6ch 角度指令 (6B) |
0x200–0x203
|
PC → MCU | MDD | Motor1-4 パラメータ設定 (各 8B) |
0x210 |
PC → MCU | MDD | 4ch モード設定 (4B) |
0x220 |
PC → MCU | MDD | 4ch 目標値指令 (8B) |
0x230 |
MCU → PC | MDD | ステータス返信 (8B) |
0x240 |
MCU → PC | MDD | 4ch エンコーダ角度 (8B) |
0x250 |
MCU → PC | MDD | 4ch エンコーダ回転速度 (8B) |
0x300 |
PC → MCU | Solenoid Valve | 12ch 電磁弁 ON/OFF (2B) |
2. 各制御モジュールの実装と工夫
モジュール共通規格
チップ STM32 F446RE
通信 CAN×2 シリアル×2
サイズ 100[mm]×60[mm]
M3穴位置 92[mm]×52[mm]
開発環境 STM32CubeIDE
① MDD(モータドライバドライバーモジュール)
Altair_MDD_V3 は、エンコーダフィードバック付きのPID制御を行うメインモジュールです。
状態遷移による安全設計
起動直後は「パラメータ設定モード」となり、PCからPIDゲイン(0x200-0x203)と制御モード(0x210: 速度/角度/位置)を受け取るまでモータは回転しません。設定が完了すると「制御実行モード」へ安全に遷移します。
工夫した点:データのパッキングとスケール
CANの1フレーム(最大8バイト)に4個のモータデータを詰め込むため、データをint16_t(little-endian)にキャストし、以下のようにスケールさせています。
-
目標値 (
0x220): 速度は $\text{rps} \times 10$、角度は $\text{deg} \times 10$、位置は $\text{mm} \times 10$
② Servo(6chサーボモジュール)
ALTAIR_SERVO_MODULE_V6 は、20ms(50Hz)のPWM波形を6ch分生成します。
工夫した点:ノイズ耐性とチャタリング防止
ロボットの電源ラインから乗りがちなノイズ対策として、GND分離,ソフトウェア側で以下の処理を実装し、サーボのジタバタを徹底的に防ぎました。
- デッドバンドの実装: 過去の指令値と1度以上の差がない場合は無視。
- 多数決フィルタ: 同一の目標角度が 3回連続 して受信された場合のみ、実際のPWM(パルス幅:0.5ms〜2.5ms)に反映。
③ Solenoid Valve(12ch電磁弁モジュール)
ALTAIR_SOLENOID_VALVE_MODULE は、エアシリンダなどを駆動するためのモジュールです。
工夫した点:ビットフィールドによる超軽量通信
12個の電磁弁のON/OFFを、わずか 2バイト のビットフラグ(Byte0: 1-8ch, Byte1: 9-12ch)にマッピング。バスの帯域をほとんど圧迫せずに高応答なバルブ制御を実現しました。
また、全モジュール共通の仕様として、「200ms以上CAN通信が途絶えたらLEDを消灯(または安全モードへ移行)」するウォッチドッグ機能を設けて安全性を担保しています。
④ AltairMD_V9(モータードライバー)
-
GND絶縁設計をした普通のモータードライバーです。
-
ハイサイドにNchMOSFETを使うためにブーストラップ回路を使用しています。
工夫した点:ビットフィールドによる超軽量通信
12個の電磁弁のON/OFFを、わずか 2バイト のビットフラグ(Byte0: 1-8ch, Byte1: 9-12ch)にマッピング。バスの帯域をほとんど圧迫せずに高応答なバルブ制御を実現しました。
また、全モジュール共通の仕様として、200ms以上CAN通信が途絶えたらLEDを消灯(または安全モードへ移行)するウォッチドッグ機能を設けて安全性を担保しています。
3. 作って終わらせない!充実のGUIエコシステム
ハードウェアやファームウェアが完成しても、デバッグがしにくければ意味がありません。今回は用途に合わせて 3つのレイヤーのGUI を用意しました。
Lev.1:モジュール個別GUI (Python / tkinter)
単体テスト用。python-can を用いて、各モジュール(MDDのPID調整など)の動作チェックが手軽に行えます。
Lev.2:統合GUI (Altair Unified GUI)
1回のCAN接続で、MDD・Servo・Solenoidのすべての画面をタブで切り替えながら一括操作・共有ログ確認ができる、実戦向きのPythonツールです。
Lev.3:ブラウザだけで動く「Altair Web Controller」
今回の開発で最も強力なツールです。Web Serial APIを活用し、Google ChromeやEdgeでURLを開くだけで、マイコン(slcanアダプタ)と直接通信してロボットを制御できます。
🔗 実際のツールはこちらで公開しています: Altair Web Controller
(※Web Serial API非対応のFirefox/Safariやスマホでは動作しません)
Web Controllerのここがすごい!
-
動的モジュール構成
画面上でカードをポンポン追加し、Base CAN IDを設定すれば同種モジュールを何台でも増設可能。 -
Google Blocklyによる自動化
Scratch感覚のブロックプログラミングで、MDDのリミットスイッチが押されたら、電磁弁をONにするといったマクロをノーコードで組めます。
Lev.4:ROS2 パッケージ「?????」
作成中
4. 開発を通じて得られた知見(Tips)
1. slcan プロトコルの手軽さは異常
専用ドライバが必要なPCANなどと違い、USB-to-CANを「シリアル通信(COMポート)」として扱える slcan は、Webアプリケーション(Web Serial API)との親和性が抜群でした。ブラウザからマイコンを叩くロボットUIを作りたい人には全力でおすすめしたい手法です。
2. 安全性を担保する「状態遷移」と「PIDゲイン送信」の工夫
MDDの制御において、起動直後に意図しない目標値が送られてモータが暴走するのを防ぐため、ファームウェア側に厳格な状態遷移を導入しました。
具体的には、起動時は必ず APP_MODE_PARAM_SET(パラメータ設定モード)から始まります。この状態では、PCから4輪分のPIDゲイン(0x200〜0x203)と制御モード設定(0x210)をすべて正しく受信するまで、モータへの出力を完全にインターロックしています。
また、限られたCANのデータ長(8B)のなかにPIDゲイン(P, I, D)と車輪径・回転方向を効率よくパッキングするため、浮動小数点(float)をそのまま送ると帯域を圧迫するため、ゲインを「1000倍」した int16_t としてパッキングして送信。 Byte6-7 のデータは、絶対値を「車輪径 [mm]」、符号を「正=通常方向、負=反転方向」と定義。これにより、1つの変数でハードウェアの物理特性とマウント方向の反転設定を同時にクリアしました。
4輪すべての設定が完了して初めて APP_MODE_CONTROL(制御実行モード)へ安全に遷移し、目標値(0x220)の受付を開始します。一度遷移するとマイコンを再起動するまでパラメータを受け付けない仕様に制限したことで、稼働中の誤設定による暴走リスクを徹底的に排除できました。また制御実行モード状態の時はパラメーター設定値のCANを停止してよいため通信の詰まり対策にもなります.
まとめと今後の展望
CANバスによる配線のシンプル化と、STM32による分散処理、そしてWeb技術を駆使した直感的なUIを組み合わせることで、ロボット開発の効率が劇的に向上しました。
特に簡単な気候実験では機械班の人間でも動かすことができています。
ソースコードや回路の詳細は、リポジトリに公開していますので、ぜひ参考にしてみてください!
- リポジトリ
- Webコントローラー
- AltairMD_V9
- Altair_solenoid_valve_V1
- Altair_MDD_V3
- ALTAIR_SERVO_MODULE_V6








