Close

Autocode-Commmunications

A project log for ICARUS Scout

The Scout is a tank-style robot.

david-gitzDavid Gitz 11/16/2017 at 12:530 Comments

I've found that when connecting different devices together it can be a bit of a burden to manage the different comm protocol/drivers between them.  This is more a problem when connecting OEM products, such as IMU's, gps's, etc.  But as these aren't as standardized this more focuses on devices that I have control over.  

For the Scout I have the following comm links:

Which is quite a lot, and each protocol has different requirements.  I really wanted to make this as generic as possible, i.e. have task specific code for reading/writing to the comm port and common encoding/decoding libraries that can be auto-generated.  This is really helpful when making changes to the comm protocol.

So here's what I've done:

1. Create a formatted xml file with each comm message specification.  This is something like:

<message name="Command" id="0xAB02">
        <description>
            <!--[CDATA[
                This message is used for command messages
            ]]-->
        </description>
        <protocols>
            <protocol name="UDP">
                <origin>GUI</origin>
                <retry>true</retry>
                <fields>
                    <field type="uint8_t" name="Command"></field>
                    <field type="uint8_t" name="Option1"></field>
                    <field type="uint8_t" name="Option2"></field>
                    <field type="uint8_t" name="Option3"></field>
                    <field type="std::string" name="CommandText"></field>
                    <field type="std::string" name="Description"></field>
                </fields>
            </protocol>
            <protocol name="Serial">
                <retry>true</retry>
                <origin>Master</origin>
                <origin>Slave</origin>
                <fields>
                    <field type="unsigned char" name="Command"></field>
                    <field type="unsigned char" name="Option1"></field>
                    <field type="unsigned char" name="Option2"></field>
                    <field type="unsigned char" name="Option3"></field>
                </fields>
            </protocol>
        </protocols>
    </message>

 Note that each message can be encoded with different protocols, such as UDP and SPI.

2. Created a python script that reads in this xml file and outputs the encoder/decoder code.  Currently I have to support 3 systems: Qt, Arduino and ROS.  Each of these systems has slightly different implementations, for example the Arduino autocode has different data types than the Qt autocode.  This script also copies the autocode to the appropriate locations on my development computer.

3. Add/update the write/read methods in each task that are affected, as the function definitions in the autocode files will change based on the message definition.

So far all the autocode files are in C++, I prefer to not use python in my projects as it tends to not run as fast.  I hoped this helps with other people's projects.  Here are some links:

Autocode Message Generation

Example Raspberry Pi auto-code using SPI and I2C

Example Raspberry Pi auto-code using UDP

Example Arduino auto-code using Serial and SPI

Example Qt auto-code using UDP

Discussions