Communication Architecture
UDP Communication
Section titled “UDP Communication”Data transmission between the perception host and the motion host is based on the UDP protocol, with raw data stored in little-endian byte order. On the perception host, the Message Transformer software package handles conversion between ROS messages and UDP messages:
- Converts UDP messages from the motion host into ROS topic messages and publishes them; also sends motion control commands from the perception host to the motion host via UDP;
- Receives control commands from the App to enable and disable certain AI functions on the perception host.

For the target IP when sending messages to the motion host, refer to Section 4.1 of the Lite3_MotionSDK documentation. The target port is 43893. By default, the motion host only reports data to the perception host. To receive data reported by the motion host, refer to Sections 4 and 5 of the Lite3_MotionSDK documentation. SSH into the motion host and modify the target address for data reporting to the development host’s static IP.
Protocol Format
Section titled “Protocol Format”First, the raw data format for UDP transmission is introduced. Based on whether complex data is carried, UDP commands can be divided into two categories: simple commands and complex commands.
Simple Commands
Section titled “Simple Commands”The simple command format is [xxxx yyyy zzzz], where each letter represents one byte.
Simple commands use the CommandHead struct to store raw data:
struct CommandHead{ uint32_t code; uint32_t paramters_size; uint32_t type;};xxxxis the value ofCommandHead.code, representing the command code.yyyyis the value ofCommandHead.paramters_size, representing the command value. When the command code has no valid command value,yyyy = 0.zzzzis the value ofCommandHead.type, used to distinguish command types. The type value for simple commands is 0, i.e.,zzzz = 0.
Usage example:
// Examplestruct CommandHead command_head = {0};command_head.code = 1; // Command codecommand_head.paramters_size = 0; // Command valuecommand_head.type = 0; // Command typesendto(sfd, &command_head, sizeof(command_head), destination_address, address_length)Complex Commands
Section titled “Complex Commands”Complex commands carry specific data content, with the format [xxxx yyyy zzzz bbbbbbbb......], where each letter represents one byte.
Complex commands use the Command struct to store raw data:
struct CommandHead{ uint32_t code; uint32_t paramters_size; uint32_t type;};
const uint32_t kDataSize = 256;
struct Command{ CommandHead head; uint32_t data[kDataSize];};xxxxis the value ofCommand.head.code, representing the command code.yyyyis the value ofCommand.head.paramters_size, representing the length of the data contentbbbbbbbb.......zzzzis the value ofCommand.head.type, used to distinguish command types. The type value for complex commands is 1, i.e.,zzzz = 1.bbbbbbbb......is the value ofCommand.data, representing the data content carried by the command.
Usage example:
// Exampleint32_t to_be_send_data[64];struct Command command = {0};command.head.code = 52; // Command codecommand.head.paramters_size = sizeof(to_be_send_data); // Data lengthcommand.head.type = 1; // Command typememcpy(&command.data, &to_be_send_data, sizeof(to_be_send_data));sendto(sfd, &command, sizeof(command.head) + command.head.paramters_size, destination_address, address_length);Receiving Complex Commands
Section titled “Receiving Complex Commands”Taking joint velocity as an example:
struct RobotJointVel{ double joint_vel[12];};
// Taking joint velocity as an examplestruct CommandMessage{ CommandHead command; uint8_t data_buffer[1024];};
CommandMessage cm;size_t recv_size = 0;recv_size = recvfrom(server_fd, &cm, sizeof(cm), 0, (sockaddr*)&client_addr, &sockaddr_in_size);
if(cm.command.type == 1){ // Check if complex command if(recv_size == cm.command.paramters_size + sizeof(cm.command)){ uint8_t* temp_values = new uint8_t[cm.command.paramters_size]; memcpy(temp_values, cm.data_buffer, cm.command.paramters_size); if(cm.command.code == 0x0903){ // Check command code, parse data RobotJointVel *joint_vel = (RobotJointVel *)temp_values; } }}