Mavlink
Introduction
The MAVLink protocol have been implemented in the Flexbot project to secure a standardized communication protocol with as little overhead as possible. This allows for not only transferring data over the serial USB interface between the Teensy and Intel NUC, but also for wireless transformation of all data from the NUC to client(s) and vice versa.
For more information of the MAVLink protocol itself see http://qgroundcontrol.org/mavlink/start.
This page will give information on how MAVLink is utilized in this project as well as how to update the main flexbot.xml message container and generate the C-headers + Python files needed.
Prerequisites
Make sure to have downloaded the newest version of the Flexbot repository and head into code/MAVLink/ and make sure flexbot.xml, Bridge/ and Generator/ is present.
Adding messages to Flexbot
All messages/signals to/from Flexbot are defined in flexbot.xml. A message is defined by an ID, name and description. All signals related to this message is defined by a type (uint8_t, float, etc), name and signal description.
E.g. to add a new message to Flexbot identify the last listed message ID and append to it:
<message id="16" name="TestSignal"> <description>Test signal for this example</description> <field type="float" name="value1">Floating point test value.</field> <field type="uint8_t" name="publish">Sets whether or not Teensy should publish this message.</field> </message>
An important note which goes for all messages is that it must contain the publish signal. This signal allows clients to subscribe to different messages and will save bandwidth as the Teensy only will publish messages that has subscribers.
By updating flexbot.xml nothing magical will happen. In order to integrate the new version of the message definitions C-headers must be generated and the source code on both Teensy and the GUI must be altered to support the new message definitions.
Generating C-headers & Python file
In order to generate the header files used by the Teensy and GUI, a MAVLink generator program is used. This translated the message definition file (flexbot.xml) into a bunch of files related to the chosen language. In order to run the generator, go to /code/MAVLink/Generator and type
python mavgenerate.py
This program should only depend on Python itself and Tkinter. See https://github.com/mavlink/mavlink for references.
In the GUI, choose flexbot.xml and set an output path. Set the protocol to version 1.0 and choose the desired language. By pressing generate, the program should generate a set files if C has been chosen and a single file for Python.
What to do with these is broken down in the sections below.
Python
For Python, the generator produces an error. This is corrected by changing line 13 from
13: from ...generator.mavcrc import x25crc
to
13: from mavcrc import x25crc
Now move the newly generated file to /code/MAVLink/Bridge and replace it with the one already existing.
C
The files generated for C will need to be put into two locations. First copy all the generated files into
/code/Teensy/src/mavlink
and replace with the ones already existing. Repeat the process for the GUI - files are located at
/code/GUI/flexbot_visualizer/mavlink
Update source code to support new messages
This is considered the most important part. This ensures that the newly introduced messages are supported by software in both the Teensy source code and in the Flexbot Visualizer. There is a bit manual labour here, but with the given MAVLink protocol there is no way around it.
Updating Teensy source code
A few steps needs to be taken here to ensure that the new message is supported. First locate and open
/code/Teensy/src/command.cpp
Starting from line 320 or so is a function called
void MAVLink_msg_handler(mavlink_message_t _msg)
This is where the incomming MAVLink messages will be processed. In order to support new messages there needs to be a section that processes each message. Follow the syntax in the code to append to the function.
E.g. for a message with ID = 2
else if(ID == 3) { // DCCmd mavlink_dcwheelcmd_t msg; mavlink_msg_dcwheelcmd_decode(&_msg,&msg); dc_wheel.set(msg.dutycycle,msg.direction); }