Skip to main content

ROS 2 Package Structure and Topic Description

This section describes the ROS 2 packages and main control interfaces for AI Sapiens.

Package Overview

PackageRole
ai_sapiensMeta package that pulls in the AI Sapiens ROS 2 stack
ai_sapiens_interfacesShared messages and services for impedance commands, RC status, mode control, and API heartbeat
ai_sapiens_bringupLaunch files and controller manager configuration for K1
ai_sapiens_descriptionURDF, meshes, MuJoCo assets, and ros2_control xacro
ai_sapiens_joint_group_impedance_controllerros2_control joint-group impedance command controller
ai_sapiens_rc_broadcasterPublishes remote-controller Joy and RC status from the HAT board
ai_sapiens_sim2realRealtime policy runtime, mode FSM, and hardware command publisher

AI Sapiens-specific message and service types live in ai_sapiens_interfaces. Controllers and Sim2Real depend on that package instead of defining their own interface types.

Control Topic Description (Impedance Control Mode)

AI Sapiens uses a ROS 2 control controller configuration file to define the joint command order for Impedance Control Mode. The controller manager loads this YAML file at bringup time, and the joint_group_impedance_controller reads the joints list as the command array order.

For the AI Sapiens K1 configuration, the controller file is:

ai_sapiens_bringup/config/k1_rev1/k1_rev1_controllers.yaml

When the controller is named joint_group_impedance_controller, its private command topic resolves to:

/joint_group_impedance_controller/commands

Each index in positions, feedforward, kp, and kd must match the same index in the YAML joints list. For example, index 0 commands left_hip_pitch_joint, index 1 commands left_hip_roll_joint, and so on.

Controller YAML

The controller manager receives the controller parameters from the bringup package. The important part for command indexing is the joints list under joint_group_impedance_controller.ros__parameters.

joint_group_impedance_controller:
ros__parameters:
# === Command array order (~/commands JointImpedanceCommand) ===
joints:
- left_hip_pitch_joint
- left_hip_roll_joint
- left_hip_yaw_joint
- left_knee_joint
- left_ankle_pitch_joint
- left_ankle_roll_joint
- right_hip_pitch_joint
- right_hip_roll_joint
- right_hip_yaw_joint
- right_knee_joint
- right_ankle_pitch_joint
- right_ankle_roll_joint
- waist_yaw_joint
- left_shoulder_pitch_joint
- left_shoulder_roll_joint
- left_shoulder_yaw_joint
- left_elbow_joint
- left_wrist_roll_joint
- right_shoulder_pitch_joint
- right_shoulder_roll_joint
- right_shoulder_yaw_joint
- right_elbow_joint
- right_wrist_roll_joint

Command Message

The command topic uses ai_sapiens_interfaces/msg/JointImpedanceCommand.msg.

std_msgs/Header header

float64[] positions # rad
float64[] feedforward # N*m
float64[] kp # N*m/rad
float64[] kd # N*m/(rad/s)

The four arrays are parallel arrays:

FieldMeaning
positions[i]Desired joint position for joints[i] in rad\mathrm{rad}.
feedforward[i]Feedforward torque for joints[i] in Nm\mathrm{N}\cdot\mathrm{m}.
kp[i]Position gain for joints[i] in Nm/rad\mathrm{N}\cdot\mathrm{m}/\mathrm{rad}.
kd[i]Damping gain for joints[i] in Nm/(rad/s)\mathrm{N}\cdot\mathrm{m}/(\mathrm{rad}/\mathrm{s}).

All four arrays should have the same length as the configured joints list. If the array lengths or order do not match the controller YAML, commands may be applied to the wrong joint or rejected by the controller.

In short, the YAML file is the source of truth for joint indexing. Any node publishing JointImpedanceCommand should build its arrays in exactly this order before sending commands to the impedance controller.