PC→CM4→G474 入出力タイミング実機調査(2026-09-20)¶
結論¶
今回のmode3の約102 ms周期の集中は、ai_cmd_v2やSTM32で初めて発生するものではない。 PCの有線インターフェースでは約15 ms間隔で送出されているが、CM4のカーネル到着時点で既に集中していた。 ブロードキャスト送信で再現し、同じ送信器を108宛てユニキャストにすると本試験では解消した。 CM4内部送信でも再現しなかった。CM4のWi-Fi省電力は全試験でoff。
原因範囲はPCのキャプチャ地点からCM4カーネル受信までのネットワーク配送経路。 約102.4 msの周期、beacon interval=100、DTIM=1、宛先による差から、APのグループ宛て配送待ちが有力。 ただしAPの無線送出とCM4の無線FW/driverの境界は直接観測していないため、AP内部の原因まで断定しない。 省電力端末の存在によるグループ配送の保留はRFC 9119 §4.3とも整合する。
条件と測定方法¶
- PC: 192.168.20.11、有線ASIXアダプター。Wi-Fiアダプターは未接続。
- CM4_108: 192.168.20.108、wlan0、SSID SSL_ibis、BSSID 7a:27:f5:f2:c7:eb、5500 MHz、DTIM=1、beacon=100。
- PC送信: 715 byte、15 ms周期(66.6667 Hz)、対象ID8のみ。STOP・速度/キック/ドリブルゼロ。
- 危険フィールドをゼロにし、ユーザーから物理的安全状態の確認を受けて実施。STOPだけで全アクチュエータを無効化できるとは扱わない。
- Qt送信器候補のソースは15 ms、192.168.20.255宛て固定、毎回socket生成。実行中のQtプロセスは確認されなかったため、今回は新規CLIで送信を自動化した。Qt UI自体は操作・変更していない。
- 固定socketと毎回socket生成の両方でbroadcast集中/unicast改善を確認。socket再生成だけでは今回の周期的集中を説明できない。
- 通常カメラとrobot_feedbackを動かしたまま、ai_cmd_v2のみ診断ビルドへ一時置換して測定。
- PC: send呼出し前後のperf_counter_nsと、有線IFのdumpcapパケットキャプチャ。
- CM4: AF_PACKET受動キャプチャのkernel timestamp、本体recvmsgのSO_TIMESTAMPNS、読出し直後とwrite前後のmonotonic時刻。受動キャプチャは通常UDPを奪わない。
- G474: 10秒間のDWT記録(170 MHz)。72 byte正常フレーム完成と500 Hz制御採用を別配列へ保存。TPRB+32bit連番で対応付け。
- STM32記録容量に合わせ本体同時計測は10秒単位。mode3 broadcastは3回以上、unicastは複数回、内部送信も比較。別途ネットワークのみ30秒試験も実施した。
- 装置間の時計は直接減算していない。CM4時計は8月29日を示しており、PCと同期していない。同一装置内の遅延と連番対応した間隔を評価した。
最終検証データ(mode3)¶
下表は runtime/timing-20260920/verified-* の代表値。単位ms。
STM32値は計測終了後にST-Link HOTPLUGで読み出した固定記録配列から算出した。
| 条件 | PC送信間隔 p50 | CM4カーネル到着間隔 p50 / p99 / max | STM32受信間隔 p50 / p99 / max |
|---|---|---|---|
| broadcast | 15.010 | 1.136 / 96.808 / 198.247 | 1.157 / 97.263 / 198.403 |
| 108 unicast | 15.001 | 15.000 / 16.244 / 16.528 | 15.225 / 16.377 / 17.150 |
| CM4 localhost | 14.999 | 14.998 / 15.043 / 15.280 | 15.231 / 15.708 / 16.092 |
PCの有線キャプチャでもbroadcastは667件、送出間隔p50=15.013/p99=15.909/max=16.372 ms。 したがって「send呼出しだけ等間隔で、PCの送出段階で100 ms分まとめていた」という説明とも一致しない。
| 処理区間 | broadcast p99 | unicast p99 | localhost p99 |
|---|---|---|---|
| CM4 kernel到着→アプリ読出し | 1.139 | 1.095 | 1.072 |
| アプリ読出し→UART write開始 | 0.027 | 0.040 | 0.014 |
| UART write呼出し所要 | 0.049 | 0.053 | 0.048 |
| STM32正常受信→制御採用 | 1.881 | 1.997 | 1.985 |
write呼出しの終了は線上送信完了ではない。STM32側の実受信記録も同時に比較して判断した。 unicastの読出し→writeは一過性max=1.560 msがあったが、約100 msの滞留は説明しない。
件数と間引き¶
- verified-broadcast: PC667→CM4 kernel/アプリ654→UART634。受信キューの最新値採用で20件を意図的に上書き。
- STM32記録窓内621受信→406制御採用。215件は次の制御tickより前に新しい指令で置き換わった。説明不能な制御採用欠落は0。
- verified-unicast: PC667→CM4/UART667。STM32記録窓内656受信→656採用。
- verified-local: 667送信→CM4/UART667。STM32記録窓内632受信→632採用。
- STM32窓はy受付から10秒、送信開始はその後である。末尾の13/11/35件など窓外の差をUART欠落と数えない。
- 最終5条件でchecksum/PE/FE/NE/ORE、診断配列overflow、apply_raceはいずれも0。CM4 socket dropとAF_PACKET capture dropも0。
- broadcastのPC→CM4件数差はキャプチャ/socket dropでは説明されず、配送経路での欠落と整合する。
mode4の確認¶
STOP・ゼロ出力でmode4も比較した。入力は66.6667 Hz、CM4のUART出力設定は100 Hz。
| 条件 | CM4 kernel入力 p50 / p99 / max | STM32 UART受信 p50 / p99 / max |
|---|---|---|
| broadcast | 1.143 / 97.919 / 198.141 | 9.803 / 10.968 / 11.259 |
| unicast | 15.008 / 16.190 / 17.265 | 9.841 / 10.954 / 10.975 |
mode4ではブリッジの周期送信が働くため、入力集中がそのままUART集中にはならなかった。 ただし新しい目標が届くタイミングはbroadcastの配送遅延の影響を受ける。 これは停止状態の経路試験であり、走行時の位置制御・目標追従・feedback変動の全問題を否定する試験ではない。 mode4は1入力→複数UART出力なので、mode3解析CLIの一対一連番照合は使用しない。
ログの信頼性と除外試験¶
- COM56の2 Mbpsログに文字欠落があり、記録数・event連番・時計単調性の検査で検出した。UART制御指令の受信エラーとは別問題。
- 計測後dumpを1 ms間隔にしても少数の欠落が残ったため、最終5条件は測定終了後にST-LinkからSRAM配列を読み出して照合した。CPUのhalt/resetや測定中のSWD読出しは行っていない。
- 最終値の根拠は
stm32_sram.binと、それを復号したstm32_sram.log。COM原本stm32.logは変更せず保存。 - 読出しアドレスはbuild 1789867492のELFから取得。0x2000174cから0x8d18 byte。別ビルドには流用不可。
- 全最終データでSRAMの件数・event連番・cycle単調性を検証済み。
actual-unicast-r3、初回mode4などの破損COMデータはSTM32の時間評価に使用しない。actual-unicast-r3-pacedはcapture件数0、actual-local-r2は完了ログなしで不採用。試験間の6秒無通信自己reset/初期化/診断状態との干渉が疑われるが、原因は断定しない。最終試験は試験間待機を追加し、非ゼロ件数と終了状態を確認した。- 未使用ポートでの初期unicast10秒試験では一過性の遅延も観測した。その後の30秒試験および実UART本試験では継続的な102 ms集中は再現しなかった。長期の無線遅延上限を保証する結果ではない。
追加実装・再解析¶
host/apps/command_timing_probe.py: mode¾の安全停止指令をPCから周期送信。絶対deadline、遅延時の追い付き連打なし、固定socket/毎回socket比較、送信CSV。cm4/bridge/forward_ai_cmd_v2.cpp:--timing-trace PATH --timing-seconds 30で上限10万件をメモリ記録し、終了時に排他的作成CSVへ出力。通常時は計測無効。host/apps/analyze_command_timing.py: mode3の区間別統計、上書き・窓外分類、ログ整合性検査。--stm-log-nameでSRAM由来ログを明示選択。- G474
Core/Src/main.c:yで10秒capture、終了後にRX/APPLY/統計を出力。診断は安全インタロックではない。開始ACKがないため、y送信だけでcapture開始成功とは判断しない。
python -m host.apps.analyze_command_timing runtime/timing-20260920/verified-broadcast runtime/timing-20260920/verified-unicast runtime/timing-20260920/verified-local --stm-log-name stm32_sram.log --json runtime/timing-20260920/reanalysis.json
最終状態と復元情報¶
- PC送信器・CM4内部送信器・診断ブリッジは停止済み。
- control_server.serviceはactive。HTTP stop/startを実行し、通常ai_cmd_v2・robot_feedback・カメラを再起動。最終statusはrunning=true。
- CM4本番のai_cmd_v2バイナリは元のまま。診断ビルドは
/tmp/orion-timing-stage/cm4/bin/ai_cmd_v2.outでのみ実行した。 - G474 Slot Aには診断追加FWを配置済み。build ID 1789867492、image CRC32C 304C3047、metadata CRC32C C391703B。書込みverify成功。通常は計測無効。
- 変更前の全Flash 512 KiBは
runtime/timing-20260920/g474-before.bin。SHA256:094005F04BA60066F018ED027AAE36AC381FA3917A71A1A1BD6DB6A439610333。復元時は対象とslot/metadataを確認し、無計画な全消去はしない。 - PC側文書のみ更新。CM4へドキュメントは配置していない。Qt送信先・AP設定・Wi-Fi省電力設定は変更していない。
- 検証: PC送信器6テスト、解析器4テスト、CM4実機上のbridge既存+新規13テスト成功。STM32全再ビルド成功(既存RWX警告のみ)。
対策候補¶
まず制御UDPを各CM4宛てユニキャストにする方式を優先して検討する。今回の比較で実効性が確認できた。 複数機体へは送信先一覧を管理して個別配信する必要があるため、既存715 byte一括broadcastを単に108固定へ変えるだけでは全機体運用の解決にはならない。 AP側のDTIM・グループ配送設定の評価は別途行う。DTIM=1でも今回の周期は残るため、DTIMだけを下げれば解決するとはしない。