Packet Information
The MicroCART project uses custom packets to communicate with the quad. This may seem complex at first, but the structure of all packets is the same, only the formatting of the data differs between packets.
Introduction
All packets are the same in the sense that they have consistent headers with a start character and all end with a checksum. The basic structure is shown below.
Index | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
Message Parameter | Begin Character | Message Type | Message ID | Data Length | Data | Checksum |
Bytes | 1 | 2 | 2 | 2 | var | 1 |
The begin character is defined in the Message enum in commands.h. Message types are defined within the MessageTypeID enum in commands.h. Message ID is managed within the backend backend.c and is just a counter that is used in client_recv to number packets. Data length varies with the command that is being sent, but the length of a command is constant. The data is sent in a specific format set by commands. Lastly, checksum is computed within packet.c.
All packets sent within the system are commands, defined by the MessageTypeID enum referenced earlier, or a VPRN packet. Much of the time when flying autonomously the commands that the user is responsible for are the getparam and setparam packets that are used to set waypoints or change values within the computation graph, see control_algorithm.c for the PID blocks.
Adding a new packet and/or command (CLI or GUI to Backend/Quad)
There are many files that need to be created and changed to add a packet and/or a command. If only adding a command that does not send a packet only the CLI and GUI, frontend, and backend must be changed. If also sending a packet then commands and quad_app must also be changed. The instructions below will take you through what must be changed in all the different areas to support new functionality. Many times a good method to creating the new files is to copy the files from another command and change what you need.
CLI and GUI
CLI
Adding to the CLI is an easy process as most of the code is used to display help messages to the user. First, create a c file and c header file for your new commands. The cli.c does not need to be edited at all, but the header cli.h needs to be changed to recognize the command that you enter. Include your new header file and add to CommandNameIds, cli_functions, and commandsNames. The header file you create only needs the functions your intend to create. Inside the c write the functions declared in the h file and make sure that you have all the checks for help and display the correct usage if need be. Then call the frontend function you create in the next step and print out the return if there is one.
GUI
The GUI is programmed using QT as such it is written in C++ and uses a thread to do communication with the backend. The main files of the GUI to edit are controlworker.h and mainwindow.h and the corresponding source files. To add connectivity to the backend add a slot and signal to the controlworker.h file and add a corresponding signal and slot on the mainwindow.h. Next, connect the slots and signals in the mainwindow.cpp file and add any additional UI to the mainwindow.ui form.
Frontend
The frontend handles the writing of the command to the backend. You must create a new c file and c header file with the new functions that will be called from the clients.
The frontend functions always take in a connection to the backend from the client and can be configured to take in the other parameters you desire. Functions in frontend_common.h handle physically writing to the backend connection, meaning that your functions must only structure your commands to be parsed in the backend later. If this command expects a response then your method must execute a blocking condition until the response is obtained, parsed, and whatever action you plan for it taken. Also if you will be defining structs for the data passed into your method, add the structs to either your header file or frontend_common.h.
Backend
The file that contains the main function in the backend is backend.c and the message that is written by the frontend is passed here. If a client connection sent the message that is being called, the function client_recv() will be called to handle the request. This function decides how to process the data based upon the first word. If it is a command that is meant for the quadcopter a different path will be taken than if it is data being sent from the VRPN system. If you intend to send a packet this is where the first difference comes in, a command for the quadcopter should be declared in commands in the quad directory (discussed later) so that it is recognized by the findCommand() function. If your function is not intended to send a packet, your changes should be made in the condition that has msg_type = -1, otherwise take a look at the else condition.
The rest of the description is only needed when sending a packet. You must create a file for encoding your new command. This will require a c file and c header file. The function that should be made is an Encode for your new command. If also expecting a response from the quadcopter a Decode function will also have to be made. The main point of the encode function is to take the written command and parse it so that the values can be added to the data of the packet, decode reads the response data and populates a string for the frontend to parse.