Hardware Bridge Layer
Overview
Section titled “Overview”lite3_transfer is the low-level hardware and ROS2 bridge layer for Lite3, responsible for:
- Communicating with Lite3 robot firmware via UDP (using
Lite3_MotionSDK) - Converting robot state to ROS2 topics (
/JOINTS_DATA,/IMU_DATA) - Converting ROS2 control commands to UDP commands (
/JOINTS_CMD) - Reading Retroid gamepad data and publishing to
/GAMEPAD_DATA - Providing
/SDK_MODEand/EMERGENCY_STOPservices
Node Information
Section titled “Node Information”# ros2 node info /lite3/lite3_transfer Subscribers: /JOINTS_CMD: drdds/msg/JointsDataCmd Publishers: /IMU_DATA: drdds/msg/ImuData /JOINTS_DATA: drdds/msg/JointsData /EMERGENCY_STOP_SIGNAL: drdds/msg/StdMsgInt32 Service Servers: /SDK_MODE: drdds/srv/StdSrvInt32 /EMERGENCY_STOP: drdds/srv/StdSrvInt32Abstract Base Class
Section titled “Abstract Base Class”lite3_transfer defines its own RobotInterface abstract base class, which is independent of (and has no inheritance relationship with) the same-named class in Lite3_sdk_deploy. It is oriented toward the hardware bridge layer responsibilities, defining interfaces for reading state from UDP and publishing ROS2 topics.
Class Members
Section titled “Class Members”std::string robot_name_; // Robot nameconst int dof_num_; // Degrees of freedom countEigen::Matrix<float, Eigen::Dynamic, 5> joint_cmd_; // Joint command matrixstd::atomic<bool> start_flag_; // Start flagState Reading Interface
Section titled “State Reading Interface”virtual void Start() = 0;virtual void Stop() = 0;virtual double GetInterfaceTimeStamp() = 0;virtual VecXf GetJointPosition() = 0;virtual VecXf GetJointVelocity() = 0;virtual VecXf GetJointTorque() = 0;virtual Vec3f GetImuRpy() = 0;virtual Vec3f GetImuAcc() = 0;virtual Vec3f GetImuOmega() = 0;virtual VecXf GetContactForce() = 0;Data Publishing Interface
Section titled “Data Publishing Interface”virtual void PublishJointData() = 0;virtual void PublishImuData() = 0;Hardware Interface
Section titled “Hardware Interface”HardwareInterface inherits RobotInterface and rclcpp::Node, and is the core class of lite3_transfer.
Initialization Example
Section titled “Initialization Example”auto hardware_node = std::make_shared<HardwareInterface>("lite3");hardware_node->Start(); // Start UDP receiving, switch to SDK modeSDK Mode Switch
Section titled “SDK Mode Switch”virtual void Start(){ receiver_->StartWork(); sender_->ControlGet(2); // SDK mode}
virtual void Stop(){ sender_->ControlGet(1); // Robot mode}Data Publishing Frequency
Section titled “Data Publishing Frequency”Publishes joint and IMU data at 200Hz by default, adjustable via /SDK_MODE service.
UDP Command Sending Frequency
Section titled “UDP Command Sending Frequency”Joint commands are sent to robot firmware via a 1000Hz timer.
Gamepad Publisher Interface
Section titled “Gamepad Publisher Interface”Gamepad Implementation Abstract Base Class
Section titled “Gamepad Implementation Abstract Base Class”GamepadInterface inherits rclcpp::Node and is the abstract base class for all gamepad implementations.
Pure virtual interfaces:
virtual void Start() = 0;virtual void Stop() = 0;virtual drdds::msg::GamepadData GetGamepadData() = 0;The base class provides a default PublishGamepadData() implementation that calls GetGamepadData() at 200Hz and publishes to /GAMEPAD_DATA.
Gamepad Data Receiving
Section titled “Gamepad Data Receiving”RetroidGamepadPublisher receives gamepad data via UDP (default port 12121).
class RetroidGamepadPublisher : public GamepadInterface {private: std::shared_ptr<RetroidGamepad> gamepad_ptr_; // UDP receiver int port_; // UDP port};Data conversion:
drdds::msg::GamepadData GetGamepadData() override { RetroidKeys rt_keys_ = gamepad_ptr_->GetKeys(); drdds::msg::GamepadData msg; msg.left_axis_x = rt_keys_.left_axis_x; msg.left_axis_y = rt_keys_.left_axis_y; msg.right_axis_x = rt_keys_.right_axis_x; msg.right_axis_y = rt_keys_.right_axis_y; msg.buttons = rt_keys_.value; // Button bitmask return msg;}Multi-threaded Executor
Section titled “Multi-threaded Executor”lite3_transfer uses MultiThreadedExecutor to run the hardware interface and gamepad publisher simultaneously:
rclcpp::executors::MultiThreadedExecutor executor;executor.add_node(hardware_node);executor.add_node(gamepad_pub);executor.spin();Emergency Stop Chain
Section titled “Emergency Stop Chain”Emergency stop is implemented through a three-layer chain:
- UDP command layer:
lite3_sdk_servicereceivesestopcommand, calls/EMERGENCY_STOPservice - Hardware layer:
lite3_transfersends emergency stop command code0x21010C0Eto robot firmware - State machine layer: Notifies
Lite3_sdk_deployvia/EMERGENCY_STOP_SIGNALto switch to JointDamping