This page explains the specific examples of communication packet processing for controlling the robot via the cradle. Section 5.4. includes sample programs in Python and C#.
This system uses little endian. Please be careful when communicating to this system from a different endian environment (big endian environment).
First, the implementation of the Instruction Packet transmission process is described.
The cradle is recognized as a USB serial device by the host PC. As for the settings for serial communication, specify 1,000,000 bps only for the baud rate, and set the other settings to default.
<aside> <img src="/icons/warning_red.svg" alt="/icons/warning_red.svg" width="40px" /> The cradle will not receive all packets until it receives a Header block (H1: 0xFF, H2: 0xFD) in a packet sent from the host PC. Even if a packet is correctly received, the command will be rejected if the reception interval between the preceding and following packets exceeds 500 ms.
</aside>
Below is an example implementation in C#. The example shows the process of sending the Write Motor Speed (INST: 0x03) command shown in Table 4-2-1.
Table 4-2-1 Example of Instruction Packet for Write Motor Speed (INST: 0x03)
H1 | H2 | LEN_L | LEN_H | INST | P1 | P2 | P3 | SUM |
---|---|---|---|---|---|---|---|---|
0xFF | 0xFD | 0x05 | 0x00 | 0x03 | 0x01 | 0xD8 | 0x28 | 0x03 |
private void writeMotorSpeed(byte id, int right, int left)
{
byte rightMotor = (byte)(right);
byte leftMotor = (byte)(left);
byte[] data = new byte[9] { 0xFF, 0xFD, 0x05, 0x00, 0x03, id, rightMotor, leftMotor, 0x00 };
data[8] = calculateCheckSum(data);
WriteSerial(data);
}
Next, we will explain the process of receiving the Status Packet.
The robot regularly sends its own information to the cradle via wireless communication. The cradle acquires the information and sends a Status Packet to the host PC. The application on the host PC side can obtain the robot status from the Status Packet and control the robot appropriately through the Instruction Packet.
Below is an example of receiving and processing a Status Packet in C#. The following example implements the receiving process in the case of Robot's Status (INST: 0x21
).
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
byte buf;
byte[] rcvData = new byte[100];
int len;
int pos = 0;
int tmpData;
try
{
len = sp.Read(rcvData, 0, 100);
while (pos < len)
{
buf = rcvData[pos++];
if (rStat == 0) rPos = 0;
rData[rPos++] = buf;
switch (rStat)
{
case 0: // Header 0xFF
rStat = (buf == 0xFF) ? (rStat + 1) : 0;
break;
case 1: // Header 0xFD
rStat = (buf == 0xFD) ? (rStat + 1) : 0;
break;
case 2: // Length_L
rLength = buf; rStat++; break;
case 3: // Length_H
rLength += (buf << 8); rStat++; break;
case 4: // Instruction
rCommand = buf;
if (rLength == 2) rStat += 2;
else rStat++;
break;
case 5: // Param
if (rPos == rLength + 3) rStat++;
break;
case 6: // CheckSum
rStat = 0;
if (buf != calculateCheckSum(rData, rPos)) break;
switch (rCommand)
{
case (byte)Command.status:
tmpId = (rData[5] & 0b01111111) - 1;
if (tmpId >= 16 || tmpId < 0) break;
robot[tmpId].position.x = (Int16)(rData[6] + (rData[7] << 8));
robot[tmpId].position.y = (Int16)(rData[8] + (rData[9] << 8));
robot[tmpId].degree = (Int16)(rData[10] + (rData[11] << 8));
robot[tmpId].voltage = (Int16)(rData[12] + (rData[13] << 8));
robot[tmpId].yaw = (Int16)(rData[14] + (rData[15] << 8));
robot[tmpId].pitch = (Int16)(rData[16] + (rData[17] << 8));
robot[tmpId].roll = (Int16)(rData[18] + (rData[19] << 8));
robot[tmpId].receiveCount++;
break;
}
break;
}
}
}
catch (Exception ex) { }
}