SDK Interfaces
Robot Base Class Interface
Section titled “Robot Base Class Interface”RobotInterface is the abstract base class for all robot integrations. It is responsible for:
- Creating a ROS2 node (node name
rl_deploy) - Providing robot state reading interfaces
- Providing joint command sending interfaces
- Providing extended reading interfaces for battery, IMU, temperature, etc.
Construction Example
Section titled “Construction Example”RobotInterface(const std::string& robot_name, int dof_num)State Reading Example
Section titled “State Reading Example”virtual VecXf GetJointPosition() = 0; // Get 12 joint positionsvirtual VecXf GetJointVelocity() = 0; // Get 12 joint velocitiesvirtual VecXf GetJointTorque() = 0; // Get 12 joint torquesvirtual Vec3f GetImuRpy() = 0; // Get IMU roll/pitch/yaw anglesvirtual Vec3f GetImuAcc() = 0; // Get IMU 3-axis accelerationvirtual Vec3f GetImuOmega() = 0; // Get IMU 3-axis angular velocityvirtual VecXf GetContactForce() = 0; // Get quadruped foot-end contact forcesCommand Sending Example
Section titled “Command Sending Example”virtual void SetJointCommand(Eigen::Matrix<float, Eigen::Dynamic, 5> input) = 0;The input matrix has 5 columns per row corresponding to: kp, goal_angle_pos, kd, goal_vel, torque_feedforward.
DDS Implementation Interface
Section titled “DDS Implementation Interface”DdsInterface is the ROS2 topic connection implementation. It subscribes to robot feedback and publishes joint commands.
Subscription and Publishing Example
Section titled “Subscription and Publishing Example”joint_cmd_pub_ = node_->create_publisher<drdds::msg::JointsDataCmd>("/JOINTS_CMD", 10); // Publish joint control commandsjoint_data_sub_ = node_->create_subscription<drdds::msg::JointsData>("/JOINTS_DATA", 10, ...); // Subscribe to joint state feedbackimu_data_sub_ = node_->create_subscription<drdds::msg::ImuData>("/IMU_DATA", 10, ...); // Subscribe to IMU datahealth_data_sub_ = node_->create_subscription<drdds::msg::BatteryData>("/BATTERY_DATA", 10, ...); // Subscribe to battery dataJoint Command Example
Section titled “Joint Command Example”SetJointCommand maps the input matrix to drdds::msg::JointsDataCmd:
msg.data.joints_data[i].position = (input(i, 1) - joint_config_[i].offset) * joint_config_[i].dir; // Target position (with offset and direction mapping)msg.data.joints_data[i].velocity = input(i, 3) * joint_dir_[i]; // Target velocitymsg.data.joints_data[i].torque = input(i, 4) * joint_dir_[i]; // Feedforward torquemsg.data.joints_data[i].kp = input(i, 0); // Position stiffness gainmsg.data.joints_data[i].kd = input(i, 2); // Velocity damping gainmsg.data.joints_data[i].control_word = kIndexMotorControl; // Control wordState Callback Example
Section titled “State Callback Example”void Handler(const drdds::msg::JointsData::SharedPtr msg) // Joint data callbackvoid HandlerIMU(const drdds::msg::ImuData::SharedPtr msg) // IMU data callbackvoid HandlerHealth(const drdds::msg::BatteryData::SharedPtr msg) // Battery data callbackRobot Control Interface
Section titled “Robot Control Interface”Lite3Interface inherits DdsInterface, is a 12 DOF quadruped robot, and does not perform offset and direction conversion on joint data.
Initialization Example
Section titled “Initialization Example”Lite3Interface(const std::string &robot_name) : DdsInterface(robot_name, 12) { ...}Joint Command Example in Real Robot Mode
Section titled “Joint Command Example in Real Robot Mode”Lite3Interface’s SetJointCommand uses input values directly without offset and direction mapping:
virtual void SetJointCommand(Eigen::Matrix<float, Eigen::Dynamic, 5> input) { for (int i = 0; i < dof_num_; ++i) { msg.data.joints_data[i].position = input(i, 1); msg.data.joints_data[i].velocity = input(i, 3); msg.data.joints_data[i].torque = input(i, 4); msg.data.joints_data[i].kp = input(i, 0); msg.data.joints_data[i].kd = input(i, 2); msg.data.joints_data[i].control_word = kIndexMotorControl; }}Joint Callback Example in Real Robot Mode
Section titled “Joint Callback Example in Real Robot Mode”Handler also reads raw values directly without offset and direction mapping:
virtual void Handler(const drdds::msg::JointsData::SharedPtr msg) override { for (int i = 0; i < dof_num_; ++i) { joint_pos_(i) = msg->data.joints_data[i].position; joint_vel_(i) = msg->data.joints_data[i].velocity; joint_tau_(i) = msg->data.joints_data[i].torque; }}ROS2 Communication Interface
Section titled “ROS2 Communication Interface”ROS2 Topics
Section titled “ROS2 Topics”Main topics:
/JOINTS_CMD— Joint control commands/JOINTS_DATA— Joint state feedback/IMU_DATA— IMU data/BATTERY_DATA— Battery data (not yet available)/GAMEPAD_DATA— Retroid gamepad data/EMERGENCY_STOP_SIGNAL— Cross-process emergency stop signal
Message Types
Section titled “Message Types”The current code directly uses message types from drdds:
drdds/msg/JointsDatadrdds/msg/JointsDataCmddrdds/msg/ImuDatadrdds/msg/BatteryDatadrdds/msg/GamepadDatadrdds/msg/StdMsgInt32
Data Flow Example
Section titled “Data Flow Example”Keyboard control mode simulation data flow:
graph LR A["/rl_deploy"] -->|/JOINTS_CMD| B["/mujoco_simulation(Sim) or /lite3(Real)"] B -->|/IMU_DATA| A B -->|/JOINTS_DATA| AGamepad control mode real robot data flow:
graph LR A["/rl_deploy"] -->|/JOINTS_CMD| B["/lite3"] B -->|/IMU_DATA| A B -->|/JOINTS_DATA| A C["/retroid_gamepad"] -->|/GAMEPAD_DATA| AROS2 Services
Section titled “ROS2 Services”lite3_transfer provides the following ROS2 services:
/SDK_MODE: Set publish frequency or exit SDK mode (drdds/srv/StdSrvInt32)/EMERGENCY_STOP: Trigger emergency stop (drdds/srv/StdSrvInt32)