Skip to content

Feature: go2 control coordinator TwistBase adapter#1357

Open
mustafab0 wants to merge 19 commits intodevfrom
feature/mustafa-go2-control-coordinator-adapter
Open

Feature: go2 control coordinator TwistBase adapter#1357
mustafab0 wants to merge 19 commits intodevfrom
feature/mustafa-go2-control-coordinator-adapter

Conversation

@mustafab0
Copy link
Contributor

@mustafab0 mustafab0 commented Feb 24, 2026

Problem

The ControlCoordinator ocannot control unitree go2 using Twist (cmd_vel)


Solution

Added UnitreeGo2Adapter implementing the TwistBaseAdapter protocol, enabling the Go2 quadruped to be driven through the ControlCoordinator. Key changes:

  • UnitreeGo2Adapter: Wraps Unitree SDK2 SportClient with DDS state feedback. Reads actual velocities from SportModeState (not command echo). Handles the Go2's init sequence (StandUp → FreeWalk → Move).
  • HardwareAdapter base protocol: Extracted connect/disconnect/is_connected into a shared base so ManipulatorAdapter and TwistBaseAdapter share a common ancestor, eliminating type: ignore[override] on the adapter property.
  • unitree-go2-keyboard-teleop blueprint: Dual-mode — simulation uses go2_connection (MujocoConnection), real hardware uses ControlCoordinator with the Go2 adapter.
  • Coordinator cleanup: Refactored subscription management into _subscribe_if() with list-based cleanup. Gripper methods use isinstance narrowing for ManipulatorAdapter.

Breaking Changes

None


How to Test

Simulation ( ONLY verifies blueprint wiring, keyboard input, MuJoCo physics — does NOT exercise the coordinator or Go2 adapter):

  1. dimos --simulation run unitree-go2-keyboard-teleop
  2. Use WASD/QE to drive the simulated Go2. Verify robot responds to input.

Real hardware (verifies the full coordinator → adapter → SDK path):

  1. Install CycloneDDS C library (required by unitree-sdk2py):
    sudo apt install cmake gcc g++
    git clone https://github.com/eclipse-cyclonedds/cyclonedds.git /tmp/cyclonedds
    cd /tmp/cyclonedds && git checkout releases/0.10.x
    mkdir build && cd build
    cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local
    cmake --build . --parallel
    sudo cmake --install .
    
  2. dimos run unitree-go2-keyboard-teleop
  3. Use WASD/QE to drive the simulated Go2. Verify robot responds to input.
  4. to verify if topics are published correctly
dimos topic echo /coordinator/joint_state
dimos topic echo /cmd_vel

closes DIM-550

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 24, 2026

Greptile Summary

Adds Unitree Go2 quadruped control through the ControlCoordinator via a new UnitreeGo2Adapter implementing the TwistBaseAdapter protocol.

Key Changes:

  • New adapter: UnitreeGo2Adapter wraps Unitree SDK2 SportClient for 3-DOF velocity control (vx, vy, wz). Handles initialization sequence (StandUp → FreeWalk → Move) and reads actual velocities from SportModeState via DDS.
  • Protocol refactoring: Extracted HardwareAdapter base protocol with connect/disconnect/is_connected methods. Both TwistBaseAdapter and ManipulatorAdapter now inherit from this shared base.
  • Coordinator improvements: Refactored subscription management into _subscribe_if() helper with list-based cleanup. Added isinstance type narrowing for gripper methods to safely handle ManipulatorAdapter vs TwistBaseAdapter.
  • Blueprint: Added unitree-go2-keyboard-teleop with dual mode support (simulation uses MuJoCo, hardware uses coordinator with Go2 adapter).

The implementation follows existing patterns and maintains backward compatibility.

Confidence Score: 4/5

  • Safe to merge with one minor potential issue in exception handling
  • Well-structured implementation following existing patterns. The protocol refactoring is clean and the adapter implementation is thorough with proper state management. One potential issue: the bare except Exception on line 166 of the adapter silently catches all errors, which could hide bugs during development.
  • Pay attention to dimos/hardware/drive_trains/unitree_go2/adapter.py for the exception handling in read_velocities()

Important Files Changed

