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#.

5.1. Endianness

This system uses little endian. Please be careful when communicating to this system from a different endian environment (big endian environment).

5.2. Implementation of Instruction Packet Transmission Process

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);
}

5.3. Receiving Status Packet

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) { }
}