Skip to content

Motion Control Protocol (UDP)

  • jy_exe version V2.2.90 or later;
  • Full system package version V4.0.0 or later.

To check the jy_exe version, log in to the motion host (default address 192.168.1.103) and run:

dpkg -l jy_exe

Note: Communication between the motion host, perception host, and gamepad uses UDP protocol with little-endian byte order for raw data.

UDP commands are divided into two categories: simple commands and complex commands.

Simple command format: [xxxx yyyy zzzz], where each letter represents one byte.

Simple commands use the CommandHead struct:

struct CommandHead{
uint32_t code;
uint32_t paramters_size;
uint32_t type;
};
  • xxxx is CommandHead.code, the command code.
  • yyyy is CommandHead.paramters_size, the command value. When no valid value exists, yyyy = 0.
  • zzzz is CommandHead.type, the command type. Simple commands have type 0, i.e., zzzz = 0.

Usage example:

struct CommandHead command_head = {0};
command_head.code = 1; // Command code
command_head.paramters_size = 0; // Command value
command_head.type = 0; // Command type
sendto(sfd,&command_head,sizeof(command_head),destination_address,address_length)

Complex commands carry complex data content, format: [xxxx yyyy zzzz bbbbb……].

Complex commands use the Command struct:

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];
};
  • xxxx is Command.head.code, the command code.
  • yyyy is Command.head.paramters_size, the length of data content bbbbb……
  • zzzz is Command.head.type, complex commands have type 1, i.e., zzzz=1.
  • bbbbb…… is Command.data, the data content.

Usage example:

int32_t to_be_send_data[64];
struct Command command = {0};
command.head.code = 52; // Command code
command.head.paramters_size = sizeof(to_be_send_data);// Data length
command.head.type = 1; // Command type
memcpy(&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);

Example using joint velocity:

struct RobotJointVel{
double joint_vel[12];
}; // Example: joint velocity
struct 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 for 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;
}
}
}

Note: For all command codes in hexadecimal form described in this section, the first 2 digits identify the command source: when sending from a gamepad or similar remote terminal, use 0x21 as the first two digits (e.g., 0x21040001); when sending from a navigation module or similar autonomous movement algorithm module, use 0x31 (e.g., 0x31040001). Command codes in the following text default to 0x21 prefix.