Skip to content

Source of truth

This page mirrors robot_driver/README.md. Edit that file to update.

Robot Driver

Overview

This package is the hardware abstraction and low-level control layer of Quad-SDK. It owns the main control loop: ingesting the most recent local plan, running state estimation, computing joint torques via the selected leg controller, and delivering those commands to simulation (Gazebo, MuJoCo) or hardware (Unitree Go1/Go2/B2 via unitree_sdk2, Ghost Robotics platforms via mblink). It also hosts the behavior state machine that transitions between safety, sit, stand, and stance/swing modes.

License

The source code is released under a MIT License.

Authors: Joe Norby and Ardalan Tajbakhsh

Affiliation: Robomechanics Lab, Carnegie Mellon University

Maintainer: David Ologan (dologan@andrew.cmu.edu)

Tested under ROS2 Jazzy on Ubuntu 24.04. This is research code; expect frequent changes and no fitness for any particular purpose.

Build

colcon build --packages-select robot_driver

Optional dependency: ONNX Runtime โ€” if available, the learned_policy controller is compiled for running learned locomotion policies.

Unit Tests

colcon test --packages-select robot_driver
colcon test-result --verbose

Usage

Launched as part of robot bringup โ€” not run standalone:

ros2 launch quad_utils quad_gazebo.py        # simulation
ros2 launch quad_utils robot_bringup.py      # hardware or sim, configurable

Architecture

The driver is a single node (robot_driver_node) composed of three pluggable abstractions:

  1. HardwareInterface โ€” talks to the physical motors. Implementations:
  2. spirit_interface โ€” Ghost Robotics Spirit via mblink.
  3. go2_interface โ€” Unitree Go2 via unitree_sdk2.
  4. go2w_interface โ€” Unitree Go2-W (wheeled) via unitree_sdk2; extends go2_interface with wheel-motor commands at LowCmd indices 12-15.
  5. StateEstimator โ€” fuses IMU, joint encoders, and optional mocap. Implementations:
  6. comp_filter_estimator โ€” complementary filter fusing IMU with mocap (or simulator pose).
  7. ekf_estimator โ€” contact-aided extended Kalman filter; calls quad_utils::QuadKD2 (Pinocchio) for forward kinematics and Jacobians.
  8. LegController โ€” produces joint torques from the local plan. Implementations:
  9. inverse_dynamics_controller โ€” default; inverts the commanded GRFs through leg dynamics.
  10. grf_pid_controller โ€” PID tracking on GRFs.
  11. inertia_estimation_controller โ€” system-identification aid.
  12. joint_controller โ€” direct joint-space PD tracking.
  13. underbrush_inverse_dynamics โ€” swing-leg variant for the Underbrush platform.
  14. learned_policy โ€” ONNX-policy controller running at a separate policy_inference_rate.

Config

  • config/robot_driver.yaml โ€” rates, filter coefficients, EKF noise/bias, learned-policy settings.
  • config/robot_driver_topics.yaml โ€” topic remappings.

Nodes

robot_driver_node

The main control-loop node. Runs at update_rate Hz (default 500 Hz). Each iteration it reads sensors, runs the state estimator, computes commands via the leg controller, and writes to the hardware interface. It also ticks the control-mode state machine (safety โ†” sit โ†” stand โ†” stance/swing) based on the received local plan, heartbeats, and control-mode commands.

Subscribed Topics

Published Topics

Key Parameters

Rates and timeouts:

  • robot_driver.update_rate (double, default: 500.0) โ€” control loop in Hz.
  • robot_driver.publish_rate (double, default: 500.0) โ€” command publish rate in Hz.
  • robot_driver.mocap_rate (double, default: 360.0) โ€” mocap frame rate (must match source or velocities mis-scale).
  • robot_driver.mocap_dropout_threshold (double, default: 0.035) โ€” s.
  • robot_driver.filter_time_constant (double, default: 0.01) โ€” s.
  • robot_driver.input_timeout (double, default: 0.2) โ€” s without a plan before safety mode.
  • robot_driver.state_timeout (double, default: 0.1) โ€” s.
  • robot_driver.heartbeat_timeout (double, default: 0.2) โ€” s.

Complementary filter โ€” state-space coefficients low_pass_{a,b,c,d} and high_pass_{a,b,c,d}, obtained from c2d(1/sยท(1-G(s))) and c2d(sยทG(s)) for a 2nd-order low-pass G(s).

EKF noise / bias (when ekf_estimator is selected): na, nv, ng, ba, bg, nf, nfk, ne, nfh, P0, contact_w, thresh_out, foot_radius, and per-axis bias_{x,y,z,r,p,w}.

Learned policy:

  • robot_driver.model_path (string) โ€” absolute path to the ONNX policy file.
  • robot_driver.policy_inference_rate (double, default: 50.0) โ€” Hz.
  • robot_driver.cmd_vel_filter_const, cmd_vel_scale โ€” applied to policy inputs.

Mode gains โ€” sit_kp/kd, stand_kp/kd, stance_kp/kd, swing_kp/kd, swing_kp_cart/kd_cart, safety_kp/kd (all 3-vectors).

Joint targets โ€” stand_joint_angles (default [0.0, 0.76, 1.52]), sit_joint_angles (default [0.0, 0.0, 0.0]).

Underbrush swing โ€” underbrush_swing.* parameters for the Underbrush controller variant.

See config/robot_driver.yaml for the full set.

Bugs & Feature Requests

Please report bugs and request features using the Issue Tracker.