feat(go2): command the robot with calibrated velocity (SPORT Move) ov…#2567
feat(go2): command the robot with calibrated velocity (SPORT Move) ov…#2567mustafab0 wants to merge 2 commits into
Conversation
…er WebRTC UnitreeWebRTCConnection.move() sent the body twist as raw normalized joystick stick deflections (lx/ly/rx) on WIRELESS_CONTROLLER, so the commanded wz/vx were never calibrated velocities — the firmware's nonlinear, speed-coupled gait mixer was the de-facto plant. move() now sends SPORT Move (api_id 1008) with real m/s & rad/s (x forward, y left, z yaw CCW), fire-and-forget at tick rate, via a shared _publish_move() helper that stop() also uses for a zero-velocity halt. Gait stays the caller's responsibility (GO2Connection already runs standup()/balance_stand() at start-up; Move works from BalanceStand). On hardware this removed a ~2.2x yaw over-turn: 0.8 rad/s commanded went from a 3.5s circle to ~10s (~224% -> ~78% of commanded yaw) — a clean linear gain characterization can now fit. Re-characterize K/tau/L on this command path.
Greptile SummarySwitches the Go2 movement command path from raw WIRELESS_CONTROLLER joystick deflections (
Confidence Score: 4/5The core change is well-scoped and the payload format matches the Unitree SPORT Move contract; the main thing to keep in mind is that the client-side auto-stop timer no longer sends an explicit zero-velocity command, relying entirely on the firmware watchdog. The payload construction (JSON-stringified parameter, monotonic id, correct topic and msg_type) looks correct. One stale docstring and the implicit firmware-watchdog dependency for auto-stop are worth addressing but don't represent a functional regression in the command path itself. dimos/robot/unitree/connection.py — specifically Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Caller
participant UnitreeWebRTCConnection
participant EventLoop
participant Firmware as Go2 Firmware
Caller->>UnitreeWebRTCConnection: "move(twist, duration=0)"
UnitreeWebRTCConnection->>UnitreeWebRTCConnection: extract x, y, yaw from twist
UnitreeWebRTCConnection->>UnitreeWebRTCConnection: reset cmd_vel_timeout timer (0.2s)
UnitreeWebRTCConnection->>EventLoop: run_coroutine_threadsafe(async_move)
EventLoop->>UnitreeWebRTCConnection: _publish_move(x, y, yaw)
UnitreeWebRTCConnection->>UnitreeWebRTCConnection: "_move_seq += 1"
UnitreeWebRTCConnection->>Firmware: "SPORT_MOD publish_without_callback api_id=1008, parameter={x,y,z}"
UnitreeWebRTCConnection-->>Caller: True
Note over UnitreeWebRTCConnection,Firmware: After 0.2s of no new move() calls...
UnitreeWebRTCConnection->>UnitreeWebRTCConnection: stop_movement() cancels timer only
Note over Firmware: Robot stops via firmware watchdog
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Caller
participant UnitreeWebRTCConnection
participant EventLoop
participant Firmware as Go2 Firmware
Caller->>UnitreeWebRTCConnection: "move(twist, duration=0)"
UnitreeWebRTCConnection->>UnitreeWebRTCConnection: extract x, y, yaw from twist
UnitreeWebRTCConnection->>UnitreeWebRTCConnection: reset cmd_vel_timeout timer (0.2s)
UnitreeWebRTCConnection->>EventLoop: run_coroutine_threadsafe(async_move)
EventLoop->>UnitreeWebRTCConnection: _publish_move(x, y, yaw)
UnitreeWebRTCConnection->>UnitreeWebRTCConnection: "_move_seq += 1"
UnitreeWebRTCConnection->>Firmware: "SPORT_MOD publish_without_callback api_id=1008, parameter={x,y,z}"
UnitreeWebRTCConnection-->>Caller: True
Note over UnitreeWebRTCConnection,Firmware: After 0.2s of no new move() calls...
UnitreeWebRTCConnection->>UnitreeWebRTCConnection: stop_movement() cancels timer only
Note over Firmware: Robot stops via firmware watchdog
|
❌ 2 Tests Failed:
View the full list of 2 ❄️ flaky test(s)
To view more test analytics, go to the Test Analytics Dashboard |
Problem
UnitreeWebRTCConnection.move() sent the body twist as raw normalized joystick stick deflections (lx/ly/rx) on WIRELESS_CONTROLLER, so the commanded wz/vx were never calibrated velocities
Solution
move() now sends SPORT Move (api_id 1008) with real m/s & rad/s (x forward, y left, z yaw CCW),
Contributor License Agreement