Feature: G1 control coordinator adapter for mobile base cmd vel#1410
Feature: G1 control coordinator adapter for mobile base cmd vel#1410
Conversation
Greptile SummaryThis PR adds two Key concerns found:
Confidence Score: 3/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User as User / KeyboardTeleop
participant CC as ControlCoordinator
participant DDS as UnitreeG1TwistAdapter (DDS)
participant WR as UnitreeG1WebRTCTwistAdapter (WebRTC)
participant G1 as Unitree G1 Robot
Note over CC,DDS: DDS path (unitree-g1-dds-coordinator)
CC->>DDS: connect()
DDS->>G1: ChannelFactoryInitialize(0, interface)
DDS->>G1: LocoClient.Init()
DDS->>G1: SetFsmId(4) — lock stand
DDS->>G1: _wait_for_fsm(4)
G1-->>DDS: FSM state = 4
DDS-->>CC: connected = True
CC->>DDS: write_enable(True)
DDS->>G1: LocoClient.Start() — FSM 200
DDS->>G1: _wait_for_fsm(200)
G1-->>DDS: FSM state = 200
DDS-->>CC: enabled = True
loop 100 Hz cmd_vel loop
User->>CC: Twist (vx, vy, wz) via LCM /cmd_vel
CC->>DDS: write_velocities([vx, vy, wz])
DDS->>G1: LocoClient.Move(vx, vy, wz)
end
CC->>DDS: disconnect()
DDS->>G1: StopMove()
Note over CC,WR: WebRTC path (unitree-g1-webrtc-coordinator)
CC->>WR: connect()
WR->>G1: UnitreeWebRTCConnection(ip)
WR->>G1: publish_request(FSM 4 — lock stand)
WR-->>CC: connected = True
CC->>WR: write_enable(True)
WR->>G1: publish_request(FSM 200 — locomotion)
WR-->>CC: enabled = True
loop cmd_vel loop
User->>CC: Twist via LCM /cmd_vel
CC->>WR: write_velocities([vx, vy, wz])
WR->>G1: conn.move(Twist)
end
CC->>WR: disconnect()
WR->>G1: send zero velocity + liedown()
Last reviewed commit: 15c93c2 |
Additional Comments (2)
The blueprint falls back to
These three places disagree. Users following the docs will set
While the adapter registry discovers the class via """Unitree G1 WebRTC humanoid robot adapter."""
from dimos.hardware.drive_trains.unitree_g1_webrtc.adapter import UnitreeG1WebRTCTwistAdapter
__all__ = ["UnitreeG1WebRTCTwistAdapter"]Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time! |
12653c3 to
9cd7865
Compare
…e} doesn't work. Expanded to explicit paths.
…d actually had something to build (python or ros files changed). Otherwise it falls back to :dev
…loneDDS 0.10.5 from source
| (needs.ros-python.result == 'success' && (needs.check-changes.outputs.python == 'true' || needs.check-changes.outputs.ros == 'true'))) | ||
| }} | ||
| from-image: ghcr.io/dimensionalos/ros-python:${{ needs.ros-python.result == 'success' && needs.check-changes.outputs.branch-tag || 'dev' }} | ||
| from-image: ghcr.io/dimensionalos/ros-python:${{ needs.ros-python.result == 'success' && (needs.check-changes.outputs.python == 'true' || needs.check-changes.outputs.ros == 'true') && needs.check-changes.outputs.branch-tag || 'dev' }} |
There was a problem hiding this comment.
pls dont touch CI unless you have very good reason
There was a problem hiding this comment.
Yes, I debated quite a bit before adding this.
The original intended to fall back to dev when ros-python didn't build, but the problem is GitHub Actions expression evaluation: ros-python.result == 'success' is true even when should-run was false (all steps skipped, job still reports success). So the original resolves to branch-tag instead of 'dev'. This causes a bug where it expects the ros-python build but gets a stale one.
This edit adds the extra check (python == 'true' || ros == 'true') so it only uses the branch tag when those files actually changed, meaning ros-python actually built something.
There was a problem hiding this comment.
I totally understand your concern here. You finally got CI to work properly I am scared of breaking it again too. 😅
|
|
||
| unitree-dds = [ | ||
| "dimos[unitree]", | ||
| "unitree-sdk2py-dimos>=1.0.1", |
There was a problem hiding this comment.
This is a high risk PR so needs careful review and will come in following release. Relies on someone else's code and we need to maintain a wheel. How many will use CycloneDDS? We likely do to this properly need very robust build matrix for py310 311 312 and macos arch etc etc
There was a problem hiding this comment.
Yes, agreed on this. I am not pushing this currently for merge.
I am testing this on multiple NUCs, building things from scratch. Already caught a few bugs, and will keep this to test longer.
Also will get more people to test.
There was a problem hiding this comment.
Cyclone DDS or DDS support it seems will be very important as we start interfacing with more OEM hardware.
We are already seeing there is no way around it when trying to work with Unitree. Similarly with Booster, and some initial tests show we would need it for Galaxea too.
I believe all OEMs have DDS support as ROS works over DDS and everyone supports it by default.
There was a problem hiding this comment.
I have uploaded the unitree-sdk2py-dimos package with custom wheel to PyPi. I have not required to do that for CycloneDDS.
|
|
||
| # Build CycloneDDS 0.10.5 from source (Ubuntu 22.04 apt only has ~0.9.x, | ||
| # but the Python cyclonedds package requires >=0.10.5 headers) | ||
| RUN git clone --branch 0.10.5 --depth 1 https://github.com/eclipse-cyclonedds/cyclonedds.git /tmp/cyclonedds && \ |
Problem
The Unitree G1 humanoid has no ControlCoordinator integration — it can only be driven through the legacy
G1ConnectionWebRTC wrapper, with no DDS support and no unified velocity (Twist) interface.Solution
Added two
TwistBaseAdapterimplementations for the G1 so it can be controlled via the ControlCoordinator'scmd_velTwist interface:unitree_g1(DDS) — wrapsLocoClientfromunitree-sdk2py-dimos. Communicates over CycloneDDS on a specified network interface (enp60s0). Handles FSM state machine: checks boot state, transitions to lock stand (FSM 4), then activates locomotion (FSM 200) on enable. Never calls Damp/ZeroTorque.unitree_g1_webrtc— wrapsUnitreeWebRTCConnectionfor environments where DDS isn't available. Manages standup and walk mode via WebRTC publish requests.Both adapters register with
TwistBaseAdapterRegistryand expose 3 DOF:[vx, vy, wz].Two coordinator blueprints added:
unitree-g1-dds-coordinatorandunitree-g1-webrtc-coordinator, both wiringKeyboardTeleopto the G1 viacmd_vel.unitree-sdk2py-dimos>=1.0.3added to theunitreeextras inpyproject.toml.Breaking Changes
None
How to Test
ROBOT_INTERFACE=enp60s0 dimos run unitree-g1-dds-coordinator— robot should stand up, WASD keys send velocity.ROBOT_IP=192.168.123.164 dimos run unitree-g1-webrtc-coordinatorPlease note, when G1 is booted first time. Robot must be put to damp mode manually. Subsequent blueprint runs don't need manual damping mode to be enabled.
closes DIM-592