学生ロボコン2026が終わったので、今年やったことをまとめておきます。
今年は回路・制御をゴリゴリ書くというよりは、機体間の通信周りとR1の操縦用GUIアプリを作っていました。
あとは運営とか会計とか、ものづくり以外の仕事もやってました。学ロボ人生もこれで一区切りです。
結果はベスト8でした。まぁいいロボコン人生だったかなと思います。
作ってたもの
ethernet2can
何を作ったか
Classic CAN ↔ Ethernet(TCP)のゲートウェイです。マイコンはSTM32G473、EthernetコントローラはW5500を使っています。
STM32G473はFDCANを3チャンネル持っているので、それを全部1本のTCP接続で扱えるようにしました。
実機はこんな感じです。RJ45コネクタがついてるとカッコ良く見えて好きです。あとはCANのXAコネクタが並んでます。
プロトコル仕様
パケットは20バイト固定のフォーマットです。
+--------+----------+----------+
| Offset | Size | Field |
+--------+----------+----------+
| 0 | 1 byte | Channel |
| 1 | 3 byte | (pad) |
| 4 | 4 byte | CAN ID |
| 8 | 4 byte | DLC等 |
| ... | 8 byte | Data |
+--------+----------+----------+
Classic CANのみ対応(データは最大8バイト)です。FDCANのデータレート部分には対応していません。
チャンネル番号はそのままペリフェラルに対応させています。
| Channel | ペリフェラル |
|---|---|
| 0 | FDCAN1 |
| 1 | FDCAN2 |
| 2 | FDCAN3 |
ちなみにシルクの配置が間違ってて制御を困らせました
CAN IDフィールドはSocketCAN互換にしました。すでに使い慣れてる人が多いフォーマットに合わせておくと、Python側のクライアントを書くときも楽です。
- Bit 31 (
0x80000000): EFF — 拡張フレームフラグ(29ビットID) - Bit 30 (
0x40000000): RTR — リモートフレームフラグ - Bit 0–28: CAN ID(標準: 下位11ビット / 拡張: 29ビット)
| フレームタイプ | ID範囲 | EFF | RTR |
|---|---|---|---|
| 標準データフレーム | 0x000–0x7FF | 0 | 0 |
| 標準リモートフレーム | 0x000–0x7FF | 0 | 1 |
| 拡張データフレーム | 0x000–0x1FFFFFFF | 1 | 0 |
| 拡張リモートフレーム | 0x000–0x1FFFFFFF | 1 | 1 |
アーキテクチャ
CAN→Ethernet方向はこんな流れです。
FDCAN割り込み (HAL_FDCAN_RxFifo0Callback)
└→ RAMキュー(64メッセージ循環バッファ)に追加(SPIなし)
└→ メインループ: キューから取り出し → W5500でTCP送信
Ethernet→CAN方向はこう。
W5500 TCP受信
└→ 20バイトパケットをパース
└→ FDCAN送信
ポイントは、割り込みハンドラの中で直接W5500のSPIにアクセスしないことです。
最初はFDCANの受信割り込みでそのままSPI送信していたのですが、メインループ側のSPIアクセスと競合してしまい、データが欠落したりタイミングがズレることがありました。
受信データを一旦RAMの循環バッファに積んでおいて、メインループ側でまとめてW5500に流す方式に変えたことで安定しました。割り込みハンドラ内でSPI(やそれに準ずる重い処理)を叩くと痛い目を見るというのが、今回の一番の学びです。
DMA?知らない子ですね…
gakurobo_controller(R1操縦用アプリ)
概要
R1の操縦システムです。DualSenseコントローラの入力をiPhoneアプリ経由でロボットに送るパイプラインを組みました。
スマホ本体にはiphone16eを使用しています。個人的に買ったiOSアプリ開発用の端末を流用しただけなので、iPhoneを使っている深い理由は特にないです。
ROS2との連携は以下のようになっています。
DualSense → iPhone (Flutter) → WebSocket → PC (ROS2) → /joy トピック
PCでROS2を動かしてフィールド全体の制御をしている前提で、操縦入力だけをiPhoneから飛ばす形です。
スマホ,コントローラ,Wi-Fiルーター間は有線で直結する構成にしています。NHKの電波管制がひどいので、無線を極力減らしたかった
最終的に無線関連のトラブルのリスクを考えて、この構成に落ち着きました。
実際の運用イメージです。iPhoneをDualSenseにマウントして、フィールド表示と操作ボタンを画面に出しています。
構成
iPhone側のアプリ(flutter/、v1.4.0)は3ページ構成にしています。
| ファイル | 内容 |
|---|---|
pages/controller_page.dart | メインコントローラ画面 |
pages/field_page.dart | フィールド表示画面 |
pages/settings_page.dart | 設定画面 |
widgets/gamepad_panel.dart | ゲームパッド入力表示 |
widgets/telemetry_panel.dart | テレメトリ表示 |
widgets/aruco_panel.dart | ArUcoマーカー関連 |
主な依存ライブラリはroslibdart(ROS2連携)とuniversal_gamepad(DualSense入力)です。
ROS2との通信をネイティブで書くのは大変なのでroslibdartでWebSocket越しにrosbridgeと喋らせています。DualSenseの入力周りもuniversal_gamepadに任せて、自前で実装するのはアプリ側のロジックとUIだけに絞りました。
自前で実装しても良かったのですが、トラブル時の問題の切り分けが面倒だったので、既存ライブラリを使用しました。
メイン画面の表示です。左から操作ボタン、ログ、ゲームパッド入力のパネルが並んでいます。rosbridgeとの接続状態もここで確認できます。
Arucoマーカーの指定などもこの画面で行います。
フィールド画面です。陣地ごとのKFSの状態やルート選択をここから操作します。 ここのUIは割と見やすくできたので、お気に入りです。
kfsおくとこんな感じになります。
それ以外(運営・会計)
ものづくり以外だと、チームの運営と会計をやっていました。
予算管理やイベント周りの調整など、地味だけどチームが大会まで走り切るために必要な仕事です。ここに書けることはあまりないですが、これも含めて今年の学ロボでした。
結果と所感
結果はベスト8でした。
ethernet2canもgakurobo_controllerも、本番までに動かし切れたという意味では満足しています。
特にethernet2canはキューイング方式に変えたあとはCAN通信周りのトラブルでロボットが止まることはなかったので、回路・通信基盤としてはちゃんと役目を果たしたと思います。
GUIアプリも依頼されてから1ヶ月半くらいで完成させられたので、ひとまずは良かったですかね。
まぁいいロボコン人生だったかな、というのが今の感想です。
一区切りついたので、ESCでも自作しようかな〜