--- id: sdk-programming title: "SDK & Programming Interface" status: established source_sections: "reference/sources/github-unitree-sdk2.md, reference/sources/github-unitree-sdk2-python.md, reference/sources/official-get-sdk.md, reference/sources/official-dds-services.md" related_topics: [ros2-integration, networking-comms, joint-configuration, sensors-perception] key_equations: [] key_terms: [unitree_sdk2, dds, cyclone_dds, pybind11, lowcmd, lowstate, motor_cmd, force_position_hybrid, domain_id] images: [] examples: [] open_questions: - "Python vs C++ API coverage parity (are all C++ features wrapped?)" - "High-level sport mode API details for G1 specifically" - "Camera API — how to access D435i frames via SDK" --- # SDK & Programming Interface Software development kits, APIs, and programming interfaces for controlling the G1. ## 1. Unitree SDK2 (C++) The primary SDK for robot control. DDS-based, works without ROS2 but remains ROS2-compatible. [T0 — GitHub] | Property | Value | |-------------------|---------------------------------------------| | Repository | https://github.com/unitreerobotics/unitree_sdk2 | | Version | v2.0.2 (as of July 2025) | | Language | C++ (99.2% of codebase) | | License | BSD-3-Clause | | Middleware | CycloneDDS v0.10.2 | | Supported OS | Ubuntu 20.04 LTS | | Architectures | aarch64 (Jetson), x86_64 (development PC) | | Compiler | GCC 9.4.0+ | | Build system | CMake 3.10+ | | GitHub stars | ~888 | ### Dependencies ``` sudo apt install cmake libyaml-cpp-dev libeigen3-dev libboost-all-dev libspdlog-dev libfmt-dev ``` ### Build & Install ```bash git clone https://github.com/unitreerobotics/unitree_sdk2.git cd unitree_sdk2 mkdir build && cd build cmake .. && make # System-wide install (optional) sudo make install # Custom install location cmake .. -DCMAKE_INSTALL_PREFIX=/custom/path sudo make install ``` ### Key Features - Request-response and topic subscription/publishing patterns - Low-level motor control (LowCmd/LowState) - High-level sport mode commands - IMU data access - Wireless controller input - Native DDS — no ROS2 dependency required ## 2. Python SDK (unitree_sdk2_python) Python wrapper maintaining API consistency with C++ SDK. [T0 — GitHub] | Property | Value | |-------------------|---------------------------------------------| | Repository | https://github.com/unitreerobotics/unitree_sdk2_python | | Binding | pybind11 | | Python version | ≥ 3.8 | | CycloneDDS version | 0.10.2 (critical — must match) | | License | BSD-3-Clause | | GitHub stars | ~579 | ### Installation ```bash git clone https://github.com/unitreerobotics/unitree_sdk2_python.git cd unitree_sdk2_python pip3 install -e . ``` **Note:** May require separate CycloneDDS compilation from source and setting the `CYCLONEDDS_HOME` environment variable. [T1] ### G1 Examples Located in `/example/g1/` directory: - **High-level control:** stand/lie down, velocity commands, attitude adjustment, trajectory tracking - **Low-level control:** direct motor position/torque commands - **Peripherals:** wireless controller, front camera (OpenCV), obstacle avoidance, LED/volume control All examples require a network interface parameter (e.g., `enp2s0`) for robot connectivity. ## 3. Control Modes The SDK supports multiple control modes via the `MotorCmd_` structure: [T0 — Developer Guide] | Mode | Field | Description | |--------------------|-------|-----------------------------------------------------| | Position control | `q` | Target joint angle in radians | | Velocity control | `dq` | Target joint velocity in rad/s | | Torque control | `tau` | Feed-forward torque in Nm | | Force-position hybrid | `q` + `tau` | Position target with torque feed-forward | | Enable/disable | `mode`| 0 = Disable motor, 1 = Enable motor | **Control loop rate:** 500 Hz (commands should be published at this rate for smooth control) ## 4. Data Streams (DDS Topics) ### Body Control | Topic | Type | Direction | Description | |-------------------|----------------------------------------|------------|-------------------------------| | `rt/lowstate` | `unitree_hg::msg::dds_::LowState_` | Subscribe | Full robot state | | `rt/lowcmd` | `unitree_hg::msg::dds_::LowCmd_` | Publish | Motor commands for all joints | ### Dexterous Hand (Dex3-1) | Topic | Type | Direction | Description | |---------------------------|-------------------------------------|------------|----------------------| | `rt/dex3/left/cmd` | `unitree_hg` protocol | Publish | Left hand commands | | `rt/dex3/right/cmd` | `unitree_hg` protocol | Publish | Right hand commands | | `rt/dex3/left/state` | `unitree_hg` protocol | Subscribe | Left hand state | | `rt/dex3/right/state` | `unitree_hg` protocol | Subscribe | Right hand state | ### LowState_ Contents (HG variant for G1) - `mode_pr`: Parallel mechanism control mode - `mode_machine`: G1 type identifier (5=g1_29dof_rev_1_0, 11-16=newer revisions) - `tick`: Timer (increments every 1ms) - `imu_state`: IMU sensor data (quaternion [w,x,y,z], angular velocity, acceleration) - `motor_state`: State for all body motors (position, velocity, torque) - `wireless_remote`: Remote control data (all zeros until button pressed) - `crc`: Checksum for data integrity ### LowCmd_ Variants [T1 — Verified 2026-02-15] The G1 uses the HG message variant (`unitree_hg_msg_dds__LowCmd_`), NOT the GO variant: | Field | HG (G1) | GO (Go2) | |-------|:---:|:---:| | `mode_pr` | Yes | No | | `mode_machine` | Yes | No | | `motor_cmd` | Yes | Yes | | `reserve` | Yes | No | | `crc` | Yes | Yes | | `head` | **No** | Yes | | `level_flag` | **No** | Yes | | `gpio` | **No** | Yes | Using the wrong variant will cause `AttributeError` at runtime. Always use `unitree_hg_msg_dds__LowCmd_()` for G1. ### mode_machine Values [T1] | Value | Model | Hip Pitch Ratio | Hip Roll Ratio | Notes | |:---:|---|:---:|:---:|---| | 2 | g1_29dof (old) | 14.3 | 14.5 | Pre-rev-1.0 | | 5 | g1_29dof_rev_1_0 | 14.3 | 22.5 | Common for EDU units | | 11 | g1_29dof_mode_11 | 22.5 | 22.5 | Newer — both hips upgraded | | 12 | g1_29dof_mode_12 | 22.5 | 22.5 | Newer variant | | 13-16 | g1_29dof_mode_13-16 | varies | 22.5 | 5010 wrist motor variants | **Important:** Always read `mode_machine` from `rt/lowstate` rather than hardcoding. The firmware uses this value to interpret joint commands with the correct gear ratios. ## 5. Development Workflow 1. **Simulation first:** Test with `unitree_mujoco` (same DDS interface, switch domain ID) 2. **Network setup:** Connect to robot's WiFi or Ethernet (192.168.123.0/24) 3. **Verify connection:** Subscribe to `rt/lowstate` to confirm data flow 4. **Start simple:** Begin with high-level sport mode commands before low-level control 5. **Deploy to Jetson:** Cross-compile or develop directly on the onboard Jetson Orin NX ## 6. Code Examples See `examples/` for worked examples. Key patterns: - **Subscriber pattern:** Create DDS subscriber for `rt/lowstate`, read joint states in callback - **Publisher pattern:** Create DDS publisher for `rt/lowcmd`, send motor commands at 500 Hz - **High-level pattern:** Use sport mode request/response API for walking, standing, etc. ## Key Relationships - Controls: [[joint-configuration]] (joint-level commands via MotorCmd_) - Reads from: [[sensors-perception]] (IMU, encoder data via LowState_) - Integrates with: [[ros2-integration]] (same DDS layer) - Communicates via: [[networking-comms]] (CycloneDDS transport)