Filename Overview
dimos/hardware/drive_trains/unitree_go2/adapter.py New UnitreeGo2Adapter implementing TwistBaseAdapter for Go2 quadruped control via Unitree SDK2. Handles DDS communication, locomotion init sequence, and velocity commands.
dimos/hardware/drive_trains/spec.py Extracted HardwareAdapter base protocol with connect/disconnect/is_connected. TwistBaseAdapter now inherits from it.
dimos/hardware/manipulators/spec.py Imports HardwareAdapter from drive_trains spec. ManipulatorAdapter now inherits from shared base.
dimos/control/coordinator.py Refactored subscription management into _subscribe_if() with list-based cleanup. Gripper methods now use isinstance narrowing for type safety.
dimos/robot/unitree/go2/blueprints/basic/unitree_go2_keyboard_teleop.py Dual-mode blueprint: simulation uses go2_connection (MuJoCo), hardware uses control_coordinator with UnitreeGo2Adapter.

Sequence Diagram

sequenceDiagram
    participant User
    participant KeyboardTeleop
    participant Coordinator as ControlCoordinator
    participant Adapter as UnitreeGo2Adapter
    participant SDK as Unitree SDK2
    participant Go2 as Go2 Hardware

    Note over User,Go2: Initialization Phase
    User->>Coordinator: start()
    Coordinator->>Adapter: connect()
    Adapter->>SDK: ChannelFactoryInitialize(0)
    SDK-->>Adapter: DDS initialized
    Adapter->>SDK: SportClient.Init()
    SDK-->>Adapter: Client ready
    Adapter->>SDK: StandUp()
    SDK->>Go2: Stand command
    Go2-->>SDK: Standing (3s)
    Adapter->>SDK: FreeWalk()
    SDK->>Go2: Activate locomotion
    Go2-->>SDK: Ready (2s)
    Adapter-->>Coordinator: Connected & Ready
    Coordinator->>Adapter: write_enable(true)
    Adapter-->>Coordinator: Enabled

    Note over User,Go2: Runtime Control Loop
    User->>KeyboardTeleop: Press W (forward)
    KeyboardTeleop->>Coordinator: Twist(/cmd_vel) [vx, vy, wz]
    Coordinator->>Coordinator: _on_twist_command()
    Coordinator->>Adapter: write_velocities([vx, vy, wz])
    Adapter->>SDK: Move(vx, vy, wz)
    SDK->>Go2: DDS velocity command
    Go2-->>SDK: SportModeState (actual velocities)
    SDK-->>Adapter: State callback
    Adapter->>Adapter: Update _latest_state
    Coordinator->>Adapter: read_velocities()
    Adapter-->>Coordinator: [actual vx, vy, wz]
    Coordinator->>Coordinator: Publish joint_state

    Note over User,Go2: Shutdown Phase
    User->>Coordinator: stop()
    Coordinator->>Adapter: disconnect()
    Adapter->>SDK: StopMove()
    SDK->>Go2: Zero velocities
    Adapter->>SDK: StandDown()
    SDK->>Go2: Sit down
    Adapter-->>Coordinator: Disconnected
Loading

Last reviewed commit: 20b9e29

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

11 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

If the prebuilt wheel doesn't work on your system (e.g. unsupported
architecture), fall back to building from source:

```bash
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instructions exist in docs/usage/transports/dds.md . This shouldn't be in Go2.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated readme to point to dds.md and cut it down quite a bit.

wanted this to be a quickstart readme. Should I delete completely?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I think you can keep it, but what I'm not sure about is this being the main readme for Go2. The homepage links to this page and most of our Go2 stuff uses WebRTC.

Maybe put this in go2/dds.md? What do you think @leshy ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed all dds related things to the existing dds.md in the docs.

This readme is not just a quick starter to load the keyboard teleop for the go2

@mustafab0 mustafab0 force-pushed the feature/mustafa-go2-control-coordinator-adapter branch from 5ea0ca9 to f6ef415 Compare February 24, 2026 19:00
@mustafab0 mustafab0 linked an issue Feb 24, 2026 that may be closed by this pull request
@mustafab0 mustafab0 changed the title Feature/mustafa go2 control coordinator adapter Feature: go2 control coordinator TwistBase adapter Feb 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rule of three: if you have three duplicate things, it's best to generalize. You can add: Write Go2 ControlCoordinator Adapter

3 participants