Robotics
gs_usb のタイムスタンプ・レイテンシ
FW と host のクロックは同期していない。header.stamp = host 受信時刻
要点: FW と host のクロックは同期していない。ROS msg の header.stamp は「host が受信した時刻」で、motor で測定された時刻ではない。既に 2-10ms 古い。
数字
| 段階 | 時間 |
|---|---|
| エンコーダ→FW サンプル | 0-1 ms |
| FW send buffer → CAN 送信開始 | ~100 µs |
| CAN 伝送 (500k+FD BRS, 6-8B) | ~60-200 µs |
| USB (gs_usb) | 1-5 ms、jitter で 10ms+ |
| driver → subscriber | ~100 µs |
| 合計 (motor 事象 → host 到着) | 典型 2-5 ms、悪い時 10ms+ |
タイムスタンプの流れ
motor 物理 → FW サンプル → FW send → CAN → USB → driver
↓ ↓
FW clock header.stamp = now()
(host と別) ← ★ここで初めて時刻が付くFW からのフィードバックに FW 時刻は乗っていない。protocol V6/V7 とも。
制御への影響
- 内側 PID (velocity/position on FW) → 影響なし。FW clock で完結
- Host からの FF 送信 → 後追い。t0 の軌道サンプルを送ると FW 到着は t0+δ (δ = 2-5ms)。v_ff=10 rad/s なら 50 mrad の誤差
対策
| 対策 | コスト | 効き |
|---|---|---|
δ を実測 → Host 側で先出し (sendTrajectoryPoint(pos(t0+δ), vel(t0+δ), acc(t0+δ))) | 小 | 中 (平均遅延は消える、jitter は残る) |
| feedback frame に FW μs counter を載せる (V8?) | 中 | 大 (bag で真の遅れが見える) |
| PTP-lite クロック同期 (ping-pong で offset+skew 推定) | 中〜大 | 大 (jitter も追える) |
ros2_control で解決するか
しない。ros2_control は host loop jitter (D) を数十µs 級に落とすが、FW↔host クロック非同期と gs_usb 遅延には効かない。これは hardware_interface 実装側の責任 (EtherCAT なら DC で解決するが CAN には無い)。
ros2_control 化のメリットは:
- Host loop jitter: 数ms → 数十µs
- 軌道 FF が標準 (JointTrajectoryController)
- MoveIt 互換
ros2_control 化のデメリット:
- RT Linux 運用が要る
- hardware_interface プラグイン実装
- timestamp 問題は残る