Programming Manual UAV
Mavlink communication in C++/Arduino IDE
Written By
Mohd Azizi Bin Ab Malek September 2016
MAvlink message communication programming procedure Request Data
Read for received communication
1
e.g function : request_data()
Handle the message receive as a usable format e.g function2:
e.g function1: communication_receive()
gcs_handleMessage (mavlink_message_t* msg)
1. Request data Request data is a function where a set of data byte are sent to the UAV flight controller that used MAVlink protocol. In normal case, Pixhawk or Ardupilot. Therefore, the byte act as a data stream request command to the flight controller to continuously send data through the port where the command is received. For example, if the Arduino/software send data to ‘Telem1’ RX port in Pixhawk, then ‘Telem1’ TX port will have constant data stream related to the MAVlink protocol. Example code: void request_data() { byte req[] = {254,6,0,255,1,66,20,0,1,0,0,1,183,129}; Serial2.write(req,14); } Note: This is based on code written by rijal. Direct method. This is not correctly implemented based on MAVlink.
Mavlink bytes array data structure hdr
len
seq sys
cmp id
Payload (len 9)
0
1
2
3
4
5
6
FE
09
4E
01
01
00 00
Fixed Header (6 octets) hdr packet header len Message length (max 9 byte) seq sequence number sys
source system
cmp
source component
crc
7
8
9
a
b
c
d
e
f
10
00
00
00
02 03 51 04 03 1C 7F
always 0xFE The length of payload byte array being sent. rolls around from 255 to 0 (will change sequently) what system is sending this message (default =1). Particularly important when identifying multiple system e.g UAV) [1=1st UAV, 2=2nd UAV and so on] what component of the system is sending the message (default=1). For most case determine autopilot. If same it is equal.
id
message ID
What is message ID. Refer Pixhawk MAVlink documents3.
Variable Sized Payload (specified in octet 1, range 0..255) Payload This is the actual packet that The range is usual 06-0e. Means that, the is being sent using mavlink payload size can be from 6-9 byte array in protocol. length. Packet Checksum crc cyclic redundancy check (CRC)
Basically, an error detecting byte. This to ensure that the message payload being sent is actually correct and complete.
Source: http://eastbay-rc.blogspot.my/2013/04/mavlink-protocol-notes-packet-decoding.html https://pixhawk.org/dev/mavlink Correct implementation: Set variable for data request stream command
Encode the command into a mavlink message
Send/write the message over serial to the UAV
void request_data() { // Set variable command for request data stream mavlink_command_long_t cmd; cmd.target_system = system_id; cmd.target_component = autopilot_id; //use set message interval to request data stream cmd.command = MAV_CMD_SET_MESSAGE_INTERVAL; //confirm transmission cmd.confirmation = true; //to stream all cmd.param1 = MAV_DATA_STREAM_ALL; //[data rate]-1=disable;0=default rate cmd.param2 = 0; // Encode mavlink_message_t message; mavlink_msg_command_long_encode(system_id, companion_id, &message, &cmd); // Send the message Serial2.write(message); return; }
2. Read for received communication Check the serial port for received data
Check if the data received is ‘parse‘-able into mavlink message
Parse the received serial data (which is in char) into mavlink message format
Handle the mavlink message
Example code: void communication_receive() { mavlink_message_t msg; mavlink_status_t status; if(Serial2.available() > 0) {} // COMMUNICATION THROUGH UART while(Serial2.available()) { uint8_t c = Serial2.read(); Serial2.write(c); // Try to get a new message if (mavlink_parse_char(MAVLINK_COMM_0, c, &msg, &status)) { gcs_handleMessage(&msg); } // And get the next one } // Update global packet drops counter // notes: not important can be delete. This is to check for error packet_drops += status.packet_rx_drop_count; }
3. Handle the message receive as a usable format. Check the received mavlink message ID
Create the case packet based on the message ID
Decode the message into packet specified to the case
Extract packet data and transfer to variable
void gcs_handleMessage(mavlink_message_t* msg) { switch (msg->msgid) { case MAVLINK_MSG_ID_HEARTBEAT: { beat = 1; mavlink_heartbeat_t packet; mavlink_msg_heartbeat_decode(msg,&packet); flightmode = packet.base_mode; break; } case MAVLINK_MSG_ID_ATTITUDE: { mavlink_attitude_t packet; // decode mavlink_msg_attitude_decode(msg, &packet); pitch = toDeg(packet.pitch); yaw = toDeg(packet.yaw); roll = toDeg(packet.roll); pitchrate = toDeg(packet.pitchspeed); break; } ... ... ...
}
// decode