+Messages are defined by the common.xml file. The C packing/unpacking code is generated from this specification, as well as the HTML documentaiton in the section above.
+
+The XML displayed here is updated on every commit and therefore up-to-date.
+
+
+
+parse_code();
+//
+//echo $display_xml;
+
+?>
\ No newline at end of file
diff --git a/mavlink-solo/doc/mavlink_to_html_table.xsl b/mavlink-solo/doc/mavlink_to_html_table.xsl
new file mode 100644
index 0000000..71fd69c
--- /dev/null
+++ b/mavlink-solo/doc/mavlink_to_html_table.xsl
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/mavlink-solo/examples/linux/.gitignore b/mavlink-solo/examples/linux/.gitignore
new file mode 100644
index 0000000..ce4f5db
--- /dev/null
+++ b/mavlink-solo/examples/linux/.gitignore
@@ -0,0 +1 @@
+mavlink_udp
diff --git a/mavlink-solo/examples/linux/README b/mavlink-solo/examples/linux/README
new file mode 100644
index 0000000..d138018
--- /dev/null
+++ b/mavlink-solo/examples/linux/README
@@ -0,0 +1,19 @@
+A more detailed version of this quickstart is available at:
+
+http://qgroundcontrol.org/dev/mavlink_linux_integration_tutorial
+
+MAVLINK UDP QUICKSTART INSTRUCTIONS
+===================================
+
+MAVLink UDP Example for *nix system (Linux, MacOS, BSD, etc.)
+
+To compile with GCC, just enter:
+
+gcc -I ../../include/common -o mavlink_udp mavlink_udp.c
+
+To run, type:
+
+./mavlink_udp
+
+
+If you run QGroundControl on the same machine, a MAV should pop up.
diff --git a/mavlink-solo/examples/linux/mavlink_udp.c b/mavlink-solo/examples/linux/mavlink_udp.c
new file mode 100644
index 0000000..6f4ce7c
--- /dev/null
+++ b/mavlink-solo/examples/linux/mavlink_udp.c
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ Copyright (C) 2010 Bryan Godbolt godbolt ( a t ) ualberta.ca
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ ****************************************************************************/
+/*
+ This program sends some data to qgroundcontrol using the mavlink protocol. The sent packets
+ cause qgroundcontrol to respond with heartbeats. Any settings or custom commands sent from
+ qgroundcontrol are printed by this program along with the heartbeats.
+
+
+ I compiled this program sucessfully on Ubuntu 10.04 with the following command
+
+ gcc -I ../../pixhawk/mavlink/include -o udp-server udp-server-test.c
+
+ the rt library is needed for the clock_gettime on linux
+ */
+/* These headers are for QNX, but should all be standard on unix/linux */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#if (defined __QNX__) | (defined __QNXNTO__)
+/* QNX specific headers */
+#include
+#else
+/* Linux / MacOS POSIX timer headers */
+#include
+#include
+#include
+#endif
+
+/* This assumes you have the mavlink headers on your include path
+ or in the same folder as this source file */
+#include
+
+
+#define BUFFER_LENGTH 2041 // minimum buffer size that can be used with qnx (I don't know why)
+
+uint64_t microsSinceEpoch();
+
+int main(int argc, char* argv[])
+{
+
+ char help[] = "--help";
+
+
+ char target_ip[100];
+
+ float position[6] = {};
+ int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ struct sockaddr_in gcAddr;
+ struct sockaddr_in locAddr;
+ //struct sockaddr_in fromAddr;
+ uint8_t buf[BUFFER_LENGTH];
+ ssize_t recsize;
+ socklen_t fromlen;
+ int bytes_sent;
+ mavlink_message_t msg;
+ uint16_t len;
+ int i = 0;
+ //int success = 0;
+ unsigned int temp = 0;
+
+ // Check if --help flag was used
+ if ((argc == 2) && (strcmp(argv[1], help) == 0))
+ {
+ printf("\n");
+ printf("\tUsage:\n\n");
+ printf("\t");
+ printf("%s", argv[0]);
+ printf(" \n");
+ printf("\tDefault for localhost: udp-server 127.0.0.1\n\n");
+ exit(EXIT_FAILURE);
+ }
+
+
+ // Change the target ip if parameter was given
+ strcpy(target_ip, "127.0.0.1");
+ if (argc == 2)
+ {
+ strcpy(target_ip, argv[1]);
+ }
+
+
+ memset(&locAddr, 0, sizeof(locAddr));
+ locAddr.sin_family = AF_INET;
+ locAddr.sin_addr.s_addr = INADDR_ANY;
+ locAddr.sin_port = htons(14551);
+
+ /* Bind the socket to port 14551 - necessary to receive packets from qgroundcontrol */
+ if (-1 == bind(sock,(struct sockaddr *)&locAddr, sizeof(struct sockaddr)))
+ {
+ perror("error bind failed");
+ close(sock);
+ exit(EXIT_FAILURE);
+ }
+
+ /* Attempt to make it non blocking */
+ if (fcntl(sock, F_SETFL, O_NONBLOCK | FASYNC) < 0)
+ {
+ fprintf(stderr, "error setting nonblocking: %s\n", strerror(errno));
+ close(sock);
+ exit(EXIT_FAILURE);
+ }
+
+
+ memset(&gcAddr, 0, sizeof(gcAddr));
+ gcAddr.sin_family = AF_INET;
+ gcAddr.sin_addr.s_addr = inet_addr(target_ip);
+ gcAddr.sin_port = htons(14550);
+
+
+
+ for (;;)
+ {
+
+ /*Send Heartbeat */
+ mavlink_msg_heartbeat_pack(1, 200, &msg, MAV_TYPE_HELICOPTER, MAV_AUTOPILOT_GENERIC, MAV_MODE_GUIDED_ARMED, 0, MAV_STATE_ACTIVE);
+ len = mavlink_msg_to_send_buffer(buf, &msg);
+ bytes_sent = sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof(struct sockaddr_in));
+
+ /* Send Status */
+ mavlink_msg_sys_status_pack(1, 200, &msg, 0, 0, 0, 500, 11000, -1, -1, 0, 0, 0, 0, 0, 0);
+ len = mavlink_msg_to_send_buffer(buf, &msg);
+ bytes_sent = sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof (struct sockaddr_in));
+
+ /* Send Local Position */
+ mavlink_msg_local_position_ned_pack(1, 200, &msg, microsSinceEpoch(),
+ position[0], position[1], position[2],
+ position[3], position[4], position[5]);
+ len = mavlink_msg_to_send_buffer(buf, &msg);
+ bytes_sent = sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof(struct sockaddr_in));
+
+ /* Send attitude */
+ mavlink_msg_attitude_pack(1, 200, &msg, microsSinceEpoch(), 1.2, 1.7, 3.14, 0.01, 0.02, 0.03);
+ len = mavlink_msg_to_send_buffer(buf, &msg);
+ bytes_sent = sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof(struct sockaddr_in));
+
+
+ memset(buf, 0, BUFFER_LENGTH);
+ recsize = recvfrom(sock, (void *)buf, BUFFER_LENGTH, 0, (struct sockaddr *)&gcAddr, &fromlen);
+ if (recsize > 0)
+ {
+ // Something received - print out all bytes and parse packet
+ mavlink_message_t msg;
+ mavlink_status_t status;
+
+ printf("Bytes Received: %d\nDatagram: ", (int)recsize);
+ for (i = 0; i < recsize; ++i)
+ {
+ temp = buf[i];
+ printf("%02x ", (unsigned char)temp);
+ if (mavlink_parse_char(MAVLINK_COMM_0, buf[i], &msg, &status))
+ {
+ // Packet received
+ printf("\nReceived packet: SYS: %d, COMP: %d, LEN: %d, MSG ID: %d\n", msg.sysid, msg.compid, msg.len, msg.msgid);
+ }
+ }
+ printf("\n");
+ }
+ memset(buf, 0, BUFFER_LENGTH);
+ sleep(1); // Sleep one second
+ }
+}
+
+
+/* QNX timer version */
+#if (defined __QNX__) | (defined __QNXNTO__)
+uint64_t microsSinceEpoch()
+{
+
+ struct timespec time;
+
+ uint64_t micros = 0;
+
+ clock_gettime(CLOCK_REALTIME, &time);
+ micros = (uint64_t)time.tv_sec * 1000000 + time.tv_nsec/1000;
+
+ return micros;
+}
+#else
+uint64_t microsSinceEpoch()
+{
+
+ struct timeval tv;
+
+ uint64_t micros = 0;
+
+ gettimeofday(&tv, NULL);
+ micros = ((uint64_t)tv.tv_sec) * 1000000 + tv.tv_usec;
+
+ return micros;
+}
+#endif
diff --git a/mavlink-solo/mavgenerate.py b/mavlink-solo/mavgenerate.py
new file mode 100755
index 0000000..8c2d2c9
--- /dev/null
+++ b/mavlink-solo/mavgenerate.py
@@ -0,0 +1,196 @@
+#!/usr/bin/env python
+"""\
+generate.py is a GUI front-end for mavgen, a python based MAVLink
+header generation tool.
+
+Notes:
+-----
+* 2012-7-16 -- dagoodman
+ Working on Mac 10.6.8 darwin, with Python 2.7.1
+
+* 2012-7-17 -- dagoodman
+ Only GUI code working on Mac 10.6.8 darwin, with Python 3.2.3
+ Working on Windows 7 SP1, with Python 2.7.3 and 3.2.3
+ Mavgen doesn't work with Python 3.x yet
+
+* 2012-9-25 -- dagoodman
+ Passing error limit into mavgen to make output cleaner.
+
+Copyright 2012 David Goodman (dagoodman@soe.ucsc.edu)
+Released under GNU GPL version 3 or later
+
+"""
+import os
+import re
+
+# Python 2.x and 3.x compatibility
+try:
+ from tkinter import *
+ import tkinter.filedialog
+ import tkinter.messagebox
+except ImportError as ex:
+ # Must be using Python 2.x, import and rename
+ from Tkinter import *
+ import tkFileDialog
+ import tkMessageBox
+
+ tkinter.filedialog = tkFileDialog
+ del tkFileDialog
+ tkinter.messagebox = tkMessageBox
+ del tkMessageBox
+
+from pymavlink.generator import mavgen
+from pymavlink.generator import mavparse
+
+title = "MAVLink Generator"
+error_limit = 5
+
+
+class Application(Frame):
+ def __init__(self, master=None):
+ Frame.__init__(self, master)
+ self.pack_propagate(0)
+ self.grid( sticky=N+S+E+W)
+ self.createWidgets()
+
+ """\
+ Creates the gui and all of its content.
+ """
+ def createWidgets(self):
+
+
+ #----------------------------------------
+ # Create the XML entry
+
+ self.xml_value = StringVar()
+ self.xml_label = Label( self, text="XML" )
+ self.xml_label.grid(row=0, column = 0)
+ self.xml_entry = Entry( self, width = 26, textvariable=self.xml_value )
+ self.xml_entry.grid(row=0, column = 1)
+ self.xml_button = Button (self, text="Browse", command=self.browseXMLFile)
+ self.xml_button.grid(row=0, column = 2)
+
+ #----------------------------------------
+ # Create the Out entry
+
+ self.out_value = StringVar()
+ self.out_label = Label( self, text="Out" )
+ self.out_label.grid(row=1,column = 0)
+ self.out_entry = Entry( self, width = 26, textvariable=self.out_value )
+ self.out_entry.grid(row=1, column = 1)
+ self.out_button = Button (self, text="Browse", command=self.browseOutDirectory)
+ self.out_button.grid(row=1, column = 2)
+
+ #----------------------------------------
+ # Create the Lang box
+
+ self.language_value = StringVar()
+ self.language_choices = mavgen.supportedLanguages
+ self.language_label = Label( self, text="Language" )
+ self.language_label.grid(row=2, column=0)
+ self.language_menu = OptionMenu(self,self.language_value,*self.language_choices)
+ self.language_value.set(mavgen.DEFAULT_LANGUAGE)
+ self.language_menu.config(width=10)
+ self.language_menu.grid(row=2, column=1,sticky=W)
+
+ #----------------------------------------
+ # Create the Protocol box
+
+ self.protocol_value = StringVar()
+ self.protocol_choices = [mavparse.PROTOCOL_0_9, mavparse.PROTOCOL_1_0]
+ self.protocol_label = Label( self, text="Protocol")
+ self.protocol_label.grid(row=3, column=0)
+ self.protocol_menu = OptionMenu(self,self.protocol_value,*self.protocol_choices)
+ self.protocol_value.set(mavgen.DEFAULT_WIRE_PROTOCOL)
+ self.protocol_menu.config(width=10)
+ self.protocol_menu.grid(row=3, column=1,sticky=W)
+
+ #----------------------------------------
+ # Create the Validate box
+
+ self.validate_value = BooleanVar()
+ self.validate_label = Label( self, text="Validate")
+ self.validate_label.grid(row=4, column=0)
+ self.validate_button = Checkbutton(self, variable=self.validate_value, onvalue=True, offvalue=False)
+ self.validate_value.set(mavgen.DEFAULT_VALIDATE)
+ self.validate_button.config(width=10)
+ self.validate_button.grid(row=4, column=1,sticky=W)
+
+ #----------------------------------------
+ # Create the generate button
+
+ self.generate_button = Button ( self, text="Generate", command=self.generateHeaders)
+ self.generate_button.grid(row=5,column=1)
+
+ """\
+ Open a file selection window to choose the XML message definition.
+ """
+ def browseXMLFile(self):
+ # TODO Allow specification of multiple XML definitions
+ xml_file = tkinter.filedialog.askopenfilename(parent=self, title='Choose a definition file')
+ if xml_file != None:
+ self.xml_value.set(xml_file)
+
+ """\
+ Open a directory selection window to choose an output directory for
+ headers.
+ """
+ def browseOutDirectory(self):
+ mavlinkFolder = os.path.dirname(os.path.realpath(__file__))
+ out_dir = tkinter.filedialog.askdirectory(parent=self,initialdir=mavlinkFolder,title='Please select an output directory')
+ if out_dir != None:
+ self.out_value.set(out_dir)
+
+ """\
+ Generates the header files and place them in the output directory.
+ """
+ def generateHeaders(self):
+ # Verify settings
+ rex = re.compile(".*\\.xml$", re.IGNORECASE)
+ if not self.xml_value.get():
+ tkinter.messagebox.showerror('Error Generating Headers','An XML message definition file must be specified.')
+ return
+
+ if not self.out_value.get():
+ tkinter.messagebox.showerror('Error Generating Headers', 'An output directory must be specified.')
+ return
+
+
+ if os.path.isdir(self.out_value.get()):
+ if not tkinter.messagebox.askokcancel('Overwrite Headers?','The output directory \'{0}\' already exists. Headers may be overwritten if they already exist.'.format(self.out_value.get())):
+ return
+
+ # Generate headers
+ opts = mavgen.Opts(self.out_value.get(), wire_protocol=self.protocol_value.get(), language=self.language_value.get(), validate=self.validate_value.get(), error_limit=error_limit);
+ args = [self.xml_value.get()]
+ try:
+ mavgen.mavgen(opts,args)
+ tkinter.messagebox.showinfo('Successfully Generated Headers', 'Headers generated successfully.')
+
+ except Exception as ex:
+ exStr = formatErrorMessage(str(ex));
+ tkinter.messagebox.showerror('Error Generating Headers','{0!s}'.format(exStr))
+ return
+
+"""\
+Format the mavgen exceptions by removing 'ERROR: '.
+"""
+def formatErrorMessage(message):
+ reObj = re.compile(r'^(ERROR):\s+',re.M);
+ matches = re.findall(reObj, message);
+ prefix = ("An error occurred in mavgen:" if len(matches) == 1 else "Errors occurred in mavgen:\n")
+ message = re.sub(reObj, '\n', message);
+
+ return prefix + message
+
+
+# End of Application class
+# ---------------------------------
+
+# ---------------------------------
+# Start
+
+if __name__ == '__main__':
+ app = Application()
+ app.master.title(title)
+ app.mainloop()
diff --git a/mavlink-solo/message_definitions/v0.9/ardupilotmega.xml b/mavlink-solo/message_definitions/v0.9/ardupilotmega.xml
new file mode 100644
index 0000000..6733531
--- /dev/null
+++ b/mavlink-solo/message_definitions/v0.9/ardupilotmega.xml
@@ -0,0 +1,270 @@
+
+
+ common.xml
+
+
+
+
+
+
+ Enumeration of possible mount operation modes
+ Load and keep safe position (Roll,Pitch,Yaw) from EEPROM and stop stabilization
+ Load and keep neutral position (Roll,Pitch,Yaw) from EEPROM.
+ Load neutral position and start MAVLink Roll,Pitch,Yaw control with stabilization
+ Load neutral position and start RC Roll,Pitch,Yaw control with stabilization
+ Load neutral position and start to point to Lat,Lon,Alt
+
+
+
+
+
+ Mission command to configure an on-board camera controller system.
+ Modes: P, TV, AV, M, Etc
+ Shutter speed: Divisor number for one second
+ Aperture: F stop number
+ ISO number e.g. 80, 100, 200, Etc
+ Exposure type enumerator
+ Command Identity
+ Main engine cut-off time before camera trigger in seconds/10 (0 means no cut-off)
+
+
+
+ Mission command to control an on-board camera controller system.
+ Session control e.g. show/hide lens
+ Zoom's absolute position
+ Zooming step value to offset zoom from the current position
+ Focus Locking, Unlocking or Re-locking
+ Shooting Command
+ Command Identity
+ Empty
+
+
+
+
+ Mission command to configure a camera or antenna mount
+ Mount operation mode (see MAV_MOUNT_MODE enum)
+ stabilize roll? (1 = yes, 0 = no)
+ stabilize pitch? (1 = yes, 0 = no)
+ stabilize yaw? (1 = yes, 0 = no)
+ Empty
+ Empty
+ Empty
+
+
+
+ Mission command to control a camera or antenna mount
+ pitch(deg*100) or lat, depending on mount mode.
+ roll(deg*100) or lon depending on mount mode
+ yaw(deg*100) or alt (in cm) depending on mount mode
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+
+
+
+ Disable fenced mode
+
+
+ Switched to guided mode to return point (fence point 0)
+
+
+
+
+
+ No last fence breach
+
+
+ Breached minimum altitude
+
+
+ Breached minimum altitude
+
+
+ Breached fence boundary
+
+
+
+
+
+
+ Offsets and calibrations values for hardware
+ sensors. This makes it easier to debug the calibration process.
+ magnetometer X offset
+ magnetometer Y offset
+ magnetometer Z offset
+ magnetic declination (radians)
+ raw pressure from barometer
+ raw temperature from barometer
+ gyro X calibration
+ gyro Y calibration
+ gyro Z calibration
+ accel X calibration
+ accel Y calibration
+ accel Z calibration
+
+
+
+ set the magnetometer offsets
+ System ID
+ Component ID
+ magnetometer X offset
+ magnetometer Y offset
+ magnetometer Z offset
+
+
+
+ state of APM memory
+ heap top
+ free memory
+
+
+
+ raw ADC output
+ ADC output 1
+ ADC output 2
+ ADC output 3
+ ADC output 4
+ ADC output 5
+ ADC output 6
+
+
+
+
+ Configure on-board Camera Control System.
+ System ID
+ Component ID
+ Mode enumeration from 1 to N //P, TV, AV, M, Etc (0 means ignore)
+ Divisor number //e.g. 1000 means 1/1000 (0 means ignore)
+ F stop number x 10 //e.g. 28 means 2.8 (0 means ignore)
+ ISO enumeration from 1 to N //e.g. 80, 100, 200, Etc (0 means ignore)
+ Exposure type enumeration from 1 to N (0 means ignore)
+ Command Identity (incremental loop: 0 to 255)//A command sent multiple times will be executed or pooled just once
+ Main engine cut-off time before camera trigger in seconds/10 (0 means no cut-off)
+ Extra parameters enumeration (0 means ignore)
+ Correspondent value to given extra_param
+
+
+
+ Control on-board Camera Control System to take shots.
+ System ID
+ Component ID
+ 0: stop, 1: start or keep it up //Session control e.g. show/hide lens
+ 1 to N //Zoom's absolute position (0 means ignore)
+ -100 to 100 //Zooming step value to offset zoom from the current position
+ 0: unlock focus or keep unlocked, 1: lock focus or keep locked, 3: re-lock focus
+ 0: ignore, 1: shot or start filming
+ Command Identity (incremental loop: 0 to 255)//A command sent multiple times will be executed or pooled just once
+ Extra parameters enumeration (0 means ignore)
+ Correspondent value to given extra_param
+
+
+
+
+ Message to configure a camera mount, directional antenna, etc.
+ System ID
+ Component ID
+ mount operating mode (see MAV_MOUNT_MODE enum)
+ (1 = yes, 0 = no)
+ (1 = yes, 0 = no)
+ (1 = yes, 0 = no)
+
+
+
+ Message to control a camera mount, directional antenna, etc.
+ System ID
+ Component ID
+ pitch(deg*100) or lat, depending on mount mode
+ roll(deg*100) or lon depending on mount mode
+ yaw(deg*100) or alt (in cm) depending on mount mode
+ if "1" it will save current trimmed position on EEPROM (just valid for NEUTRAL and LANDING)
+
+
+
+ Message with some status from APM to GCS about camera or antenna mount
+ System ID
+ Component ID
+ pitch(deg*100) or lat, depending on mount mode
+ roll(deg*100) or lon depending on mount mode
+ yaw(deg*100) or alt (in cm) depending on mount mode
+
+
+
+
+ A fence point. Used to set a point when from
+ GCS -> MAV. Also used to return a point from MAV -> GCS
+ System ID
+ Component ID
+ point index (first point is 1, 0 is for return point)
+ total number of points (for sanity checking)
+ Latitude of point
+ Longitude of point
+
+
+
+ Request a current fence point from MAV
+ System ID
+ Component ID
+ point index (first point is 1, 0 is for return point)
+
+
+
+ Status of geo-fencing. Sent in extended
+ status stream when fencing enabled
+ 0 if currently inside fence, 1 if outside
+ number of fence breaches
+ last breach type (see FENCE_BREACH_* enum)
+ time of last breach in milliseconds since boot
+
+
+
+ Status of DCM attitude estimator
+ X gyro drift estimate rad/s
+ Y gyro drift estimate rad/s
+ Z gyro drift estimate rad/s
+ average accel_weight
+ average renormalisation value
+ average error_roll_pitch value
+ average error_yaw value
+
+
+
+ Status of simulation environment, if used
+ Roll angle (rad)
+ Pitch angle (rad)
+ Yaw angle (rad)
+ X acceleration m/s/s
+ Y acceleration m/s/s
+ Z acceleration m/s/s
+ Angular speed around X axis rad/s
+ Angular speed around Y axis rad/s
+ Angular speed around Z axis rad/s
+
+
+
+ Status of key hardware
+ board voltage (mV)
+ I2C error count
+
+
+
+ Status generated by radio
+ local signal strength
+ remote signal strength
+ how full the tx buffer is as a percentage
+ background noise level
+ remote background noise level
+ receive errors
+ count of error corrected packets
+
+
+
diff --git a/mavlink-solo/message_definitions/v0.9/common.xml b/mavlink-solo/message_definitions/v0.9/common.xml
new file mode 100644
index 0000000..dd4ea84
--- /dev/null
+++ b/mavlink-solo/message_definitions/v0.9/common.xml
@@ -0,0 +1,941 @@
+
+
+ 2
+
+
+ Commands to be executed by the MAV. They can be executed on user request,
+ or as part of a mission script. If the action is used in a mission, the parameter mapping
+ to the waypoint/mission message is as follows:
+ Param 1, Param 2, Param 3, Param 4, X: Param 5, Y:Param 6, Z:Param 7. This command list is similar what
+ ARINC 424 is for commercial aircraft: A data format how to interpret waypoint/mission data.
+
+ Navigate to waypoint.
+ Hold time in decimal seconds. (ignored by fixed wing, time to stay at waypoint for rotary wing)
+ Acceptance radius in meters (if the sphere with this radius is hit, the waypoint counts as reached)
+ 0 to pass through the WP, if > 0 radius in meters to pass by WP. Positive value for clockwise orbit, negative value for counter-clockwise orbit. Allows trajectory control.
+ Desired yaw angle at waypoint (rotary wing)
+ Latitude
+ Longitude
+ Altitude
+
+
+ Loiter around this waypoint an unlimited amount of time
+ Empty
+ Empty
+ Radius around waypoint, in meters. If positive loiter clockwise, else counter-clockwise
+ Desired yaw angle.
+ Latitude
+ Longitude
+ Altitude
+
+
+ Loiter around this waypoint for X turns
+ Turns
+ Empty
+ Radius around waypoint, in meters. If positive loiter clockwise, else counter-clockwise
+ Desired yaw angle.
+ Latitude
+ Longitude
+ Altitude
+
+
+ Loiter around this waypoint for X seconds
+ Seconds (decimal)
+ Empty
+ Radius around waypoint, in meters. If positive loiter clockwise, else counter-clockwise
+ Desired yaw angle.
+ Latitude
+ Longitude
+ Altitude
+
+
+ Return to launch location
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Land at location
+ Empty
+ Empty
+ Empty
+ Desired yaw angle.
+ Latitude
+ Longitude
+ Altitude
+
+
+ Takeoff from ground / hand
+ Minimum pitch (if airspeed sensor present), desired pitch without sensor
+ Empty
+ Empty
+ Yaw angle (if magnetometer present), ignored without magnetometer
+ Latitude
+ Longitude
+ Altitude
+
+
+ Sets the region of interest (ROI) for a sensor set or the
+ vehicle itself. This can then be used by the vehicles control
+ system to control the vehicle attitude and the attitude of various
+ sensors such as cameras.
+ Region of intereset mode. (see MAV_ROI enum)
+ Waypoint index/ target ID. (see MAV_ROI enum)
+ ROI index (allows a vehicle to manage multiple ROI's)
+ Empty
+ x the location of the fixed ROI (see MAV_FRAME)
+ y
+ z
+
+
+ Control autonomous path planning on the MAV.
+ 0: Disable local obstacle avoidance / local path planning (without resetting map), 1: Enable local path planning, 2: Enable and reset local path planning
+ 0: Disable full path planning (without resetting map), 1: Enable, 2: Enable and reset map/occupancy grid, 3: Enable and reset planned route, but not occupancy grid
+ Empty
+ Yaw angle at goal, in compass degrees, [0..360]
+ Latitude/X of goal
+ Longitude/Y of goal
+ Altitude/Z of goal
+
+
+ NOP - This command is only used to mark the upper limit of the NAV/ACTION commands in the enumeration
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Delay mission state machine.
+ Delay in seconds (decimal)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Ascend/descend at rate. Delay mission state machine until desired altitude reached.
+ Descent / Ascend rate (m/s)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Finish Altitude
+
+
+ Delay mission state machine until within desired distance of next NAV point.
+ Distance (meters)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Reach a certain target angle.
+ target angle: [0-360], 0 is north
+ speed during yaw change:[deg per second]
+ direction: negative: counter clockwise, positive: clockwise [-1,1]
+ relative offset or absolute angle: [ 1,0]
+ Empty
+ Empty
+ Empty
+
+
+ NOP - This command is only used to mark the upper limit of the CONDITION commands in the enumeration
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Set system mode.
+ Mode, as defined by ENUM MAV_MODE
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Jump to the desired command in the mission list. Repeat this action only the specified number of times
+ Sequence number
+ Repeat count
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Change speed and/or throttle set points.
+ Speed type (0=Airspeed, 1=Ground Speed)
+ Speed (m/s, -1 indicates no change)
+ Throttle ( Percent, -1 indicates no change)
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Changes the home location either to the current location or a specified location.
+ Use current (1=use current location, 0=use specified location)
+ Empty
+ Empty
+ Empty
+ Latitude
+ Longitude
+ Altitude
+
+
+ Set a system parameter. Caution! Use of this command requires knowledge of the numeric enumeration value of the parameter.
+ Parameter number
+ Parameter value
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Set a relay to a condition.
+ Relay number
+ Setting (1=on, 0=off, others possible depending on system hardware)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Cycle a relay on and off for a desired number of cyles with a desired period.
+ Relay number
+ Cycle count
+ Cycle time (seconds, decimal)
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Set a servo to a desired PWM value.
+ Servo number
+ PWM (microseconds, 1000 to 2000 typical)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Cycle a between its nominal setting and a desired PWM for a desired number of cycles with a desired period.
+ Servo number
+ PWM (microseconds, 1000 to 2000 typical)
+ Cycle count
+ Cycle time (seconds)
+ Empty
+ Empty
+ Empty
+
+
+ Control onboard camera capturing.
+ Camera ID (-1 for all)
+ Transmission: 0: disabled, 1: enabled compressed, 2: enabled raw
+ Transmission mode: 0: video stream, >0: single images every n seconds (decimal)
+ Recording: 0: disabled, 1: enabled compressed, 2: enabled raw
+ Empty
+ Empty
+ Empty
+
+
+ Sets the region of interest (ROI) for a sensor set or the
+ vehicle itself. This can then be used by the vehicles control
+ system to control the vehicle attitude and the attitude of various
+ devices such as cameras.
+
+ Region of interest mode. (see MAV_ROI enum)
+ Waypoint index/ target ID. (see MAV_ROI enum)
+ ROI index (allows a vehicle to manage multiple cameras etc.)
+ Empty
+ x the location of the fixed ROI (see MAV_FRAME)
+ y
+ z
+
+
+ NOP - This command is only used to mark the upper limit of the DO commands in the enumeration
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Trigger calibration. This command will be only accepted if in pre-flight mode.
+ Gyro calibration: 0: no, 1: yes
+ Magnetometer calibration: 0: no, 1: yes
+ Ground pressure: 0: no, 1: yes
+ Radio calibration: 0: no, 1: yes
+ Empty
+ Empty
+ Empty
+
+
+ Request storage of different parameter values and logs. This command will be only accepted if in pre-flight mode.
+ Parameter storage: 0: READ FROM FLASH/EEPROM, 1: WRITE CURRENT TO FLASH/EEPROM
+ Mission storage: 0: READ FROM FLASH/EEPROM, 1: WRITE CURRENT TO FLASH/EEPROM
+ Reserved
+ Reserved
+ Empty
+ Empty
+ Empty
+
+
+
+ Data stream IDs. A data stream is not a fixed set of messages, but rather a
+ recommendation to the autopilot software. Individual autopilots may or may not obey
+ the recommended messages.
+
+
+ Enable all data streams
+
+
+ Enable IMU_RAW, GPS_RAW, GPS_STATUS packets.
+
+
+ Enable GPS_STATUS, CONTROL_STATUS, AUX_STATUS
+
+
+ Enable RC_CHANNELS_SCALED, RC_CHANNELS_RAW, SERVO_OUTPUT_RAW
+
+
+ Enable ATTITUDE_CONTROLLER_OUTPUT, POSITION_CONTROLLER_OUTPUT, NAV_CONTROLLER_OUTPUT.
+
+
+ Enable LOCAL_POSITION, GLOBAL_POSITION/GLOBAL_POSITION_INT messages.
+
+
+ Dependent on the autopilot
+
+
+ Dependent on the autopilot
+
+
+ Dependent on the autopilot
+
+
+
+ The ROI (region of interest) for the vehicle. This can be
+ be used by the vehicle for camera/vehicle attitude alignment (see
+ MAV_CMD_NAV_ROI).
+
+
+ No region of interest.
+
+
+ Point toward next waypoint.
+
+
+ Point toward given waypoint.
+
+
+ Point toward fixed location.
+
+
+ Point toward of given id.
+
+
+
+
+
+ The heartbeat message shows that a system is present and responding. The type of the MAV and Autopilot hardware allow the receiving system to treat further messages from this system appropriate (e.g. by laying out the user interface based on the autopilot).
+ Type of the MAV (quadrotor, helicopter, etc., up to 15 types, defined in MAV_TYPE ENUM)
+ Type of the Autopilot: 0: Generic, 1: PIXHAWK, 2: SLUGS, 3: Ardupilot (up to 15 types), defined in MAV_AUTOPILOT_TYPE ENUM
+ MAVLink version
+
+
+ The boot message indicates that a system is starting. The onboard software version allows to keep track of onboard soft/firmware revisions.
+ The onboard software version
+
+
+ The system time is the time of the master clock, typically the computer clock of the main onboard computer.
+ Timestamp of the master clock in microseconds since UNIX epoch.
+
+
+ A ping message either requesting or responding to a ping. This allows to measure the system latencies, including serial port, radio modem and UDP connections.
+ PING sequence
+ 0: request ping from all receiving systems, if greater than 0: message is a ping response and number is the system id of the requesting system
+ 0: request ping from all receiving components, if greater than 0: message is a ping response and number is the system id of the requesting system
+ Unix timestamp in microseconds
+
+
+ UTC date and time from GPS module
+ GPS UTC date ddmmyy
+ GPS UTC time hhmmss
+
+
+ Request to control this MAV
+ System the GCS requests control for
+ 0: request control of this MAV, 1: Release control of this MAV
+ 0: key as plaintext, 1-255: future, different hashing/encryption variants. The GCS should in general use the safest mode possible initially and then gradually move down the encryption level if it gets a NACK message indicating an encryption mismatch.
+ Password / Key, depending on version plaintext or encrypted. 25 or less characters, NULL terminated. The characters may involve A-Z, a-z, 0-9, and "!?,.-"
+
+
+ Accept / deny control of this MAV
+ ID of the GCS this message
+ 0: request control of this MAV, 1: Release control of this MAV
+ 0: ACK, 1: NACK: Wrong passkey, 2: NACK: Unsupported passkey encryption method, 3: NACK: Already under control
+
+
+ Emit an encrypted signature / key identifying this system. PLEASE NOTE: This protocol has been kept simple, so transmitting the key requires an encrypted channel for true safety.
+ key
+
+
+ This message acknowledges an action. IMPORTANT: The acknowledgement can be also negative, e.g. the MAV rejects a reset message because it is in-flight. The action ids are defined in ENUM MAV_ACTION in mavlink/include/mavlink_types.h
+ The action id
+ 0: Action DENIED, 1: Action executed
+
+
+ An action message allows to execute a certain onboard action. These include liftoff, land, storing parameters too EEPROM, shutddown, etc. The action ids are defined in ENUM MAV_ACTION in mavlink/include/mavlink_types.h
+ The system executing the action
+ The component executing the action
+ The action id
+
+
+ Set the system mode, as defined by enum MAV_MODE in mavlink/include/mavlink_types.h. There is no target component id as the mode is by definition for the overall aircraft, not only for one component.
+ The system setting the mode
+ The new mode
+
+
+ Set the system navigation mode, as defined by enum MAV_NAV_MODE in mavlink/include/mavlink_types.h. The navigation mode applies to the whole aircraft and thus all components.
+ The system setting the mode
+ The new navigation mode
+
+
+ Request to read the onboard parameter with the param_id string id. Onboard parameters are stored as key[const char*] -> value[float]. This allows to send a parameter to any other component (such as the GCS) without the need of previous knowledge of possible parameter names. Thus the same GCS can store different parameters for different autopilots. See also http://qgroundcontrol.org/parameter_interface for a full documentation of QGroundControl and IMU code.
+ System ID
+ Component ID
+ Onboard parameter id
+ Parameter index. Send -1 to use the param ID field as identifier
+
+
+ Request all parameters of this component. After his request, all parameters are emitted.
+ System ID
+ Component ID
+
+
+ Emit the value of a onboard parameter. The inclusion of param_count and param_index in the message allows the recipient to keep track of received parameters and allows him to re-request missing parameters after a loss or timeout.
+ Onboard parameter id
+ Onboard parameter value
+ Total number of onboard parameters
+ Index of this onboard parameter
+
+
+ Set a parameter value TEMPORARILY to RAM. It will be reset to default on system reboot. Send the ACTION MAV_ACTION_STORAGE_WRITE to PERMANENTLY write the RAM contents to EEPROM. IMPORTANT: The receiving component should acknowledge the new parameter value by sending a param_value message to all communication partners. This will also ensure that multiple GCS all have an up-to-date list of all parameters. If the sending GCS did not receive a PARAM_VALUE message within its timeout time, it should re-send the PARAM_SET message.
+ System ID
+ Component ID
+ Onboard parameter id
+ Onboard parameter value
+
+
+ The global position, as returned by the Global Positioning System (GPS). This is
+NOT the global position estimate of the sytem, but rather a RAW sensor value. See message GLOBAL_POSITION for the global position estimate. Coordinate frame is right-handed, Z-axis up (GPS frame)
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ 0-1: no fix, 2: 2D fix, 3: 3D fix. Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix.
+ Latitude in 1E7 degrees
+ Longitude in 1E7 degrees
+ Altitude in 1E3 meters (millimeters)
+ GPS HDOP
+ GPS VDOP
+ GPS ground speed (m/s)
+ Compass heading in degrees, 0..360 degrees
+
+
+ The RAW IMU readings for the usual 9DOF sensor setup. This message should contain the scaled values to the described units
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ X acceleration (mg)
+ Y acceleration (mg)
+ Z acceleration (mg)
+ Angular speed around X axis (millirad /sec)
+ Angular speed around Y axis (millirad /sec)
+ Angular speed around Z axis (millirad /sec)
+ X Magnetic field (milli tesla)
+ Y Magnetic field (milli tesla)
+ Z Magnetic field (milli tesla)
+
+
+ The positioning status, as reported by GPS. This message is intended to display status information about each satellite visible to the receiver. See message GLOBAL_POSITION for the global position estimate. This message can contain information for up to 20 satellites.
+ Number of satellites visible
+ Global satellite ID
+ 0: Satellite not used, 1: used for localization
+ Elevation (0: right on top of receiver, 90: on the horizon) of satellite
+ Direction of satellite, 0: 0 deg, 255: 360 deg.
+ Signal to noise ratio of satellite
+
+
+ The RAW IMU readings for the usual 9DOF sensor setup. This message should always contain the true raw values without any scaling to allow data capture and system debugging.
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ X acceleration (raw)
+ Y acceleration (raw)
+ Z acceleration (raw)
+ Angular speed around X axis (raw)
+ Angular speed around Y axis (raw)
+ Angular speed around Z axis (raw)
+ X Magnetic field (raw)
+ Y Magnetic field (raw)
+ Z Magnetic field (raw)
+
+
+ The RAW pressure readings for the typical setup of one absolute pressure and one differential pressure sensor. The sensor values should be the raw, UNSCALED ADC values.
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ Absolute pressure (raw)
+ Differential pressure 1 (raw)
+ Differential pressure 2 (raw)
+ Raw Temperature measurement (raw)
+
+
+ The pressure readings for the typical setup of one absolute and differential pressure sensor. The units are as specified in each field.
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ Absolute pressure (hectopascal)
+ Differential pressure 1 (hectopascal)
+ Temperature measurement (0.01 degrees celsius)
+
+
+ The attitude in the aeronautical frame (right-handed, Z-down, X-front, Y-right).
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ Roll angle (rad)
+ Pitch angle (rad)
+ Yaw angle (rad)
+ Roll angular speed (rad/s)
+ Pitch angular speed (rad/s)
+ Yaw angular speed (rad/s)
+
+
+ The filtered local position (e.g. fused computer vision and accelerometers). Coordinate frame is right-handed, Z-axis down (aeronautical frame)
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ X Position
+ Y Position
+ Z Position
+ X Speed
+ Y Speed
+ Z Speed
+
+
+ The filtered global position (e.g. fused GPS and accelerometers). Coordinate frame is right-handed, Z-axis up (GPS frame)
+ Timestamp (microseconds since unix epoch)
+ Latitude, in degrees
+ Longitude, in degrees
+ Absolute altitude, in meters
+ X Speed (in Latitude direction, positive: going north)
+ Y Speed (in Longitude direction, positive: going east)
+ Z Speed (in Altitude direction, positive: going up)
+
+
+ The global position, as returned by the Global Positioning System (GPS). This is
+NOT the global position estimate of the sytem, but rather a RAW sensor value. See message GLOBAL_POSITION for the global position estimate. Coordinate frame is right-handed, Z-axis up (GPS frame)
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ 0-1: no fix, 2: 2D fix, 3: 3D fix. Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix.
+ Latitude in degrees
+ Longitude in degrees
+ Altitude in meters
+ GPS HDOP
+ GPS VDOP
+ GPS ground speed
+ Compass heading in degrees, 0..360 degrees
+
+
+ The general system state. If the system is following the MAVLink standard, the system state is mainly defined by three orthogonal states/modes: The system mode, which is either LOCKED (motors shut down and locked), MANUAL (system under RC control), GUIDED (system with autonomous position control, position setpoint controlled manually) or AUTO (system guided by path/waypoint planner). The NAV_MODE defined the current flight state: LIFTOFF (often an open-loop maneuver), LANDING, WAYPOINTS or VECTOR. This represents the internal navigation state machine. The system status shows wether the system is currently active or not and if an emergency occured. During the CRITICAL and EMERGENCY states the MAV is still considered to be active, but should start emergency procedures autonomously. After a failure occured it should first move from active to critical to allow manual intervention and then move to emergency after a certain timeout.
+ System mode, see MAV_MODE ENUM in mavlink/include/mavlink_types.h
+ Navigation mode, see MAV_NAV_MODE ENUM
+ System status flag, see MAV_STATUS ENUM
+ Maximum usage in percent of the mainloop time, (0%: 0, 100%: 1000) should be always below 1000
+ Battery voltage, in millivolts (1 = 1 millivolt)
+ Remaining battery energy: (0%: 0, 100%: 1000)
+ Dropped packets (packets that were corrupted on reception on the MAV)
+
+
+ The RAW values of the RC channels received. The standard PPM modulation is as follows: 1000 microseconds: 0%, 2000 microseconds: 100%. Individual receivers/transmitters might violate this specification.
+ RC channel 1 value, in microseconds
+ RC channel 2 value, in microseconds
+ RC channel 3 value, in microseconds
+ RC channel 4 value, in microseconds
+ RC channel 5 value, in microseconds
+ RC channel 6 value, in microseconds
+ RC channel 7 value, in microseconds
+ RC channel 8 value, in microseconds
+ Receive signal strength indicator, 0: 0%, 255: 100%
+
+
+ The scaled values of the RC channels received. (-100%) -10000, (0%) 0, (100%) 10000
+ RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000
+ RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000
+ RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000
+ RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000
+ RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000
+ RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000
+ RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000
+ RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000
+ Receive signal strength indicator, 0: 0%, 255: 100%
+
+
+ The RAW values of the servo outputs (for RC input from the remote, use the RC_CHANNELS messages). The standard PPM modulation is as follows: 1000 microseconds: 0%, 2000 microseconds: 100%.
+ Servo output 1 value, in microseconds
+ Servo output 2 value, in microseconds
+ Servo output 3 value, in microseconds
+ Servo output 4 value, in microseconds
+ Servo output 5 value, in microseconds
+ Servo output 6 value, in microseconds
+ Servo output 7 value, in microseconds
+ Servo output 8 value, in microseconds
+
+
+ Message encoding a waypoint. This message is emitted to announce
+ the presence of a waypoint and to set a waypoint on the system. The waypoint can be either in x, y, z meters (type: LOCAL) or x:lat, y:lon, z:altitude. Local frame is Z-down, right handed, global frame is Z-up, right handed
+ System ID
+ Component ID
+ Sequence
+ The coordinate system of the waypoint. see MAV_FRAME in mavlink_types.h
+ The scheduled action for the waypoint. see MAV_COMMAND in common.xml MAVLink specs
+ false:0, true:1
+ autocontinue to next wp
+ PARAM1 / For NAV command waypoints: Radius in which the waypoint is accepted as reached, in meters
+ PARAM2 / For NAV command waypoints: Time that the MAV should stay inside the PARAM1 radius before advancing, in milliseconds
+ PARAM3 / For LOITER command waypoints: Orbit to circle around the waypoint, in meters. If positive the orbit direction should be clockwise, if negative the orbit direction should be counter-clockwise.
+ PARAM4 / For NAV and LOITER command waypoints: Yaw orientation in degrees, [0..360] 0 = NORTH
+ PARAM5 / local: x position, global: latitude
+ PARAM6 / y position: global: longitude
+ PARAM7 / z position: global: altitude
+
+
+ Request the information of the waypoint with the sequence number seq. The response of the system to this message should be a WAYPOINT message.
+ System ID
+ Component ID
+ Sequence
+
+
+ Set the waypoint with sequence number seq as current waypoint. This means that the MAV will continue to this waypoint on the shortest path (not following the waypoints in-between).
+ System ID
+ Component ID
+ Sequence
+
+
+ Message that announces the sequence number of the current active waypoint. The MAV will fly towards this waypoint.
+ Sequence
+
+
+ Request the overall list of waypoints from the system/component.
+ System ID
+ Component ID
+
+
+ This message is emitted as response to WAYPOINT_REQUEST_LIST by the MAV. The GCS can then request the individual waypoints based on the knowledge of the total number of waypoints.
+ System ID
+ Component ID
+ Number of Waypoints in the Sequence
+
+
+ Delete all waypoints at once.
+ System ID
+ Component ID
+
+
+ A certain waypoint has been reached. The system will either hold this position (or circle on the orbit) or (if the autocontinue on the WP was set) continue to the next waypoint.
+ Sequence
+
+
+ Ack message during waypoint handling. The type field states if this message is a positive ack (type=0) or if an error happened (type=non-zero).
+ System ID
+ Component ID
+ 0: OK, 1: Error
+
+
+ As local waypoints exist, the global waypoint reference allows to transform between the local coordinate frame and the global (GPS) coordinate frame. This can be necessary when e.g. in- and outdoor settings are connected and the MAV should move from in- to outdoor.
+ System ID
+ Component ID
+ global position * 1E7
+ global position * 1E7
+ global position * 1000
+
+
+ Once the MAV sets a new GPS-Local correspondence, this message announces the origin (0,0,0) position
+ Latitude (WGS84), expressed as * 1E7
+ Longitude (WGS84), expressed as * 1E7
+ Altitude(WGS84), expressed as * 1000
+
+
+ Set the setpoint for a local position controller. This is the position in local coordinates the MAV should fly to. This message is sent by the path/waypoint planner to the onboard position controller. As some MAVs have a degree of freedom in yaw (e.g. all helicopters/quadrotors), the desired yaw angle is part of the message.
+ System ID
+ Component ID
+ x position
+ y position
+ z position
+ Desired yaw angle
+
+
+ Transmit the current local setpoint of the controller to other MAVs (collision avoidance) and to the GCS.
+ x position
+ y position
+ z position
+ Desired yaw angle
+
+
+ Position fix: 0: lost, 2: 2D position fix, 3: 3D position fix
+ Vision position fix: 0: lost, 1: 2D local position hold, 2: 2D global position fix, 3: 3D global position fix
+ GPS position fix: 0: no reception, 1: Minimum 1 satellite, but no position fix, 2: 2D position fix, 3: 3D position fix
+ Attitude estimation health: 0: poor, 255: excellent
+ 0: Attitude control disabled, 1: enabled
+ 0: X, Y position control disabled, 1: enabled
+ 0: Z position control disabled, 1: enabled
+ 0: Yaw angle control disabled, 1: enabled
+
+
+ Set a safety zone (volume), which is defined by two corners of a cube. This message can be used to tell the MAV which setpoints/waypoints to accept and which to reject. Safety areas are often enforced by national or competition regulations.
+ System ID
+ Component ID
+ Coordinate frame, as defined by MAV_FRAME enum in mavlink_types.h. Can be either global, GPS, right-handed with Z axis up or local, right handed, Z axis down.
+ x position 1 / Latitude 1
+ y position 1 / Longitude 1
+ z position 1 / Altitude 1
+ x position 2 / Latitude 2
+ y position 2 / Longitude 2
+ z position 2 / Altitude 2
+
+
+ Read out the safety zone the MAV currently assumes.
+ Coordinate frame, as defined by MAV_FRAME enum in mavlink_types.h. Can be either global, GPS, right-handed with Z axis up or local, right handed, Z axis down.
+ x position 1 / Latitude 1
+ y position 1 / Longitude 1
+ z position 1 / Altitude 1
+ x position 2 / Latitude 2
+ y position 2 / Longitude 2
+ z position 2 / Altitude 2
+
+
+ Set roll, pitch and yaw.
+ System ID
+ Component ID
+ Desired roll angle in radians
+ Desired pitch angle in radians
+ Desired yaw angle in radians
+ Collective thrust, normalized to 0 .. 1
+
+
+ Set roll, pitch and yaw.
+ System ID
+ Component ID
+ Desired roll angular speed in rad/s
+ Desired pitch angular speed in rad/s
+ Desired yaw angular speed in rad/s
+ Collective thrust, normalized to 0 .. 1
+
+
+ Setpoint in roll, pitch, yaw currently active on the system.
+ Timestamp in micro seconds since unix epoch
+ Desired roll angle in radians
+ Desired pitch angle in radians
+ Desired yaw angle in radians
+ Collective thrust, normalized to 0 .. 1
+
+
+ Setpoint in rollspeed, pitchspeed, yawspeed currently active on the system.
+ Timestamp in micro seconds since unix epoch
+ Desired roll angular speed in rad/s
+ Desired pitch angular speed in rad/s
+ Desired yaw angular speed in rad/s
+ Collective thrust, normalized to 0 .. 1
+
+
+ Outputs of the APM navigation controller. The primary use of this message is to check the response and signs
+of the controller before actual flight and to assist with tuning controller parameters
+ Current desired roll in degrees
+ Current desired pitch in degrees
+ Current desired heading in degrees
+ Bearing to current waypoint/target in degrees
+ Distance to active waypoint in meters
+ Current altitude error in meters
+ Current airspeed error in meters/second
+ Current crosstrack error on x-y plane in meters
+
+
+ The goal position of the system. This position is the input to any navigation or path planning algorithm and does NOT represent the current controller setpoint.
+ x position
+ y position
+ z position
+ yaw orientation in radians, 0 = NORTH
+
+
+ Corrects the systems state by adding an error correction term to the position and velocity, and by rotating the attitude by a correction angle.
+ x position error
+ y position error
+ z position error
+ roll error (radians)
+ pitch error (radians)
+ yaw error (radians)
+ x velocity
+ y velocity
+ z velocity
+
+
+ The system setting the altitude
+ The new altitude in meters
+
+
+ The target requested to send the message stream.
+ The target requested to send the message stream.
+ The ID of the requested message type
+ Update rate in Hertz
+ 1 to start sending, 0 to stop sending.
+
+
+ This packet is useful for high throughput
+ applications such as hardware in the loop simulations.
+
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ Roll angle (rad)
+ Pitch angle (rad)
+ Yaw angle (rad)
+ Roll angular speed (rad/s)
+ Pitch angular speed (rad/s)
+ Yaw angular speed (rad/s)
+ Latitude, expressed as * 1E7
+ Longitude, expressed as * 1E7
+ Altitude in meters, expressed as * 1000 (millimeters)
+ Ground X Speed (Latitude), expressed as m/s * 100
+ Ground Y Speed (Longitude), expressed as m/s * 100
+ Ground Z Speed (Altitude), expressed as m/s * 100
+ X acceleration (mg)
+ Y acceleration (mg)
+ Z acceleration (mg)
+
+
+ Hardware in the loop control outputs
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ Control output -3 .. 1
+ Control output -1 .. 1
+ Control output -1 .. 1
+ Throttle 0 .. 1
+ System mode (MAV_MODE)
+ Navigation mode (MAV_NAV_MODE)
+
+
+ The system to be controlled
+ roll
+ pitch
+ yaw
+ thrust
+ roll control enabled auto:0, manual:1
+ pitch auto:0, manual:1
+ yaw auto:0, manual:1
+ thrust auto:0, manual:1
+
+
+ The RAW values of the RC channels sent to the MAV to override info received from the RC radio. A value of -1 means no change to that channel. A value of 0 means control of that channel should be released back to the RC radio. The standard PPM modulation is as follows: 1000 microseconds: 0%, 2000 microseconds: 100%. Individual receivers/transmitters might violate this specification.
+ System ID
+ Component ID
+ RC channel 1 value, in microseconds
+ RC channel 2 value, in microseconds
+ RC channel 3 value, in microseconds
+ RC channel 4 value, in microseconds
+ RC channel 5 value, in microseconds
+ RC channel 6 value, in microseconds
+ RC channel 7 value, in microseconds
+ RC channel 8 value, in microseconds
+
+
+ The filtered global position (e.g. fused GPS and accelerometers). The position is in GPS-frame (right-handed, Z-up)
+ Latitude, expressed as * 1E7
+ Longitude, expressed as * 1E7
+ Altitude in meters, expressed as * 1000 (millimeters)
+ Ground X Speed (Latitude), expressed as m/s * 100
+ Ground Y Speed (Longitude), expressed as m/s * 100
+ Ground Z Speed (Altitude), expressed as m/s * 100
+
+
+ Metrics typically displayed on a HUD for fixed wing aircraft
+ Current airspeed in m/s
+ Current ground speed in m/s
+ Current heading in degrees, in compass units (0..360, 0=north)
+ Current throttle setting in integer percent, 0 to 100
+ Current altitude (MSL), in meters
+ Current climb rate in meters/second
+
+
+ Send a command with up to four parameters to the MAV
+ System which should execute the command
+ Component which should execute the command, 0 for all components
+ Command ID, as defined by MAV_CMD enum.
+ 0: First transmission of this command. 1-255: Confirmation transmissions (e.g. for kill command)
+ Parameter 1, as defined by MAV_CMD enum.
+ Parameter 2, as defined by MAV_CMD enum.
+ Parameter 3, as defined by MAV_CMD enum.
+ Parameter 4, as defined by MAV_CMD enum.
+
+
+ Report status of a command. Includes feedback wether the command was executed
+ Current airspeed in m/s
+ 1: Action ACCEPTED and EXECUTED, 1: Action TEMPORARY REJECTED/DENIED, 2: Action PERMANENTLY DENIED, 3: Action UNKNOWN/UNSUPPORTED, 4: Requesting CONFIRMATION
+
+
+ Optical flow from a flow sensor (e.g. optical mouse sensor)
+ Timestamp (UNIX)
+ Sensor ID
+ Flow in pixels in x-sensor direction
+ Flow in pixels in y-sensor direction
+ Optical flow quality / confidence. 0: bad, 255: maximum quality
+ Ground distance in meters
+
+
+ Object has been detected
+ Timestamp in milliseconds since system boot
+ Object ID
+ Object type: 0: image, 1: letter, 2: ground vehicle, 3: air vehicle, 4: surface vehicle, 5: sub-surface vehicle, 6: human, 7: animal
+ Name of the object as defined by the detector
+ Detection quality / confidence. 0: bad, 255: maximum confidence
+ Angle of the object with respect to the body frame in NED coordinates in radians. 0: front
+ Ground distance in meters
+
+
+
+ Name
+ Timestamp
+ x
+ y
+ z
+
+
+ Send a key-value pair as float. The use of this message is discouraged for normal packets, but a quite efficient way for testing new messages and getting experimental debug output.
+ Name of the debug variable
+ Floating point value
+
+
+ Send a key-value pair as integer. The use of this message is discouraged for normal packets, but a quite efficient way for testing new messages and getting experimental debug output.
+ Name of the debug variable
+ Signed integer value
+
+
+ Status text message. These messages are printed in yellow in the COMM console of QGroundControl. WARNING: They consume quite some bandwidth, so use only for important status and error messages. If implemented wisely, these messages are buffered on the MCU and sent only at a limited rate (e.g. 10 Hz).
+ Severity of status, 0 = info message, 255 = critical fault
+ Status text message, without null termination character
+
+
+ Send a debug value. The index is used to discriminate between values. These values show up in the plot of QGroundControl as DEBUG N.
+ index of debug variable
+ DEBUG value
+
+
+
diff --git a/mavlink-solo/message_definitions/v0.9/minimal.xml b/mavlink-solo/message_definitions/v0.9/minimal.xml
new file mode 100644
index 0000000..5b41a49
--- /dev/null
+++ b/mavlink-solo/message_definitions/v0.9/minimal.xml
@@ -0,0 +1,13 @@
+
+
+ 2
+
+
+
+ The heartbeat message shows that a system is present and responding. The type of the MAV and Autopilot hardware allow the receiving system to treat further messages from this system appropriate (e.g. by laying out the user interface based on the autopilot).
+ Type of the MAV (quadrotor, helicopter, etc., up to 15 types, defined in MAV_TYPE ENUM)
+ Type of the Autopilot: 0: Generic, 1: PIXHAWK, 2: SLUGS, 3: Ardupilot (up to 15 types), defined in MAV_AUTOPILOT_TYPE ENUM
+ MAVLink version
+
+
+
diff --git a/mavlink-solo/message_definitions/v0.9/pixhawk.xml b/mavlink-solo/message_definitions/v0.9/pixhawk.xml
new file mode 100644
index 0000000..a9a51d6
--- /dev/null
+++ b/mavlink-solo/message_definitions/v0.9/pixhawk.xml
@@ -0,0 +1,227 @@
+
+
+ common.xml
+
+
+ Content Types for data transmission handshake
+
+
+
+
+
+
+
+ Camera id
+ Camera mode: 0 = auto, 1 = manual
+ Trigger pin, 0-3 for PtGrey FireFly
+ Shutter interval, in microseconds
+ Exposure time, in microseconds
+ Camera gain
+
+
+ Timestamp
+ IMU seq
+ Roll angle in rad
+ Pitch angle in rad
+ Yaw angle in rad
+ Local frame Z coordinate (height over ground)
+ GPS X coordinate
+ GPS Y coordinate
+ Global frame altitude
+ Ground truth X
+ Ground truth Y
+ Ground truth Z
+
+
+ 0 to disable, 1 to enable
+
+
+ Camera id
+ Camera # (starts with 0)
+ Timestamp
+ Until which timestamp this buffer will stay valid
+ The image sequence number
+ Position of the image in the buffer, starts with 0
+ Image width
+ Image height
+ Image depth
+ Image channels
+ Shared memory area key
+ Exposure time, in microseconds
+ Camera gain
+ Roll angle in rad
+ Pitch angle in rad
+ Yaw angle in rad
+ Local frame Z coordinate (height over ground)
+ GPS X coordinate
+ GPS Y coordinate
+ Global frame altitude
+ Ground truth X
+ Ground truth Y
+ Ground truth Z
+
+
+ Timestamp (milliseconds)
+ Global X position
+ Global Y position
+ Global Z position
+ Roll angle in rad
+ Pitch angle in rad
+ Yaw angle in rad
+
+
+ Timestamp (milliseconds)
+ Global X position
+ Global Y position
+ Global Z position
+ Roll angle in rad
+ Pitch angle in rad
+ Yaw angle in rad
+
+
+ Timestamp (milliseconds)
+ Global X speed
+ Global Y speed
+ Global Z speed
+
+
+ Message sent to the MAV to set a new position as reference for the controller
+ System ID
+ Component ID
+ ID of waypoint, 0 for plain position
+ x position
+ y position
+ z position
+ yaw orientation in radians, 0 = NORTH
+
+
+ Message sent to the MAV to set a new offset from the currently controlled position
+ System ID
+ Component ID
+ x position offset
+ y position offset
+ z position offset
+ yaw orientation offset in radians, 0 = NORTH
+
+
+
+ ID of waypoint, 0 for plain position
+ x position
+ y position
+ z position
+ yaw orientation in radians, 0 = NORTH
+
+
+ ID
+ x position
+ y position
+ z position
+ roll orientation
+ pitch orientation
+ yaw orientation
+
+
+ ADC1 (J405 ADC3, LPC2148 AD0.6)
+ ADC2 (J405 ADC5, LPC2148 AD0.2)
+ ADC3 (J405 ADC6, LPC2148 AD0.1)
+ ADC4 (J405 ADC7, LPC2148 AD1.3)
+ Battery voltage
+ Temperature (degrees celcius)
+ Barometric pressure (hecto Pascal)
+
+
+ Watchdog ID
+ Number of processes
+
+
+ Watchdog ID
+ Process ID
+ Process name
+ Process arguments
+ Timeout (seconds)
+
+
+ Watchdog ID
+ Process ID
+ Is running / finished / suspended / crashed
+ Is muted
+ PID
+ Number of crashes
+
+
+ Target system ID
+ Watchdog ID
+ Process ID
+ Command ID
+
+
+ 0: Pattern, 1: Letter
+ Confidence of detection
+ Pattern file name
+ Accepted as true detection, 0 no, 1 yes
+
+
+ Notifies the operator about a point of interest (POI). This can be anything detected by the
+ system. This generic message is intented to help interfacing to generic visualizations and to display
+ the POI on a map.
+
+ 0: Notice, 1: Warning, 2: Critical, 3: Emergency, 4: Debug
+ 0: blue, 1: yellow, 2: red, 3: orange, 4: green, 5: magenta
+ 0: global, 1:local
+ 0: no timeout, >1: timeout in seconds
+ X Position
+ Y Position
+ Z Position
+ POI name
+
+
+ Notifies the operator about the connection of two point of interests (POI). This can be anything detected by the
+ system. This generic message is intented to help interfacing to generic visualizations and to display
+ the POI on a map.
+
+ 0: Notice, 1: Warning, 2: Critical, 3: Emergency, 4: Debug
+ 0: blue, 1: yellow, 2: red, 3: orange, 4: green, 5: magenta
+ 0: global, 1:local
+ 0: no timeout, >1: timeout in seconds
+ X1 Position
+ Y1 Position
+ Z1 Position
+ X2 Position
+ Y2 Position
+ Z2 Position
+ POI connection name
+
+
+ type of requested/acknowledged data (as defined in ENUM DATA_TYPES in mavlink/include/mavlink_types.h)
+ total data size in bytes (set on ACK only)
+ number of packets beeing sent (set on ACK only)
+ payload size per packet (normally 253 byte, see DATA field size in message ENCAPSULATED_DATA) (set on ACK only)
+ JPEG quality out of [1,100]
+
+
+ sequence number (starting with 0 on every transmission)
+ image data bytes
+
+
+ x position in m
+ y position in m
+ z position in m
+ Orientation assignment 0: false, 1:true
+ Size in pixels
+ Orientation
+ Descriptor
+ Harris operator response at this location
+
+
+ The system to be controlled
+ roll
+ pitch
+ yaw
+ thrust
+ roll control enabled auto:0, manual:1
+ pitch auto:0, manual:1
+ yaw auto:0, manual:1
+ thrust auto:0, manual:1
+
+
+
diff --git a/mavlink-solo/message_definitions/v0.9/slugs.xml b/mavlink-solo/message_definitions/v0.9/slugs.xml
new file mode 100644
index 0000000..db08abb
--- /dev/null
+++ b/mavlink-solo/message_definitions/v0.9/slugs.xml
@@ -0,0 +1,148 @@
+
+
+ common.xml
+
+
+
+
+
+
+
+ Sensor and DSC control loads.
+
+ Sensor DSC Load
+ Control DSC Load
+ Battery Voltage in millivolts
+
+
+
+
+ Air data for altitude and airspeed computation.
+
+ Dynamic pressure (Pa)
+ Static pressure (Pa)
+ Board temperature
+
+
+
+ Accelerometer and gyro biases.
+ Accelerometer X bias (m/s)
+ Accelerometer Y bias (m/s)
+ Accelerometer Z bias (m/s)
+ Gyro X bias (rad/s)
+ Gyro Y bias (rad/s)
+ Gyro Z bias (rad/s)
+
+
+
+ Configurable diagnostic messages.
+ Diagnostic float 1
+ Diagnostic float 2
+ Diagnostic float 3
+ Diagnostic short 1
+ Diagnostic short 2
+ Diagnostic short 3
+
+
+
+ Data used in the navigation algorithm.
+ Measured Airspeed prior to the Nav Filter
+ Commanded Roll
+ Commanded Pitch
+ Commanded Turn rate
+ Y component of the body acceleration
+ Total Distance to Run on this leg of Navigation
+ Remaining distance to Run on this leg of Navigation
+ Origin WP
+ Destination WP
+
+
+
+ Configurable data log probes to be used inside Simulink
+ Log value 1
+ Log value 2
+ Log value 3
+ Log value 4
+ Log value 5
+ Log value 6
+
+
+
+ Pilot console PWM messges.
+ Year reported by Gps
+ Month reported by Gps
+ Day reported by Gps
+ Hour reported by Gps
+ Min reported by Gps
+ Sec reported by Gps
+ Visible sattelites reported by Gps
+
+
+
+ Mid Level commands sent from the GS to the autopilot. These are only sent when being opperated in mid-level commands mode from the ground; for periodic report of these commands generated from the autopilot see message XXXX.
+ The system setting the commands
+ Commanded Airspeed
+ Log value 2
+ Log value 3
+
+
+
+
+ This message configures the Selective Passthrough mode. it allows to select which control surfaces the Pilot can control from his console. It is implemented as a bitfield as follows:
+ Position Bit Code
+ =================================
+ 15-8 Reserved
+ 7 dt_pass 128
+ 6 dla_pass 64
+ 5 dra_pass 32
+ 4 dr_pass 16
+ 3 dle_pass 8
+ 2 dre_pass 4
+ 1 dlf_pass 2
+ 0 drf_pass 1
+ Where Bit 15 is the MSb. 0 = AP has control of the surface; 1 = Pilot Console has control of the surface.
+ The system setting the commands
+ Bitfield containing the PT configuration
+
+
+
+
+
+ Action messages focused on the SLUGS AP.
+ The system reporting the action
+ Action ID. See apDefinitions.h in the SLUGS /clib directory for the ID names
+ Value associated with the action
+
+
+
+
diff --git a/mavlink-solo/message_definitions/v0.9/test.xml b/mavlink-solo/message_definitions/v0.9/test.xml
new file mode 100644
index 0000000..43a11e3
--- /dev/null
+++ b/mavlink-solo/message_definitions/v0.9/test.xml
@@ -0,0 +1,31 @@
+
+
+ 3
+
+
+ Test all field types
+ char
+ string
+ uint8_t
+ uint16_t
+ uint32_t
+ uint64_t
+ int8_t
+ int16_t
+ int32_t
+ int64_t
+ float
+ double
+ uint8_t_array
+ uint16_t_array
+ uint32_t_array
+ uint64_t_array
+ int8_t_array
+ int16_t_array
+ int32_t_array
+ int64_t_array
+ float_array
+ double_array
+
+
+
diff --git a/mavlink-solo/message_definitions/v0.9/ualberta.xml b/mavlink-solo/message_definitions/v0.9/ualberta.xml
new file mode 100644
index 0000000..4023aa9
--- /dev/null
+++ b/mavlink-solo/message_definitions/v0.9/ualberta.xml
@@ -0,0 +1,54 @@
+
+
+ common.xml
+
+
+ Available autopilot modes for ualberta uav
+ Raw input pulse widts sent to output
+ Inputs are normalized using calibration, the converted back to raw pulse widths for output
+ dfsdfs
+ dfsfds
+ dfsdfsdfs
+
+
+ Navigation filter mode
+
+ AHRS mode
+ INS/GPS initialization mode
+ INS/GPS mode
+
+
+ Mode currently commanded by pilot
+ sdf
+ dfs
+ Rotomotion mode
+
+
+
+
+ Accelerometer and Gyro biases from the navigation filter
+ Timestamp (microseconds)
+ b_f[0]
+ b_f[1]
+ b_f[2]
+ b_f[0]
+ b_f[1]
+ b_f[2]
+
+
+ Complete set of calibration parameters for the radio
+ Aileron setpoints: left, center, right
+ Elevator setpoints: nose down, center, nose up
+ Rudder setpoints: nose left, center, nose right
+ Tail gyro mode/gain setpoints: heading hold, rate mode
+ Pitch curve setpoints (every 25%)
+ Throttle curve setpoints (every 25%)
+
+
+ System status specific to ualberta uav
+ System mode, see UALBERTA_AUTOPILOT_MODE ENUM
+ Navigation mode, see UALBERTA_NAV_MODE ENUM
+ Pilot mode, see UALBERTA_PILOT_MODE
+
+
+
diff --git a/mavlink-solo/message_definitions/v1.0/ASLUAV.xml b/mavlink-solo/message_definitions/v1.0/ASLUAV.xml
new file mode 100644
index 0000000..feb1095
--- /dev/null
+++ b/mavlink-solo/message_definitions/v1.0/ASLUAV.xml
@@ -0,0 +1,123 @@
+
+
+
+
+ common.xml
+
+
+ Voltage and current sensor data
+ Power board voltage sensor reading in volts
+ Power board current sensor reading in amps
+ Board current sensor 1 reading in amps
+ Board current sensor 2 reading in amps
+
+
+ Maximum Power Point Tracker (MPPT) sensor data for solar module power performance tracking
+ MPPT last timestamp
+ MPPT1 voltage
+ MPPT1 current
+ MPPT1 pwm
+ MPPT1 status
+ MPPT2 voltage
+ MPPT2 current
+ MPPT2 pwm
+ MPPT2 status
+ MPPT3 voltage
+ MPPT3 current
+ MPPT3 pwm
+ MPPT3 status
+
+
+ ASL-fixed-wing controller data
+ Timestamp
+ ASLCTRL control-mode (manual, stabilized, auto, etc...)
+ See sourcecode for a description of these values...
+
+
+ Pitch angle [deg]
+ Pitch angle reference[deg]
+
+
+
+
+
+
+ Airspeed reference [m/s]
+
+ Yaw angle [deg]
+ Yaw angle reference[deg]
+ Roll angle [deg]
+ Roll angle reference[deg]
+
+
+
+
+
+
+
+
+ ASL-fixed-wing controller debug data
+ Debug data
+ Debug data
+ Debug data
+ Debug data
+ Debug data
+ Debug data
+ Debug data
+ Debug data
+ Debug data
+ Debug data
+ Debug data
+
+
+ Extended state information for ASLUAVs
+ Status of the position-indicator LEDs
+ Status of the IRIDIUM satellite communication system
+ Status vector for up to 8 servos
+ Motor RPM
+
+
+
+ Extended EKF state estimates for ASLUAVs
+ Time since system start [us]
+ Magnitude of wind velocity (in lateral inertial plane) [m/s]
+ Wind heading angle from North [rad]
+ Z (Down) component of inertial wind velocity [m/s]
+ Magnitude of air velocity [m/s]
+ Sideslip angle [rad]
+ Angle of attack [rad]
+
+
+ Off-board controls/commands for ASLUAVs
+ Time since system start [us]
+ Elevator command [~]
+ Throttle command [~]
+ Throttle 2 command [~]
+ Left aileron command [~]
+ Right aileron command [~]
+ Rudder command [~]
+ Off-board computer status
+
+
+ Atmospheric sensors (temperature, humidity, ...)
+ Ambient temperature [degrees Celsius]
+ Relative humidity [%]
+
+
+ Battery pack monitoring data for Li-Ion batteries
+ Battery pack temperature in [deg C]
+ Battery pack voltage in [mV]
+ Battery pack current in [mA]
+ Battery pack state-of-charge
+ Battery monitor status report bits in Hex
+ Battery monitor serial number in Hex
+ Battery monitor sensor host FET control in Hex
+ Battery pack cell 1 voltage in [mV]
+ Battery pack cell 2 voltage in [mV]
+ Battery pack cell 3 voltage in [mV]
+ Battery pack cell 4 voltage in [mV]
+ Battery pack cell 5 voltage in [mV]
+ Battery pack cell 6 voltage in [mV]
+
+
+
diff --git a/mavlink-solo/message_definitions/v1.0/ardupilotmega.xml b/mavlink-solo/message_definitions/v1.0/ardupilotmega.xml
new file mode 100644
index 0000000..3ff1bc4
--- /dev/null
+++ b/mavlink-solo/message_definitions/v1.0/ardupilotmega.xml
@@ -0,0 +1,1342 @@
+
+
+ common.xml
+
+
+
+
+
+
+
+ Mission command to perform motor test
+ motor sequence number (a number from 1 to max number of motors on the vehicle)
+ throttle type (0=throttle percentage, 1=PWM, 2=pilot throttle channel pass-through. See MOTOR_TEST_THROTTLE_TYPE enum)
+ throttle
+ timeout (in seconds)
+ Empty
+ Empty
+ Empty
+
+
+ Mission command to operate EPM gripper
+ gripper number (a number from 1 to max number of grippers on the vehicle)
+ gripper action (0=release, 1=grab. See GRIPPER_ACTIONS enum)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+ A system wide power-off event has been initiated.
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+
+ FLY button has been clicked.
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+ FLY button has been held for 1.5 seconds.
+ Takeoff altitude
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+ PAUSE button has been clicked.
+ 1 if Solo is in a shot mode, 0 otherwise
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+ Initiate a magnetometer calibration
+ uint8_t bitmask of magnetometers (0 means all)
+ Automatically retry on failure (0=no retry, 1=retry).
+ Save without user input (0=require input, 1=autosave).
+ Delay (seconds)
+ Empty
+ Empty
+ Empty
+
+
+ Initiate a magnetometer calibration
+ uint8_t bitmask of magnetometers (0 means all)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Cancel a running magnetometer calibration
+ uint8_t bitmask of magnetometers (0 means all)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+ Reply with the version banner
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+ Causes the gimbal to reset and boot as if it was just powered on
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+ Command autopilot to get into factory test/diagnostic mode
+ 0 means get out of test mode, 1 means get into test mode
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+ Reports progress and success or failure of gimbal axis calibration procedure
+ Gimbal axis we're reporting calibration progress for
+ Current calibration progress for this axis, 0x64=100%
+ Status of the calibration
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Starts commutation calibration on the gimbal
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Erases gimbal application and parameters
+ Magic number
+ Magic number
+ Magic number
+ Magic number
+ Magic number
+ Magic number
+ Magic number
+
+
+
+
+
+
+ pre-initialization
+ disabled
+ checking limits
+ a limit has been breached
+ taking action eg. RTL
+ we're no longer in breach of a limit
+
+
+
+
+ pre-initialization
+ disabled
+ checking limits
+
+
+
+
+ Flags in RALLY_POINT message
+ Flag set when requiring favorable winds for landing.
+ Flag set when plane is to immediately descend to break altitude and land without GCS intervention. Flag not set when plane is to loiter at Rally point until commanded to land.
+
+
+
+
+
+ Disable parachute release
+
+
+ Enable parachute release
+
+
+ Release parachute
+
+
+
+
+
+
+ throttle as a percentage from 0 ~ 100
+
+
+ throttle as an absolute PWM value (normally in range of 1000~2000)
+
+
+ throttle pass-through from pilot's transmitter
+
+
+
+
+
+ Gripper actions.
+
+ gripper release of cargo
+
+
+ gripper grabs onto cargo
+
+
+
+
+
+ Camera heartbeat, announce camera component ID at 1hz
+ Camera image triggered
+ Camera connection lost
+ Camera unknown error
+ Camera battery low. Parameter p1 shows reported voltage
+ Camera storage low. Parameter p1 shows reported shots remaining
+ Camera storage low. Parameter p1 shows reported video minutes remaining
+
+
+
+
+ Shooting video, not stills
+ Unable to achieve requested exposure (e.g. shutter speed too low)
+ Closed loop feedback from camera, we know for sure it has successfully taken a picture
+ Open loop camera, an image trigger has been requested but we can't know for sure it has successfully taken a picture
+
+
+
+
+
+ Gimbal is powered on but has not started initializing yet
+
+
+ Gimbal is currently running calibration on the pitch axis
+
+
+ Gimbal is currently running calibration on the roll axis
+
+
+ Gimbal is currently running calibration on the yaw axis
+
+
+ Gimbal has finished calibrating and initializing, but is relaxed pending reception of first rate command from copter
+
+
+ Gimbal is actively stabilizing
+
+
+ Gimbal is relaxed because it missed more than 10 expected rate command messages in a row. Gimbal will move back to active mode when it receives a new rate command
+
+
+
+
+
+ Gimbal yaw axis
+
+
+ Gimbal pitch axis
+
+
+ Gimbal roll axis
+
+
+
+
+
+ Axis calibration is in progress
+
+
+ Axis calibration succeeded
+
+
+ Axis calibration failed
+
+
+
+
+
+ Whether or not this axis requires calibration is unknown at this time
+
+
+ This axis requires calibration
+
+
+ This axis does not require calibration
+
+
+
+
+
+
+ No GoPro connected
+
+
+ The detected GoPro is not HeroBus compatible
+
+
+ A HeroBus compatible GoPro is connected
+
+
+ An unrecoverable error was encountered with the connected GoPro, it may require a power cycle
+
+
+
+
+
+
+ GoPro is currently recording
+
+
+
+
+
+ The write message with ID indicated succeeded
+
+
+ The write message with ID indicated failed
+
+
+
+
+
+ (Get/Set)
+
+
+ (Get/Set)
+
+
+ (___/Set)
+
+
+ (Get/___)
+
+
+ (Get/___)
+
+
+ (Get/Set)
+
+
+
+ (Get/Set)
+
+
+ (Get/Set)
+
+
+ (Get/Set)
+
+
+ (Get/Set)
+
+
+ (Get/Set) Hero 3+ Only
+
+
+ (Get/Set) Hero 3+ Only
+
+
+ (Get/Set) Hero 3+ Only
+
+
+ (Get/Set) Hero 3+ Only
+
+
+ (Get/Set) Hero 3+ Only
+
+
+ (Get/Set)
+
+
+
+ (Get/Set)
+
+
+
+
+
+ Video mode
+
+
+ Photo mode
+
+
+ Burst mode, hero 3+ only
+
+
+ Time lapse mode, hero 3+ only
+
+
+ Multi shot mode, hero 4 only
+
+
+ Playback mode, hero 4 only, silver only except when LCD or HDMI is connected to black
+
+
+ Playback mode, hero 4 only
+
+
+ Mode not yet known
+
+
+
+
+
+ 848 x 480 (480p)
+
+
+ 1280 x 720 (720p)
+
+
+ 1280 x 960 (960p)
+
+
+ 1920 x 1080 (1080p)
+
+
+ 1920 x 1440 (1440p)
+
+
+ 2704 x 1440 (2.7k-17:9)
+
+
+ 2704 x 1524 (2.7k-16:9)
+
+
+ 2704 x 2028 (2.7k-4:3)
+
+
+ 3840 x 2160 (4k-16:9)
+
+
+ 4096 x 2160 (4k-17:9)
+
+
+ 1280 x 720 (720p-SuperView)
+
+
+ 1920 x 1080 (1080p-SuperView)
+
+
+ 2704 x 1520 (2.7k-SuperView)
+
+
+ 3840 x 2160 (4k-SuperView)
+
+
+
+
+
+ 12 FPS
+
+
+ 15 FPS
+
+
+ 24 FPS
+
+
+ 25 FPS
+
+
+ 30 FPS
+
+
+ 48 FPS
+
+
+ 50 FPS
+
+
+ 60 FPS
+
+
+ 80 FPS
+
+
+ 90 FPS
+
+
+ 100 FPS
+
+
+ 120 FPS
+
+
+ 240 FPS
+
+
+ 12.5 FPS
+
+
+
+
+
+ 0x00: Wide
+
+
+ 0x01: Medium
+
+
+ 0x02: Narrow
+
+
+
+
+
+ 0=NTSC, 1=PAL
+
+
+
+
+
+ 5MP Medium
+
+
+ 7MP Medium
+
+
+ 7MP Wide
+
+
+ 10MP Wide
+
+
+ 12MP Wide
+
+
+
+
+
+ Auto
+
+
+ 3000K
+
+
+ 5500K
+
+
+ 6500K
+
+
+ Camera Raw
+
+
+
+
+
+ Auto
+
+
+ Neutral
+
+
+
+
+
+ ISO 400
+
+
+ ISO 800 (Only Hero 4)
+
+
+ ISO 1600
+
+
+ ISO 3200 (Only Hero 4)
+
+
+ ISO 6400
+
+
+
+
+
+ Low Sharpness
+
+
+ Medium Sharpness
+
+
+ High Sharpness
+
+
+
+
+
+ -5.0 EV (Hero 3+ Only)
+
+
+ -4.5 EV (Hero 3+ Only)
+
+
+ -4.0 EV (Hero 3+ Only)
+
+
+ -3.5 EV (Hero 3+ Only)
+
+
+ -3.0 EV (Hero 3+ Only)
+
+
+ -2.5 EV (Hero 3+ Only)
+
+
+ -2.0 EV
+
+
+ -1.5 EV
+
+
+ -1.0 EV
+
+
+ -0.5 EV
+
+
+ 0.0 EV
+
+
+ +0.5 EV
+
+
+ +1.0 EV
+
+
+ +1.5 EV
+
+
+ +2.0 EV
+
+
+ +2.5 EV (Hero 3+ Only)
+
+
+ +3.0 EV (Hero 3+ Only)
+
+
+ +3.5 EV (Hero 3+ Only)
+
+
+ +4.0 EV (Hero 3+ Only)
+
+
+ +4.5 EV (Hero 3+ Only)
+
+
+ +5.0 EV (Hero 3+ Only)
+
+
+
+
+
+ Charging disabled
+
+
+ Charging enabled
+
+
+
+
+
+ Unknown gopro model
+
+
+ Hero 3+ Silver (HeroBus not supported by GoPro)
+
+
+ Hero 3+ Black
+
+
+ Hero 4 Silver
+
+
+ Hero 4 Black
+
+
+
+
+
+ 3 Shots / 1 Second
+
+
+ 5 Shots / 1 Second
+
+
+ 10 Shots / 1 Second
+
+
+ 10 Shots / 2 Second
+
+
+ 10 Shots / 3 Second (Hero 4 Only)
+
+
+ 30 Shots / 1 Second
+
+
+ 30 Shots / 2 Second
+
+
+ 30 Shots / 3 Second
+
+
+ 30 Shots / 6 Second
+
+
+
+
+
+ LED patterns off (return control to regular vehicle control)
+ LEDs show pattern during firmware update
+ Custom Pattern using custom bytes fields
+
+
+
+
+ Flags in EKF_STATUS message
+ set if EKF's attitude estimate is good
+ set if EKF's horizontal velocity estimate is good
+ set if EKF's vertical velocity estimate is good
+ set if EKF's horizontal position (relative) estimate is good
+ set if EKF's horizontal position (absolute) estimate is good
+ set if EKF's vertical position (absolute) estimate is good
+ set if EKF's vertical position (above ground) estimate is good
+ EKF is in constant position mode and does not know it's absolute or relative position
+ set if EKF's predicted horizontal position (relative) estimate is good
+ set if EKF's predicted horizontal position (absolute) estimate is good
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Special ACK block numbers control activation of dataflash log streaming
+
+
+
+ UAV to stop sending DataFlash blocks
+
+
+
+ UAV to start sending DataFlash blocks
+
+
+
+
+ Possible remote log data block statuses
+
+ This block has NOT been received
+
+
+ This block has been received
+
+
+
+
+
+
+
+ Offsets and calibrations values for hardware
+ sensors. This makes it easier to debug the calibration process.
+ magnetometer X offset
+ magnetometer Y offset
+ magnetometer Z offset
+ magnetic declination (radians)
+ raw pressure from barometer
+ raw temperature from barometer
+ gyro X calibration
+ gyro Y calibration
+ gyro Z calibration
+ accel X calibration
+ accel Y calibration
+ accel Z calibration
+
+
+
+ Deprecated. Use MAV_CMD_PREFLIGHT_SET_SENSOR_OFFSETS instead. Set the magnetometer offsets
+ System ID
+ Component ID
+ magnetometer X offset
+ magnetometer Y offset
+ magnetometer Z offset
+
+
+
+ state of APM memory
+ heap top
+ free memory
+
+
+
+ raw ADC output
+ ADC output 1
+ ADC output 2
+ ADC output 3
+ ADC output 4
+ ADC output 5
+ ADC output 6
+
+
+
+
+ Configure on-board Camera Control System.
+ System ID
+ Component ID
+ Mode enumeration from 1 to N //P, TV, AV, M, Etc (0 means ignore)
+ Divisor number //e.g. 1000 means 1/1000 (0 means ignore)
+ F stop number x 10 //e.g. 28 means 2.8 (0 means ignore)
+ ISO enumeration from 1 to N //e.g. 80, 100, 200, Etc (0 means ignore)
+ Exposure type enumeration from 1 to N (0 means ignore)
+ Command Identity (incremental loop: 0 to 255)//A command sent multiple times will be executed or pooled just once
+ Main engine cut-off time before camera trigger in seconds/10 (0 means no cut-off)
+ Extra parameters enumeration (0 means ignore)
+ Correspondent value to given extra_param
+
+
+
+ Control on-board Camera Control System to take shots.
+ System ID
+ Component ID
+ 0: stop, 1: start or keep it up //Session control e.g. show/hide lens
+ 1 to N //Zoom's absolute position (0 means ignore)
+ -100 to 100 //Zooming step value to offset zoom from the current position
+ 0: unlock focus or keep unlocked, 1: lock focus or keep locked, 3: re-lock focus
+ 0: ignore, 1: shot or start filming
+ Command Identity (incremental loop: 0 to 255)//A command sent multiple times will be executed or pooled just once
+ Extra parameters enumeration (0 means ignore)
+ Correspondent value to given extra_param
+
+
+
+
+ Message to configure a camera mount, directional antenna, etc.
+ System ID
+ Component ID
+ mount operating mode (see MAV_MOUNT_MODE enum)
+ (1 = yes, 0 = no)
+ (1 = yes, 0 = no)
+ (1 = yes, 0 = no)
+
+
+
+ Message to control a camera mount, directional antenna, etc.
+ System ID
+ Component ID
+ pitch(deg*100) or lat, depending on mount mode
+ roll(deg*100) or lon depending on mount mode
+ yaw(deg*100) or alt (in cm) depending on mount mode
+ if "1" it will save current trimmed position on EEPROM (just valid for NEUTRAL and LANDING)
+
+
+
+ Message with some status from APM to GCS about camera or antenna mount
+ System ID
+ Component ID
+ pitch(deg*100)
+ roll(deg*100)
+ yaw(deg*100)
+
+
+
+
+ A fence point. Used to set a point when from
+ GCS -> MAV. Also used to return a point from MAV -> GCS
+ System ID
+ Component ID
+ point index (first point is 1, 0 is for return point)
+ total number of points (for sanity checking)
+ Latitude of point
+ Longitude of point
+
+
+
+ Request a current fence point from MAV
+ System ID
+ Component ID
+ point index (first point is 1, 0 is for return point)
+
+
+
+ Status of geo-fencing. Sent in extended
+ status stream when fencing enabled
+ 0 if currently inside fence, 1 if outside
+ number of fence breaches
+ last breach type (see FENCE_BREACH_* enum)
+ time of last breach in milliseconds since boot
+
+
+
+ Status of DCM attitude estimator
+ X gyro drift estimate rad/s
+ Y gyro drift estimate rad/s
+ Z gyro drift estimate rad/s
+ average accel_weight
+ average renormalisation value
+ average error_roll_pitch value
+ average error_yaw value
+
+
+
+ Status of simulation environment, if used
+ Roll angle (rad)
+ Pitch angle (rad)
+ Yaw angle (rad)
+ X acceleration m/s/s
+ Y acceleration m/s/s
+ Z acceleration m/s/s
+ Angular speed around X axis rad/s
+ Angular speed around Y axis rad/s
+ Angular speed around Z axis rad/s
+ Latitude in degrees * 1E7
+ Longitude in degrees * 1E7
+
+
+
+ Status of key hardware
+ board voltage (mV)
+ I2C error count
+
+
+
+ Status generated by radio
+ local signal strength
+ remote signal strength
+ how full the tx buffer is as a percentage
+ background noise level
+ remote background noise level
+ receive errors
+ count of error corrected packets
+
+
+
+
+
+ Status of AP_Limits. Sent in extended
+ status stream when AP_Limits is enabled
+ state of AP_Limits, (see enum LimitState, LIMITS_STATE)
+ time of last breach in milliseconds since boot
+ time of last recovery action in milliseconds since boot
+ time of last successful recovery in milliseconds since boot
+ time of last all-clear in milliseconds since boot
+ number of fence breaches
+ AP_Limit_Module bitfield of enabled modules, (see enum moduleid or LIMIT_MODULE)
+ AP_Limit_Module bitfield of required modules, (see enum moduleid or LIMIT_MODULE)
+ AP_Limit_Module bitfield of triggered modules, (see enum moduleid or LIMIT_MODULE)
+
+
+
+ Wind estimation
+ wind direction that wind is coming from (degrees)
+ wind speed in ground plane (m/s)
+ vertical wind speed (m/s)
+
+
+
+ Data packet, size 16
+ data type
+ data length
+ raw data
+
+
+
+ Data packet, size 32
+ data type
+ data length
+ raw data
+
+
+
+ Data packet, size 64
+ data type
+ data length
+ raw data
+
+
+
+ Data packet, size 96
+ data type
+ data length
+ raw data
+
+
+
+ Rangefinder reporting
+ distance in meters
+ raw voltage if available, zero otherwise
+
+
+
+ Airspeed auto-calibration
+ GPS velocity north m/s
+ GPS velocity east m/s
+ GPS velocity down m/s
+ Differential pressure pascals
+ Estimated to true airspeed ratio
+ Airspeed ratio
+ EKF state x
+ EKF state y
+ EKF state z
+ EKF Pax
+ EKF Pby
+ EKF Pcz
+
+
+
+
+ A rally point. Used to set a point when from GCS -> MAV. Also used to return a point from MAV -> GCS
+ System ID
+ Component ID
+ point index (first point is 0)
+ total number of points (for sanity checking)
+ Latitude of point in degrees * 1E7
+ Longitude of point in degrees * 1E7
+ Transit / loiter altitude in meters relative to home
+
+ Break altitude in meters relative to home
+ Heading to aim for when landing. In centi-degrees.
+ See RALLY_FLAGS enum for definition of the bitmask.
+
+
+
+ Request a current rally point from MAV. MAV should respond with a RALLY_POINT message. MAV should not respond if the request is invalid.
+ System ID
+ Component ID
+ point index (first point is 0)
+
+
+
+ Status of compassmot calibration
+ throttle (percent*10)
+ current (amps)
+ interference (percent)
+ Motor Compensation X
+ Motor Compensation Y
+ Motor Compensation Z
+
+
+
+
+
+ Status of secondary AHRS filter if available
+ Roll angle (rad)
+ Pitch angle (rad)
+ Yaw angle (rad)
+ Altitude (MSL)
+ Latitude in degrees * 1E7
+ Longitude in degrees * 1E7
+
+
+
+
+ Camera Event
+ Image timestamp (microseconds since UNIX epoch, according to camera clock)
+ System ID
+ Camera ID
+ Image index
+ See CAMERA_STATUS_TYPES enum for definition of the bitmask
+ Parameter 1 (meaning depends on event, see CAMERA_STATUS_TYPES enum)
+ Parameter 2 (meaning depends on event, see CAMERA_STATUS_TYPES enum)
+ Parameter 3 (meaning depends on event, see CAMERA_STATUS_TYPES enum)
+ Parameter 4 (meaning depends on event, see CAMERA_STATUS_TYPES enum)
+
+
+
+
+ Camera Capture Feedback
+ Image timestamp (microseconds since UNIX epoch), as passed in by CAMERA_STATUS message (or autopilot if no CCB)
+ System ID
+ Camera ID
+ Image index
+ Latitude in (deg * 1E7)
+ Longitude in (deg * 1E7)
+ Altitude Absolute (meters AMSL)
+ Altitude Relative (meters above HOME location)
+ Camera Roll angle (earth frame, degrees, +-180)
+ Camera Pitch angle (earth frame, degrees, +-180)
+ Camera Yaw (earth frame, degrees, 0-360, true)
+ Focal Length (mm)
+ See CAMERA_FEEDBACK_FLAGS enum for definition of the bitmask
+
+
+
+ 2nd Battery status
+ voltage in millivolts
+ Battery current, in 10*milliamperes (1 = 10 milliampere), -1: autopilot does not measure the current
+
+
+
+ Status of third AHRS filter if available. This is for ANU research group (Ali and Sean)
+ Roll angle (rad)
+ Pitch angle (rad)
+ Yaw angle (rad)
+ Altitude (MSL)
+ Latitude in degrees * 1E7
+ Longitude in degrees * 1E7
+ test variable1
+ test variable2
+ test variable3
+ test variable4
+
+
+
+ Request the autopilot version from the system/component.
+ System ID
+ Component ID
+
+
+
+
+ Send a block of log data to remote location
+ System ID
+ Component ID
+ log data block sequence number
+ log data block
+
+
+
+ Send Status of each log block that autopilot board might have sent
+ System ID
+ Component ID
+ log data block sequence number
+ log data block status
+
+
+
+ Control vehicle LEDs
+ System ID
+ Component ID
+ Instance (LED instance to control or 255 for all LEDs)
+ Pattern (see LED_PATTERN_ENUM)
+ Custom Byte Length
+ Custom Bytes
+
+
+
+ Reports progress of compass calibration.
+ Compass being calibrated
+ Bitmask of compasses being calibrated
+ Status (see MAG_CAL_STATUS enum)
+ Attempt number
+ Completion percentage
+ Bitmask of sphere sections (see http://en.wikipedia.org/wiki/Geodesic_grid)
+ Body frame direction vector for display
+ Body frame direction vector for display
+ Body frame direction vector for display
+
+
+
+ Reports results of completed compass calibration. Sent until MAG_CAL_ACK received.
+ Compass being calibrated
+ Bitmask of compasses being calibrated
+ Status (see MAG_CAL_STATUS enum)
+ 0=requires a MAV_CMD_DO_ACCEPT_MAG_CAL, 1=saved to parameters
+ RMS milligauss residuals
+ X offset
+ Y offset
+ Z offset
+ X diagonal (matrix 11)
+ Y diagonal (matrix 22)
+ Z diagonal (matrix 33)
+ X off-diagonal (matrix 12 and 21)
+ Y off-diagonal (matrix 13 and 31)
+ Z off-diagonal (matrix 32 and 23)
+
+
+
+
+ EKF Status message including flags and variances
+ Flags
+ Velocity variance
+ Horizontal Position variance
+ Vertical Position variance
+ Compass variance
+ Terrain Altitude variance
+
+
+
+
+ PID tuning information
+ axis
+ desired rate (degrees/s)
+ achieved rate (degrees/s)
+ FF component
+ P component
+ I component
+ D component
+
+
+
+ 3 axis gimbal mesuraments
+ System ID
+ Component ID
+ Time since last update (seconds)
+ Delta angle X (radians)
+ Delta angle Y (radians)
+ Delta angle X (radians)
+ Delta velocity X (m/s)
+ Delta velocity Y (m/s)
+ Delta velocity Z (m/s)
+ Joint ROLL (radians)
+ Joint EL (radians)
+ Joint AZ (radians)
+
+
+
+ Control message for rate gimbal
+ System ID
+ Component ID
+ Demanded angular rate X (rad/s)
+ Demanded angular rate Y (rad/s)
+ Demanded angular rate Z (rad/s)
+
+
+
+
+ 100 Hz gimbal torque command telemetry
+
+ System ID
+ Component ID
+ Roll Torque Command
+ Elevation Torque Command
+ Azimuth Torque Command
+
+
+
+
+ Heartbeat from a HeroBus attached GoPro
+ Status
+ Current capture mode
+ additional status bits
+
+
+ Request a GOPRO_COMMAND response from the GoPro
+ System ID
+ Component ID
+ Command ID
+
+
+ Response from a GOPRO_COMMAND get request
+ Command ID
+ Status
+ Value
+
+
+ Request to set a GOPRO_COMMAND with a desired
+ System ID
+ Component ID
+ Command ID
+ Value
+
+
+ Response from a GOPRO_COMMAND set request
+ Command ID
+ Status
+
+
+
+
+ Accuracy statistics for GPS lock
+ Which instance of GPS we're reporting on
+ GPS-reported horizontal accuracy
+ GPS-reported speed accuracy
+ GPS-reported, filtered horizontal velocity
+ GPS-reported, filtered vertical velocity
+ GPS position drift
+ Which fields pass EKF checks
+
+
+
diff --git a/mavlink-solo/message_definitions/v1.0/autoquad.xml b/mavlink-solo/message_definitions/v1.0/autoquad.xml
new file mode 100644
index 0000000..30fe3f1
--- /dev/null
+++ b/mavlink-solo/message_definitions/v1.0/autoquad.xml
@@ -0,0 +1,142 @@
+
+
+ common.xml
+ 3
+
+
+ Available operating modes/statuses for AutoQuad flight controller.
+ Bitmask up to 32 bits. Low side bits for base modes, high side for
+ additional active features/modifiers/constraints.
+
+ System is initializing
+
+
+
+ System is standing by, not active
+
+
+ Stabilized, under full manual control
+
+
+ Altitude hold engaged
+
+
+ Position hold engaged
+
+
+ Dynamic Velocity Hold is active
+
+
+ Autonomous mission execution mode
+
+
+
+
+ System is in failsafe recovery mode
+
+
+ Automatic Return to Home is active
+
+
+ Heading-Free locked mode active
+
+
+ Heading-Free dynamic mode active
+
+
+ Ceiling altitude is set
+
+
+ Craft is at ceiling altitude
+
+
+
+
+
+ Start/stop AutoQuad telemetry values stream.
+ Start or stop (1 or 0)
+ Stream frequency in us
+ Dataset ID (refer to aq_mavlink.h::mavlinkCustomDataSets enum in AQ flight controller code)
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Command AutoQuad to go to a particular place at a set speed.
+ Latitude
+ Lontitude
+ Altitude
+ Speed
+ Empty
+ Empty
+ Empty
+
+
+ Request AutoQuad firmware version number.
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+
+
+ Motor/ESC telemetry data.
+
+
+
+
+
+ Sends up to 20 raw float values.
+ Index of message
+ value1
+ value2
+ value3
+ value4
+ value5
+ value6
+ value7
+ value8
+ value9
+ value10
+ value11
+ value12
+ value13
+ value14
+ value15
+ value16
+ value17
+ value18
+ value19
+ value20
+
+
+ Sends ESC32 telemetry data for up to 4 motors. Multiple messages may be sent in sequence when system has > 4 motors. Data is described as follows:
+ // unsigned int state : 3;
+ // unsigned int vin : 12; // x 100
+ // unsigned int amps : 14; // x 100
+ // unsigned int rpm : 15;
+ // unsigned int duty : 8; // x (255/100)
+ // - Data Version 2 -
+ // unsigned int errors : 9; // Bad detects error count
+ // - Data Version 3 -
+ // unsigned int temp : 9; // (Deg C + 32) * 4
+ // unsigned int errCode : 3;
+
+ Timestamp of the component clock since boot time in ms.
+ Sequence number of message (first set of 4 motors is #1, next 4 is #2, etc).
+ Total number of active ESCs/motors on the system.
+ Number of active ESCs in this sequence (1 through this many array members will be populated with data)
+ ESC/Motor ID
+ Age of each ESC telemetry reading in ms compared to boot time. A value of 0xFFFF means timeout/no data.
+ Version of data structure (determines contents).
+ Data bits 1-32 for each ESC.
+ Data bits 33-64 for each ESC.
+
+
+
diff --git a/mavlink-solo/message_definitions/v1.0/common.xml b/mavlink-solo/message_definitions/v1.0/common.xml
new file mode 100644
index 0000000..a2fd107
--- /dev/null
+++ b/mavlink-solo/message_definitions/v1.0/common.xml
@@ -0,0 +1,2836 @@
+
+
+ 3
+
+
+ Micro air vehicle / autopilot classes. This identifies the individual model.
+
+ Generic autopilot, full support for everything
+
+
+ PIXHAWK autopilot, http://pixhawk.ethz.ch
+
+
+ SLUGS autopilot, http://slugsuav.soe.ucsc.edu
+
+
+ ArduPilotMega / ArduCopter, http://diydrones.com
+
+
+ OpenPilot, http://openpilot.org
+
+
+ Generic autopilot only supporting simple waypoints
+
+
+ Generic autopilot supporting waypoints and other simple navigation commands
+
+
+ Generic autopilot supporting the full mission command set
+
+
+ No valid autopilot, e.g. a GCS or other MAVLink component
+
+
+ PPZ UAV - http://nongnu.org/paparazzi
+
+
+ UAV Dev Board
+
+
+ FlexiPilot
+
+
+ PX4 Autopilot - http://pixhawk.ethz.ch/px4/
+
+
+ SMACCMPilot - http://smaccmpilot.org
+
+
+ AutoQuad -- http://autoquad.org
+
+
+ Armazila -- http://armazila.com
+
+
+ Aerob -- http://aerob.ru
+
+
+ ASLUAV autopilot -- http://www.asl.ethz.ch
+
+
+
+
+ Generic micro air vehicle.
+
+
+ Fixed wing aircraft.
+
+
+ Quadrotor
+
+
+ Coaxial helicopter
+
+
+ Normal helicopter with tail rotor.
+
+
+ Ground installation
+
+
+ Operator control unit / ground control station
+
+
+ Airship, controlled
+
+
+ Free balloon, uncontrolled
+
+
+ Rocket
+
+
+ Ground rover
+
+
+ Surface vessel, boat, ship
+
+
+ Submarine
+
+
+ Hexarotor
+
+
+ Octorotor
+
+
+ Octorotor
+
+
+ Flapping wing
+
+
+ Flapping wing
+
+
+ Onboard companion controller
+
+
+ Two-rotor VTOL using control surfaces in vertical operation in addition. Tailsitter.
+
+
+ Quad-rotor VTOL using a V-shaped quad config in vertical operation. Tailsitter.
+
+
+
+ VTOL reserved 1
+
+
+ VTOL reserved 2
+
+
+ VTOL reserved 3
+
+
+ VTOL reserved 4
+
+
+ VTOL reserved 5
+
+
+ Onboard gimbal
+
+
+
+
+ These flags encode the MAV mode.
+
+ 0b10000000 MAV safety set to armed. Motors are enabled / running / can start. Ready to fly.
+
+
+ 0b01000000 remote control input is enabled.
+
+
+ 0b00100000 hardware in the loop simulation. All motors / actuators are blocked, but internal software is full operational.
+
+
+ 0b00010000 system stabilizes electronically its attitude (and optionally position). It needs however further control inputs to move around.
+
+
+ 0b00001000 guided mode enabled, system flies MISSIONs / mission items.
+
+
+ 0b00000100 autonomous mode enabled, system finds its own goal positions. Guided flag can be set or not, depends on the actual implementation.
+
+
+ 0b00000010 system has a test mode enabled. This flag is intended for temporary system tests and should not be used for stable implementations.
+
+
+ 0b00000001 Reserved for future use.
+
+
+
+ These values encode the bit positions of the decode position. These values can be used to read the value of a flag bit by combining the base_mode variable with AND with the flag position value. The result will be either 0 or 1, depending on if the flag is set or not.
+
+ First bit: 10000000
+
+
+ Second bit: 01000000
+
+
+ Third bit: 00100000
+
+
+ Fourth bit: 00010000
+
+
+ Fifth bit: 00001000
+
+
+ Sixt bit: 00000100
+
+
+ Seventh bit: 00000010
+
+
+ Eighth bit: 00000001
+
+
+
+ Override command, pauses current mission execution and moves immediately to a position
+
+ Hold at the current position.
+
+
+ Continue with the next item in mission execution.
+
+
+ Hold at the current position of the system
+
+
+ Hold at the position specified in the parameters of the DO_HOLD action
+
+
+
+ These defines are predefined OR-combined mode flags. There is no need to use values from this enum, but it
+ simplifies the use of the mode flags. Note that manual input is enabled in all modes as a safety override.
+
+ System is not ready to fly, booting, calibrating, etc. No flag is set.
+
+
+ System is allowed to be active, under assisted RC control.
+
+
+ System is allowed to be active, under assisted RC control.
+
+
+ System is allowed to be active, under manual (RC) control, no stabilization
+
+
+ System is allowed to be active, under manual (RC) control, no stabilization
+
+
+ System is allowed to be active, under autonomous control, manual setpoint
+
+
+ System is allowed to be active, under autonomous control, manual setpoint
+
+
+ System is allowed to be active, under autonomous control and navigation (the trajectory is decided onboard and not pre-programmed by MISSIONs)
+
+
+ System is allowed to be active, under autonomous control and navigation (the trajectory is decided onboard and not pre-programmed by MISSIONs)
+
+
+ UNDEFINED mode. This solely depends on the autopilot - use with caution, intended for developers only.
+
+
+ UNDEFINED mode. This solely depends on the autopilot - use with caution, intended for developers only.
+
+
+
+
+ Uninitialized system, state is unknown.
+
+
+ System is booting up.
+
+
+ System is calibrating and not flight-ready.
+
+
+ System is grounded and on standby. It can be launched any time.
+
+
+ System is active and might be already airborne. Motors are engaged.
+
+
+ System is in a non-normal flight mode. It can however still navigate.
+
+
+ System is in a non-normal flight mode. It lost control over parts or over the whole airframe. It is in mayday and going down.
+
+
+ System just initialized its power-down sequence, will shut down now.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ These encode the sensors whose status is sent as part of the SYS_STATUS message.
+
+ 0x01 3D gyro
+
+
+ 0x02 3D accelerometer
+
+
+ 0x04 3D magnetometer
+
+
+ 0x08 absolute pressure
+
+
+ 0x10 differential pressure
+
+
+ 0x20 GPS
+
+
+ 0x40 optical flow
+
+
+ 0x80 computer vision position
+
+
+ 0x100 laser based position
+
+
+ 0x200 external ground truth (Vicon or Leica)
+
+
+ 0x400 3D angular rate control
+
+
+ 0x800 attitude stabilization
+
+
+ 0x1000 yaw position
+
+
+ 0x2000 z/altitude control
+
+
+ 0x4000 x/y position control
+
+
+ 0x8000 motor outputs / control
+
+
+ 0x10000 rc receiver
+
+
+ 0x20000 2nd 3D gyro
+
+
+ 0x40000 2nd 3D accelerometer
+
+
+ 0x80000 2nd 3D magnetometer
+
+
+ 0x100000 geofence
+
+
+ 0x200000 AHRS subsystem health
+
+
+ 0x400000 Terrain subsystem health
+
+
+
+
+ Global coordinate frame, WGS84 coordinate system. First value / x: latitude, second value / y: longitude, third value / z: positive altitude over mean sea level (MSL)
+
+
+ Local coordinate frame, Z-up (x: north, y: east, z: down).
+
+
+ NOT a coordinate frame, indicates a mission command.
+
+
+ Global coordinate frame, WGS84 coordinate system, relative altitude over ground with respect to the home position. First value / x: latitude, second value / y: longitude, third value / z: positive altitude with 0 being at the altitude of the home location.
+
+
+ Local coordinate frame, Z-down (x: east, y: north, z: up)
+
+
+ Global coordinate frame, WGS84 coordinate system. First value / x: latitude in degrees*1.0e-7, second value / y: longitude in degrees*1.0e-7, third value / z: positive altitude over mean sea level (MSL)
+
+
+ Global coordinate frame, WGS84 coordinate system, relative altitude over ground with respect to the home position. First value / x: latitude in degrees*10e-7, second value / y: longitude in degrees*10e-7, third value / z: positive altitude with 0 being at the altitude of the home location.
+
+
+ Offset to the current local frame. Anything expressed in this frame should be added to the current local frame position.
+
+
+ Setpoint in body NED frame. This makes sense if all position control is externalized - e.g. useful to command 2 m/s^2 acceleration to the right.
+
+
+ Offset in body NED frame. This makes sense if adding setpoints to the current flight path, to avoid an obstacle - e.g. useful to command 2 m/s^2 acceleration to the east.
+
+
+ Global coordinate frame with above terrain level altitude. WGS84 coordinate system, relative altitude over terrain with respect to the waypoint coordinate. First value / x: latitude in degrees, second value / y: longitude in degrees, third value / z: positive altitude in meters with 0 being at ground level in terrain model.
+
+
+ Global coordinate frame with above terrain level altitude. WGS84 coordinate system, relative altitude over terrain with respect to the waypoint coordinate. First value / x: latitude in degrees*10e-7, second value / y: longitude in degrees*10e-7, third value / z: positive altitude in meters with 0 being at ground level in terrain model.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Disable fenced mode
+
+
+ Switched to guided mode to return point (fence point 0)
+
+
+ Report fence breach, but don't take action
+
+
+ Switched to guided mode to return point (fence point 0) with manual throttle control
+
+
+
+
+
+ No last fence breach
+
+
+ Breached minimum altitude
+
+
+ Breached maximum altitude
+
+
+ Breached fence boundary
+
+
+
+
+ Enumeration of possible mount operation modes
+ Load and keep safe position (Roll,Pitch,Yaw) from permant memory and stop stabilization
+ Load and keep neutral position (Roll,Pitch,Yaw) from permanent memory.
+ Load neutral position and start MAVLink Roll,Pitch,Yaw control with stabilization
+ Load neutral position and start RC Roll,Pitch,Yaw control with stabilization
+ Load neutral position and start to point to Lat,Lon,Alt
+
+
+ Commands to be executed by the MAV. They can be executed on user request, or as part of a mission script. If the action is used in a mission, the parameter mapping to the waypoint/mission message is as follows: Param 1, Param 2, Param 3, Param 4, X: Param 5, Y:Param 6, Z:Param 7. This command list is similar what ARINC 424 is for commercial aircraft: A data format how to interpret waypoint/mission data.
+
+ Navigate to MISSION.
+ Hold time in decimal seconds. (ignored by fixed wing, time to stay at MISSION for rotary wing)
+ Acceptance radius in meters (if the sphere with this radius is hit, the MISSION counts as reached)
+ 0 to pass through the WP, if > 0 radius in meters to pass by WP. Positive value for clockwise orbit, negative value for counter-clockwise orbit. Allows trajectory control.
+ Desired yaw angle at MISSION (rotary wing)
+ Latitude
+ Longitude
+ Altitude
+
+
+ Loiter around this MISSION an unlimited amount of time
+ Empty
+ Empty
+ Radius around MISSION, in meters. If positive loiter clockwise, else counter-clockwise
+ Desired yaw angle.
+ Latitude
+ Longitude
+ Altitude
+
+
+ Loiter around this MISSION for X turns
+ Turns
+ Empty
+ Radius around MISSION, in meters. If positive loiter clockwise, else counter-clockwise
+ Desired yaw angle.
+ Latitude
+ Longitude
+ Altitude
+
+
+ Loiter around this MISSION for X seconds
+ Seconds (decimal)
+ Empty
+ Radius around MISSION, in meters. If positive loiter clockwise, else counter-clockwise
+ Desired yaw angle.
+ Latitude
+ Longitude
+ Altitude
+
+
+ Return to launch location
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Land at location
+ Empty
+ Empty
+ Empty
+ Desired yaw angle.
+ Latitude
+ Longitude
+ Altitude
+
+
+ Takeoff from ground / hand
+ Minimum pitch (if airspeed sensor present), desired pitch without sensor
+ Empty
+ Empty
+ Yaw angle (if magnetometer present), ignored without magnetometer
+ Latitude
+ Longitude
+ Altitude
+
+
+ Continue on the current course and climb/descend to specified altitude. When the altitude is reached continue to the next command (i.e., don't proceed to the next command until the desired altitude is reached.
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Desired altitude in meters
+
+
+ Begin loiter at the specified Latitude and Longitude. If Lat=Lon=0, then loiter at the current position. Don't consider the navigation command complete (don't leave loiter) until the altitude has been reached. Additionally, if the Heading Required parameter is non-zero the aircraft will not leave the loiter until heading toward the next waypoint.
+ Heading Required (0 = False)
+ Radius in meters. If positive loiter clockwise, negative counter-clockwise, 0 means no change to standard loiter.
+ Empty
+ Empty
+ Latitude
+ Longitude
+ Altitude
+
+
+ Sets the region of interest (ROI) for a sensor set or the vehicle itself. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras.
+ Region of intereset mode. (see MAV_ROI enum)
+ MISSION index/ target ID. (see MAV_ROI enum)
+ ROI index (allows a vehicle to manage multiple ROI's)
+ Empty
+ x the location of the fixed ROI (see MAV_FRAME)
+ y
+ z
+
+
+ Control autonomous path planning on the MAV.
+ 0: Disable local obstacle avoidance / local path planning (without resetting map), 1: Enable local path planning, 2: Enable and reset local path planning
+ 0: Disable full path planning (without resetting map), 1: Enable, 2: Enable and reset map/occupancy grid, 3: Enable and reset planned route, but not occupancy grid
+ Empty
+ Yaw angle at goal, in compass degrees, [0..360]
+ Latitude/X of goal
+ Longitude/Y of goal
+ Altitude/Z of goal
+
+
+ Navigate to MISSION using a spline path.
+ Hold time in decimal seconds. (ignored by fixed wing, time to stay at MISSION for rotary wing)
+ Empty
+ Empty
+ Empty
+ Latitude/X of goal
+ Longitude/Y of goal
+ Altitude/Z of goal
+
+
+
+
+
+ hand control over to an external controller
+ On / Off (> 0.5f on)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ NOP - This command is only used to mark the upper limit of the NAV/ACTION commands in the enumeration
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Delay mission state machine.
+ Delay in seconds (decimal)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Ascend/descend at rate. Delay mission state machine until desired altitude reached.
+ Descent / Ascend rate (m/s)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Finish Altitude
+
+
+ Delay mission state machine until within desired distance of next NAV point.
+ Distance (meters)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Reach a certain target angle.
+ target angle: [0-360], 0 is north
+ speed during yaw change:[deg per second]
+ direction: negative: counter clockwise, positive: clockwise [-1,1]
+ relative offset or absolute angle: [ 1,0]
+ Empty
+ Empty
+ Empty
+
+
+ NOP - This command is only used to mark the upper limit of the CONDITION commands in the enumeration
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Set system mode.
+ Mode, as defined by ENUM MAV_MODE
+ Custom mode - this is system specific, please refer to the individual autopilot specifications for details.
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Jump to the desired command in the mission list. Repeat this action only the specified number of times
+ Sequence number
+ Repeat count
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Change speed and/or throttle set points.
+ Speed type (0=Airspeed, 1=Ground Speed)
+ Speed (m/s, -1 indicates no change)
+ Throttle ( Percent, -1 indicates no change)
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Changes the home location either to the current location or a specified location.
+ Use current (1=use current location, 0=use specified location)
+ Empty
+ Empty
+ Empty
+ Latitude
+ Longitude
+ Altitude
+
+
+ Set a system parameter. Caution! Use of this command requires knowledge of the numeric enumeration value of the parameter.
+ Parameter number
+ Parameter value
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Set a relay to a condition.
+ Relay number
+ Setting (1=on, 0=off, others possible depending on system hardware)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Cycle a relay on and off for a desired number of cyles with a desired period.
+ Relay number
+ Cycle count
+ Cycle time (seconds, decimal)
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Set a servo to a desired PWM value.
+ Servo number
+ PWM (microseconds, 1000 to 2000 typical)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Cycle a between its nominal setting and a desired PWM for a desired number of cycles with a desired period.
+ Servo number
+ PWM (microseconds, 1000 to 2000 typical)
+ Cycle count
+ Cycle time (seconds)
+ Empty
+ Empty
+ Empty
+
+
+ Terminate flight immediately
+ Flight termination activated if > 0.5
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Mission command to perform a landing. This is used as a marker in a mission to tell the autopilot where a sequence of mission items that represents a landing starts. It may also be sent via a COMMAND_LONG to trigger a landing, in which case the nearest (geographically) landing sequence in the mission will be used. The Latitude/Longitude is optional, and may be set to 0/0 if not needed. If specified then it will be used to help find the closest landing sequence.
+ Empty
+ Empty
+ Empty
+ Empty
+ Latitude
+ Longitude
+ Empty
+
+
+ Mission command to perform a landing from a rally point.
+ Break altitude (meters)
+ Landing speed (m/s)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Mission command to safely abort an autonmous landing.
+ Altitude (meters)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Control onboard camera system.
+ Camera ID (-1 for all)
+ Transmission: 0: disabled, 1: enabled compressed, 2: enabled raw
+ Transmission mode: 0: video stream, >0: single images every n seconds (decimal)
+ Recording: 0: disabled, 1: enabled compressed, 2: enabled raw
+ Empty
+ Empty
+ Empty
+
+
+ Sets the region of interest (ROI) for a sensor set or the vehicle itself. This can then be used by the vehicles control system to control the vehicle attitude and the attitude of various sensors such as cameras.
+ Region of intereset mode. (see MAV_ROI enum)
+ MISSION index/ target ID. (see MAV_ROI enum)
+ ROI index (allows a vehicle to manage multiple ROI's)
+ Empty
+ x the location of the fixed ROI (see MAV_FRAME)
+ y
+ z
+
+
+
+
+ Mission command to configure an on-board camera controller system.
+ Modes: P, TV, AV, M, Etc
+ Shutter speed: Divisor number for one second
+ Aperture: F stop number
+ ISO number e.g. 80, 100, 200, Etc
+ Exposure type enumerator
+ Command Identity
+ Main engine cut-off time before camera trigger in seconds/10 (0 means no cut-off)
+
+
+
+ Mission command to control an on-board camera controller system.
+ Session control e.g. show/hide lens
+ Zoom's absolute position
+ Zooming step value to offset zoom from the current position
+ Focus Locking, Unlocking or Re-locking
+ Shooting Command
+ Command Identity
+ Empty
+
+
+
+
+ Mission command to configure a camera or antenna mount
+ Mount operation mode (see MAV_MOUNT_MODE enum)
+ stabilize roll? (1 = yes, 0 = no)
+ stabilize pitch? (1 = yes, 0 = no)
+ stabilize yaw? (1 = yes, 0 = no)
+ Empty
+ Empty
+ Empty
+
+
+
+ Mission command to control a camera or antenna mount
+ pitch or lat in degrees, depending on mount mode.
+ roll or lon in degrees depending on mount mode
+ yaw or alt (in meters) depending on mount mode
+ reserved
+ reserved
+ reserved
+ MAV_MOUNT_MODE enum value
+
+
+
+ Mission command to set CAM_TRIGG_DIST for this flight
+ Camera trigger distance (meters)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+ Mission command to enable the geofence
+ enable? (0=disable, 1=enable)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+ Mission command to trigger a parachute
+ action (0=disable, 1=enable, 2=release, for some systems see PARACHUTE_ACTION enum, not in general message set.)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+ Change to/from inverted flight
+ inverted (0=normal, 1=inverted)
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+ Mission command to control a camera or antenna mount, using a quaternion as reference.
+ q1 - quaternion param #1, w (1 in null-rotation)
+ q2 - quaternion param #2, x (0 in null-rotation)
+ q3 - quaternion param #3, y (0 in null-rotation)
+ q4 - quaternion param #4, z (0 in null-rotation)
+ Empty
+ Empty
+ Empty
+
+
+
+ set id of master controller
+ System ID
+ Component ID
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+ set limits for external control
+ timeout - maximum time (in seconds) that external controller will be allowed to control vehicle. 0 means no timeout
+ absolute altitude min (in meters, AMSL) - if vehicle moves below this alt, the command will be aborted and the mission will continue. 0 means no lower altitude limit
+ absolute altitude max (in meters)- if vehicle moves above this alt, the command will be aborted and the mission will continue. 0 means no upper altitude limit
+ horizontal move limit (in meters, AMSL) - if vehicle moves more than this distance from it's location at the moment the command was executed, the command will be aborted and the mission will continue. 0 means no horizontal altitude limit
+ Empty
+ Empty
+ Empty
+
+
+
+ NOP - This command is only used to mark the upper limit of the DO commands in the enumeration
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+ Trigger calibration. This command will be only accepted if in pre-flight mode.
+ Gyro calibration: 0: no, 1: yes
+ Magnetometer calibration: 0: no, 1: yes
+ Ground pressure: 0: no, 1: yes
+ Radio calibration: 0: no, 1: yes
+ Accelerometer calibration: 0: no, 1: yes
+ Compass/Motor interference calibration: 0: no, 1: yes
+ Empty
+
+
+ Set sensor offsets. This command will be only accepted if in pre-flight mode.
+ Sensor to adjust the offsets for: 0: gyros, 1: accelerometer, 2: magnetometer, 3: barometer, 4: optical flow, 5: second magnetometer
+ X axis offset (or generic dimension 1), in the sensor's raw units
+ Y axis offset (or generic dimension 2), in the sensor's raw units
+ Z axis offset (or generic dimension 3), in the sensor's raw units
+ Generic dimension 4, in the sensor's raw units
+ Generic dimension 5, in the sensor's raw units
+ Generic dimension 6, in the sensor's raw units
+
+
+ Request storage of different parameter values and logs. This command will be only accepted if in pre-flight mode.
+ Parameter storage: 0: READ FROM FLASH/EEPROM, 1: WRITE CURRENT TO FLASH/EEPROM
+ Mission storage: 0: READ FROM FLASH/EEPROM, 1: WRITE CURRENT TO FLASH/EEPROM
+ Onboard logging: 0: Ignore, 1: Start default rate logging, -1: Stop logging, > 1: start logging with rate of param 3 in Hz (e.g. set to 1000 for 1000 Hz logging)
+ Reserved
+ Empty
+ Empty
+ Empty
+
+
+ Request the reboot or shutdown of system components.
+ 0: Do nothing for autopilot, 1: Reboot autopilot, 2: Shutdown autopilot.
+ 0: Do nothing for onboard computer, 1: Reboot onboard computer, 2: Shutdown onboard computer.
+ Reserved
+ Reserved
+ Empty
+ Empty
+ Empty
+
+
+ Hold / continue the current action
+ MAV_GOTO_DO_HOLD: hold MAV_GOTO_DO_CONTINUE: continue with next item in mission plan
+ MAV_GOTO_HOLD_AT_CURRENT_POSITION: Hold at current position MAV_GOTO_HOLD_AT_SPECIFIED_POSITION: hold at specified position
+ MAV_FRAME coordinate frame of hold point
+ Desired yaw angle in degrees
+ Latitude / X position
+ Longitude / Y position
+ Altitude / Z position
+
+
+ start running a mission
+ first_item: the first mission item to run
+ last_item: the last mission item to run (after this item is run, the mission ends)
+
+
+ Arms / Disarms a component
+ 1 to arm, 0 to disarm
+
+
+ Starts receiver pairing
+ 0:Spektrum
+ 0:Spektrum DSM2, 1:Spektrum DSMX
+
+
+ Request autopilot capabilities
+ 1: Request autopilot version
+ Reserved (all remaining params)
+
+
+ Start image capture sequence
+ Duration between two consecutive pictures (in seconds)
+ Number of images to capture total - 0 for unlimited capture
+ Resolution in megapixels (0.3 for 640x480, 1.3 for 1280x720, etc)
+
+
+
+ Stop image capture sequence
+ Reserved
+ Reserved
+
+
+
+ Enable or disable on-board camera triggering system.
+ Trigger enable/disable (0 for disable, 1 for start)
+ Shutter integration time (in ms)
+ Reserved
+
+
+
+ Starts video capture
+ Camera ID (0 for all cameras), 1 for first, 2 for second, etc.
+ Frames per second
+ Resolution in megapixels (0.3 for 640x480, 1.3 for 1280x720, etc)
+
+
+
+ Stop the current video capture
+ Reserved
+ Reserved
+
+
+
+ Create a panorama at the current position
+ Viewing angle horizontal of the panorama (in degrees, +- 0.5 the total angle)
+ Viewing angle vertical of panorama (in degrees)
+ Speed of the horizontal rotation (in degrees per second)
+ Speed of the vertical rotation (in degrees per second)
+
+
+
+
+
+
+ Deploy payload on a Lat / Lon / Alt position. This includes the navigation to reach the required release position and velocity.
+ Operation mode. 0: prepare single payload deploy (overwriting previous requests), but do not execute it. 1: execute payload deploy immediately (rejecting further deploy commands during execution, but allowing abort). 2: add payload deploy to existing deployment list.
+ Desired approach vector in degrees compass heading (0..360). A negative value indicates the system can define the approach vector at will.
+ Desired ground speed at release time. This can be overriden by the airframe in case it needs to meet minimum airspeed. A negative value indicates the system can define the ground speed at will.
+ Minimum altitude clearance to the release position in meters. A negative value indicates the system can define the clearance at will.
+ Latitude unscaled for MISSION_ITEM or in 1e7 degrees for MISSION_ITEM_INT
+ Longitude unscaled for MISSION_ITEM or in 1e7 degrees for MISSION_ITEM_INT
+ Altitude, in meters AMSL
+
+
+ Control the payload deployment.
+ Operation mode. 0: Abort deployment, continue normal mission. 1: switch to payload deploment mode. 100: delete first payload deployment request. 101: delete all payload deployment requests.
+ Reserved
+ Reserved
+ Reserved
+ Reserved
+ Reserved
+ Reserved
+
+
+
+
+ Data stream IDs. A data stream is not a fixed set of messages, but rather a
+ recommendation to the autopilot software. Individual autopilots may or may not obey
+ the recommended messages.
+
+ Enable all data streams
+
+
+ Enable IMU_RAW, GPS_RAW, GPS_STATUS packets.
+
+
+ Enable GPS_STATUS, CONTROL_STATUS, AUX_STATUS
+
+
+ Enable RC_CHANNELS_SCALED, RC_CHANNELS_RAW, SERVO_OUTPUT_RAW
+
+
+ Enable ATTITUDE_CONTROLLER_OUTPUT, POSITION_CONTROLLER_OUTPUT, NAV_CONTROLLER_OUTPUT.
+
+
+ Enable LOCAL_POSITION, GLOBAL_POSITION/GLOBAL_POSITION_INT messages.
+
+
+ Dependent on the autopilot
+
+
+ Dependent on the autopilot
+
+
+ Dependent on the autopilot
+
+
+
+ The ROI (region of interest) for the vehicle. This can be
+ be used by the vehicle for camera/vehicle attitude alignment (see
+ MAV_CMD_NAV_ROI).
+
+ No region of interest.
+
+
+ Point toward next MISSION.
+
+
+ Point toward given MISSION.
+
+
+ Point toward fixed location.
+
+
+ Point toward of given id.
+
+
+
+ ACK / NACK / ERROR values as a result of MAV_CMDs and for mission item transmission.
+
+ Command / mission item is ok.
+
+
+ Generic error message if none of the other reasons fails or if no detailed error reporting is implemented.
+
+
+ The system is refusing to accept this command from this source / communication partner.
+
+
+ Command or mission item is not supported, other commands would be accepted.
+
+
+ The coordinate frame of this command / mission item is not supported.
+
+
+ The coordinate frame of this command is ok, but he coordinate values exceed the safety limits of this system. This is a generic error, please use the more specific error messages below if possible.
+
+
+ The X or latitude value is out of range.
+
+
+ The Y or longitude value is out of range.
+
+
+ The Z or altitude value is out of range.
+
+
+
+ Specifies the datatype of a MAVLink parameter.
+
+ 8-bit unsigned integer
+
+
+ 8-bit signed integer
+
+
+ 16-bit unsigned integer
+
+
+ 16-bit signed integer
+
+
+ 32-bit unsigned integer
+
+
+ 32-bit signed integer
+
+
+ 64-bit unsigned integer
+
+
+ 64-bit signed integer
+
+
+ 32-bit floating-point
+
+
+ 64-bit floating-point
+
+
+
+ result from a mavlink command
+
+ Command ACCEPTED and EXECUTED
+
+
+ Command TEMPORARY REJECTED/DENIED
+
+
+ Command PERMANENTLY DENIED
+
+
+ Command UNKNOWN/UNSUPPORTED
+
+
+ Command executed, but failed
+
+
+
+ result in a mavlink mission ack
+
+ mission accepted OK
+
+
+ generic error / not accepting mission commands at all right now
+
+
+ coordinate frame is not supported
+
+
+ command is not supported
+
+
+ mission item exceeds storage space
+
+
+ one of the parameters has an invalid value
+
+
+ param1 has an invalid value
+
+
+ param2 has an invalid value
+
+
+ param3 has an invalid value
+
+
+ param4 has an invalid value
+
+
+ x/param5 has an invalid value
+
+
+ y/param6 has an invalid value
+
+
+ param7 has an invalid value
+
+
+ received waypoint out of sequence
+
+
+ not accepting any mission commands from this communication partner
+
+
+
+ Indicates the severity level, generally used for status messages to indicate their relative urgency. Based on RFC-5424 using expanded definitions at: http://www.kiwisyslog.com/kb/info:-syslog-message-levels/.
+
+ System is unusable. This is a "panic" condition.
+
+
+ Action should be taken immediately. Indicates error in non-critical systems.
+
+
+ Action must be taken immediately. Indicates failure in a primary system.
+
+
+ Indicates an error in secondary/redundant systems.
+
+
+ Indicates about a possible future error if this is not resolved within a given timeframe. Example would be a low battery warning.
+
+
+ An unusual event has occured, though not an error condition. This should be investigated for the root cause.
+
+
+ Normal operational messages. Useful for logging. No action is required for these messages.
+
+
+ Useful non-operational messages that can assist in debugging. These should not occur during normal operation.
+
+
+
+ Power supply status flags (bitmask)
+
+ main brick power supply valid
+
+
+ main servo power supply valid for FMU
+
+
+ USB power is connected
+
+
+ peripheral supply is in over-current state
+
+
+ hi-power peripheral supply is in over-current state
+
+
+ Power status has changed since boot
+
+
+
+ SERIAL_CONTROL device types
+
+ First telemetry port
+
+
+ Second telemetry port
+
+
+ First GPS port
+
+
+ Second GPS port
+
+
+
+ SERIAL_CONTROL flags (bitmask)
+
+ Set if this is a reply
+
+
+ Set if the sender wants the receiver to send a response as another SERIAL_CONTROL message
+
+
+ Set if access to the serial port should be removed from whatever driver is currently using it, giving exclusive access to the SERIAL_CONTROL protocol. The port can be handed back by sending a request without this flag set
+
+
+ Block on writes to the serial port
+
+
+ Send multiple replies until port is drained
+
+
+
+ Enumeration of distance sensor types
+
+ Laser rangefinder, e.g. LightWare SF02/F or PulsedLight units
+
+
+ Ultrasound rangefinder, e.g. MaxBotix units
+
+
+ Infrared rangefinder, e.g. Sharp units
+
+
+
+ Enumeration of sensor orientation, according to its rotations
+
+ Roll: 0, Pitch: 0, Yaw: 0
+
+
+ Roll: 0, Pitch: 0, Yaw: 45
+
+
+ Roll: 0, Pitch: 0, Yaw: 90
+
+
+ Roll: 0, Pitch: 0, Yaw: 135
+
+
+ Roll: 0, Pitch: 0, Yaw: 180
+
+
+ Roll: 0, Pitch: 0, Yaw: 225
+
+
+ Roll: 0, Pitch: 0, Yaw: 270
+
+
+ Roll: 0, Pitch: 0, Yaw: 315
+
+
+ Roll: 180, Pitch: 0, Yaw: 0
+
+
+ Roll: 180, Pitch: 0, Yaw: 45
+
+
+ Roll: 180, Pitch: 0, Yaw: 90
+
+
+ Roll: 180, Pitch: 0, Yaw: 135
+
+
+ Roll: 0, Pitch: 180, Yaw: 0
+
+
+ Roll: 180, Pitch: 0, Yaw: 225
+
+
+ Roll: 180, Pitch: 0, Yaw: 270
+
+
+ Roll: 180, Pitch: 0, Yaw: 315
+
+
+ Roll: 90, Pitch: 0, Yaw: 0
+
+
+ Roll: 90, Pitch: 0, Yaw: 45
+
+
+ Roll: 90, Pitch: 0, Yaw: 90
+
+
+ Roll: 90, Pitch: 0, Yaw: 135
+
+
+ Roll: 270, Pitch: 0, Yaw: 0
+
+
+ Roll: 270, Pitch: 0, Yaw: 45
+
+
+ Roll: 270, Pitch: 0, Yaw: 90
+
+
+ Roll: 270, Pitch: 0, Yaw: 135
+
+
+ Roll: 0, Pitch: 90, Yaw: 0
+
+
+ Roll: 0, Pitch: 270, Yaw: 0
+
+
+ Roll: 0, Pitch: 180, Yaw: 90
+
+
+ Roll: 0, Pitch: 180, Yaw: 270
+
+
+ Roll: 90, Pitch: 90, Yaw: 0
+
+
+ Roll: 180, Pitch: 90, Yaw: 0
+
+
+ Roll: 270, Pitch: 90, Yaw: 0
+
+
+ Roll: 90, Pitch: 180, Yaw: 0
+
+
+ Roll: 270, Pitch: 180, Yaw: 0
+
+
+ Roll: 90, Pitch: 270, Yaw: 0
+
+
+ Roll: 180, Pitch: 270, Yaw: 0
+
+
+ Roll: 270, Pitch: 270, Yaw: 0
+
+
+ Roll: 90, Pitch: 180, Yaw: 90
+
+
+ Roll: 90, Pitch: 0, Yaw: 270
+
+
+ Roll: 315, Pitch: 315, Yaw: 315
+
+
+
+ Bitmask of (optional) autopilot capabilities (64 bit). If a bit is set, the autopilot supports this capability.
+
+ Autopilot supports MISSION float message type.
+
+
+ Autopilot supports the new param float message type.
+
+
+ Autopilot supports MISSION_INT scaled integer message type.
+
+
+ Autopilot supports COMMAND_INT scaled integer message type.
+
+
+ Autopilot supports the new param union message type.
+
+
+ Autopilot supports the new param union message type.
+
+
+ Autopilot supports commanding attitude offboard.
+
+
+ Autopilot supports commanding position and velocity targets in local NED frame.
+
+
+ Autopilot supports commanding position and velocity targets in global scaled integers.
+
+
+ Autopilot supports terrain protocol / data handling.
+
+
+ Autopilot supports direct actuator control.
+
+
+
+ Enumeration of estimator types
+
+ This is a naive estimator without any real covariance feedback.
+
+
+ Computer vision based estimate. Might be up to scale.
+
+
+ Visual-inertial estimate.
+
+
+ Plain GPS estimate.
+
+
+ Estimator integrating GPS and inertial sensing.
+
+
+
+ Enumeration of battery types
+
+ Not specified.
+
+
+ Lithium polymere battery
+
+
+ Lithium ferrite battery
+
+
+ Lithium-ION battery
+
+
+ Nickel metal hydride battery
+
+
+
+ Enumeration of battery functions
+
+ Lithium polymere battery
+
+
+ Battery supports all flight systems
+
+
+ Battery for the propulsion system
+
+
+ Avionics battery
+
+
+ Payload battery
+
+
+
+
+
+ The heartbeat message shows that a system is present and responding. The type of the MAV and Autopilot hardware allow the receiving system to treat further messages from this system appropriate (e.g. by laying out the user interface based on the autopilot).
+ Type of the MAV (quadrotor, helicopter, etc., up to 15 types, defined in MAV_TYPE ENUM)
+ Autopilot type / class. defined in MAV_AUTOPILOT ENUM
+ System mode bitfield, see MAV_MODE_FLAG ENUM in mavlink/include/mavlink_types.h
+ A bitfield for use for autopilot-specific flags.
+ System status flag, see MAV_STATE ENUM
+ MAVLink version, not writable by user, gets added by protocol because of magic data type: uint8_t_mavlink_version
+
+
+ The general system state. If the system is following the MAVLink standard, the system state is mainly defined by three orthogonal states/modes: The system mode, which is either LOCKED (motors shut down and locked), MANUAL (system under RC control), GUIDED (system with autonomous position control, position setpoint controlled manually) or AUTO (system guided by path/waypoint planner). The NAV_MODE defined the current flight state: LIFTOFF (often an open-loop maneuver), LANDING, WAYPOINTS or VECTOR. This represents the internal navigation state machine. The system status shows wether the system is currently active or not and if an emergency occured. During the CRITICAL and EMERGENCY states the MAV is still considered to be active, but should start emergency procedures autonomously. After a failure occured it should first move from active to critical to allow manual intervention and then move to emergency after a certain timeout.
+ Bitmask showing which onboard controllers and sensors are present. Value of 0: not present. Value of 1: present. Indices defined by ENUM MAV_SYS_STATUS_SENSOR
+ Bitmask showing which onboard controllers and sensors are enabled: Value of 0: not enabled. Value of 1: enabled. Indices defined by ENUM MAV_SYS_STATUS_SENSOR
+ Bitmask showing which onboard controllers and sensors are operational or have an error: Value of 0: not enabled. Value of 1: enabled. Indices defined by ENUM MAV_SYS_STATUS_SENSOR
+ Maximum usage in percent of the mainloop time, (0%: 0, 100%: 1000) should be always below 1000
+ Battery voltage, in millivolts (1 = 1 millivolt)
+ Battery current, in 10*milliamperes (1 = 10 milliampere), -1: autopilot does not measure the current
+ Remaining battery energy: (0%: 0, 100%: 100), -1: autopilot estimate the remaining battery
+ Communication drops in percent, (0%: 0, 100%: 10'000), (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV)
+ Communication errors (UART, I2C, SPI, CAN), dropped packets on all links (packets that were corrupted on reception on the MAV)
+ Autopilot-specific errors
+ Autopilot-specific errors
+ Autopilot-specific errors
+ Autopilot-specific errors
+
+
+ The system time is the time of the master clock, typically the computer clock of the main onboard computer.
+ Timestamp of the master clock in microseconds since UNIX epoch.
+ Timestamp of the component clock since boot time in milliseconds.
+
+
+
+ A ping message either requesting or responding to a ping. This allows to measure the system latencies, including serial port, radio modem and UDP connections.
+ Unix timestamp in microseconds or since system boot if smaller than MAVLink epoch (1.1.2009)
+ PING sequence
+ 0: request ping from all receiving systems, if greater than 0: message is a ping response and number is the system id of the requesting system
+ 0: request ping from all receiving components, if greater than 0: message is a ping response and number is the system id of the requesting system
+
+
+ Request to control this MAV
+ System the GCS requests control for
+ 0: request control of this MAV, 1: Release control of this MAV
+ 0: key as plaintext, 1-255: future, different hashing/encryption variants. The GCS should in general use the safest mode possible initially and then gradually move down the encryption level if it gets a NACK message indicating an encryption mismatch.
+ Password / Key, depending on version plaintext or encrypted. 25 or less characters, NULL terminated. The characters may involve A-Z, a-z, 0-9, and "!?,.-"
+
+
+ Accept / deny control of this MAV
+ ID of the GCS this message
+ 0: request control of this MAV, 1: Release control of this MAV
+ 0: ACK, 1: NACK: Wrong passkey, 2: NACK: Unsupported passkey encryption method, 3: NACK: Already under control
+
+
+ Emit an encrypted signature / key identifying this system. PLEASE NOTE: This protocol has been kept simple, so transmitting the key requires an encrypted channel for true safety.
+ key
+
+
+ Set the system mode, as defined by enum MAV_MODE. There is no target component id as the mode is by definition for the overall aircraft, not only for one component.
+ The system setting the mode
+ The new base mode
+ The new autopilot-specific mode. This field can be ignored by an autopilot.
+
+
+
+ Request to read the onboard parameter with the param_id string id. Onboard parameters are stored as key[const char*] -> value[float]. This allows to send a parameter to any other component (such as the GCS) without the need of previous knowledge of possible parameter names. Thus the same GCS can store different parameters for different autopilots. See also http://qgroundcontrol.org/parameter_interface for a full documentation of QGroundControl and IMU code.
+ System ID
+ Component ID
+ Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string
+ Parameter index. Send -1 to use the param ID field as identifier (else the param id will be ignored)
+
+
+ Request all parameters of this component. After his request, all parameters are emitted.
+ System ID
+ Component ID
+
+
+ Emit the value of a onboard parameter. The inclusion of param_count and param_index in the message allows the recipient to keep track of received parameters and allows him to re-request missing parameters after a loss or timeout.
+ Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string
+ Onboard parameter value
+ Onboard parameter type: see the MAV_PARAM_TYPE enum for supported data types.
+ Total number of onboard parameters
+ Index of this onboard parameter
+
+
+ Set a parameter value TEMPORARILY to RAM. It will be reset to default on system reboot. Send the ACTION MAV_ACTION_STORAGE_WRITE to PERMANENTLY write the RAM contents to EEPROM. IMPORTANT: The receiving component should acknowledge the new parameter value by sending a param_value message to all communication partners. This will also ensure that multiple GCS all have an up-to-date list of all parameters. If the sending GCS did not receive a PARAM_VALUE message within its timeout time, it should re-send the PARAM_SET message.
+ System ID
+ Component ID
+ Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string
+ Onboard parameter value
+ Onboard parameter type: see the MAV_PARAM_TYPE enum for supported data types.
+
+
+ The global position, as returned by the Global Positioning System (GPS). This is
+ NOT the global position estimate of the system, but rather a RAW sensor value. See message GLOBAL_POSITION for the global position estimate. Coordinate frame is right-handed, Z-axis up (GPS frame).
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ 0-1: no fix, 2: 2D fix, 3: 3D fix, 4: DGPS, 5: RTK. Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix.
+ Latitude (WGS84), in degrees * 1E7
+ Longitude (WGS84), in degrees * 1E7
+ Altitude (AMSL, NOT WGS84), in meters * 1000 (positive for up). Note that virtually all GPS modules provide the AMSL altitude in addition to the WGS84 altitude.
+ GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: UINT16_MAX
+ GPS VDOP vertical dilution of position in cm (m*100). If unknown, set to: UINT16_MAX
+ GPS ground speed (m/s * 100). If unknown, set to: UINT16_MAX
+ Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: UINT16_MAX
+ Number of satellites visible. If unknown, set to 255
+
+
+ The positioning status, as reported by GPS. This message is intended to display status information about each satellite visible to the receiver. See message GLOBAL_POSITION for the global position estimate. This message can contain information for up to 20 satellites.
+ Number of satellites visible
+ Global satellite ID
+ 0: Satellite not used, 1: used for localization
+ Elevation (0: right on top of receiver, 90: on the horizon) of satellite
+ Direction of satellite, 0: 0 deg, 255: 360 deg.
+ Signal to noise ratio of satellite
+
+
+ The RAW IMU readings for the usual 9DOF sensor setup. This message should contain the scaled values to the described units
+ Timestamp (milliseconds since system boot)
+ X acceleration (mg)
+ Y acceleration (mg)
+ Z acceleration (mg)
+ Angular speed around X axis (millirad /sec)
+ Angular speed around Y axis (millirad /sec)
+ Angular speed around Z axis (millirad /sec)
+ X Magnetic field (milli tesla)
+ Y Magnetic field (milli tesla)
+ Z Magnetic field (milli tesla)
+
+
+ The RAW IMU readings for the usual 9DOF sensor setup. This message should always contain the true raw values without any scaling to allow data capture and system debugging.
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ X acceleration (raw)
+ Y acceleration (raw)
+ Z acceleration (raw)
+ Angular speed around X axis (raw)
+ Angular speed around Y axis (raw)
+ Angular speed around Z axis (raw)
+ X Magnetic field (raw)
+ Y Magnetic field (raw)
+ Z Magnetic field (raw)
+
+
+ The RAW pressure readings for the typical setup of one absolute pressure and one differential pressure sensor. The sensor values should be the raw, UNSCALED ADC values.
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ Absolute pressure (raw)
+ Differential pressure 1 (raw)
+ Differential pressure 2 (raw)
+ Raw Temperature measurement (raw)
+
+
+ The pressure readings for the typical setup of one absolute and differential pressure sensor. The units are as specified in each field.
+ Timestamp (milliseconds since system boot)
+ Absolute pressure (hectopascal)
+ Differential pressure 1 (hectopascal)
+ Temperature measurement (0.01 degrees celsius)
+
+
+ The attitude in the aeronautical frame (right-handed, Z-down, X-front, Y-right).
+ Timestamp (milliseconds since system boot)
+ Roll angle (rad, -pi..+pi)
+ Pitch angle (rad, -pi..+pi)
+ Yaw angle (rad, -pi..+pi)
+ Roll angular speed (rad/s)
+ Pitch angular speed (rad/s)
+ Yaw angular speed (rad/s)
+
+
+ The attitude in the aeronautical frame (right-handed, Z-down, X-front, Y-right), expressed as quaternion. Quaternion order is w, x, y, z and a zero rotation would be expressed as (1 0 0 0).
+ Timestamp (milliseconds since system boot)
+ Quaternion component 1, w (1 in null-rotation)
+ Quaternion component 2, x (0 in null-rotation)
+ Quaternion component 3, y (0 in null-rotation)
+ Quaternion component 4, z (0 in null-rotation)
+ Roll angular speed (rad/s)
+ Pitch angular speed (rad/s)
+ Yaw angular speed (rad/s)
+
+
+ The filtered local position (e.g. fused computer vision and accelerometers). Coordinate frame is right-handed, Z-axis down (aeronautical frame, NED / north-east-down convention)
+ Timestamp (milliseconds since system boot)
+ X Position
+ Y Position
+ Z Position
+ X Speed
+ Y Speed
+ Z Speed
+
+
+ The filtered global position (e.g. fused GPS and accelerometers). The position is in GPS-frame (right-handed, Z-up). It
+ is designed as scaled integer message since the resolution of float is not sufficient.
+ Timestamp (milliseconds since system boot)
+ Latitude, expressed as * 1E7
+ Longitude, expressed as * 1E7
+ Altitude in meters, expressed as * 1000 (millimeters), AMSL (not WGS84 - note that virtually all GPS modules provide the AMSL as well)
+ Altitude above ground in meters, expressed as * 1000 (millimeters)
+ Ground X Speed (Latitude), expressed as m/s * 100
+ Ground Y Speed (Longitude), expressed as m/s * 100
+ Ground Z Speed (Altitude), expressed as m/s * 100
+ Compass heading in degrees * 100, 0.0..359.99 degrees. If unknown, set to: UINT16_MAX
+
+
+ The scaled values of the RC channels received. (-100%) -10000, (0%) 0, (100%) 10000. Channels that are inactive should be set to UINT16_MAX.
+ Timestamp (milliseconds since system boot)
+ Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows for more than 8 servos.
+ RC channel 1 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX.
+ RC channel 2 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX.
+ RC channel 3 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX.
+ RC channel 4 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX.
+ RC channel 5 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX.
+ RC channel 6 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX.
+ RC channel 7 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX.
+ RC channel 8 value scaled, (-100%) -10000, (0%) 0, (100%) 10000, (invalid) INT16_MAX.
+ Receive signal strength indicator, 0: 0%, 100: 100%, 255: invalid/unknown.
+
+
+ The RAW values of the RC channels received. The standard PPM modulation is as follows: 1000 microseconds: 0%, 2000 microseconds: 100%. Individual receivers/transmitters might violate this specification.
+ Timestamp (milliseconds since system boot)
+ Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows for more than 8 servos.
+ RC channel 1 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 2 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 3 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 4 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 5 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 6 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 7 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 8 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ Receive signal strength indicator, 0: 0%, 100: 100%, 255: invalid/unknown.
+
+
+ The RAW values of the servo outputs (for RC input from the remote, use the RC_CHANNELS messages). The standard PPM modulation is as follows: 1000 microseconds: 0%, 2000 microseconds: 100%.
+ Timestamp (microseconds since system boot)
+ Servo output port (set of 8 outputs = 1 port). Most MAVs will just use one, but this allows to encode more than 8 servos.
+ Servo output 1 value, in microseconds
+ Servo output 2 value, in microseconds
+ Servo output 3 value, in microseconds
+ Servo output 4 value, in microseconds
+ Servo output 5 value, in microseconds
+ Servo output 6 value, in microseconds
+ Servo output 7 value, in microseconds
+ Servo output 8 value, in microseconds
+
+
+ Request a partial list of mission items from the system/component. http://qgroundcontrol.org/mavlink/waypoint_protocol. If start and end index are the same, just send one waypoint.
+ System ID
+ Component ID
+ Start index, 0 by default
+ End index, -1 by default (-1: send list to end). Else a valid index of the list
+
+
+ This message is sent to the MAV to write a partial list. If start index == end index, only one item will be transmitted / updated. If the start index is NOT 0 and above the current list size, this request should be REJECTED!
+ System ID
+ Component ID
+ Start index, 0 by default and smaller / equal to the largest index of the current onboard list.
+ End index, equal or greater than start index.
+
+
+ Message encoding a mission item. This message is emitted to announce
+ the presence of a mission item and to set a mission item on the system. The mission item can be either in x, y, z meters (type: LOCAL) or x:lat, y:lon, z:altitude. Local frame is Z-down, right handed (NED), global frame is Z-up, right handed (ENU). See also http://qgroundcontrol.org/mavlink/waypoint_protocol.
+ System ID
+ Component ID
+ Sequence
+ The coordinate system of the MISSION. see MAV_FRAME in mavlink_types.h
+ The scheduled action for the MISSION. see MAV_CMD in common.xml MAVLink specs
+ false:0, true:1
+ autocontinue to next wp
+ PARAM1, see MAV_CMD enum
+ PARAM2, see MAV_CMD enum
+ PARAM3, see MAV_CMD enum
+ PARAM4, see MAV_CMD enum
+ PARAM5 / local: x position, global: latitude
+ PARAM6 / y position: global: longitude
+ PARAM7 / z position: global: altitude (relative or absolute, depending on frame.
+
+
+ Request the information of the mission item with the sequence number seq. The response of the system to this message should be a MISSION_ITEM message. http://qgroundcontrol.org/mavlink/waypoint_protocol
+ System ID
+ Component ID
+ Sequence
+
+
+ Set the mission item with sequence number seq as current item. This means that the MAV will continue to this mission item on the shortest path (not following the mission items in-between).
+ System ID
+ Component ID
+ Sequence
+
+
+ Message that announces the sequence number of the current active mission item. The MAV will fly towards this mission item.
+ Sequence
+
+
+ Request the overall list of mission items from the system/component.
+ System ID
+ Component ID
+
+
+ This message is emitted as response to MISSION_REQUEST_LIST by the MAV and to initiate a write transaction. The GCS can then request the individual mission item based on the knowledge of the total number of MISSIONs.
+ System ID
+ Component ID
+ Number of mission items in the sequence
+
+
+ Delete all mission items at once.
+ System ID
+ Component ID
+
+
+ A certain mission item has been reached. The system will either hold this position (or circle on the orbit) or (if the autocontinue on the WP was set) continue to the next MISSION.
+ Sequence
+
+
+ Ack message during MISSION handling. The type field states if this message is a positive ack (type=0) or if an error happened (type=non-zero).
+ System ID
+ Component ID
+ See MAV_MISSION_RESULT enum
+
+
+ As local waypoints exist, the global MISSION reference allows to transform between the local coordinate frame and the global (GPS) coordinate frame. This can be necessary when e.g. in- and outdoor settings are connected and the MAV should move from in- to outdoor.
+ System ID
+ Latitude (WGS84), in degrees * 1E7
+ Longitude (WGS84, in degrees * 1E7
+ Altitude (AMSL), in meters * 1000 (positive for up)
+
+
+ Once the MAV sets a new GPS-Local correspondence, this message announces the origin (0,0,0) position
+ Latitude (WGS84), in degrees * 1E7
+ Longitude (WGS84), in degrees * 1E7
+ Altitude (AMSL), in meters * 1000 (positive for up)
+
+
+ Bind a RC channel to a parameter. The parameter should change accoding to the RC channel value.
+ System ID
+ Component ID
+ Onboard parameter id, terminated by NULL if the length is less than 16 human-readable chars and WITHOUT null termination (NULL) byte if the length is exactly 16 chars - applications have to provide 16+1 bytes storage if the ID is stored as string
+ Parameter index. Send -1 to use the param ID field as identifier (else the param id will be ignored), send -2 to disable any existing map for this rc_channel_index.
+ Index of parameter RC channel. Not equal to the RC channel id. Typically correpsonds to a potentiometer-knob on the RC.
+ Initial parameter value
+ Scale, maps the RC range [-1, 1] to a parameter value
+ Minimum param value. The protocol does not define if this overwrites an onboard minimum value. (Depends on implementation)
+ Maximum param value. The protocol does not define if this overwrites an onboard maximum value. (Depends on implementation)
+
+
+ Set a safety zone (volume), which is defined by two corners of a cube. This message can be used to tell the MAV which setpoints/MISSIONs to accept and which to reject. Safety areas are often enforced by national or competition regulations.
+ System ID
+ Component ID
+ Coordinate frame, as defined by MAV_FRAME enum in mavlink_types.h. Can be either global, GPS, right-handed with Z axis up or local, right handed, Z axis down.
+ x position 1 / Latitude 1
+ y position 1 / Longitude 1
+ z position 1 / Altitude 1
+ x position 2 / Latitude 2
+ y position 2 / Longitude 2
+ z position 2 / Altitude 2
+
+
+ Read out the safety zone the MAV currently assumes.
+ Coordinate frame, as defined by MAV_FRAME enum in mavlink_types.h. Can be either global, GPS, right-handed with Z axis up or local, right handed, Z axis down.
+ x position 1 / Latitude 1
+ y position 1 / Longitude 1
+ z position 1 / Altitude 1
+ x position 2 / Latitude 2
+ y position 2 / Longitude 2
+ z position 2 / Altitude 2
+
+
+ The attitude in the aeronautical frame (right-handed, Z-down, X-front, Y-right), expressed as quaternion. Quaternion order is w, x, y, z and a zero rotation would be expressed as (1 0 0 0).
+ Timestamp (milliseconds since system boot)
+ Quaternion components, w, x, y, z (1 0 0 0 is the null-rotation)
+ Roll angular speed (rad/s)
+ Pitch angular speed (rad/s)
+ Yaw angular speed (rad/s)
+ Attitude covariance
+
+
+ Outputs of the APM navigation controller. The primary use of this message is to check the response and signs of the controller before actual flight and to assist with tuning controller parameters.
+ Current desired roll in degrees
+ Current desired pitch in degrees
+ Current desired heading in degrees
+ Bearing to current MISSION/target in degrees
+ Distance to active MISSION in meters
+ Current altitude error in meters
+ Current airspeed error in meters/second
+ Current crosstrack error on x-y plane in meters
+
+
+ The filtered global position (e.g. fused GPS and accelerometers). The position is in GPS-frame (right-handed, Z-up). It is designed as scaled integer message since the resolution of float is not sufficient. NOTE: This message is intended for onboard networks / companion computers and higher-bandwidth links and optimized for accuracy and completeness. Please use the GLOBAL_POSITION_INT message for a minimal subset.
+ Timestamp (milliseconds since system boot)
+ Timestamp (microseconds since UNIX epoch) in UTC. 0 for unknown. Commonly filled by the precision time source of a GPS receiver.
+ Class id of the estimator this estimate originated from.
+ Latitude, expressed as degrees * 1E7
+ Longitude, expressed as degrees * 1E7
+ Altitude in meters, expressed as * 1000 (millimeters), above MSL
+ Altitude above ground in meters, expressed as * 1000 (millimeters)
+ Ground X Speed (Latitude), expressed as m/s
+ Ground Y Speed (Longitude), expressed as m/s
+ Ground Z Speed (Altitude), expressed as m/s
+ Covariance matrix (first six entries are the first ROW, next six entries are the second row, etc.)
+
+
+ The filtered local position (e.g. fused computer vision and accelerometers). Coordinate frame is right-handed, Z-axis down (aeronautical frame, NED / north-east-down convention)
+ Timestamp (milliseconds since system boot). 0 for system without monotonic timestamp
+ Timestamp (microseconds since UNIX epoch) in UTC. 0 for unknown. Commonly filled by the precision time source of a GPS receiver.
+ Class id of the estimator this estimate originated from.
+ X Position
+ Y Position
+ Z Position
+ X Speed (m/s)
+ Y Speed (m/s)
+ Z Speed (m/s)
+ X Acceleration (m/s^2)
+ Y Acceleration (m/s^2)
+ Z Acceleration (m/s^2)
+ Covariance matrix upper right triangular (first nine entries are the first ROW, next eight entries are the second row, etc.)
+
+
+ The PPM values of the RC channels received. The standard PPM modulation is as follows: 1000 microseconds: 0%, 2000 microseconds: 100%. Individual receivers/transmitters might violate this specification.
+ Timestamp (milliseconds since system boot)
+ Total number of RC channels being received. This can be larger than 18, indicating that more channels are available but not given in this message. This value should be 0 when no RC channels are available.
+ RC channel 1 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 2 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 3 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 4 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 5 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 6 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 7 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 8 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 9 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 10 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 11 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 12 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 13 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 14 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 15 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 16 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 17 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ RC channel 18 value, in microseconds. A value of UINT16_MAX implies the channel is unused.
+ Receive signal strength indicator, 0: 0%, 100: 100%, 255: invalid/unknown.
+
+
+ The target requested to send the message stream.
+ The target requested to send the message stream.
+ The ID of the requested data stream
+ The requested interval between two messages of this type
+ 1 to start sending, 0 to stop sending.
+
+
+ The ID of the requested data stream
+ The requested interval between two messages of this type
+ 1 stream is enabled, 0 stream is stopped.
+
+
+ This message provides an API for manually controlling the vehicle using standard joystick axes nomenclature, along with a joystick-like input device. Unused axes can be disabled an buttons are also transmit as boolean values of their
+ The system to be controlled.
+ X-axis, normalized to the range [-1000,1000]. A value of INT16_MAX indicates that this axis is invalid. Generally corresponds to forward(1000)-backward(-1000) movement on a joystick and the pitch of a vehicle.
+ Y-axis, normalized to the range [-1000,1000]. A value of INT16_MAX indicates that this axis is invalid. Generally corresponds to left(-1000)-right(1000) movement on a joystick and the roll of a vehicle.
+ Z-axis, normalized to the range [-1000,1000]. A value of INT16_MAX indicates that this axis is invalid. Generally corresponds to a separate slider movement with maximum being 1000 and minimum being -1000 on a joystick and the thrust of a vehicle.
+ R-axis, normalized to the range [-1000,1000]. A value of INT16_MAX indicates that this axis is invalid. Generally corresponds to a twisting of the joystick, with counter-clockwise being 1000 and clockwise being -1000, and the yaw of a vehicle.
+ A bitfield corresponding to the joystick buttons' current state, 1 for pressed, 0 for released. The lowest bit corresponds to Button 1.
+
+
+ The RAW values of the RC channels sent to the MAV to override info received from the RC radio. A value of UINT16_MAX means no change to that channel. A value of 0 means control of that channel should be released back to the RC radio. The standard PPM modulation is as follows: 1000 microseconds: 0%, 2000 microseconds: 100%. Individual receivers/transmitters might violate this specification.
+ System ID
+ Component ID
+ RC channel 1 value, in microseconds. A value of UINT16_MAX means to ignore this field.
+ RC channel 2 value, in microseconds. A value of UINT16_MAX means to ignore this field.
+ RC channel 3 value, in microseconds. A value of UINT16_MAX means to ignore this field.
+ RC channel 4 value, in microseconds. A value of UINT16_MAX means to ignore this field.
+ RC channel 5 value, in microseconds. A value of UINT16_MAX means to ignore this field.
+ RC channel 6 value, in microseconds. A value of UINT16_MAX means to ignore this field.
+ RC channel 7 value, in microseconds. A value of UINT16_MAX means to ignore this field.
+ RC channel 8 value, in microseconds. A value of UINT16_MAX means to ignore this field.
+
+
+ Message encoding a mission item. This message is emitted to announce
+ the presence of a mission item and to set a mission item on the system. The mission item can be either in x, y, z meters (type: LOCAL) or x:lat, y:lon, z:altitude. Local frame is Z-down, right handed (NED), global frame is Z-up, right handed (ENU). See alsohttp://qgroundcontrol.org/mavlink/waypoint_protocol.
+ System ID
+ Component ID
+ Waypoint ID (sequence number). Starts at zero. Increases monotonically for each waypoint, no gaps in the sequence (0,1,2,3,4).
+ The coordinate system of the MISSION. see MAV_FRAME in mavlink_types.h
+ The scheduled action for the MISSION. see MAV_CMD in common.xml MAVLink specs
+ false:0, true:1
+ autocontinue to next wp
+ PARAM1, see MAV_CMD enum
+ PARAM2, see MAV_CMD enum
+ PARAM3, see MAV_CMD enum
+ PARAM4, see MAV_CMD enum
+ PARAM5 / local: x position in meters * 1e4, global: latitude in degrees * 10^7
+ PARAM6 / y position: local: x position in meters * 1e4, global: longitude in degrees *10^7
+ PARAM7 / z position: global: altitude in meters (relative or absolute, depending on frame.
+
+
+ Metrics typically displayed on a HUD for fixed wing aircraft
+ Current airspeed in m/s
+ Current ground speed in m/s
+ Current heading in degrees, in compass units (0..360, 0=north)
+ Current throttle setting in integer percent, 0 to 100
+ Current altitude (MSL), in meters
+ Current climb rate in meters/second
+
+
+ Message encoding a command with parameters as scaled integers. Scaling depends on the actual command value.
+ System ID
+ Component ID
+ The coordinate system of the COMMAND. see MAV_FRAME in mavlink_types.h
+ The scheduled action for the mission item. see MAV_CMD in common.xml MAVLink specs
+ false:0, true:1
+ autocontinue to next wp
+ PARAM1, see MAV_CMD enum
+ PARAM2, see MAV_CMD enum
+ PARAM3, see MAV_CMD enum
+ PARAM4, see MAV_CMD enum
+ PARAM5 / local: x position in meters * 1e4, global: latitude in degrees * 10^7
+ PARAM6 / local: y position in meters * 1e4, global: longitude in degrees * 10^7
+ PARAM7 / z position: global: altitude in meters (relative or absolute, depending on frame.
+
+
+ Send a command with up to seven parameters to the MAV
+ System which should execute the command
+ Component which should execute the command, 0 for all components
+ Command ID, as defined by MAV_CMD enum.
+ 0: First transmission of this command. 1-255: Confirmation transmissions (e.g. for kill command)
+ Parameter 1, as defined by MAV_CMD enum.
+ Parameter 2, as defined by MAV_CMD enum.
+ Parameter 3, as defined by MAV_CMD enum.
+ Parameter 4, as defined by MAV_CMD enum.
+ Parameter 5, as defined by MAV_CMD enum.
+ Parameter 6, as defined by MAV_CMD enum.
+ Parameter 7, as defined by MAV_CMD enum.
+
+
+ Report status of a command. Includes feedback wether the command was executed.
+ Command ID, as defined by MAV_CMD enum.
+ See MAV_RESULT enum
+
+
+ Setpoint in roll, pitch, yaw and thrust from the operator
+ Timestamp in milliseconds since system boot
+ Desired roll rate in radians per second
+ Desired pitch rate in radians per second
+ Desired yaw rate in radians per second
+ Collective thrust, normalized to 0 .. 1
+ Flight mode switch position, 0.. 255
+ Override mode switch position, 0.. 255
+
+
+ Set the vehicle attitude and body angular rates.
+ Timestamp in milliseconds since system boot
+ System ID
+ Component ID
+ Mappings: If any of these bits are set, the corresponding input should be ignored: bit 1: body roll rate, bit 2: body pitch rate, bit 3: body yaw rate. bit 4-bit 6: reserved, bit 7: throttle, bit 8: attitude
+ Attitude quaternion (w, x, y, z order, zero-rotation is 1, 0, 0, 0)
+ Body roll rate in radians per second
+ Body roll rate in radians per second
+ Body roll rate in radians per second
+ Collective thrust, normalized to 0 .. 1 (-1 .. 1 for vehicles capable of reverse trust)
+
+
+ Set the vehicle attitude and body angular rates.
+ Timestamp in milliseconds since system boot
+ Mappings: If any of these bits are set, the corresponding input should be ignored: bit 1: body roll rate, bit 2: body pitch rate, bit 3: body yaw rate. bit 4-bit 7: reserved, bit 8: attitude
+ Attitude quaternion (w, x, y, z order, zero-rotation is 1, 0, 0, 0)
+ Body roll rate in radians per second
+ Body roll rate in radians per second
+ Body roll rate in radians per second
+ Collective thrust, normalized to 0 .. 1 (-1 .. 1 for vehicles capable of reverse trust)
+
+
+ Set vehicle position, velocity and acceleration setpoint in local frame.
+ Timestamp in milliseconds since system boot
+ System ID
+ Component ID
+ Valid options are: MAV_FRAME_LOCAL_NED = 1, MAV_FRAME_LOCAL_OFFSET_NED = 7, MAV_FRAME_BODY_NED = 8, MAV_FRAME_BODY_OFFSET_NED = 9
+ Bitmask to indicate which dimensions should be ignored by the vehicle: a value of 0b0000000000000000 or 0b0000001000000000 indicates that none of the setpoint dimensions should be ignored. If bit 10 is set the floats afx afy afz should be interpreted as force instead of acceleration. Mapping: bit 1: x, bit 2: y, bit 3: z, bit 4: vx, bit 5: vy, bit 6: vz, bit 7: ax, bit 8: ay, bit 9: az, bit 10: is force setpoint, bit 11: yaw, bit 12: yaw rate
+ X Position in NED frame in meters
+ Y Position in NED frame in meters
+ Z Position in NED frame in meters (note, altitude is negative in NED)
+ X velocity in NED frame in meter / s
+ Y velocity in NED frame in meter / s
+ Z velocity in NED frame in meter / s
+ X acceleration or force (if bit 10 of type_mask is set) in NED frame in meter / s^2 or N
+ Y acceleration or force (if bit 10 of type_mask is set) in NED frame in meter / s^2 or N
+ Z acceleration or force (if bit 10 of type_mask is set) in NED frame in meter / s^2 or N
+ yaw setpoint in rad
+ yaw rate setpoint in rad/s
+
+
+ Set vehicle position, velocity and acceleration setpoint in local frame.
+ Timestamp in milliseconds since system boot
+ Valid options are: MAV_FRAME_LOCAL_NED = 1, MAV_FRAME_LOCAL_OFFSET_NED = 7, MAV_FRAME_BODY_NED = 8, MAV_FRAME_BODY_OFFSET_NED = 9
+ Bitmask to indicate which dimensions should be ignored by the vehicle: a value of 0b0000000000000000 or 0b0000001000000000 indicates that none of the setpoint dimensions should be ignored. If bit 10 is set the floats afx afy afz should be interpreted as force instead of acceleration. Mapping: bit 1: x, bit 2: y, bit 3: z, bit 4: vx, bit 5: vy, bit 6: vz, bit 7: ax, bit 8: ay, bit 9: az, bit 10: is force setpoint, bit 11: yaw, bit 12: yaw rate
+ X Position in NED frame in meters
+ Y Position in NED frame in meters
+ Z Position in NED frame in meters (note, altitude is negative in NED)
+ X velocity in NED frame in meter / s
+ Y velocity in NED frame in meter / s
+ Z velocity in NED frame in meter / s
+ X acceleration or force (if bit 10 of type_mask is set) in NED frame in meter / s^2 or N
+ Y acceleration or force (if bit 10 of type_mask is set) in NED frame in meter / s^2 or N
+ Z acceleration or force (if bit 10 of type_mask is set) in NED frame in meter / s^2 or N
+ yaw setpoint in rad
+ yaw rate setpoint in rad/s
+
+
+ Set vehicle position, velocity and acceleration setpoint in the WGS84 coordinate system.
+ Timestamp in milliseconds since system boot. The rationale for the timestamp in the setpoint is to allow the system to compensate for the transport delay of the setpoint. This allows the system to compensate processing latency.
+ System ID
+ Component ID
+ Valid options are: MAV_FRAME_GLOBAL_INT = 5, MAV_FRAME_GLOBAL_RELATIVE_ALT_INT = 6, MAV_FRAME_GLOBAL_TERRAIN_ALT_INT = 11
+ Bitmask to indicate which dimensions should be ignored by the vehicle: a value of 0b0000000000000000 or 0b0000001000000000 indicates that none of the setpoint dimensions should be ignored. If bit 10 is set the floats afx afy afz should be interpreted as force instead of acceleration. Mapping: bit 1: x, bit 2: y, bit 3: z, bit 4: vx, bit 5: vy, bit 6: vz, bit 7: ax, bit 8: ay, bit 9: az, bit 10: is force setpoint, bit 11: yaw, bit 12: yaw rate
+ X Position in WGS84 frame in 1e7 * meters
+ Y Position in WGS84 frame in 1e7 * meters
+ Altitude in meters in AMSL altitude, not WGS84 if absolute or relative, above terrain if GLOBAL_TERRAIN_ALT_INT
+ X velocity in NED frame in meter / s
+ Y velocity in NED frame in meter / s
+ Z velocity in NED frame in meter / s
+ X acceleration or force (if bit 10 of type_mask is set) in NED frame in meter / s^2 or N
+ Y acceleration or force (if bit 10 of type_mask is set) in NED frame in meter / s^2 or N
+ Z acceleration or force (if bit 10 of type_mask is set) in NED frame in meter / s^2 or N
+ yaw setpoint in rad
+ yaw rate setpoint in rad/s
+
+
+ Set vehicle position, velocity and acceleration setpoint in the WGS84 coordinate system.
+ Timestamp in milliseconds since system boot. The rationale for the timestamp in the setpoint is to allow the system to compensate for the transport delay of the setpoint. This allows the system to compensate processing latency.
+ Valid options are: MAV_FRAME_GLOBAL_INT = 5, MAV_FRAME_GLOBAL_RELATIVE_ALT_INT = 6, MAV_FRAME_GLOBAL_TERRAIN_ALT_INT = 11
+ Bitmask to indicate which dimensions should be ignored by the vehicle: a value of 0b0000000000000000 or 0b0000001000000000 indicates that none of the setpoint dimensions should be ignored. If bit 10 is set the floats afx afy afz should be interpreted as force instead of acceleration. Mapping: bit 1: x, bit 2: y, bit 3: z, bit 4: vx, bit 5: vy, bit 6: vz, bit 7: ax, bit 8: ay, bit 9: az, bit 10: is force setpoint, bit 11: yaw, bit 12: yaw rate
+ X Position in WGS84 frame in 1e7 * meters
+ Y Position in WGS84 frame in 1e7 * meters
+ Altitude in meters in AMSL altitude, not WGS84 if absolute or relative, above terrain if GLOBAL_TERRAIN_ALT_INT
+ X velocity in NED frame in meter / s
+ Y velocity in NED frame in meter / s
+ Z velocity in NED frame in meter / s
+ X acceleration or force (if bit 10 of type_mask is set) in NED frame in meter / s^2 or N
+ Y acceleration or force (if bit 10 of type_mask is set) in NED frame in meter / s^2 or N
+ Z acceleration or force (if bit 10 of type_mask is set) in NED frame in meter / s^2 or N
+ yaw setpoint in rad
+ yaw rate setpoint in rad/s
+
+
+ The offset in X, Y, Z and yaw between the LOCAL_POSITION_NED messages of MAV X and the global coordinate frame in NED coordinates. Coordinate frame is right-handed, Z-axis down (aeronautical frame, NED / north-east-down convention)
+ Timestamp (milliseconds since system boot)
+ X Position
+ Y Position
+ Z Position
+ Roll
+ Pitch
+ Yaw
+
+
+ DEPRECATED PACKET! Suffers from missing airspeed fields and singularities due to Euler angles. Please use HIL_STATE_QUATERNION instead. Sent from simulation to autopilot. This packet is useful for high throughput applications such as hardware in the loop simulations.
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ Roll angle (rad)
+ Pitch angle (rad)
+ Yaw angle (rad)
+ Body frame roll / phi angular speed (rad/s)
+ Body frame pitch / theta angular speed (rad/s)
+ Body frame yaw / psi angular speed (rad/s)
+ Latitude, expressed as * 1E7
+ Longitude, expressed as * 1E7
+ Altitude in meters, expressed as * 1000 (millimeters)
+ Ground X Speed (Latitude), expressed as m/s * 100
+ Ground Y Speed (Longitude), expressed as m/s * 100
+ Ground Z Speed (Altitude), expressed as m/s * 100
+ X acceleration (mg)
+ Y acceleration (mg)
+ Z acceleration (mg)
+
+
+ Sent from autopilot to simulation. Hardware in the loop control outputs
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ Control output -1 .. 1
+ Control output -1 .. 1
+ Control output -1 .. 1
+ Throttle 0 .. 1
+ Aux 1, -1 .. 1
+ Aux 2, -1 .. 1
+ Aux 3, -1 .. 1
+ Aux 4, -1 .. 1
+ System mode (MAV_MODE)
+ Navigation mode (MAV_NAV_MODE)
+
+
+ Sent from simulation to autopilot. The RAW values of the RC channels received. The standard PPM modulation is as follows: 1000 microseconds: 0%, 2000 microseconds: 100%. Individual receivers/transmitters might violate this specification.
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ RC channel 1 value, in microseconds
+ RC channel 2 value, in microseconds
+ RC channel 3 value, in microseconds
+ RC channel 4 value, in microseconds
+ RC channel 5 value, in microseconds
+ RC channel 6 value, in microseconds
+ RC channel 7 value, in microseconds
+ RC channel 8 value, in microseconds
+ RC channel 9 value, in microseconds
+ RC channel 10 value, in microseconds
+ RC channel 11 value, in microseconds
+ RC channel 12 value, in microseconds
+ Receive signal strength indicator, 0: 0%, 255: 100%
+
+
+ Optical flow from a flow sensor (e.g. optical mouse sensor)
+ Timestamp (UNIX)
+ Sensor ID
+ Flow in pixels * 10 in x-sensor direction (dezi-pixels)
+ Flow in pixels * 10 in y-sensor direction (dezi-pixels)
+ Flow in meters in x-sensor direction, angular-speed compensated
+ Flow in meters in y-sensor direction, angular-speed compensated
+ Optical flow quality / confidence. 0: bad, 255: maximum quality
+ Ground distance in meters. Positive value: distance known. Negative value: Unknown distance
+
+
+ Timestamp (microseconds, synced to UNIX time or since system boot)
+ Global X position
+ Global Y position
+ Global Z position
+ Roll angle in rad
+ Pitch angle in rad
+ Yaw angle in rad
+
+
+ Timestamp (microseconds, synced to UNIX time or since system boot)
+ Global X position
+ Global Y position
+ Global Z position
+ Roll angle in rad
+ Pitch angle in rad
+ Yaw angle in rad
+
+
+ Timestamp (microseconds, synced to UNIX time or since system boot)
+ Global X speed
+ Global Y speed
+ Global Z speed
+
+
+ Timestamp (microseconds, synced to UNIX time or since system boot)
+ Global X position
+ Global Y position
+ Global Z position
+ Roll angle in rad
+ Pitch angle in rad
+ Yaw angle in rad
+
+
+ The IMU readings in SI units in NED body frame
+ Timestamp (microseconds, synced to UNIX time or since system boot)
+ X acceleration (m/s^2)
+ Y acceleration (m/s^2)
+ Z acceleration (m/s^2)
+ Angular speed around X axis (rad / sec)
+ Angular speed around Y axis (rad / sec)
+ Angular speed around Z axis (rad / sec)
+ X Magnetic field (Gauss)
+ Y Magnetic field (Gauss)
+ Z Magnetic field (Gauss)
+ Absolute pressure in millibar
+ Differential pressure in millibar
+ Altitude calculated from pressure
+ Temperature in degrees celsius
+ Bitmask for fields that have updated since last message, bit 0 = xacc, bit 12: temperature
+
+
+ Optical flow from an angular rate flow sensor (e.g. PX4FLOW or mouse sensor)
+ Timestamp (microseconds, synced to UNIX time or since system boot)
+ Sensor ID
+ Integration time in microseconds. Divide integrated_x and integrated_y by the integration time to obtain average flow. The integration time also indicates the.
+ Flow in radians around X axis (Sensor RH rotation about the X axis induces a positive flow. Sensor linear motion along the positive Y axis induces a negative flow.)
+ Flow in radians around Y axis (Sensor RH rotation about the Y axis induces a positive flow. Sensor linear motion along the positive X axis induces a positive flow.)
+ RH rotation around X axis (rad)
+ RH rotation around Y axis (rad)
+ RH rotation around Z axis (rad)
+ Temperature * 100 in centi-degrees Celsius
+ Optical flow quality / confidence. 0: no valid flow, 255: maximum quality
+ Time in microseconds since the distance was sampled.
+ Distance to the center of the flow field in meters. Positive value (including zero): distance known. Negative value: Unknown distance.
+
+
+ The IMU readings in SI units in NED body frame
+ Timestamp (microseconds, synced to UNIX time or since system boot)
+ X acceleration (m/s^2)
+ Y acceleration (m/s^2)
+ Z acceleration (m/s^2)
+ Angular speed around X axis in body frame (rad / sec)
+ Angular speed around Y axis in body frame (rad / sec)
+ Angular speed around Z axis in body frame (rad / sec)
+ X Magnetic field (Gauss)
+ Y Magnetic field (Gauss)
+ Z Magnetic field (Gauss)
+ Absolute pressure in millibar
+ Differential pressure (airspeed) in millibar
+ Altitude calculated from pressure
+ Temperature in degrees celsius
+ Bitmask for fields that have updated since last message, bit 0 = xacc, bit 12: temperature
+
+
+
+ Status of simulation environment, if used
+ True attitude quaternion component 1, w (1 in null-rotation)
+ True attitude quaternion component 2, x (0 in null-rotation)
+ True attitude quaternion component 3, y (0 in null-rotation)
+ True attitude quaternion component 4, z (0 in null-rotation)
+ Attitude roll expressed as Euler angles, not recommended except for human-readable outputs
+ Attitude pitch expressed as Euler angles, not recommended except for human-readable outputs
+ Attitude yaw expressed as Euler angles, not recommended except for human-readable outputs
+ X acceleration m/s/s
+ Y acceleration m/s/s
+ Z acceleration m/s/s
+ Angular speed around X axis rad/s
+ Angular speed around Y axis rad/s
+ Angular speed around Z axis rad/s
+ Latitude in degrees
+ Longitude in degrees
+ Altitude in meters
+ Horizontal position standard deviation
+ Vertical position standard deviation
+ True velocity in m/s in NORTH direction in earth-fixed NED frame
+ True velocity in m/s in EAST direction in earth-fixed NED frame
+ True velocity in m/s in DOWN direction in earth-fixed NED frame
+
+
+
+ Status generated by radio and injected into MAVLink stream.
+ Local signal strength
+ Remote signal strength
+ Remaining free buffer space in percent.
+ Background noise level
+ Remote background noise level
+ Receive errors
+ Count of error corrected packets
+
+
+ File transfer message
+ Network ID (0 for broadcast)
+ System ID (0 for broadcast)
+ Component ID (0 for broadcast)
+ Variable length payload. The length is defined by the remaining message length when subtracting the header and other fields. The entire content of this block is opaque unless you understand any the encoding message_type. The particular encoding used can be extension specific and might not always be documented as part of the mavlink specification.
+
+
+ Time synchronization message.
+ Time sync timestamp 1
+ Time sync timestamp 2
+
+
+ Camera-IMU triggering and synchronisation message.
+ Timestamp for the image frame in microseconds
+ Image frame sequence
+
+
+ The global position, as returned by the Global Positioning System (GPS). This is
+ NOT the global position estimate of the sytem, but rather a RAW sensor value. See message GLOBAL_POSITION for the global position estimate. Coordinate frame is right-handed, Z-axis up (GPS frame).
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ 0-1: no fix, 2: 2D fix, 3: 3D fix. Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix.
+ Latitude (WGS84), in degrees * 1E7
+ Longitude (WGS84), in degrees * 1E7
+ Altitude (AMSL, not WGS84), in meters * 1000 (positive for up)
+ GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: 65535
+ GPS VDOP vertical dilution of position in cm (m*100). If unknown, set to: 65535
+ GPS ground speed (m/s * 100). If unknown, set to: 65535
+ GPS velocity in cm/s in NORTH direction in earth-fixed NED frame
+ GPS velocity in cm/s in EAST direction in earth-fixed NED frame
+ GPS velocity in cm/s in DOWN direction in earth-fixed NED frame
+ Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: 65535
+ Number of satellites visible. If unknown, set to 255
+
+
+ Simulated optical flow from a flow sensor (e.g. PX4FLOW or optical mouse sensor)
+ Timestamp (microseconds, synced to UNIX time or since system boot)
+ Sensor ID
+ Integration time in microseconds. Divide integrated_x and integrated_y by the integration time to obtain average flow. The integration time also indicates the.
+ Flow in radians around X axis (Sensor RH rotation about the X axis induces a positive flow. Sensor linear motion along the positive Y axis induces a negative flow.)
+ Flow in radians around Y axis (Sensor RH rotation about the Y axis induces a positive flow. Sensor linear motion along the positive X axis induces a positive flow.)
+ RH rotation around X axis (rad)
+ RH rotation around Y axis (rad)
+ RH rotation around Z axis (rad)
+ Temperature * 100 in centi-degrees Celsius
+ Optical flow quality / confidence. 0: no valid flow, 255: maximum quality
+ Time in microseconds since the distance was sampled.
+ Distance to the center of the flow field in meters. Positive value (including zero): distance known. Negative value: Unknown distance.
+
+
+ Sent from simulation to autopilot, avoids in contrast to HIL_STATE singularities. This packet is useful for high throughput applications such as hardware in the loop simulations.
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ Vehicle attitude expressed as normalized quaternion in w, x, y, z order (with 1 0 0 0 being the null-rotation)
+ Body frame roll / phi angular speed (rad/s)
+ Body frame pitch / theta angular speed (rad/s)
+ Body frame yaw / psi angular speed (rad/s)
+ Latitude, expressed as * 1E7
+ Longitude, expressed as * 1E7
+ Altitude in meters, expressed as * 1000 (millimeters)
+ Ground X Speed (Latitude), expressed as m/s * 100
+ Ground Y Speed (Longitude), expressed as m/s * 100
+ Ground Z Speed (Altitude), expressed as m/s * 100
+ Indicated airspeed, expressed as m/s * 100
+ True airspeed, expressed as m/s * 100
+ X acceleration (mg)
+ Y acceleration (mg)
+ Z acceleration (mg)
+
+
+ The RAW IMU readings for secondary 9DOF sensor setup. This message should contain the scaled values to the described units
+ Timestamp (milliseconds since system boot)
+ X acceleration (mg)
+ Y acceleration (mg)
+ Z acceleration (mg)
+ Angular speed around X axis (millirad /sec)
+ Angular speed around Y axis (millirad /sec)
+ Angular speed around Z axis (millirad /sec)
+ X Magnetic field (milli tesla)
+ Y Magnetic field (milli tesla)
+ Z Magnetic field (milli tesla)
+
+
+ Request a list of available logs. On some systems calling this may stop on-board logging until LOG_REQUEST_END is called.
+ System ID
+ Component ID
+ First log id (0 for first available)
+ Last log id (0xffff for last available)
+
+
+ Reply to LOG_REQUEST_LIST
+ Log id
+ Total number of logs
+ High log number
+ UTC timestamp of log in seconds since 1970, or 0 if not available
+ Size of the log (may be approximate) in bytes
+
+
+ Request a chunk of a log
+ System ID
+ Component ID
+ Log id (from LOG_ENTRY reply)
+ Offset into the log
+ Number of bytes
+
+
+ Reply to LOG_REQUEST_DATA
+ Log id (from LOG_ENTRY reply)
+ Offset into the log
+ Number of bytes (zero for end of log)
+ log data
+
+
+ Erase all logs
+ System ID
+ Component ID
+
+
+ Stop log transfer and resume normal logging
+ System ID
+ Component ID
+
+
+ data for injecting into the onboard GPS (used for DGPS)
+ System ID
+ Component ID
+ data length
+ raw data (110 is enough for 12 satellites of RTCMv2)
+
+
+ Second GPS data. Coordinate frame is right-handed, Z-axis up (GPS frame).
+ Timestamp (microseconds since UNIX epoch or microseconds since system boot)
+ 0-1: no fix, 2: 2D fix, 3: 3D fix, 4: DGPS fix, 5: RTK Fix. Some applications will not use the value of this field unless it is at least two, so always correctly fill in the fix.
+ Latitude (WGS84), in degrees * 1E7
+ Longitude (WGS84), in degrees * 1E7
+ Altitude (AMSL, not WGS84), in meters * 1000 (positive for up)
+ GPS HDOP horizontal dilution of position in cm (m*100). If unknown, set to: UINT16_MAX
+ GPS VDOP vertical dilution of position in cm (m*100). If unknown, set to: UINT16_MAX
+ GPS ground speed (m/s * 100). If unknown, set to: UINT16_MAX
+ Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: UINT16_MAX
+ Number of satellites visible. If unknown, set to 255
+ Number of DGPS satellites
+ Age of DGPS info
+
+
+ Power supply status
+ 5V rail voltage in millivolts
+ servo rail voltage in millivolts
+ power supply status flags (see MAV_POWER_STATUS enum)
+
+
+ Control a serial port. This can be used for raw access to an onboard serial peripheral such as a GPS or telemetry radio. It is designed to make it possible to update the devices firmware via MAVLink messages or change the devices settings. A message with zero bytes can be used to change just the baudrate.
+ See SERIAL_CONTROL_DEV enum
+ See SERIAL_CONTROL_FLAG enum
+ Timeout for reply data in milliseconds
+ Baudrate of transfer. Zero means no change.
+ how many bytes in this transfer
+ serial data
+
+
+ RTK GPS data. Gives information on the relative baseline calculation the GPS is reporting
+ Time since boot of last baseline message received in ms.
+ Identification of connected RTK receiver.
+ GPS Week Number of last baseline
+ GPS Time of Week of last baseline
+ GPS-specific health report for RTK data.
+ Rate of baseline messages being received by GPS, in HZ
+ Current number of sats used for RTK calculation.
+ Coordinate system of baseline. 0 == ECEF, 1 == NED
+ Current baseline in ECEF x or NED north component in mm.
+ Current baseline in ECEF y or NED east component in mm.
+ Current baseline in ECEF z or NED down component in mm.
+ Current estimate of baseline accuracy.
+ Current number of integer ambiguity hypotheses.
+
+
+ RTK GPS data. Gives information on the relative baseline calculation the GPS is reporting
+ Time since boot of last baseline message received in ms.
+ Identification of connected RTK receiver.
+ GPS Week Number of last baseline
+ GPS Time of Week of last baseline
+ GPS-specific health report for RTK data.
+ Rate of baseline messages being received by GPS, in HZ
+ Current number of sats used for RTK calculation.
+ Coordinate system of baseline. 0 == ECEF, 1 == NED
+ Current baseline in ECEF x or NED north component in mm.
+ Current baseline in ECEF y or NED east component in mm.
+ Current baseline in ECEF z or NED down component in mm.
+ Current estimate of baseline accuracy.
+ Current number of integer ambiguity hypotheses.
+
+
+ The RAW IMU readings for 3rd 9DOF sensor setup. This message should contain the scaled values to the described units
+ Timestamp (milliseconds since system boot)
+ X acceleration (mg)
+ Y acceleration (mg)
+ Z acceleration (mg)
+ Angular speed around X axis (millirad /sec)
+ Angular speed around Y axis (millirad /sec)
+ Angular speed around Z axis (millirad /sec)
+ X Magnetic field (milli tesla)
+ Y Magnetic field (milli tesla)
+ Z Magnetic field (milli tesla)
+
+
+ type of requested/acknowledged data (as defined in ENUM DATA_TYPES in mavlink/include/mavlink_types.h)
+ total data size in bytes (set on ACK only)
+ Width of a matrix or image
+ Height of a matrix or image
+ number of packets beeing sent (set on ACK only)
+ payload size per packet (normally 253 byte, see DATA field size in message ENCAPSULATED_DATA) (set on ACK only)
+ JPEG quality out of [1,100]
+
+
+ sequence number (starting with 0 on every transmission)
+ image data bytes
+
+
+ Time since system boot
+ Minimum distance the sensor can measure in centimeters
+ Maximum distance the sensor can measure in centimeters
+ Current distance reading
+ Type from MAV_DISTANCE_SENSOR enum.
+ Onboard ID of the sensor
+ Direction the sensor faces from MAV_SENSOR_ORIENTATION enum.
+ Measurement covariance in centimeters, 0 for unknown / invalid readings
+
+
+ Request for terrain data and terrain status
+ Latitude of SW corner of first grid (degrees *10^7)
+ Longitude of SW corner of first grid (in degrees *10^7)
+ Grid spacing in meters
+ Bitmask of requested 4x4 grids (row major 8x7 array of grids, 56 bits)
+
+
+ Terrain data sent from GCS. The lat/lon and grid_spacing must be the same as a lat/lon from a TERRAIN_REQUEST
+ Latitude of SW corner of first grid (degrees *10^7)
+ Longitude of SW corner of first grid (in degrees *10^7)
+ Grid spacing in meters
+ bit within the terrain request mask
+ Terrain data in meters AMSL
+
+
+ Request that the vehicle report terrain height at the given location. Used by GCS to check if vehicle has all terrain data needed for a mission.
+ Latitude (degrees *10^7)
+ Longitude (degrees *10^7)
+
+
+ Response from a TERRAIN_CHECK request
+ Latitude (degrees *10^7)
+ Longitude (degrees *10^7)
+ grid spacing (zero if terrain at this location unavailable)
+ Terrain height in meters AMSL
+ Current vehicle height above lat/lon terrain height (meters)
+ Number of 4x4 terrain blocks waiting to be received or read from disk
+ Number of 4x4 terrain blocks in memory
+
+
+ Barometer readings for 2nd barometer
+ Timestamp (milliseconds since system boot)
+ Absolute pressure (hectopascal)
+ Differential pressure 1 (hectopascal)
+ Temperature measurement (0.01 degrees celsius)
+
+
+ Motion capture attitude and position
+ Timestamp (micros since boot or Unix epoch)
+ Attitude quaternion (w, x, y, z order, zero-rotation is 1, 0, 0, 0)
+ X position in meters (NED)
+ Y position in meters (NED)
+ Z position in meters (NED)
+
+
+ Set the vehicle attitude and body angular rates.
+ Timestamp (micros since boot or Unix epoch)
+ Actuator group. The "_mlx" indicates this is a multi-instance message and a MAVLink parser should use this field to difference between instances.
+ System ID
+ Component ID
+ Actuator controls. Normed to -1..+1 where 0 is neutral position. Throttle for single rotation direction motors is 0..1, negative range for reverse direction. Standard mapping for attitude controls (group 0): (index 0-7): roll, pitch, yaw, throttle, flaps, spoilers, airbrakes, landing gear. Load a pass-through mixer to repurpose them as generic outputs.
+
+
+ Set the vehicle attitude and body angular rates.
+ Timestamp (micros since boot or Unix epoch)
+ Actuator group. The "_mlx" indicates this is a multi-instance message and a MAVLink parser should use this field to difference between instances.
+ Actuator controls. Normed to -1..+1 where 0 is neutral position. Throttle for single rotation direction motors is 0..1, negative range for reverse direction. Standard mapping for attitude controls (group 0): (index 0-7): roll, pitch, yaw, throttle, flaps, spoilers, airbrakes, landing gear. Load a pass-through mixer to repurpose them as generic outputs.
+
+
+
+ Battery information
+ Battery ID
+ Function of the battery
+ Type (chemistry) of the battery
+ Temperature of the battery in centi-degrees celsius. INT16_MAX for unknown temperature.
+ Battery voltage of cells, in millivolts (1 = 1 millivolt)
+ Battery current, in 10*milliamperes (1 = 10 milliampere), -1: autopilot does not measure the current
+ Consumed charge, in milliampere hours (1 = 1 mAh), -1: autopilot does not provide mAh consumption estimate
+ Consumed energy, in 100*Joules (intergrated U*I*dt) (1 = 100 Joule), -1: autopilot does not provide energy consumption estimate
+ Remaining battery energy: (0%: 0, 100%: 100), -1: autopilot does not estimate the remaining battery
+
+
+ Version and capability of autopilot software
+ bitmask of capabilities (see MAV_PROTOCOL_CAPABILITY enum)
+ Firmware version number
+ Middleware version number
+ Operating system version number
+ HW / board version (last 8 bytes should be silicon ID, if any)
+ Custom version field, commonly the first 8 bytes of the git hash. This is not an unique identifier, but should allow to identify the commit using the main version number even for very large code bases.
+ Custom version field, commonly the first 8 bytes of the git hash. This is not an unique identifier, but should allow to identify the commit using the main version number even for very large code bases.
+ Custom version field, commonly the first 8 bytes of the git hash. This is not an unique identifier, but should allow to identify the commit using the main version number even for very large code bases.
+ ID of the board vendor
+ ID of the product
+ UID if provided by hardware
+
+
+ The location of a landing area captured from a downward facing camera
+ The ID of the target if multiple targets are present
+ MAV_FRAME enum specifying the whether the following feilds are earth-frame, body-frame, etc.
+ X-axis angular offset (in radians) of the target from the center of the image
+ Y-axis angular offset (in radians) of the target from the center of the image
+ Distance to the target from the vehicle in meters
+
+
+
+ File transfer message
+ Network ID (0 for broadcast)
+ System ID (0 for broadcast)
+ Component ID (0 for broadcast)
+ Variable length payload. The length is defined by the remaining message length when subtracting the header and other fields. The entire content of this block is opaque unless you understand any the encoding message_type. The particular encoding used can be extension specific and might not always be documented as part of the mavlink specification.
+
+
+ Message implementing parts of the V2 payload specs in V1 frames for transitional support.
+ Network ID (0 for broadcast)
+ System ID (0 for broadcast)
+ Component ID (0 for broadcast)
+ A code that identifies the software component that understands this message (analogous to usb device classes or mime type strings). If this code is less than 32768, it is considered a 'registered' protocol extension and the corresponding entry should be added to https://github.com/mavlink/mavlink/extension-message-ids.xml. Software creators can register blocks of message IDs as needed (useful for GCS specific metadata, etc...). Message_types greater than 32767 are considered local experiments and should not be checked in to any widely distributed codebase.
+ Variable length payload. The length is defined by the remaining message length when subtracting the header and other fields. The entire content of this block is opaque unless you understand any the encoding message_type. The particular encoding used can be extension specific and might not always be documented as part of the mavlink specification.
+
+
+ Send raw controller memory. The use of this message is discouraged for normal packets, but a quite efficient way for testing new messages and getting experimental debug output.
+ Starting address of the debug variables
+ Version code of the type variable. 0=unknown, type ignored and assumed int16_t. 1=as below
+ Type code of the memory variables. for ver = 1: 0=16 x int16_t, 1=16 x uint16_t, 2=16 x Q15, 3=16 x 1Q14
+ Memory contents at specified address
+
+
+ Name
+ Timestamp
+ x
+ y
+ z
+
+
+ Send a key-value pair as float. The use of this message is discouraged for normal packets, but a quite efficient way for testing new messages and getting experimental debug output.
+ Timestamp (milliseconds since system boot)
+ Name of the debug variable
+ Floating point value
+
+
+ Send a key-value pair as integer. The use of this message is discouraged for normal packets, but a quite efficient way for testing new messages and getting experimental debug output.
+ Timestamp (milliseconds since system boot)
+ Name of the debug variable
+ Signed integer value
+
+
+ Status text message. These messages are printed in yellow in the COMM console of QGroundControl. WARNING: They consume quite some bandwidth, so use only for important status and error messages. If implemented wisely, these messages are buffered on the MCU and sent only at a limited rate (e.g. 10 Hz).
+ Severity of status. Relies on the definitions within RFC-5424. See enum MAV_SEVERITY.
+ Status text message, without null termination character
+
+
+ Send a debug value. The index is used to discriminate between values. These values show up in the plot of QGroundControl as DEBUG N.
+ Timestamp (milliseconds since system boot)
+ index of debug variable
+ DEBUG value
+
+
+
diff --git a/mavlink-solo/message_definitions/v1.0/matrixpilot.xml b/mavlink-solo/message_definitions/v1.0/matrixpilot.xml
new file mode 100644
index 0000000..29d368d
--- /dev/null
+++ b/mavlink-solo/message_definitions/v1.0/matrixpilot.xml
@@ -0,0 +1,284 @@
+
+
+ common.xml
+
+
+
+
+
+
+
+ Action required when performing CMD_PREFLIGHT_STORAGE
+
+ Read all parameters from storage
+
+
+ Write all parameters to storage
+
+
+ Clear all parameters in storage
+
+
+ Read specific parameters from storage
+
+
+ Write specific parameters to storage
+
+
+ Clear specific parameters in storage
+
+
+ do nothing
+
+
+
+
+
+ Request storage of different parameter values and logs. This command will be only accepted if in pre-flight mode.
+ Storage action: Action defined by MAV_PREFLIGHT_STORAGE_ACTION_ADVANCED
+ Storage area as defined by parameter database
+ Storage flags as defined by parameter database
+ Empty
+ Empty
+ Empty
+ Empty
+
+
+
+
+
+
+
+
+ Depreciated but used as a compiler flag. Do not remove
+ System ID
+ Component ID
+
+
+ Reqest reading of flexifunction data
+ System ID
+ Component ID
+ Type of flexifunction data requested
+ index into data where needed
+
+
+ Flexifunction type and parameters for component at function index from buffer
+ System ID
+ Component ID
+ Function index
+ Total count of functions
+ Address in the flexifunction data, Set to 0xFFFF to use address in target memory
+ Size of the
+ Settings data
+
+
+ Flexifunction type and parameters for component at function index from buffer
+ System ID
+ Component ID
+ Function index
+ result of acknowledge, 0=fail, 1=good
+
+
+ Acknowldge sucess or failure of a flexifunction command
+ System ID
+ Component ID
+ 0=inputs, 1=outputs
+ index of first directory entry to write
+ count of directory entries to write
+ Settings data
+
+
+ Acknowldge sucess or failure of a flexifunction command
+ System ID
+ Component ID
+ 0=inputs, 1=outputs
+ index of first directory entry to write
+ count of directory entries to write
+ result of acknowledge, 0=fail, 1=good
+
+
+ Acknowldge sucess or failure of a flexifunction command
+ System ID
+ Component ID
+ Flexifunction command type
+
+
+ Acknowldge sucess or failure of a flexifunction command
+ Command acknowledged
+ result of acknowledge
+
+
+ Backwards compatible MAVLink version of SERIAL_UDB_EXTRA - F2: Format Part A
+ Serial UDB Extra Time
+ Serial UDB Extra Status
+ Serial UDB Extra Latitude
+ Serial UDB Extra Longitude
+ Serial UDB Extra Altitude
+ Serial UDB Extra Waypoint Index
+ Serial UDB Extra Rmat 0
+ Serial UDB Extra Rmat 1
+ Serial UDB Extra Rmat 2
+ Serial UDB Extra Rmat 3
+ Serial UDB Extra Rmat 4
+ Serial UDB Extra Rmat 5
+ Serial UDB Extra Rmat 6
+ Serial UDB Extra Rmat 7
+ Serial UDB Extra Rmat 8
+ Serial UDB Extra GPS Course Over Ground
+ Serial UDB Extra Speed Over Ground
+ Serial UDB Extra CPU Load
+ Serial UDB Extra Voltage in MilliVolts
+ Serial UDB Extra 3D IMU Air Speed
+ Serial UDB Extra Estimated Wind 0
+ Serial UDB Extra Estimated Wind 1
+ Serial UDB Extra Estimated Wind 2
+ Serial UDB Extra Magnetic Field Earth 0
+ Serial UDB Extra Magnetic Field Earth 1
+ Serial UDB Extra Magnetic Field Earth 2
+ Serial UDB Extra Number of Sattelites in View
+ Serial UDB Extra GPS Horizontal Dilution of Precision
+
+
+ Backwards compatible version of SERIAL_UDB_EXTRA - F2: Part B
+ Serial UDB Extra Time
+ Serial UDB Extra PWM Input Channel 1
+ Serial UDB Extra PWM Input Channel 2
+ Serial UDB Extra PWM Input Channel 3
+ Serial UDB Extra PWM Input Channel 4
+ Serial UDB Extra PWM Input Channel 5
+ Serial UDB Extra PWM Input Channel 6
+ Serial UDB Extra PWM Input Channel 7
+ Serial UDB Extra PWM Input Channel 8
+ Serial UDB Extra PWM Input Channel 9
+ Serial UDB Extra PWM Input Channel 10
+ Serial UDB Extra PWM Output Channel 1
+ Serial UDB Extra PWM Output Channel 2
+ Serial UDB Extra PWM Output Channel 3
+ Serial UDB Extra PWM Output Channel 4
+ Serial UDB Extra PWM Output Channel 5
+ Serial UDB Extra PWM Output Channel 6
+ Serial UDB Extra PWM Output Channel 7
+ Serial UDB Extra PWM Output Channel 8
+ Serial UDB Extra PWM Output Channel 9
+ Serial UDB Extra PWM Output Channel 10
+ Serial UDB Extra IMU Location X
+ Serial UDB Extra IMU Location Y
+ Serial UDB Extra IMU Location Z
+ Serial UDB Extra Status Flags
+ Serial UDB Extra Oscillator Failure Count
+ Serial UDB Extra IMU Velocity X
+ Serial UDB Extra IMU Velocity Y
+ Serial UDB Extra IMU Velocity Z
+ Serial UDB Extra Current Waypoint Goal X
+ Serial UDB Extra Current Waypoint Goal Y
+ Serial UDB Extra Current Waypoint Goal Z
+ Serial UDB Extra Stack Memory Free
+
+
+ Backwards compatible version of SERIAL_UDB_EXTRA F4: format
+ Serial UDB Extra Roll Stabilization with Ailerons Enabled
+ Serial UDB Extra Roll Stabilization with Rudder Enabled
+ Serial UDB Extra Pitch Stabilization Enabled
+ Serial UDB Extra Yaw Stabilization using Rudder Enabled
+ Serial UDB Extra Yaw Stabilization using Ailerons Enabled
+ Serial UDB Extra Navigation with Ailerons Enabled
+ Serial UDB Extra Navigation with Rudder Enabled
+ Serial UDB Extra Type of Alitude Hold when in Stabilized Mode
+ Serial UDB Extra Type of Alitude Hold when in Waypoint Mode
+ Serial UDB Extra Firmware racing mode enabled
+
+
+ Backwards compatible version of SERIAL_UDB_EXTRA F5: format
+ Serial UDB YAWKP_AILERON Gain for Proporional control of navigation
+ Serial UDB YAWKD_AILERON Gain for Rate control of navigation
+ Serial UDB Extra ROLLKP Gain for Proportional control of roll stabilization
+ Serial UDB Extra ROLLKD Gain for Rate control of roll stabilization
+ YAW_STABILIZATION_AILERON Proportional control
+ Gain For Boosting Manual Aileron control When Plane Stabilized
+
+
+ Backwards compatible version of SERIAL_UDB_EXTRA F6: format
+ Serial UDB Extra PITCHGAIN Proportional Control
+ Serial UDB Extra Pitch Rate Control
+ Serial UDB Extra Rudder to Elevator Mix
+ Serial UDB Extra Roll to Elevator Mix
+ Gain For Boosting Manual Elevator control When Plane Stabilized
+
+
+ Backwards compatible version of SERIAL_UDB_EXTRA F7: format
+ Serial UDB YAWKP_RUDDER Gain for Proporional control of navigation
+ Serial UDB YAWKD_RUDDER Gain for Rate control of navigation
+ Serial UDB Extra ROLLKP_RUDDER Gain for Proportional control of roll stabilization
+ Serial UDB Extra ROLLKD_RUDDER Gain for Rate control of roll stabilization
+ SERIAL UDB EXTRA Rudder Boost Gain to Manual Control when stabilized
+ Serial UDB Extra Return To Landing - Angle to Pitch Plane Down
+
+
+ Backwards compatible version of SERIAL_UDB_EXTRA F8: format
+ Serial UDB Extra HEIGHT_TARGET_MAX
+ Serial UDB Extra HEIGHT_TARGET_MIN
+ Serial UDB Extra ALT_HOLD_THROTTLE_MIN
+ Serial UDB Extra ALT_HOLD_THROTTLE_MAX
+ Serial UDB Extra ALT_HOLD_PITCH_MIN
+ Serial UDB Extra ALT_HOLD_PITCH_MAX
+ Serial UDB Extra ALT_HOLD_PITCH_HIGH
+
+
+ Backwards compatible version of SERIAL_UDB_EXTRA F13: format
+ Serial UDB Extra GPS Week Number
+ Serial UDB Extra MP Origin Latitude
+ Serial UDB Extra MP Origin Longitude
+ Serial UDB Extra MP Origin Altitude Above Sea Level
+
+
+ Backwards compatible version of SERIAL_UDB_EXTRA F14: format
+ Serial UDB Extra Wind Estimation Enabled
+ Serial UDB Extra Type of GPS Unit
+ Serial UDB Extra Dead Reckoning Enabled
+ Serial UDB Extra Type of UDB Hardware
+ Serial UDB Extra Type of Airframe
+ Serial UDB Extra Reboot Regitster of DSPIC
+ Serial UDB Extra Last dspic Trap Flags
+ Serial UDB Extra Type Program Address of Last Trap
+ Serial UDB Extra Number of Ocillator Failures
+ Serial UDB Extra UDB Internal Clock Configuration
+ Serial UDB Extra Type of Flight Plan
+
+
+ Backwards compatible version of SERIAL_UDB_EXTRA F15 and F16: format
+ Serial UDB Extra Model Name Of Vehicle
+ Serial UDB Extra Registraton Number of Vehicle
+
+
+ Serial UDB Extra Name of Expected Lead Pilot
+ Serial UDB Extra URL of Lead Pilot or Team
+
+
+ The altitude measured by sensors and IMU
+ Timestamp (milliseconds since system boot)
+ GPS altitude in meters, expressed as * 1000 (millimeters), above MSL
+ IMU altitude above ground in meters, expressed as * 1000 (millimeters)
+ barometeric altitude above ground in meters, expressed as * 1000 (millimeters)
+ Optical flow altitude above ground in meters, expressed as * 1000 (millimeters)
+ Rangefinder Altitude above ground in meters, expressed as * 1000 (millimeters)
+ Extra altitude above ground in meters, expressed as * 1000 (millimeters)
+
+
+ The airspeed measured by sensors and IMU
+ Timestamp (milliseconds since system boot)
+ Airspeed estimate from IMU, cm/s
+ Pitot measured forward airpseed, cm/s
+ Hot wire anenometer measured airspeed, cm/s
+ Ultrasonic measured airspeed, cm/s
+ Angle of attack sensor, degrees * 10
+ Yaw angle sensor, degrees * 10
+
+
+
+
diff --git a/mavlink-solo/message_definitions/v1.0/minimal.xml b/mavlink-solo/message_definitions/v1.0/minimal.xml
new file mode 100644
index 0000000..88985a5
--- /dev/null
+++ b/mavlink-solo/message_definitions/v1.0/minimal.xml
@@ -0,0 +1,189 @@
+
+
+ 2
+
+
+ Micro air vehicle / autopilot classes. This identifies the individual model.
+
+ Generic autopilot, full support for everything
+
+
+ PIXHAWK autopilot, http://pixhawk.ethz.ch
+
+
+ SLUGS autopilot, http://slugsuav.soe.ucsc.edu
+
+
+ ArduPilotMega / ArduCopter, http://diydrones.com
+
+
+ OpenPilot, http://openpilot.org
+
+
+ Generic autopilot only supporting simple waypoints
+
+
+ Generic autopilot supporting waypoints and other simple navigation commands
+
+
+ Generic autopilot supporting the full mission command set
+
+
+ No valid autopilot, e.g. a GCS or other MAVLink component
+
+
+ PPZ UAV - http://nongnu.org/paparazzi
+
+
+ UAV Dev Board
+
+
+ FlexiPilot
+
+
+
+
+ Generic micro air vehicle.
+
+
+ Fixed wing aircraft.
+
+
+ Quadrotor
+
+
+ Coaxial helicopter
+
+
+ Normal helicopter with tail rotor.
+
+
+ Ground installation
+
+
+ Operator control unit / ground control station
+
+
+ Airship, controlled
+
+
+ Free balloon, uncontrolled
+
+
+ Rocket
+
+
+ Ground rover
+
+
+ Surface vessel, boat, ship
+
+
+ Submarine
+
+
+ Hexarotor
+
+
+ Octorotor
+
+
+ Octorotor
+
+
+ Flapping wing
+
+
+
+ These flags encode the MAV mode.
+
+ 0b10000000 MAV safety set to armed. Motors are enabled / running / can start. Ready to fly.
+
+
+ 0b01000000 remote control input is enabled.
+
+
+ 0b00100000 hardware in the loop simulation. All motors / actuators are blocked, but internal software is full operational.
+
+
+ 0b00010000 system stabilizes electronically its attitude (and optionally position). It needs however further control inputs to move around.
+
+
+ 0b00001000 guided mode enabled, system flies MISSIONs / mission items.
+
+
+ 0b00000100 autonomous mode enabled, system finds its own goal positions. Guided flag can be set or not, depends on the actual implementation.
+
+
+ 0b00000010 system has a test mode enabled. This flag is intended for temporary system tests and should not be used for stable implementations.
+
+
+ 0b00000001 Reserved for future use.
+
+
+
+ These values encode the bit positions of the decode position. These values can be used to read the value of a flag bit by combining the base_mode variable with AND with the flag position value. The result will be either 0 or 1, depending on if the flag is set or not.
+
+ First bit: 10000000
+
+
+ Second bit: 01000000
+
+
+ Third bit: 00100000
+
+
+ Fourth bit: 00010000
+
+
+ Fifth bit: 00001000
+
+
+ Sixt bit: 00000100
+
+
+ Seventh bit: 00000010
+
+
+ Eighth bit: 00000001
+
+
+
+
+ Uninitialized system, state is unknown.
+
+
+ System is booting up.
+
+
+ System is calibrating and not flight-ready.
+
+
+ System is grounded and on standby. It can be launched any time.
+
+
+ System is active and might be already airborne. Motors are engaged.
+
+
+ System is in a non-normal flight mode. It can however still navigate.
+
+
+ System is in a non-normal flight mode. It lost control over parts or over the whole airframe. It is in mayday and going down.
+
+
+ System just initialized its power-down sequence, will shut down now.
+
+
+
+
+
+ The heartbeat message shows that a system is present and responding. The type of the MAV and Autopilot hardware allow the receiving system to treat further messages from this system appropriate (e.g. by laying out the user interface based on the autopilot).
+ Type of the MAV (quadrotor, helicopter, etc., up to 15 types, defined in MAV_TYPE ENUM)
+ Autopilot type / class. defined in MAV_AUTOPILOT ENUM
+ System mode bitfield, see MAV_MODE_FLAGS ENUM in mavlink/include/mavlink_types.h
+ A bitfield for use for autopilot-specific flags.
+ System status flag, see MAV_STATE ENUM
+ MAVLink version
+
+
+
diff --git a/mavlink-solo/message_definitions/v1.0/pixhawk.xml b/mavlink-solo/message_definitions/v1.0/pixhawk.xml
new file mode 100644
index 0000000..91d1bf2
--- /dev/null
+++ b/mavlink-solo/message_definitions/v1.0/pixhawk.xml
@@ -0,0 +1,227 @@
+
+
+ common.xml
+
+
+ Content Types for data transmission handshake
+
+
+
+
+
+
+
+ Starts a search
+ 1 to arm, 0 to disarm
+
+
+ Starts a search
+ 1 to arm, 0 to disarm
+
+
+ Starts a search
+ 1 to arm, 0 to disarm
+
+
+
+
+
+ Camera id
+ Camera mode: 0 = auto, 1 = manual
+ Trigger pin, 0-3 for PtGrey FireFly
+ Shutter interval, in microseconds
+ Exposure time, in microseconds
+ Camera gain
+
+
+ Timestamp
+ IMU seq
+ Roll angle in rad
+ Pitch angle in rad
+ Yaw angle in rad
+ Local frame Z coordinate (height over ground)
+ GPS X coordinate
+ GPS Y coordinate
+ Global frame altitude
+ Ground truth X
+ Ground truth Y
+ Ground truth Z
+
+
+ 0 to disable, 1 to enable
+
+
+ Camera id
+ Camera # (starts with 0)
+ Timestamp
+ Until which timestamp this buffer will stay valid
+ The image sequence number
+ Position of the image in the buffer, starts with 0
+ Image width
+ Image height
+ Image depth
+ Image channels
+ Shared memory area key
+ Exposure time, in microseconds
+ Camera gain
+ Roll angle in rad
+ Pitch angle in rad
+ Yaw angle in rad
+ Local frame Z coordinate (height over ground)
+ GPS X coordinate
+ GPS Y coordinate
+ Global frame altitude
+ Ground truth X
+ Ground truth Y
+ Ground truth Z
+
+
+ Message sent to the MAV to set a new offset from the currently controlled position
+ System ID
+ Component ID
+ x position offset
+ y position offset
+ z position offset
+ yaw orientation offset in radians, 0 = NORTH
+
+
+
+ ID of waypoint, 0 for plain position
+ x position
+ y position
+ z position
+ yaw orientation in radians, 0 = NORTH
+
+
+ ID
+ x position
+ y position
+ z position
+ roll orientation
+ pitch orientation
+ yaw orientation
+
+
+ ADC1 (J405 ADC3, LPC2148 AD0.6)
+ ADC2 (J405 ADC5, LPC2148 AD0.2)
+ ADC3 (J405 ADC6, LPC2148 AD0.1)
+ ADC4 (J405 ADC7, LPC2148 AD1.3)
+ Battery voltage
+ Temperature (degrees celcius)
+ Barometric pressure (hecto Pascal)
+
+
+ Watchdog ID
+ Number of processes
+
+
+ Watchdog ID
+ Process ID
+ Process name
+ Process arguments
+ Timeout (seconds)
+
+
+ Watchdog ID
+ Process ID
+ Is running / finished / suspended / crashed
+ Is muted
+ PID
+ Number of crashes
+
+
+ Target system ID
+ Watchdog ID
+ Process ID
+ Command ID
+
+
+ 0: Pattern, 1: Letter
+ Confidence of detection
+ Pattern file name
+ Accepted as true detection, 0 no, 1 yes
+
+
+ Notifies the operator about a point of interest (POI). This can be anything detected by the
+ system. This generic message is intented to help interfacing to generic visualizations and to display
+ the POI on a map.
+
+ 0: Notice, 1: Warning, 2: Critical, 3: Emergency, 4: Debug
+ 0: blue, 1: yellow, 2: red, 3: orange, 4: green, 5: magenta
+ 0: global, 1:local
+ 0: no timeout, >1: timeout in seconds
+ X Position
+ Y Position
+ Z Position
+ POI name
+
+
+ Notifies the operator about the connection of two point of interests (POI). This can be anything detected by the
+ system. This generic message is intented to help interfacing to generic visualizations and to display
+ the POI on a map.
+
+ 0: Notice, 1: Warning, 2: Critical, 3: Emergency, 4: Debug
+ 0: blue, 1: yellow, 2: red, 3: orange, 4: green, 5: magenta
+ 0: global, 1:local
+ 0: no timeout, >1: timeout in seconds
+ X1 Position
+ Y1 Position
+ Z1 Position
+ X2 Position
+ Y2 Position
+ Z2 Position
+ POI connection name
+
+
+ x position in m
+ y position in m
+ z position in m
+ Orientation assignment 0: false, 1:true
+ Size in pixels
+ Orientation
+ Descriptor
+ Harris operator response at this location
+
+
+ The system to be controlled
+ roll
+ pitch
+ yaw
+ thrust
+ roll control enabled auto:0, manual:1
+ pitch auto:0, manual:1
+ yaw auto:0, manual:1
+ thrust auto:0, manual:1
+
+
+ Number of detections
+ Number of cluster iterations
+ Best score
+ Latitude of the best detection * 1E7
+ Longitude of the best detection * 1E7
+ Altitude of the best detection * 1E3
+ Best detection ID
+ Best cluster ID
+ Best cluster ID
+ Number of images already processed
+ Number of images still to process
+ Average images per seconds processed
+
+
+ Uptime of system
+ CPU frequency
+ CPU load in percent
+ RAM usage in percent
+ RAM size in GiB
+ Swap usage in percent
+ Swap size in GiB
+ Disk health (-1: N/A, 0: ERR, 1: RO, 2: RW)
+ Disk usage in percent
+ Disk total in GiB
+ Temperature
+ Supply voltage V
+ Network load inbound KiB/s
+ Network load outbound in KiB/s
+
+
+
diff --git a/mavlink-solo/message_definitions/v1.0/python_array_test.xml b/mavlink-solo/message_definitions/v1.0/python_array_test.xml
new file mode 100644
index 0000000..f230d01
--- /dev/null
+++ b/mavlink-solo/message_definitions/v1.0/python_array_test.xml
@@ -0,0 +1,67 @@
+
+
+
+common.xml
+
+
+ Array test #0.
+ Stub field
+ Value array
+ Value array
+ Value array
+ Value array
+
+
+ Array test #1.
+ Value array
+
+
+ Array test #3.
+ Stub field
+ Value array
+
+
+ Array test #4.
+ Value array
+ Stub field
+
+
+ Array test #5.
+ Value array
+ Value array
+
+
+ Array test #6.
+ Stub field
+ Stub field
+ Stub field
+ Value array
+ Value array
+ Value array
+ Value array
+ Value array
+ Value array
+ Value array
+ Value array
+ Value array
+
+
+ Array test #7.
+ Value array
+ Value array
+ Value array
+ Value array
+ Value array
+ Value array
+ Value array
+ Value array
+ Value array
+
+
+ Array test #8.
+ Stub field
+ Value array
+ Value array
+
+
+
diff --git a/mavlink-solo/message_definitions/v1.0/slugs.xml b/mavlink-solo/message_definitions/v1.0/slugs.xml
new file mode 100755
index 0000000..a985eab
--- /dev/null
+++ b/mavlink-solo/message_definitions/v1.0/slugs.xml
@@ -0,0 +1,339 @@
+
+
+ common.xml
+
+
+
+
+
+ Does nothing.
+ 1 to arm, 0 to disarm
+
+
+
+
+
+ Return vehicle to base.
+ 0: return to base, 1: track mobile base
+
+
+ Stops the vehicle from returning to base and resumes flight.
+
+
+ Turns the vehicle's visible or infrared lights on or off.
+ 0: visible lights, 1: infrared lights
+ 0: turn on, 1: turn off
+
+
+ Requests vehicle to send current mid-level commands to ground station.
+
+
+ Requests storage of mid-level commands.
+ Mid-level command storage: 0: read from flash/EEPROM, 1: write to flash/EEPROM
+
+
+
+
+
+ Slugs-specific navigation modes.
+
+ No change to SLUGS mode.
+
+
+ Vehicle is in liftoff mode.
+
+
+ Vehicle is in passthrough mode, being controlled by a pilot.
+
+
+ Vehicle is in waypoint mode, navigating to waypoints.
+
+
+ Vehicle is executing mid-level commands.
+
+
+ Vehicle is returning to the home location.
+
+
+ Vehicle is landing.
+
+
+ Lost connection with vehicle.
+
+
+ Vehicle is in selective passthrough mode, where selected surfaces are being manually controlled.
+
+
+ Vehicle is in ISR mode, performing reconaissance at a point specified by ISR_LOCATION message.
+
+
+ Vehicle is patrolling along lines between waypoints.
+
+
+ Vehicle is grounded or an error has occurred.
+
+
+
+
+ These flags encode the control surfaces for selective passthrough mode. If a bit is set then the pilot console
+ has control of the surface, and if not then the autopilot has control of the surface.
+
+ 0b10000000 Throttle control passes through to pilot console.
+
+
+ 0b01000000 Left aileron control passes through to pilot console.
+
+
+ 0b00100000 Right aileron control passes through to pilot console.
+
+
+ 0b00010000 Rudder control passes through to pilot console.
+
+
+ 0b00001000 Left elevator control passes through to pilot console.
+
+
+ 0b00000100 Right elevator control passes through to pilot console.
+
+
+ 0b00000010 Left flap control passes through to pilot console.
+
+
+ 0b00000001 Right flap control passes through to pilot console.
+
+
+
+
+
+
+
+ Sensor and DSC control loads.
+ Sensor DSC Load
+ Control DSC Load
+ Battery Voltage in millivolts
+
+
+
+ Accelerometer and gyro biases.
+ Accelerometer X bias (m/s)
+ Accelerometer Y bias (m/s)
+ Accelerometer Z bias (m/s)
+ Gyro X bias (rad/s)
+ Gyro Y bias (rad/s)
+ Gyro Z bias (rad/s)
+
+
+
+ Configurable diagnostic messages.
+ Diagnostic float 1
+ Diagnostic float 2
+ Diagnostic float 3
+ Diagnostic short 1
+ Diagnostic short 2
+ Diagnostic short 3
+
+
+
+ Data used in the navigation algorithm.
+ Measured Airspeed prior to the nav filter in m/s
+ Commanded Roll
+ Commanded Pitch
+ Commanded Turn rate
+ Y component of the body acceleration
+ Total Distance to Run on this leg of Navigation
+ Remaining distance to Run on this leg of Navigation
+ Origin WP
+ Destination WP
+ Commanded altitude in 0.1 m
+
+
+
+ Configurable data log probes to be used inside Simulink
+ Log value 1
+ Log value 2
+ Log value 3
+ Log value 4
+ Log value 5
+ Log value 6
+
+
+
+ Pilot console PWM messges.
+ Year reported by Gps
+ Month reported by Gps
+ Day reported by Gps
+ Hour reported by Gps
+ Min reported by Gps
+ Sec reported by Gps
+ Clock Status. See table 47 page 211 OEMStar Manual
+ Visible satellites reported by Gps
+ Used satellites in Solution
+ GPS+GLONASS satellites in Solution
+ GPS and GLONASS usage mask (bit 0 GPS_used? bit_4 GLONASS_used?)
+ Percent used GPS
+
+
+
+ Mid Level commands sent from the GS to the autopilot. These are only sent when being operated in mid-level commands mode from the ground.
+ The system setting the commands
+ Commanded Altitude in meters
+ Commanded Airspeed in m/s
+ Commanded Turnrate in rad/s
+
+
+
+ This message sets the control surfaces for selective passthrough mode.
+ The system setting the commands
+ Bitfield containing the passthrough configuration, see CONTROL_SURFACE_FLAG ENUM.
+
+
+
+ Orders generated to the SLUGS camera mount.
+ The system reporting the action
+ Order the mount to pan: -1 left, 0 No pan motion, +1 right
+ Order the mount to tilt: -1 down, 0 No tilt motion, +1 up
+ Order the zoom values 0 to 10
+ Orders the camera mount to move home. The other fields are ignored when this field is set. 1: move home, 0 ignored
+
+
+
+ Control for surface; pending and order to origin.
+ The system setting the commands
+ ID control surface send 0: throttle 1: aileron 2: elevator 3: rudder
+ Pending
+ Order to origin
+
+
+
+
+
+
+ Transmits the last known position of the mobile GS to the UAV. Very relevant when Track Mobile is enabled
+ The system reporting the action
+ Mobile Latitude
+ Mobile Longitude
+
+
+
+ Control for camara.
+ The system setting the commands
+ ID 0: brightness 1: aperture 2: iris 3: ICR 4: backlight
+ 1: up/on 2: down/off 3: auto/reset/no action
+
+
+
+ Transmits the position of watch
+ The system reporting the action
+ ISR Latitude
+ ISR Longitude
+ ISR Height
+ Option 1
+ Option 2
+ Option 3
+
+
+
+
+
+
+ Transmits the readings from the voltage and current sensors
+ It is the value of reading 2: 0 - Current, 1 - Foreward Sonar, 2 - Back Sonar, 3 - RPM
+ Voltage in uS of PWM. 0 uS = 0V, 20 uS = 21.5V
+ Depends on the value of r2Type (0) Current consumption in uS of PWM, 20 uS = 90Amp (1) Distance in cm (2) Distance in cm (3) Absolute value
+
+
+
+ Transmits the actual Pan, Tilt and Zoom values of the camera unit
+ The actual Zoom Value
+ The Pan value in 10ths of degree
+ The Tilt value in 10ths of degree
+
+
+
+ Transmits the actual status values UAV in flight
+ The ID system reporting the action
+ Latitude UAV
+ Longitude UAV
+ Altitude UAV
+ Speed UAV
+ Course UAV
+
+
+
+ This contains the status of the GPS readings
+ Number of times checksum has failed
+ The quality indicator, 0=fix not available or invalid, 1=GPS fix, 2=C/A differential GPS, 6=Dead reckoning mode, 7=Manual input mode (fixed position), 8=Simulator mode, 9= WAAS a
+ Indicates if GN, GL or GP messages are being received
+ A = data valid, V = data invalid
+ Magnetic variation, degrees
+ Magnetic variation direction E/W. Easterly variation (E) subtracts from True course and Westerly variation (W) adds to True course
+ Positioning system mode indicator. A - Autonomous;D-Differential; E-Estimated (dead reckoning) mode;M-Manual input; N-Data not valid
+
+
+
+ Transmits the diagnostics data from the Novatel OEMStar GPS
+ The Time Status. See Table 8 page 27 Novatel OEMStar Manual
+ Status Bitfield. See table 69 page 350 Novatel OEMstar Manual
+ solution Status. See table 44 page 197
+ position type. See table 43 page 196
+ velocity type. See table 43 page 196
+ Age of the position solution in seconds
+ Times the CRC has failed since boot
+
+
+
+ Diagnostic data Sensor MCU
+ Float field 1
+ Float field 2
+ Int 16 field 1
+ Int 8 field 1
+
+
+
+
+ The boot message indicates that a system is starting. The onboard software version allows to keep track of onboard soft/firmware revisions. This message allows the sensor and control MCUs to communicate version numbers on startup.
+ The onboard software version
+
+
+
diff --git a/mavlink-solo/message_definitions/v1.0/test.xml b/mavlink-solo/message_definitions/v1.0/test.xml
new file mode 100644
index 0000000..02bc032
--- /dev/null
+++ b/mavlink-solo/message_definitions/v1.0/test.xml
@@ -0,0 +1,31 @@
+
+
+ 3
+
+
+ Test all field types
+ char
+ string
+ uint8_t
+ uint16_t
+ uint32_t
+ uint64_t
+ int8_t
+ int16_t
+ int32_t
+ int64_t
+ float
+ double
+ uint8_t_array
+ uint16_t_array
+ uint32_t_array
+ uint64_t_array
+ int8_t_array
+ int16_t_array
+ int32_t_array
+ int64_t_array
+ float_array
+ double_array
+
+
+
diff --git a/mavlink-solo/message_definitions/v1.0/ualberta.xml b/mavlink-solo/message_definitions/v1.0/ualberta.xml
new file mode 100644
index 0000000..bb57e84
--- /dev/null
+++ b/mavlink-solo/message_definitions/v1.0/ualberta.xml
@@ -0,0 +1,76 @@
+
+
+ common.xml
+
+
+ Available autopilot modes for ualberta uav
+
+ Raw input pulse widts sent to output
+
+
+ Inputs are normalized using calibration, the converted back to raw pulse widths for output
+
+
+ dfsdfs
+
+
+ dfsfds
+
+
+ dfsdfsdfs
+
+
+
+ Navigation filter mode
+
+
+ AHRS mode
+
+
+ INS/GPS initialization mode
+
+
+ INS/GPS mode
+
+
+
+ Mode currently commanded by pilot
+
+ sdf
+
+
+ dfs
+
+
+ Rotomotion mode
+
+
+
+
+
+ Accelerometer and Gyro biases from the navigation filter
+ Timestamp (microseconds)
+ b_f[0]
+ b_f[1]
+ b_f[2]
+ b_f[0]
+ b_f[1]
+ b_f[2]
+
+
+ Complete set of calibration parameters for the radio
+ Aileron setpoints: left, center, right
+ Elevator setpoints: nose down, center, nose up
+ Rudder setpoints: nose left, center, nose right
+ Tail gyro mode/gain setpoints: heading hold, rate mode
+ Pitch curve setpoints (every 25%)
+ Throttle curve setpoints (every 25%)
+
+
+ System status specific to ualberta uav
+ System mode, see UALBERTA_AUTOPILOT_MODE ENUM
+ Navigation mode, see UALBERTA_NAV_MODE ENUM
+ Pilot mode, see UALBERTA_PILOT_MODE
+
+
+
diff --git a/mavlink-solo/missionlib/mavlink_missionlib_data.h b/mavlink-solo/missionlib/mavlink_missionlib_data.h
new file mode 100644
index 0000000..c825fbc
--- /dev/null
+++ b/mavlink-solo/missionlib/mavlink_missionlib_data.h
@@ -0,0 +1,58 @@
+/*******************************************************************************
+
+ Copyright (C) 2011 Lorenz Meier lm ( a t ) inf.ethz.ch
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ ****************************************************************************/
+
+/* This assumes you have the mavlink headers on your include path
+ or in the same folder as this source file */
+
+// Disable auto-data structures
+#ifndef MAVLINK_NO_DATA
+#define MAVLINK_NO_DATA
+#endif
+
+#include "mavlink.h"
+#include
+
+/* MISSION LIB DATA STORAGE */
+
+enum MAVLINK_PM_PARAMETERS
+{
+ MAVLINK_PM_PARAM_SYSTEM_ID,
+ MAVLINK_PM_PARAM_ATT_K_D,
+ MAVLINK_PM_MAX_PARAM_COUNT // VERY IMPORTANT! KEEP THIS AS LAST ENTRY
+};
+
+
+/* DO NOT EDIT THIS FILE BELOW THIS POINT! */
+
+#ifndef MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN
+#define MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN 16
+#endif
+
+
+//extern void mavlink_pm_queued_send();
+struct mavlink_pm_storage {
+ char param_names[MAVLINK_PM_MAX_PARAM_COUNT][MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN]; ///< Parameter names
+ float param_values[MAVLINK_PM_MAX_PARAM_COUNT]; ///< Parameter values
+ uint16_t next_param;
+ uint16_t size;
+};
+
+typedef struct mavlink_pm_storage mavlink_pm_storage;
+
+void mavlink_pm_reset_params(mavlink_pm_storage* pm);
diff --git a/mavlink-solo/missionlib/mavlink_parameters.c b/mavlink-solo/missionlib/mavlink_parameters.c
new file mode 100644
index 0000000..18a05b3
--- /dev/null
+++ b/mavlink-solo/missionlib/mavlink_parameters.c
@@ -0,0 +1,150 @@
+/*******************************************************************************
+
+ Copyright (C) 2011 Lorenz Meier lm ( a t ) inf.ethz.ch
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ ****************************************************************************/
+
+#include "mavlink_missionlib_data.h"
+#include "mavlink_parameters.h"
+#include "math.h" /* isinf / isnan checks */
+
+extern mavlink_system_t mavlink_system;
+extern mavlink_pm_storage pm;
+
+extern void mavlink_missionlib_send_message(mavlink_message_t* msg);
+extern void mavlink_missionlib_send_gcs_string(const char* string);
+
+void mavlink_pm_message_handler(const mavlink_channel_t chan, const mavlink_message_t* msg)
+{
+ switch (msg->msgid)
+ {
+ case MAVLINK_MSG_ID_PARAM_REQUEST_LIST:
+ {
+ // Start sending parameters
+ pm.next_param = 0;
+ mavlink_missionlib_send_gcs_string("PM SENDING LIST");
+ }
+ break;
+ case MAVLINK_MSG_ID_PARAM_SET:
+ {
+ mavlink_param_set_t set;
+ mavlink_msg_param_set_decode(msg, &set);
+
+ // Check if this message is for this system
+ if (set.target_system == mavlink_system.sysid && set.target_component == mavlink_system.compid)
+ {
+ char* key = set.param_id;
+
+ for (uint16_t i = 0; i < MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN; i++)
+ {
+ bool match = true;
+ for (uint16_t j = 0; j < MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN; j++)
+ {
+ // Compare
+ if (pm.param_names[i][j] != key[j])
+ {
+ match = false;
+ }
+
+ // End matching if null termination is reached
+ if (pm.param_names[i][j] == '\0')
+ {
+ break;
+ }
+ }
+
+ // Check if matched
+ if (match)
+ {
+ // Only write and emit changes if there is actually a difference
+ // AND only write if new value is NOT "not-a-number"
+ // AND is NOT infinity
+ if (pm.param_values[i] != set.param_value
+ && !isnan(set.param_value)
+ && !isinf(set.param_value))
+ {
+ pm.param_values[i] = set.param_value;
+ // Report back new value
+#ifndef MAVLINK_USE_CONVENIENCE_FUNCTIONS
+ mavlink_message_t tx_msg;
+ mavlink_msg_param_value_pack_chan(mavlink_system.sysid,
+ mavlink_system.compid,
+ MAVLINK_COMM_0,
+ &tx_msg,
+ pm.param_names[i],
+ pm.param_values[i],
+ MAVLINK_TYPE_FLOAT,
+ pm.size,
+ i);
+ mavlink_missionlib_send_message(&tx_msg);
+#else
+ mavlink_msg_param_value_send(MAVLINK_COMM_0,
+ pm.param_names[i],
+ pm.param_values[i],
+ MAVLINK_TYPE_FLOAT,
+ pm.size,
+ i);
+#endif
+
+ mavlink_missionlib_send_gcs_string("PM received param");
+ } // End valid value check
+ } // End match check
+ } // End for loop
+ } // End system ID check
+
+ } // End case
+ break;
+
+ } // End switch
+
+}
+
+ /**
+ * @brief Send low-priority messages at a maximum rate of xx Hertz
+ *
+ * This function sends messages at a lower rate to not exceed the wireless
+ * bandwidth. It sends one message each time it is called until the buffer is empty.
+ * Call this function with xx Hertz to increase/decrease the bandwidth.
+ */
+ void mavlink_pm_queued_send(void)
+ {
+ //send parameters one by one
+ if (pm.next_param < pm.size)
+ {
+ //for (int i.. all active comm links)
+#ifndef MAVLINK_USE_CONVENIENCE_FUNCTIONS
+ mavlink_message_t tx_msg;
+ mavlink_msg_param_value_pack_chan(mavlink_system.sysid,
+ mavlink_system.compid,
+ MAVLINK_COMM_0,
+ &tx_msg,
+ pm.param_names[pm.next_param],
+ pm.param_values[pm.next_param],
+ MAVLINK_TYPE_FLOAT,
+ pm.size,
+ pm.next_param);
+ mavlink_missionlib_send_message(&tx_msg);
+#else
+ mavlink_msg_param_value_send(MAVLINK_COMM_0,
+ pm.param_names[pm.next_param],
+ pm.param_values[pm.next_param],
+ MAV_DATA_TYPE_FLOAT,
+ pm.size,
+ pm.next_param);
+#endif
+ pm.next_param++;
+ }
+ }
diff --git a/mavlink-solo/missionlib/mavlink_parameters.h b/mavlink-solo/missionlib/mavlink_parameters.h
new file mode 100644
index 0000000..0d7841f
--- /dev/null
+++ b/mavlink-solo/missionlib/mavlink_parameters.h
@@ -0,0 +1,38 @@
+/*******************************************************************************
+
+ Copyright (C) 2011 Lorenz Meier lm ( a t ) inf.ethz.ch
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ ****************************************************************************/
+
+/* This assumes you have the mavlink headers on your include path
+ or in the same folder as this source file */
+
+// Disable auto-data structures
+#ifndef MAVLINK_NO_DATA
+#define MAVLINK_NO_DATA
+#endif
+
+#include "mavlink.h"
+#include
+
+/* PARAMETER MANAGER - MISSION LIB */
+
+#ifndef MAVLINK_PM_TEXT_FEEDBACK
+#define MAVLINK_PM_TEXT_FEEDBACK 1 ///< Report back status information as text
+#endif
+
+void mavlink_pm_message_handler(const mavlink_channel_t chan, const mavlink_message_t* msg);
+void mavlink_pm_queued_send(void);
\ No newline at end of file
diff --git a/mavlink-solo/missionlib/testing/.gitignore b/mavlink-solo/missionlib/testing/.gitignore
new file mode 100644
index 0000000..0776965
--- /dev/null
+++ b/mavlink-solo/missionlib/testing/.gitignore
@@ -0,0 +1,3 @@
+*.o
+udptest
+build
diff --git a/mavlink-solo/missionlib/testing/Makefile b/mavlink-solo/missionlib/testing/Makefile
new file mode 100644
index 0000000..134aa47
--- /dev/null
+++ b/mavlink-solo/missionlib/testing/Makefile
@@ -0,0 +1,12 @@
+VERSION = 1.00
+CC = gcc
+CFLAGS = -I ../../include/common -Wall -Werror -DVERSION=\"$(MAVLINK_VERSION)\" -std=c99
+LDFLAGS = ""
+
+OBJ = udp.o
+
+udptest: $(OBJ)
+ $(CC) $(CFLAGS) -o udptest $(OBJ) $(LDFLAGS)
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c $<
\ No newline at end of file
diff --git a/mavlink-solo/missionlib/testing/main.c b/mavlink-solo/missionlib/testing/main.c
new file mode 100644
index 0000000..21aa1f7
--- /dev/null
+++ b/mavlink-solo/missionlib/testing/main.c
@@ -0,0 +1,373 @@
+/*******************************************************************************
+
+ Copyright (C) 2011 Lorenz Meier lm ( a t ) inf.ethz.ch
+ and Bryan Godbolt godbolt ( a t ) ualberta.ca
+
+ adapted from example written by Bryan Godbolt godbolt ( a t ) ualberta.ca
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ ****************************************************************************/
+/*
+ This program sends some data to qgroundcontrol using the mavlink protocol. The sent packets
+ cause qgroundcontrol to respond with heartbeats. Any settings or custom commands sent from
+ qgroundcontrol are printed by this program along with the heartbeats.
+
+
+ I compiled this program sucessfully on Ubuntu 10.04 with the following command
+
+ gcc -I ../../pixhawk/mavlink/include -o udp-server udp.c
+
+ the rt library is needed for the clock_gettime on linux
+ */
+/* These headers are for QNX, but should all be standard on unix/linux */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#if (defined __QNX__) | (defined __QNXNTO__)
+/* QNX specific headers */
+#include
+#else
+/* Linux / MacOS POSIX timer headers */
+#include
+#include
+#include
+#endif
+
+/* FIRST: MAVLink setup */
+//#define MAVLINK_CONFIGURED
+//#define MAVLINK_NO_DATA
+//#define MAVLINK_WPM_VERBOSE
+
+/* 0: Include MAVLink types */
+#include "mavlink_types.h"
+
+/* 1: Define mavlink system storage */
+mavlink_system_t mavlink_system;
+
+/* 2: Include actual protocol, REQUIRES mavlink_system */
+#include "mavlink.h"
+
+/* 3: Define waypoint helper functions */
+void mavlink_wpm_send_message(mavlink_message_t* msg);
+void mavlink_wpm_send_gcs_string(const char* string);
+uint64_t mavlink_wpm_get_system_timestamp();
+void mavlink_missionlib_send_message(mavlink_message_t* msg);
+void mavlink_missionlib_send_gcs_string(const char* string);
+uint64_t mavlink_missionlib_get_system_timestamp();
+
+/* 4: Include waypoint protocol */
+#include "waypoints.h"
+mavlink_wpm_storage wpm;
+
+
+#include "mavlink_missionlib_data.h"
+#include "mavlink_parameters.h"
+
+mavlink_pm_storage pm;
+
+/**
+ * @brief reset all parameters to default
+ * @warning DO NOT USE THIS IN FLIGHT!
+ */
+void mavlink_pm_reset_params(mavlink_pm_storage* pm)
+{
+ pm->size = MAVLINK_PM_MAX_PARAM_COUNT;
+ // 1) MAVLINK_PM_PARAM_SYSTEM_ID
+ pm->param_values[MAVLINK_PM_PARAM_SYSTEM_ID] = 12;
+ strcpy(pm->param_names[MAVLINK_PM_PARAM_SYSTEM_ID], "SYS_ID");
+ // 2) MAVLINK_PM_PARAM_ATT_K_D
+ pm->param_values[MAVLINK_PM_PARAM_ATT_K_D] = 0.3f;
+ strcpy(pm->param_names[MAVLINK_PM_PARAM_ATT_K_D], "ATT_K_D");
+}
+
+
+#define BUFFER_LENGTH 2041 // minimum buffer size that can be used with qnx (I don't know why)
+
+char help[] = "--help";
+
+
+char target_ip[100];
+
+float position[6] = {};
+int sock;
+struct sockaddr_in gcAddr;
+struct sockaddr_in locAddr;
+uint8_t buf[BUFFER_LENGTH];
+ssize_t recsize;
+socklen_t fromlen;
+int bytes_sent;
+mavlink_message_t msg;
+uint16_t len;
+int i = 0;
+unsigned int temp = 0;
+
+uint64_t microsSinceEpoch();
+
+
+
+
+/* Provide the interface functions for the waypoint manager */
+
+/*
+ * @brief Sends a MAVLink message over UDP
+ */
+
+void mavlink_missionlib_send_message(mavlink_message_t* msg)
+{
+ uint8_t buf[MAVLINK_MAX_PACKET_LEN];
+ uint16_t len = mavlink_msg_to_send_buffer(buf, msg);
+ uint16_t bytes_sent = sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof (struct sockaddr_in));
+
+ printf("SENT %d bytes\n", bytes_sent);
+}
+
+void mavlink_missionlib_send_gcs_string(const char* string)
+{
+ const int len = 50;
+ mavlink_statustext_t status;
+ int i = 0;
+ while (i < len - 1)
+ {
+ status.text[i] = string[i];
+ if (string[i] == '\0')
+ break;
+ i++;
+ }
+ status.text[i] = '\0'; // Enforce null termination
+ mavlink_message_t msg;
+
+ mavlink_msg_statustext_encode(mavlink_system.sysid, mavlink_system.compid, &msg, &status);
+ mavlink_missionlib_send_message(&msg);
+}
+
+uint64_t mavlink_missionlib_get_system_timestamp()
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return ((uint64_t)tv.tv_sec) * 1000000 + tv.tv_usec;
+}
+
+float roll, pitch, yaw;
+uint32_t latitude, longitude, altitude;
+uint16_t speedx, speedy, speedz;
+float rollspeed, pitchspeed, yawspeed;
+bool hilEnabled = false;
+
+int main(int argc, char* argv[])
+{
+ // Initialize MAVLink
+ mavlink_wpm_init(&wpm);
+ mavlink_system.sysid = 5;
+ mavlink_system.compid = 20;
+ mavlink_pm_reset_params(&pm);
+
+ int32_t ground_distance;
+ uint32_t time_ms;
+
+
+
+ // Create socket
+ sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
+ // Check if --help flag was used
+ if ((argc == 2) && (strcmp(argv[1], help) == 0))
+ {
+ printf("\n");
+ printf("\tUsage:\n\n");
+ printf("\t");
+ printf("%s", argv[0]);
+ printf(" \n");
+ printf("\tDefault for localhost: udp-server 127.0.0.1\n\n");
+ exit(EXIT_FAILURE);
+ }
+
+
+ // Change the target ip if parameter was given
+ strcpy(target_ip, "127.0.0.1");
+ if (argc == 2)
+ {
+ strcpy(target_ip, argv[1]);
+ }
+
+
+ memset(&locAddr, 0, sizeof(locAddr));
+ locAddr.sin_family = AF_INET;
+ locAddr.sin_addr.s_addr = INADDR_ANY;
+ locAddr.sin_port = htons(14551);
+
+ /* Bind the socket to port 14551 - necessary to receive packets from qgroundcontrol */
+ if (-1 == bind(sock,(struct sockaddr *)&locAddr, sizeof(struct sockaddr)))
+ {
+ perror("error bind failed");
+ close(sock);
+ exit(EXIT_FAILURE);
+ }
+
+ /* Attempt to make it non blocking */
+ if (fcntl(sock, F_SETFL, O_NONBLOCK | FASYNC) < 0)
+ {
+ fprintf(stderr, "error setting nonblocking: %s\n", strerror(errno));
+ close(sock);
+ exit(EXIT_FAILURE);
+ }
+
+
+ memset(&gcAddr, 0, sizeof(gcAddr));
+ gcAddr.sin_family = AF_INET;
+ gcAddr.sin_addr.s_addr = inet_addr(target_ip);
+ gcAddr.sin_port = htons(14550);
+
+
+ printf("MAVLINK MISSION LIBRARY EXAMPLE PROCESS INITIALIZATION DONE, RUNNING..\n");
+
+
+ for (;;)
+ {
+ bytes_sent = 0;
+
+ /* Send Heartbeat */
+ mavlink_msg_heartbeat_pack(mavlink_system.sysid, 200, &msg, MAV_TYPE_HELICOPTER, MAV_AUTOPILOT_GENERIC, 0, 0, 0);
+ len = mavlink_msg_to_send_buffer(buf, &msg);
+ bytes_sent += sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof(struct sockaddr_in));
+
+ /* Send Status */
+ mavlink_msg_sys_status_pack(1, 200, &msg, MAV_MODE_GUIDED_ARMED, 0, MAV_STATE_ACTIVE, 500, 7500, 0, 0, 0, 0, 0, 0, 0, 0);
+ len = mavlink_msg_to_send_buffer(buf, &msg);
+ bytes_sent += sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof (struct sockaddr_in));
+
+ /* Send Local Position */
+ mavlink_msg_local_position_ned_pack(mavlink_system.sysid, 200, &msg, microsSinceEpoch(),
+ position[0], position[1], position[2],
+ position[3], position[4], position[5]);
+ len = mavlink_msg_to_send_buffer(buf, &msg);
+ bytes_sent += sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof(struct sockaddr_in));
+
+ /* Send global position */
+ if (hilEnabled)
+ {
+ mavlink_msg_global_position_int_pack(mavlink_system.sysid, 200, &msg, time_ms, latitude, longitude, altitude, ground_distance, speedx, speedy, speedz, (yaw/M_PI)*180*100);
+ len = mavlink_msg_to_send_buffer(buf, &msg);
+ bytes_sent += sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof(struct sockaddr_in));
+ }
+
+ /* Send attitude */
+ mavlink_msg_attitude_pack(mavlink_system.sysid, 200, &msg, microsSinceEpoch(), roll, pitch, yaw, rollspeed, pitchspeed, yawspeed);
+ len = mavlink_msg_to_send_buffer(buf, &msg);
+ bytes_sent += sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof(struct sockaddr_in));
+
+ /* Send HIL outputs */
+ float roll_ailerons = 0; // -1 .. 1
+ float pitch_elevator = 0.2; // -1 .. 1
+ float yaw_rudder = 0.1; // -1 .. 1
+ float throttle = 0.9; // 0 .. 1
+ mavlink_msg_hil_controls_pack_chan(mavlink_system.sysid, mavlink_system.compid, MAVLINK_COMM_0, &msg, microsSinceEpoch(), roll_ailerons, pitch_elevator, yaw_rudder, throttle, mavlink_system.mode, mavlink_system.nav_mode, 0, 0, 0, 0);
+ len = mavlink_msg_to_send_buffer(buf, &msg);
+ bytes_sent += sendto(sock, buf, len, 0, (struct sockaddr*)&gcAddr, sizeof(struct sockaddr_in));
+
+ memset(buf, 0, BUFFER_LENGTH);
+ recsize = recvfrom(sock, (void *)buf, BUFFER_LENGTH, 0, (struct sockaddr *)&gcAddr, &fromlen);
+ if (recsize > 0)
+ {
+ // Something received - print out all bytes and parse packet
+ mavlink_message_t msg;
+ mavlink_status_t status;
+
+ printf("Bytes Received: %d\nDatagram: ", (int)recsize);
+ for (i = 0; i < recsize; ++i)
+ {
+ temp = buf[i];
+ printf("%02x ", (unsigned char)temp);
+ if (mavlink_parse_char(MAVLINK_COMM_0, buf[i], &msg, &status))
+ {
+ // Packet received
+ printf("\nReceived packet: SYS: %d, COMP: %d, LEN: %d, MSG ID: %d\n", msg.sysid, msg.compid, msg.len, msg.msgid);
+
+ // Handle packet with waypoint component
+ mavlink_wpm_message_handler(&msg);
+
+ // Handle packet with parameter component
+ mavlink_pm_message_handler(MAVLINK_COMM_0, &msg);
+
+ // Print HIL values sent to system
+ if (msg.msgid == MAVLINK_MSG_ID_HIL_STATE)
+ {
+ mavlink_hil_state_t hil;
+ mavlink_msg_hil_state_decode(&msg, &hil);
+ printf("Received HIL state:\n");
+ printf("R: %f P: %f Y: %f\n", hil.roll, hil.pitch, hil.yaw);
+ roll = hil.roll;
+ pitch = hil.pitch;
+ yaw = hil.yaw;
+ rollspeed = hil.rollspeed;
+ pitchspeed = hil.pitchspeed;
+ yawspeed = hil.yawspeed;
+ speedx = hil.vx;
+ speedy = hil.vy;
+ speedz = hil.vz;
+ latitude = hil.lat;
+ longitude = hil.lon;
+ altitude = hil.alt;
+ hilEnabled = true;
+ }
+ }
+ }
+ printf("\n");
+ }
+ memset(buf, 0, BUFFER_LENGTH);
+ usleep(10000); // Sleep 10 ms
+
+
+ // Send one parameter
+ mavlink_pm_queued_send();
+ }
+}
+
+
+/* QNX timer version */
+#if (defined __QNX__) | (defined __QNXNTO__)
+uint64_t microsSinceEpoch()
+{
+
+ struct timespec time;
+
+ uint64_t micros = 0;
+
+ clock_gettime(CLOCK_REALTIME, &time);
+ micros = (uint64_t)time.tv_sec * 100000 + time.tv_nsec/1000;
+
+ return micros;
+}
+#else
+uint64_t microsSinceEpoch()
+{
+
+ struct timeval tv;
+
+ uint64_t micros = 0;
+
+ gettimeofday(&tv, NULL);
+ micros = ((uint64_t)tv.tv_sec) * 1000000 + tv.tv_usec;
+
+ return micros;
+}
+#endif
\ No newline at end of file
diff --git a/mavlink-solo/missionlib/testing/mavlink_missionlib_data.h b/mavlink-solo/missionlib/testing/mavlink_missionlib_data.h
new file mode 100644
index 0000000..a040941
--- /dev/null
+++ b/mavlink-solo/missionlib/testing/mavlink_missionlib_data.h
@@ -0,0 +1,54 @@
+/*******************************************************************************
+
+ Copyright (C) 2011 Lorenz Meier lm ( a t ) inf.ethz.ch
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ ****************************************************************************/
+
+/* This assumes you have the mavlink headers on your include path
+ or in the same folder as this source file */
+
+// Disable auto-data structures
+#ifndef MAVLINK_NO_DATA
+#define MAVLINK_NO_DATA
+#endif
+
+#include "mavlink.h"
+#include
+
+/* MISSION LIB DATA STORAGE */
+
+enum MAVLINK_PM_PARAMETERS
+{
+ MAVLINK_PM_PARAM_SYSTEM_ID,
+ MAVLINK_PM_PARAM_ATT_K_D,
+ MAVLINK_PM_MAX_PARAM_COUNT // VERY IMPORTANT! KEEP THIS AS LAST ENTRY
+};
+
+
+/* DO NOT EDIT THIS FILE BELOW THIS POINT! */
+
+
+//extern void mavlink_pm_queued_send();
+struct mavlink_pm_storage {
+ char param_names[MAVLINK_PM_MAX_PARAM_COUNT][MAVLINK_MSG_PARAM_VALUE_FIELD_PARAM_ID_LEN]; ///< Parameter names
+ float param_values[MAVLINK_PM_MAX_PARAM_COUNT]; ///< Parameter values
+ uint16_t next_param;
+ uint16_t size;
+};
+
+typedef struct mavlink_pm_storage mavlink_pm_storage;
+
+void mavlink_pm_reset_params(mavlink_pm_storage* pm);
\ No newline at end of file
diff --git a/mavlink-solo/missionlib/testing/udptest.xcodeproj/project.pbxproj b/mavlink-solo/missionlib/testing/udptest.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..7bc7657
--- /dev/null
+++ b/mavlink-solo/missionlib/testing/udptest.xcodeproj/project.pbxproj
@@ -0,0 +1,222 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 45;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 348868D013F512010005F759 /* mavlink_parameters.c in Sources */ = {isa = PBXBuildFile; fileRef = 348868CF13F512010005F759 /* mavlink_parameters.c */; };
+ 34E8AFDB13F5064C001100AA /* waypoints.c in Sources */ = {isa = PBXBuildFile; fileRef = 34E8AFDA13F5064C001100AA /* waypoints.c */; };
+ 8DD76FAC0486AB0100D96B5E /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* main.c */; settings = {ATTRIBUTES = (); }; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 8DD76FAF0486AB0100D96B5E /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 8;
+ dstPath = /usr/share/man/man1/;
+ dstSubfolderSpec = 0;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 08FB7796FE84155DC02AAC07 /* main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; };
+ 348868CF13F512010005F759 /* mavlink_parameters.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mavlink_parameters.c; path = ../mavlink_parameters.c; sourceTree = SOURCE_ROOT; };
+ 348868D113F512080005F759 /* mavlink_parameters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mavlink_parameters.h; path = ../mavlink_parameters.h; sourceTree = SOURCE_ROOT; };
+ 34E8AFDA13F5064C001100AA /* waypoints.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = waypoints.c; path = ../waypoints.c; sourceTree = SOURCE_ROOT; };
+ 34E8AFDC13F50659001100AA /* waypoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = waypoints.h; path = ../waypoints.h; sourceTree = SOURCE_ROOT; };
+ 8DD76FB20486AB0100D96B5E /* udptest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = udptest; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 8DD76FAD0486AB0100D96B5E /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 08FB7794FE84155DC02AAC07 /* udptest */ = {
+ isa = PBXGroup;
+ children = (
+ 34E8AFDC13F50659001100AA /* waypoints.h */,
+ 08FB7795FE84155DC02AAC07 /* Source */,
+ C6A0FF2B0290797F04C91782 /* Documentation */,
+ 1AB674ADFE9D54B511CA2CBB /* Products */,
+ );
+ name = udptest;
+ sourceTree = "";
+ };
+ 08FB7795FE84155DC02AAC07 /* Source */ = {
+ isa = PBXGroup;
+ children = (
+ 348868D113F512080005F759 /* mavlink_parameters.h */,
+ 348868CF13F512010005F759 /* mavlink_parameters.c */,
+ 34E8AFDA13F5064C001100AA /* waypoints.c */,
+ 08FB7796FE84155DC02AAC07 /* main.c */,
+ );
+ name = Source;
+ sourceTree = "";
+ };
+ 1AB674ADFE9D54B511CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8DD76FB20486AB0100D96B5E /* udptest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ C6A0FF2B0290797F04C91782 /* Documentation */ = {
+ isa = PBXGroup;
+ children = (
+ );
+ name = Documentation;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 8DD76FA90486AB0100D96B5E /* udptest */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "udptest" */;
+ buildPhases = (
+ 8DD76FAB0486AB0100D96B5E /* Sources */,
+ 8DD76FAD0486AB0100D96B5E /* Frameworks */,
+ 8DD76FAF0486AB0100D96B5E /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = udptest;
+ productInstallPath = "$(HOME)/bin";
+ productName = udptest;
+ productReference = 8DD76FB20486AB0100D96B5E /* udptest */;
+ productType = "com.apple.product-type.tool";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 08FB7793FE84155DC02AAC07 /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "udptest" */;
+ compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
+ mainGroup = 08FB7794FE84155DC02AAC07 /* udptest */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 8DD76FA90486AB0100D96B5E /* udptest */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8DD76FAB0486AB0100D96B5E /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8DD76FAC0486AB0100D96B5E /* main.c in Sources */,
+ 34E8AFDB13F5064C001100AA /* waypoints.c in Sources */,
+ 348868D013F512010005F759 /* mavlink_parameters.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 1DEB928608733DD80010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INSTALL_PATH = /usr/local/bin;
+ PRODUCT_NAME = udptest;
+ };
+ name = Debug;
+ };
+ 1DEB928708733DD80010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_MODEL_TUNING = G5;
+ INSTALL_PATH = /usr/local/bin;
+ PRODUCT_NAME = udptest;
+ };
+ name = Release;
+ };
+ 1DEB928A08733DD80010E9CD /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ ../../include/,
+ ../../include/common/,
+ );
+ ONLY_ACTIVE_ARCH = YES;
+ PREBINDING = NO;
+ SDKROOT = macosx10.6;
+ };
+ name = Debug;
+ };
+ 1DEB928B08733DD80010E9CD /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ SDKROOT = macosx10.6;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "udptest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB928608733DD80010E9CD /* Debug */,
+ 1DEB928708733DD80010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "udptest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 1DEB928A08733DD80010E9CD /* Debug */,
+ 1DEB928B08733DD80010E9CD /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
+}
diff --git a/mavlink-solo/missionlib/waypoints.c b/mavlink-solo/missionlib/waypoints.c
new file mode 100644
index 0000000..44bddb6
--- /dev/null
+++ b/mavlink-solo/missionlib/waypoints.c
@@ -0,0 +1,1028 @@
+/*******************************************************************************
+
+ Copyright (C) 2011 Lorenz Meier lm ( a t ) inf.ethz.ch
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ ****************************************************************************/
+
+#include "waypoints.h"
+#include
+
+bool debug = true;
+bool verbose = true;
+
+extern mavlink_wpm_storage wpm;
+
+extern void mavlink_missionlib_send_message(mavlink_message_t* msg);
+extern void mavlink_missionlib_send_gcs_string(const char* string);
+extern uint64_t mavlink_missionlib_get_system_timestamp();
+extern void mavlink_missionlib_current_waypoint_changed(uint16_t index, float param1,
+ float param2, float param3, float param4, float param5_lat_x,
+ float param6_lon_y, float param7_alt_z, uint8_t frame, uint16_t command);
+
+
+#define MAVLINK_WPM_NO_PRINTF
+
+uint8_t mavlink_wpm_comp_id = MAV_COMP_ID_MISSIONPLANNER;
+
+void mavlink_wpm_init(mavlink_wpm_storage* state)
+{
+ // Set all waypoints to zero
+
+ // Set count to zero
+ state->size = 0;
+ state->max_size = MAVLINK_WPM_MAX_WP_COUNT;
+ state->current_state = MAVLINK_WPM_STATE_IDLE;
+ state->current_partner_sysid = 0;
+ state->current_partner_compid = 0;
+ state->timestamp_lastaction = 0;
+ state->timestamp_last_send_setpoint = 0;
+ state->timeout = MAVLINK_WPM_PROTOCOL_TIMEOUT_DEFAULT;
+ state->delay_setpoint = MAVLINK_WPM_SETPOINT_DELAY_DEFAULT;
+ state->idle = false; ///< indicates if the system is following the waypoints or is waiting
+ state->current_active_wp_id = -1; ///< id of current waypoint
+ state->yaw_reached = false; ///< boolean for yaw attitude reached
+ state->pos_reached = false; ///< boolean for position reached
+ state->timestamp_lastoutside_orbit = 0;///< timestamp when the MAV was last outside the orbit or had the wrong yaw value
+ state->timestamp_firstinside_orbit = 0;///< timestamp when the MAV was the first time after a waypoint change inside the orbit and had the correct yaw value
+
+}
+
+/*
+ * @brief Sends an waypoint ack message
+ */
+void mavlink_wpm_send_waypoint_ack(uint8_t sysid, uint8_t compid, uint8_t type)
+{
+ mavlink_message_t msg;
+ mavlink_mission_ack_t wpa;
+
+ wpa.target_system = wpm.current_partner_sysid;
+ wpa.target_component = wpm.current_partner_compid;
+ wpa.type = type;
+
+ mavlink_msg_mission_ack_encode(mavlink_system.sysid, mavlink_wpm_comp_id, &msg, &wpa);
+ mavlink_missionlib_send_message(&msg);
+
+ // FIXME TIMING usleep(paramClient->getParamValue("PROTOCOLDELAY"));
+
+ if (MAVLINK_WPM_TEXT_FEEDBACK)
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("Sent waypoint ACK");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Sent waypoint ack (%u) to ID %u\n", wpa.type, wpa.target_system);
+#endif
+ mavlink_missionlib_send_gcs_string("Sent waypoint ACK");
+ }
+}
+
+/*
+ * @brief Broadcasts the new target waypoint and directs the MAV to fly there
+ *
+ * This function broadcasts its new active waypoint sequence number and
+ * sends a message to the controller, advising it to fly to the coordinates
+ * of the waypoint with a given orientation
+ *
+ * @param seq The waypoint sequence number the MAV should fly to.
+ */
+void mavlink_wpm_send_waypoint_current(uint16_t seq)
+{
+ if(seq < wpm.size)
+ {
+ mavlink_mission_item_t *cur = &(wpm.waypoints[seq]);
+
+ mavlink_message_t msg;
+ mavlink_mission_current_t wpc;
+
+ wpc.seq = cur->seq;
+
+ mavlink_msg_mission_current_encode(mavlink_system.sysid, mavlink_wpm_comp_id, &msg, &wpc);
+ mavlink_missionlib_send_message(&msg);
+
+ // FIXME TIMING usleep(paramClient->getParamValue("PROTOCOLDELAY"));
+
+ if (MAVLINK_WPM_TEXT_FEEDBACK) mavlink_missionlib_send_gcs_string("Set current waypoint\n"); //// printf("Broadcasted new current waypoint %u\n", wpc.seq);
+ }
+ else
+ {
+ if (MAVLINK_WPM_TEXT_FEEDBACK) mavlink_missionlib_send_gcs_string("ERROR: wp index out of bounds\n");
+ }
+}
+
+/*
+ * @brief Directs the MAV to fly to a position
+ *
+ * Sends a message to the controller, advising it to fly to the coordinates
+ * of the waypoint with a given orientation
+ *
+ * @param seq The waypoint sequence number the MAV should fly to.
+ */
+void mavlink_wpm_send_setpoint(uint16_t seq)
+{
+ if(seq < wpm.size)
+ {
+ mavlink_mission_item_t *cur = &(wpm.waypoints[seq]);
+ mavlink_missionlib_current_waypoint_changed(cur->seq, cur->param1,
+ cur->param2, cur->param3, cur->param4, cur->x,
+ cur->y, cur->z, cur->frame, cur->command);
+
+ wpm.timestamp_last_send_setpoint = mavlink_missionlib_get_system_timestamp();
+ }
+ else
+ {
+ if (MAVLINK_WPM_TEXT_FEEDBACK) mavlink_missionlib_send_gcs_string("ERROR: Waypoint index out of bounds\n"); //// if (verbose) // printf("ERROR: index out of bounds\n");
+ }
+}
+
+void mavlink_wpm_send_waypoint_count(uint8_t sysid, uint8_t compid, uint16_t count)
+{
+ mavlink_message_t msg;
+ mavlink_mission_count_t wpc;
+
+ wpc.target_system = wpm.current_partner_sysid;
+ wpc.target_component = wpm.current_partner_compid;
+ wpc.count = count;
+
+ mavlink_msg_mission_count_encode(mavlink_system.sysid, mavlink_wpm_comp_id, &msg, &wpc);
+ mavlink_missionlib_send_message(&msg);
+
+ if (MAVLINK_WPM_TEXT_FEEDBACK) mavlink_missionlib_send_gcs_string("Sent waypoint count"); //// if (verbose) // printf("Sent waypoint count (%u) to ID %u\n", wpc.count, wpc.target_system);
+
+ // FIXME TIMING usleep(paramClient->getParamValue("PROTOCOLDELAY"));
+}
+
+void mavlink_wpm_send_waypoint(uint8_t sysid, uint8_t compid, uint16_t seq)
+{
+ if (seq < wpm.size)
+ {
+ mavlink_message_t msg;
+ mavlink_mission_item_t *wp = &(wpm.waypoints[seq]);
+ wp->target_system = wpm.current_partner_sysid;
+ wp->target_component = wpm.current_partner_compid;
+ mavlink_msg_mission_item_encode(mavlink_system.sysid, mavlink_wpm_comp_id, &msg, wp);
+ mavlink_missionlib_send_message(&msg);
+ if (MAVLINK_WPM_TEXT_FEEDBACK) mavlink_missionlib_send_gcs_string("Sent waypoint"); //// if (verbose) // printf("Sent waypoint %u to ID %u\n", wp->seq, wp->target_system);
+
+ // FIXME TIMING usleep(paramClient->getParamValue("PROTOCOLDELAY"));
+ }
+ else
+ {
+ if (MAVLINK_WPM_TEXT_FEEDBACK) mavlink_missionlib_send_gcs_string("ERROR: Waypoint index out of bounds\n");
+ }
+}
+
+void mavlink_wpm_send_waypoint_request(uint8_t sysid, uint8_t compid, uint16_t seq)
+{
+ if (seq < wpm.max_size)
+ {
+ mavlink_message_t msg;
+ mavlink_mission_request_t wpr;
+ wpr.target_system = wpm.current_partner_sysid;
+ wpr.target_component = wpm.current_partner_compid;
+ wpr.seq = seq;
+ mavlink_msg_mission_request_encode(mavlink_system.sysid, mavlink_wpm_comp_id, &msg, &wpr);
+ mavlink_missionlib_send_message(&msg);
+ if (MAVLINK_WPM_TEXT_FEEDBACK) mavlink_missionlib_send_gcs_string("Sent waypoint request"); //// if (verbose) // printf("Sent waypoint request %u to ID %u\n", wpr.seq, wpr.target_system);
+
+ // FIXME TIMING usleep(paramClient->getParamValue("PROTOCOLDELAY"));
+ }
+ else
+ {
+ if (MAVLINK_WPM_TEXT_FEEDBACK) mavlink_missionlib_send_gcs_string("ERROR: Waypoint index exceeds list capacity\n");
+ }
+}
+
+/*
+ * @brief emits a message that a waypoint reached
+ *
+ * This function broadcasts a message that a waypoint is reached.
+ *
+ * @param seq The waypoint sequence number the MAV has reached.
+ */
+void mavlink_wpm_send_waypoint_reached(uint16_t seq)
+{
+ mavlink_message_t msg;
+ mavlink_mission_item_reached_t wp_reached;
+
+ wp_reached.seq = seq;
+
+ mavlink_msg_mission_item_reached_encode(mavlink_system.sysid, mavlink_wpm_comp_id, &msg, &wp_reached);
+ mavlink_missionlib_send_message(&msg);
+
+ if (MAVLINK_WPM_TEXT_FEEDBACK) mavlink_missionlib_send_gcs_string("Sent waypoint reached message"); //// if (verbose) // printf("Sent waypoint %u reached message\n", wp_reached.seq);
+
+ // FIXME TIMING usleep(paramClient->getParamValue("PROTOCOLDELAY"));
+}
+
+//float mavlink_wpm_distance_to_segment(uint16_t seq, float x, float y, float z)
+//{
+// if (seq < wpm.size)
+// {
+// mavlink_mission_item_t *cur = waypoints->at(seq);
+//
+// const PxVector3 A(cur->x, cur->y, cur->z);
+// const PxVector3 C(x, y, z);
+//
+// // seq not the second last waypoint
+// if ((uint16_t)(seq+1) < wpm.size)
+// {
+// mavlink_mission_item_t *next = waypoints->at(seq+1);
+// const PxVector3 B(next->x, next->y, next->z);
+// const float r = (B-A).dot(C-A) / (B-A).lengthSquared();
+// if (r >= 0 && r <= 1)
+// {
+// const PxVector3 P(A + r*(B-A));
+// return (P-C).length();
+// }
+// else if (r < 0.f)
+// {
+// return (C-A).length();
+// }
+// else
+// {
+// return (C-B).length();
+// }
+// }
+// else
+// {
+// return (C-A).length();
+// }
+// }
+// else
+// {
+// // if (verbose) // printf("ERROR: index out of bounds\n");
+// }
+// return -1.f;
+//}
+
+float mavlink_wpm_distance_to_point(uint16_t seq, float x, float y, float z)
+{
+// if (seq < wpm.size)
+// {
+// mavlink_mission_item_t *cur = waypoints->at(seq);
+//
+// const PxVector3 A(cur->x, cur->y, cur->z);
+// const PxVector3 C(x, y, z);
+//
+// return (C-A).length();
+// }
+// else
+// {
+// // if (verbose) // printf("ERROR: index out of bounds\n");
+// }
+ return -1.f;
+}
+
+void mavlink_wpm_loop()
+{
+ //check for timed-out operations
+ uint64_t now = mavlink_missionlib_get_system_timestamp();
+ if (now-wpm.timestamp_lastaction > wpm.timeout && wpm.current_state != MAVLINK_WPM_STATE_IDLE)
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("Operation timeout switching -> IDLE");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Last operation (state=%u) timed out, changing state to MAVLINK_WPM_STATE_IDLE\n", wpm.current_state);
+#endif
+ wpm.current_state = MAVLINK_WPM_STATE_IDLE;
+ wpm.current_count = 0;
+ wpm.current_partner_sysid = 0;
+ wpm.current_partner_compid = 0;
+ wpm.current_wp_id = -1;
+
+ if(wpm.size == 0)
+ {
+ wpm.current_active_wp_id = -1;
+ }
+ }
+
+ if(now-wpm.timestamp_last_send_setpoint > wpm.delay_setpoint && wpm.current_active_wp_id < wpm.size)
+ {
+ mavlink_wpm_send_setpoint(wpm.current_active_wp_id);
+ }
+}
+
+void mavlink_wpm_message_handler(const mavlink_message_t* msg)
+{
+ uint64_t now = mavlink_missionlib_get_system_timestamp();
+ switch(msg->msgid)
+ {
+ case MAVLINK_MSG_ID_ATTITUDE:
+ {
+ if(msg->sysid == mavlink_system.sysid && wpm.current_active_wp_id < wpm.size)
+ {
+ mavlink_mission_item_t *wp = &(wpm.waypoints[wpm.current_active_wp_id]);
+ if(wp->frame == MAV_FRAME_LOCAL_ENU || wp->frame == MAV_FRAME_LOCAL_NED)
+ {
+ mavlink_attitude_t att;
+ mavlink_msg_attitude_decode(msg, &att);
+ float yaw_tolerance = wpm.accept_range_yaw;
+ //compare current yaw
+ if (att.yaw - yaw_tolerance >= 0.0f && att.yaw + yaw_tolerance < 2.f*M_PI)
+ {
+ if (att.yaw - yaw_tolerance <= wp->param4 && att.yaw + yaw_tolerance >= wp->param4)
+ wpm.yaw_reached = true;
+ }
+ else if(att.yaw - yaw_tolerance < 0.0f)
+ {
+ float lowerBound = 360.0f + att.yaw - yaw_tolerance;
+ if (lowerBound < wp->param4 || wp->param4 < att.yaw + yaw_tolerance)
+ wpm.yaw_reached = true;
+ }
+ else
+ {
+ float upperBound = att.yaw + yaw_tolerance - 2.f*M_PI;
+ if (att.yaw - yaw_tolerance < wp->param4 || wp->param4 < upperBound)
+ wpm.yaw_reached = true;
+ }
+ }
+ }
+ break;
+ }
+
+ case MAVLINK_MSG_ID_LOCAL_POSITION_NED:
+ {
+ if(msg->sysid == mavlink_system.sysid && wpm.current_active_wp_id < wpm.size)
+ {
+ mavlink_mission_item_t *wp = &(wpm.waypoints[wpm.current_active_wp_id]);
+
+ if(wp->frame == MAV_FRAME_LOCAL_ENU || MAV_FRAME_LOCAL_NED)
+ {
+ mavlink_local_position_ned_t pos;
+ mavlink_msg_local_position_ned_decode(msg, &pos);
+ //// if (debug) // printf("Received new position: x: %f | y: %f | z: %f\n", pos.x, pos.y, pos.z);
+
+ wpm.pos_reached = false;
+
+ // compare current position (given in message) with current waypoint
+ float orbit = wp->param1;
+
+ float dist;
+// if (wp->param2 == 0)
+// {
+// // FIXME segment distance
+// //dist = mavlink_wpm_distance_to_segment(current_active_wp_id, pos.x, pos.y, pos.z);
+// }
+// else
+// {
+ dist = mavlink_wpm_distance_to_point(wpm.current_active_wp_id, pos.x, pos.y, pos.z);
+// }
+
+ if (dist >= 0.f && dist <= orbit && wpm.yaw_reached)
+ {
+ wpm.pos_reached = true;
+ }
+ }
+ }
+ break;
+ }
+
+// case MAVLINK_MSG_ID_CMD: // special action from ground station
+// {
+// mavlink_cmd_t action;
+// mavlink_msg_cmd_decode(msg, &action);
+// if(action.target == mavlink_system.sysid)
+// {
+// // if (verbose) std::cerr << "Waypoint: received message with action " << action.action << std::endl;
+// switch (action.action)
+// {
+// // case MAV_ACTION_LAUNCH:
+// // // if (verbose) std::cerr << "Launch received" << std::endl;
+// // current_active_wp_id = 0;
+// // if (wpm.size>0)
+// // {
+// // setActive(waypoints[current_active_wp_id]);
+// // }
+// // else
+// // // if (verbose) std::cerr << "No launch, waypointList empty" << std::endl;
+// // break;
+//
+// // case MAV_ACTION_CONTINUE:
+// // // if (verbose) std::c
+// // err << "Continue received" << std::endl;
+// // idle = false;
+// // setActive(waypoints[current_active_wp_id]);
+// // break;
+//
+// // case MAV_ACTION_HALT:
+// // // if (verbose) std::cerr << "Halt received" << std::endl;
+// // idle = true;
+// // break;
+//
+// // default:
+// // // if (verbose) std::cerr << "Unknown action received with id " << action.action << ", no action taken" << std::endl;
+// // break;
+// }
+// }
+// break;
+// }
+
+ case MAVLINK_MSG_ID_MISSION_ACK:
+ {
+ mavlink_mission_ack_t wpa;
+ mavlink_msg_mission_ack_decode(msg, &wpa);
+
+ if((msg->sysid == wpm.current_partner_sysid && msg->compid == wpm.current_partner_compid) && (wpa.target_system == mavlink_system.sysid /*&& wpa.target_component == mavlink_wpm_comp_id*/))
+ {
+ wpm.timestamp_lastaction = now;
+
+ if (wpm.current_state == MAVLINK_WPM_STATE_SENDLIST || wpm.current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS)
+ {
+ if (wpm.current_wp_id == wpm.size-1)
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("Got last WP ACK state -> IDLE");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Received ACK after having sent last waypoint, going to state MAVLINK_WPM_STATE_IDLE\n");
+#endif
+ wpm.current_state = MAVLINK_WPM_STATE_IDLE;
+ wpm.current_wp_id = 0;
+ }
+ }
+ }
+ else
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("REJ. WP CMD: curr partner id mismatch");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("IGNORED WAYPOINT COMMAND BECAUSE TARGET SYSTEM AND COMPONENT OR COMM PARTNER ID MISMATCH\n");
+#endif
+ }
+ break;
+ }
+
+ case MAVLINK_MSG_ID_MISSION_SET_CURRENT:
+ {
+ mavlink_mission_set_current_t wpc;
+ mavlink_msg_mission_set_current_decode(msg, &wpc);
+
+ if(wpc.target_system == mavlink_system.sysid /*&& wpc.target_component == mavlink_wpm_comp_id*/)
+ {
+ wpm.timestamp_lastaction = now;
+
+ if (wpm.current_state == MAVLINK_WPM_STATE_IDLE)
+ {
+ if (wpc.seq < wpm.size)
+ {
+ // if (verbose) // printf("Received MAVLINK_MSG_ID_MISSION_ITEM_SET_CURRENT\n");
+ wpm.current_active_wp_id = wpc.seq;
+ uint32_t i;
+ for(i = 0; i < wpm.size; i++)
+ {
+ if (i == wpm.current_active_wp_id)
+ {
+ wpm.waypoints[i].current = true;
+ }
+ else
+ {
+ wpm.waypoints[i].current = false;
+ }
+ }
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("NEW WP SET");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("New current waypoint %u\n", wpm.current_active_wp_id);
+#endif
+ wpm.yaw_reached = false;
+ wpm.pos_reached = false;
+ mavlink_wpm_send_waypoint_current(wpm.current_active_wp_id);
+ mavlink_wpm_send_setpoint(wpm.current_active_wp_id);
+ wpm.timestamp_firstinside_orbit = 0;
+ }
+ else
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("IGN WP CURR CMD: Not in list");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_SET_CURRENT: Index out of bounds\n");
+#endif
+ }
+ }
+ else
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("IGN WP CURR CMD: Busy");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("IGNORED WAYPOINT COMMAND BECAUSE NOT IN IDLE STATE\n");
+#endif
+ }
+ }
+ else
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("REJ. WP CMD: target id mismatch");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("IGNORED WAYPOINT COMMAND BECAUSE TARGET SYSTEM AND COMPONENT OR COMM PARTNER ID MISMATCH\n");
+#endif
+ }
+ break;
+ }
+
+ case MAVLINK_MSG_ID_MISSION_REQUEST_LIST:
+ {
+ mavlink_mission_request_list_t wprl;
+ mavlink_msg_mission_request_list_decode(msg, &wprl);
+ if(wprl.target_system == mavlink_system.sysid /*&& wprl.target_component == mavlink_wpm_comp_id*/)
+ {
+ wpm.timestamp_lastaction = now;
+
+ if (wpm.current_state == MAVLINK_WPM_STATE_IDLE || wpm.current_state == MAVLINK_WPM_STATE_SENDLIST)
+ {
+ if (wpm.size > 0)
+ {
+ //if (verbose && wpm.current_state == MAVLINK_WPM_STATE_IDLE) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST_LIST from %u changing state to MAVLINK_WPM_STATE_SENDLIST\n", msg->sysid);
+// if (verbose && wpm.current_state == MAVLINK_WPM_STATE_SENDLIST) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST_LIST again from %u staying in state MAVLINK_WPM_STATE_SENDLIST\n", msg->sysid);
+ wpm.current_state = MAVLINK_WPM_STATE_SENDLIST;
+ wpm.current_wp_id = 0;
+ wpm.current_partner_sysid = msg->sysid;
+ wpm.current_partner_compid = msg->compid;
+ }
+ else
+ {
+ // if (verbose) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST_LIST from %u but have no waypoints, staying in \n", msg->sysid);
+ }
+ wpm.current_count = wpm.size;
+ mavlink_wpm_send_waypoint_count(msg->sysid,msg->compid, wpm.current_count);
+ }
+ else
+ {
+ // if (verbose) // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST_LIST because i'm doing something else already (state=%i).\n", wpm.current_state);
+ }
+ }
+ else
+ {
+ // if (verbose) // printf("IGNORED WAYPOINT COMMAND BECAUSE TARGET SYSTEM AND COMPONENT MISMATCH\n");
+ }
+
+ break;
+ }
+
+ case MAVLINK_MSG_ID_MISSION_REQUEST:
+ {
+ mavlink_mission_request_t wpr;
+ mavlink_msg_mission_request_decode(msg, &wpr);
+ if(msg->sysid == wpm.current_partner_sysid && msg->compid == wpm.current_partner_compid && wpr.target_system == mavlink_system.sysid /*&& wpr.target_component == mavlink_wpm_comp_id*/)
+ {
+ wpm.timestamp_lastaction = now;
+
+ //ensure that we are in the correct state and that the first request has id 0 and the following requests have either the last id (re-send last waypoint) or last_id+1 (next waypoint)
+ if ((wpm.current_state == MAVLINK_WPM_STATE_SENDLIST && wpr.seq == 0) || (wpm.current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS && (wpr.seq == wpm.current_wp_id || wpr.seq == wpm.current_wp_id + 1) && wpr.seq < wpm.size))
+ {
+ if (wpm.current_state == MAVLINK_WPM_STATE_SENDLIST)
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("GOT WP REQ, state -> SEND");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST of waypoint %u from %u changing state to MAVLINK_WPM_STATE_SENDLIST_SENDWPS\n", wpr.seq, msg->sysid);
+#endif
+ }
+ if (wpm.current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS && wpr.seq == wpm.current_wp_id + 1)
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("GOT 2nd WP REQ");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST of waypoint %u from %u staying in state MAVLINK_WPM_STATE_SENDLIST_SENDWPS\n", wpr.seq, msg->sysid);
+#endif
+ }
+ if (wpm.current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS && wpr.seq == wpm.current_wp_id)
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("GOT 2nd WP REQ");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Got MAVLINK_MSG_ID_MISSION_ITEM_REQUEST of waypoint %u (again) from %u staying in state MAVLINK_WPM_STATE_SENDLIST_SENDWPS\n", wpr.seq, msg->sysid);
+#endif
+ }
+
+ wpm.current_state = MAVLINK_WPM_STATE_SENDLIST_SENDWPS;
+ wpm.current_wp_id = wpr.seq;
+ mavlink_wpm_send_waypoint(wpm.current_partner_sysid, wpm.current_partner_compid, wpr.seq);
+ }
+ else
+ {
+ // if (verbose)
+ {
+ if (!(wpm.current_state == MAVLINK_WPM_STATE_SENDLIST || wpm.current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS))
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("REJ. WP CMD: Busy");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST because i'm doing something else already (state=%i).\n", wpm.current_state);
+#endif
+ break;
+ }
+ else if (wpm.current_state == MAVLINK_WPM_STATE_SENDLIST)
+ {
+ if (wpr.seq != 0)
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("REJ. WP CMD: First id != 0");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST because the first requested waypoint ID (%u) was not 0.\n", wpr.seq);
+#endif
+ }
+ }
+ else if (wpm.current_state == MAVLINK_WPM_STATE_SENDLIST_SENDWPS)
+ {
+ if (wpr.seq != wpm.current_wp_id && wpr.seq != wpm.current_wp_id + 1)
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("REJ. WP CMD: Req. WP was unexpected");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST because the requested waypoint ID (%u) was not the expected (%u or %u).\n", wpr.seq, wpm.current_wp_id, wpm.current_wp_id+1);
+#endif
+ }
+ else if (wpr.seq >= wpm.size)
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("REJ. WP CMD: Req. WP not in list");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST because the requested waypoint ID (%u) was out of bounds.\n", wpr.seq);
+#endif
+ }
+ }
+ else
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("REJ. WP CMD: ?");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST - FIXME: missed error description\n");
+#endif
+ }
+ }
+ }
+ }
+ else
+ {
+ //we we're target but already communicating with someone else
+ if((wpr.target_system == mavlink_system.sysid /*&& wpr.target_component == mavlink_wpm_comp_id*/) && !(msg->sysid == wpm.current_partner_sysid && msg->compid == wpm.current_partner_compid))
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("REJ. WP CMD: Busy");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_REQUEST from ID %u because i'm already talking to ID %u.\n", msg->sysid, wpm.current_partner_sysid);
+#endif
+ }
+ else
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("REJ. WP CMD: target id mismatch");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("IGNORED WAYPOINT COMMAND BECAUSE TARGET SYSTEM AND COMPONENT OR COMM PARTNER ID MISMATCH\n");
+#endif
+ }
+
+ }
+ break;
+ }
+
+ case MAVLINK_MSG_ID_MISSION_COUNT:
+ {
+ mavlink_mission_count_t wpc;
+ mavlink_msg_mission_count_decode(msg, &wpc);
+ if(wpc.target_system == mavlink_system.sysid/* && wpc.target_component == mavlink_wpm_comp_id*/)
+ {
+ wpm.timestamp_lastaction = now;
+
+ if (wpm.current_state == MAVLINK_WPM_STATE_IDLE || (wpm.current_state == MAVLINK_WPM_STATE_GETLIST && wpm.current_wp_id == 0))
+ {
+ if (wpc.count > 0)
+ {
+ if (wpm.current_state == MAVLINK_WPM_STATE_IDLE)
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("WP CMD OK: state -> GETLIST");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Got MAVLINK_MSG_ID_MISSION_ITEM_COUNT (%u) from %u changing state to MAVLINK_WPM_STATE_GETLIST\n", wpc.count, msg->sysid);
+#endif
+ }
+ if (wpm.current_state == MAVLINK_WPM_STATE_GETLIST)
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("WP CMD OK AGAIN");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Got MAVLINK_MSG_ID_MISSION_ITEM_COUNT (%u) again from %u\n", wpc.count, msg->sysid);
+#endif
+ }
+
+ wpm.current_state = MAVLINK_WPM_STATE_GETLIST;
+ wpm.current_wp_id = 0;
+ wpm.current_partner_sysid = msg->sysid;
+ wpm.current_partner_compid = msg->compid;
+ wpm.current_count = wpc.count;
+
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("CLR RCV BUF: READY");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("clearing receive buffer and readying for receiving waypoints\n");
+#endif
+ wpm.rcv_size = 0;
+ //while(waypoints_receive_buffer->size() > 0)
+// {
+// delete waypoints_receive_buffer->back();
+// waypoints_receive_buffer->pop_back();
+// }
+
+ mavlink_wpm_send_waypoint_request(wpm.current_partner_sysid, wpm.current_partner_compid, wpm.current_wp_id);
+ }
+ else if (wpc.count == 0)
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("COUNT 0");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("got waypoint count of 0, clearing waypoint list and staying in state MAVLINK_WPM_STATE_IDLE\n");
+#endif
+ wpm.rcv_size = 0;
+ //while(waypoints_receive_buffer->size() > 0)
+// {
+// delete waypoints->back();
+// waypoints->pop_back();
+// }
+ wpm.current_active_wp_id = -1;
+ wpm.yaw_reached = false;
+ wpm.pos_reached = false;
+ break;
+
+ }
+ else
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("IGN WP CMD");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Ignoring MAVLINK_MSG_ID_MISSION_ITEM_COUNT from %u with count of %u\n", msg->sysid, wpc.count);
+#endif
+ }
+ }
+ else
+ {
+ if (!(wpm.current_state == MAVLINK_WPM_STATE_IDLE || wpm.current_state == MAVLINK_WPM_STATE_GETLIST))
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("REJ. WP CMD: Busy");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_COUNT because i'm doing something else already (state=%i).\n", wpm.current_state);
+#endif
+ }
+ else if (wpm.current_state == MAVLINK_WPM_STATE_GETLIST && wpm.current_wp_id != 0)
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("REJ. WP CMD: Busy");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_COUNT because i'm already receiving waypoint %u.\n", wpm.current_wp_id);
+#endif
+ }
+ else
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("REJ. WP CMD: ?");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_COUNT - FIXME: missed error description\n");
+#endif
+ }
+ }
+ }
+ else
+ {
+#ifdef MAVLINK_WPM_NO_PRINTF
+ mavlink_missionlib_send_gcs_string("REJ. WP CMD: target id mismatch");
+#else
+ if (MAVLINK_WPM_VERBOSE) printf("IGNORED WAYPOINT COMMAND BECAUSE TARGET SYSTEM AND COMPONENT OR COMM PARTNER ID MISMATCH\n");
+#endif
+ }
+
+ }
+ break;
+
+ case MAVLINK_MSG_ID_MISSION_ITEM:
+ {
+ mavlink_mission_item_t wp;
+ mavlink_msg_mission_item_decode(msg, &wp);
+
+ mavlink_missionlib_send_gcs_string("GOT WP");
+
+ if((msg->sysid == wpm.current_partner_sysid && msg->compid == wpm.current_partner_compid) && (wp.target_system == mavlink_system.sysid /*&& wp.target_component == mavlink_wpm_comp_id*/))
+ {
+ wpm.timestamp_lastaction = now;
+
+ //ensure that we are in the correct state and that the first waypoint has id 0 and the following waypoints have the correct ids
+ if ((wpm.current_state == MAVLINK_WPM_STATE_GETLIST && wp.seq == 0) || (wpm.current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS && wp.seq == wpm.current_wp_id && wp.seq < wpm.current_count))
+ {
+// if (verbose && wpm.current_state == MAVLINK_WPM_STATE_GETLIST) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM %u from %u changing state to MAVLINK_WPM_STATE_GETLIST_GETWPS\n", wp.seq, msg->sysid);
+// if (verbose && wpm.current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS && wp.seq == wpm.current_wp_id) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM %u from %u\n", wp.seq, msg->sysid);
+// if (verbose && wpm.current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS && wp.seq-1 == wpm.current_wp_id) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM %u (again) from %u\n", wp.seq, msg->sysid);
+//
+ wpm.current_state = MAVLINK_WPM_STATE_GETLIST_GETWPS;
+ mavlink_mission_item_t* newwp = &(wpm.rcv_waypoints[wp.seq]);
+ memcpy(newwp, &wp, sizeof(mavlink_mission_item_t));
+ wpm.current_wp_id = wp.seq + 1;
+
+ // if (verbose) // printf ("Added new waypoint to list. X= %f\t Y= %f\t Z= %f\t Yaw= %f\n", newwp->x, newwp->y, newwp->z, newwp->param4);
+
+ if(wpm.current_wp_id == wpm.current_count && wpm.current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS)
+ {
+ mavlink_missionlib_send_gcs_string("GOT ALL WPS");
+ // if (verbose) // printf("Got all %u waypoints, changing state to MAVLINK_WPM_STATE_IDLE\n", wpm.current_count);
+
+ mavlink_wpm_send_waypoint_ack(wpm.current_partner_sysid, wpm.current_partner_compid, 0);
+
+ if (wpm.current_active_wp_id > wpm.rcv_size-1)
+ {
+ wpm.current_active_wp_id = wpm.rcv_size-1;
+ }
+
+ // switch the waypoints list
+ // FIXME CHECK!!!
+ for (int i = 0; i < wpm.current_count; ++i)
+ {
+ wpm.waypoints[i] = wpm.rcv_waypoints[i];
+ }
+ wpm.size = wpm.current_count;
+
+ //get the new current waypoint
+ uint32_t i;
+ for(i = 0; i < wpm.size; i++)
+ {
+ if (wpm.waypoints[i].current == 1)
+ {
+ wpm.current_active_wp_id = i;
+ //// if (verbose) // printf("New current waypoint %u\n", current_active_wp_id);
+ wpm.yaw_reached = false;
+ wpm.pos_reached = false;
+ mavlink_wpm_send_waypoint_current(wpm.current_active_wp_id);
+ mavlink_wpm_send_setpoint(wpm.current_active_wp_id);
+ wpm.timestamp_firstinside_orbit = 0;
+ break;
+ }
+ }
+
+ if (i == wpm.size)
+ {
+ wpm.current_active_wp_id = -1;
+ wpm.yaw_reached = false;
+ wpm.pos_reached = false;
+ wpm.timestamp_firstinside_orbit = 0;
+ }
+
+ wpm.current_state = MAVLINK_WPM_STATE_IDLE;
+ }
+ else
+ {
+ mavlink_wpm_send_waypoint_request(wpm.current_partner_sysid, wpm.current_partner_compid, wpm.current_wp_id);
+ }
+ }
+ else
+ {
+ if (wpm.current_state == MAVLINK_WPM_STATE_IDLE)
+ {
+ //we're done receiving waypoints, answer with ack.
+ mavlink_wpm_send_waypoint_ack(wpm.current_partner_sysid, wpm.current_partner_compid, 0);
+ // printf("Received MAVLINK_MSG_ID_MISSION_ITEM while state=MAVLINK_WPM_STATE_IDLE, answered with WAYPOINT_ACK.\n");
+ }
+ // if (verbose)
+ {
+ if (!(wpm.current_state == MAVLINK_WPM_STATE_GETLIST || wpm.current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS))
+ {
+ // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u because i'm doing something else already (state=%i).\n", wp.seq, wpm.current_state);
+ break;
+ }
+ else if (wpm.current_state == MAVLINK_WPM_STATE_GETLIST)
+ {
+ if(!(wp.seq == 0))
+ {
+ // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM because the first waypoint ID (%u) was not 0.\n", wp.seq);
+ }
+ else
+ {
+ // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u - FIXME: missed error description\n", wp.seq);
+ }
+ }
+ else if (wpm.current_state == MAVLINK_WPM_STATE_GETLIST_GETWPS)
+ {
+ if (!(wp.seq == wpm.current_wp_id))
+ {
+ // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM because the waypoint ID (%u) was not the expected %u.\n", wp.seq, wpm.current_wp_id);
+ }
+ else if (!(wp.seq < wpm.current_count))
+ {
+ // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM because the waypoint ID (%u) was out of bounds.\n", wp.seq);
+ }
+ else
+ {
+ // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u - FIXME: missed error description\n", wp.seq);
+ }
+ }
+ else
+ {
+ // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u - FIXME: missed error description\n", wp.seq);
+ }
+ }
+ }
+ }
+ else
+ {
+ //we we're target but already communicating with someone else
+ if((wp.target_system == mavlink_system.sysid /*&& wp.target_component == mavlink_wpm_comp_id*/) && !(msg->sysid == wpm.current_partner_sysid && msg->compid == wpm.current_partner_compid) && wpm.current_state != MAVLINK_WPM_STATE_IDLE)
+ {
+ // if (verbose) // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u from ID %u because i'm already talking to ID %u.\n", wp.seq, msg->sysid, wpm.current_partner_sysid);
+ }
+ else if(wp.target_system == mavlink_system.sysid /* && wp.target_component == mavlink_wpm_comp_id*/)
+ {
+ // if (verbose) // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM %u from ID %u because i have no idea what to do with it\n", wp.seq, msg->sysid);
+ }
+ }
+ break;
+ }
+
+ case MAVLINK_MSG_ID_MISSION_CLEAR_ALL:
+ {
+ mavlink_mission_clear_all_t wpca;
+ mavlink_msg_mission_clear_all_decode(msg, &wpca);
+
+ if(wpca.target_system == mavlink_system.sysid /*&& wpca.target_component == mavlink_wpm_comp_id */ && wpm.current_state == MAVLINK_WPM_STATE_IDLE)
+ {
+ wpm.timestamp_lastaction = now;
+
+ // if (verbose) // printf("Got MAVLINK_MSG_ID_MISSION_ITEM_CLEAR_LIST from %u deleting all waypoints\n", msg->sysid);
+ // Delete all waypoints
+ wpm.size = 0;
+ wpm.current_active_wp_id = -1;
+ wpm.yaw_reached = false;
+ wpm.pos_reached = false;
+ }
+ else if (wpca.target_system == mavlink_system.sysid /*&& wpca.target_component == mavlink_wpm_comp_id */ && wpm.current_state != MAVLINK_WPM_STATE_IDLE)
+ {
+ // if (verbose) // printf("Ignored MAVLINK_MSG_ID_MISSION_ITEM_CLEAR_LIST from %u because i'm doing something else already (state=%i).\n", msg->sysid, wpm.current_state);
+ }
+ break;
+ }
+
+ default:
+ {
+ // if (debug) // printf("Waypoint: received message of unknown type");
+ break;
+ }
+ }
+
+ //check if the current waypoint was reached
+ if (wpm.pos_reached /*wpm.yaw_reached &&*/ && !wpm.idle)
+ {
+ if (wpm.current_active_wp_id < wpm.size)
+ {
+ mavlink_mission_item_t *cur_wp = &(wpm.waypoints[wpm.current_active_wp_id]);
+
+ if (wpm.timestamp_firstinside_orbit == 0)
+ {
+ // Announce that last waypoint was reached
+ // if (verbose) // printf("*** Reached waypoint %u ***\n", cur_wp->seq);
+ mavlink_wpm_send_waypoint_reached(cur_wp->seq);
+ wpm.timestamp_firstinside_orbit = now;
+ }
+
+ // check if the MAV was long enough inside the waypoint orbit
+ //if (now-timestamp_lastoutside_orbit > (cur_wp->hold_time*1000))
+ if(now-wpm.timestamp_firstinside_orbit >= cur_wp->param2*1000)
+ {
+ if (cur_wp->autocontinue)
+ {
+ cur_wp->current = 0;
+ if (wpm.current_active_wp_id == wpm.size - 1 && wpm.size > 1)
+ {
+ //the last waypoint was reached, if auto continue is
+ //activated restart the waypoint list from the beginning
+ wpm.current_active_wp_id = 1;
+ }
+ else
+ {
+ if ((uint16_t)(wpm.current_active_wp_id + 1) < wpm.size)
+ wpm.current_active_wp_id++;
+ }
+
+ // Fly to next waypoint
+ wpm.timestamp_firstinside_orbit = 0;
+ mavlink_wpm_send_waypoint_current(wpm.current_active_wp_id);
+ mavlink_wpm_send_setpoint(wpm.current_active_wp_id);
+ wpm.waypoints[wpm.current_active_wp_id].current = true;
+ wpm.pos_reached = false;
+ wpm.yaw_reached = false;
+ // if (verbose) // printf("Set new waypoint (%u)\n", wpm.current_active_wp_id);
+ }
+ }
+ }
+ }
+ else
+ {
+ wpm.timestamp_lastoutside_orbit = now;
+ }
+}
+
diff --git a/mavlink-solo/missionlib/waypoints.h b/mavlink-solo/missionlib/waypoints.h
new file mode 100644
index 0000000..49374f6
--- /dev/null
+++ b/mavlink-solo/missionlib/waypoints.h
@@ -0,0 +1,104 @@
+/*******************************************************************************
+
+ Copyright (C) 2011 Lorenz Meier lm ( a t ) inf.ethz.ch
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ ****************************************************************************/
+
+/* This assumes you have the mavlink headers on your include path
+ or in the same folder as this source file */
+
+// Disable auto-data structures
+#ifndef MAVLINK_NO_DATA
+#define MAVLINK_NO_DATA
+#endif
+
+#include
+extern void mavlink_send_uart_bytes(mavlink_channel_t chan, uint8_t* buffer, uint16_t len);
+
+#ifndef MAVLINK_SEND_UART_BYTES
+#define MAVLINK_SEND_UART_BYTES(chan, buffer, len) mavlink_send_uart_bytes(chan, buffer, len)
+#endif
+extern mavlink_system_t mavlink_system;
+#include
+#include
+
+// FIXME XXX - TO BE MOVED TO XML
+enum MAVLINK_WPM_STATES
+{
+ MAVLINK_WPM_STATE_IDLE = 0,
+ MAVLINK_WPM_STATE_SENDLIST,
+ MAVLINK_WPM_STATE_SENDLIST_SENDWPS,
+ MAVLINK_WPM_STATE_GETLIST,
+ MAVLINK_WPM_STATE_GETLIST_GETWPS,
+ MAVLINK_WPM_STATE_GETLIST_GOTALL,
+ MAVLINK_WPM_STATE_ENUM_END
+};
+
+enum MAVLINK_WPM_CODES
+{
+ MAVLINK_WPM_CODE_OK = 0,
+ MAVLINK_WPM_CODE_ERR_WAYPOINT_ACTION_NOT_SUPPORTED,
+ MAVLINK_WPM_CODE_ERR_WAYPOINT_FRAME_NOT_SUPPORTED,
+ MAVLINK_WPM_CODE_ERR_WAYPOINT_OUT_OF_BOUNDS,
+ MAVLINK_WPM_CODE_ERR_WAYPOINT_MAX_NUMBER_EXCEEDED,
+ MAVLINK_WPM_CODE_ENUM_END
+};
+
+
+/* WAYPOINT MANAGER - MISSION LIB */
+
+#define MAVLINK_WPM_MAX_WP_COUNT 15
+#define MAVLINK_WPM_CONFIG_IN_FLIGHT_UPDATE ///< Enable double buffer and in-flight updates
+#ifndef MAVLINK_WPM_TEXT_FEEDBACK
+#define MAVLINK_WPM_TEXT_FEEDBACK 0 ///< Report back status information as text
+#endif
+#define MAVLINK_WPM_PROTOCOL_TIMEOUT_DEFAULT 5000 ///< Protocol communication timeout in milliseconds
+#define MAVLINK_WPM_SETPOINT_DELAY_DEFAULT 1000 ///< When to send a new setpoint
+#define MAVLINK_WPM_PROTOCOL_DELAY_DEFAULT 40
+
+
+struct mavlink_wpm_storage {
+ mavlink_mission_item_t waypoints[MAVLINK_WPM_MAX_WP_COUNT]; ///< Currently active waypoints
+#ifdef MAVLINK_WPM_CONFIG_IN_FLIGHT_UPDATE
+ mavlink_mission_item_t rcv_waypoints[MAVLINK_WPM_MAX_WP_COUNT]; ///< Receive buffer for next waypoints
+#endif
+ uint16_t size;
+ uint16_t max_size;
+ uint16_t rcv_size;
+ enum MAVLINK_WPM_STATES current_state;
+ uint16_t current_wp_id; ///< Waypoint in current transmission
+ uint16_t current_active_wp_id; ///< Waypoint the system is currently heading towards
+ uint16_t current_count;
+ uint8_t current_partner_sysid;
+ uint8_t current_partner_compid;
+ uint64_t timestamp_lastaction;
+ uint64_t timestamp_last_send_setpoint;
+ uint64_t timestamp_firstinside_orbit;
+ uint64_t timestamp_lastoutside_orbit;
+ uint32_t timeout;
+ uint32_t delay_setpoint;
+ float accept_range_yaw;
+ float accept_range_distance;
+ bool yaw_reached;
+ bool pos_reached;
+ bool idle;
+};
+
+typedef struct mavlink_wpm_storage mavlink_wpm_storage;
+
+void mavlink_wpm_init(mavlink_wpm_storage* state);
+void mavlink_wpm_loop();
+void mavlink_wpm_message_handler(const mavlink_message_t* msg);
diff --git a/mavlink-solo/out_c/checksum.h b/mavlink-solo/out_c/checksum.h
new file mode 100644
index 0000000..ff74c37
--- /dev/null
+++ b/mavlink-solo/out_c/checksum.h
@@ -0,0 +1,90 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _CHECKSUM_H_
+#define _CHECKSUM_H_
+
+
+/**
+ *
+ * CALCULATE THE CHECKSUM
+ *
+ */
+
+#define X25_INIT_CRC 0xffff
+#define X25_VALIDATE_CRC 0xf0b8
+
+#ifndef HAVE_CRC_ACCUMULATE
+/**
+ * @brief Accumulate the X.25 CRC by adding one char at a time.
+ *
+ * The checksum function adds the hash of one char at a time to the
+ * 16 bit checksum (uint16_t).
+ *
+ * @param data new char to hash
+ * @param crcAccum the already accumulated checksum
+ **/
+static inline void crc_accumulate(uint8_t data, uint16_t *crcAccum)
+{
+ /*Accumulate one byte of data into the CRC*/
+ uint8_t tmp;
+
+ tmp = data ^ (uint8_t)(*crcAccum &0xff);
+ tmp ^= (tmp<<4);
+ *crcAccum = (*crcAccum>>8) ^ (tmp<<8) ^ (tmp <<3) ^ (tmp>>4);
+}
+#endif
+
+
+/**
+ * @brief Initiliaze the buffer for the X.25 CRC
+ *
+ * @param crcAccum the 16 bit X.25 CRC
+ */
+static inline void crc_init(uint16_t* crcAccum)
+{
+ *crcAccum = X25_INIT_CRC;
+}
+
+
+/**
+ * @brief Calculates the X.25 checksum on a byte buffer
+ *
+ * @param pBuffer buffer containing the byte array to hash
+ * @param length length of the byte array
+ * @return the checksum over the buffer bytes
+ **/
+static inline uint16_t crc_calculate(const uint8_t* pBuffer, uint16_t length)
+{
+ uint16_t crcTmp;
+ crc_init(&crcTmp);
+ while (length--) {
+ crc_accumulate(*pBuffer++, &crcTmp);
+ }
+ return crcTmp;
+}
+
+
+/**
+ * @brief Accumulate the X.25 CRC by adding an array of bytes
+ *
+ * The checksum function adds the hash of one char at a time to the
+ * 16 bit checksum (uint16_t).
+ *
+ * @param data new bytes to hash
+ * @param crcAccum the already accumulated checksum
+ **/
+static inline void crc_accumulate_buffer(uint16_t *crcAccum, const char *pBuffer, uint16_t length)
+{
+ const uint8_t *p = (const uint8_t *)pBuffer;
+ while (length--) {
+ crc_accumulate(*p++, crcAccum);
+ }
+}
+
+#endif /* _CHECKSUM_H_ */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/mavlink-solo/pc.in b/mavlink-solo/pc.in
new file mode 100644
index 0000000..e02ba17
--- /dev/null
+++ b/mavlink-solo/pc.in
@@ -0,0 +1,7 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=@CMAKE_INSTALL_PREFIX@
+
+Name: @PROJECT_NAME@
+Description: MAVLink micro air vehicle marshalling / communication library
+Version: @PROJECT_VERSION@
+Cflags: -I@CMAKE_INSTALL_PREFIX@/include/@PROJECT_NAME@
diff --git a/mavlink-solo/pymavlink/APM_Mavtest/APM_Mavtest.pde b/mavlink-solo/pymavlink/APM_Mavtest/APM_Mavtest.pde
new file mode 100644
index 0000000..b903b5c
--- /dev/null
+++ b/mavlink-solo/pymavlink/APM_Mavtest/APM_Mavtest.pde
@@ -0,0 +1,55 @@
+/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: t -*-
+
+/*
+ send all possible mavlink messages
+ Andrew Tridgell July 2011
+*/
+
+// AVR runtime
+#include
+#include
+#include
+#include
+
+// Libraries
+#include
+#include
+#include
+#include "mavtest.h"
+
+FastSerialPort0(Serial); // FTDI/console
+FastSerialPort1(Serial1); // GPS port
+FastSerialPort3(Serial3); // Telemetry port
+
+#define SERIAL0_BAUD 115200
+#define SERIAL3_BAUD 115200
+
+void setup() {
+ Serial.begin(SERIAL0_BAUD, 128, 128);
+ Serial3.begin(SERIAL3_BAUD, 128, 128);
+ mavlink_comm_0_port = &Serial;
+ mavlink_comm_1_port = &Serial3;
+}
+
+
+
+void loop()
+{
+ Serial.println("Starting MAVLink test generator\n");
+ while (1) {
+ mavlink_msg_heartbeat_send(
+ MAVLINK_COMM_0,
+ mavlink_system.type,
+ MAV_AUTOPILOT_ARDUPILOTMEGA);
+
+ mavlink_msg_heartbeat_send(
+ MAVLINK_COMM_1,
+ mavlink_system.type,
+ MAV_AUTOPILOT_ARDUPILOTMEGA);
+
+ mavtest_generate_outputs(MAVLINK_COMM_0);
+ mavtest_generate_outputs(MAVLINK_COMM_1);
+ delay(500);
+ }
+}
+
diff --git a/mavlink-solo/pymavlink/APM_Mavtest/Makefile b/mavlink-solo/pymavlink/APM_Mavtest/Makefile
new file mode 100644
index 0000000..7ca38b1
--- /dev/null
+++ b/mavlink-solo/pymavlink/APM_Mavtest/Makefile
@@ -0,0 +1,10 @@
+#
+# Trivial makefile for building APM
+#
+
+#
+# Select 'mega' for the original APM, or 'mega2560' for the V2 APM.
+#
+BOARD = mega2560
+
+include ../libraries/AP_Common/Arduino.mk
diff --git a/mavlink-solo/pymavlink/DFReader.py b/mavlink-solo/pymavlink/DFReader.py
new file mode 100644
index 0000000..317da01
--- /dev/null
+++ b/mavlink-solo/pymavlink/DFReader.py
@@ -0,0 +1,673 @@
+#!/usr/bin/env python
+'''
+APM DataFlash log file reader
+
+Copyright Andrew Tridgell 2011
+Released under GNU GPL version 3 or later
+
+Partly based on SDLog2Parser by Anton Babushkin
+'''
+
+import struct, time, os
+from . import mavutil
+
+FORMAT_TO_STRUCT = {
+ "b": ("b", None, int),
+ "B": ("B", None, int),
+ "h": ("h", None, int),
+ "H": ("H", None, int),
+ "i": ("i", None, int),
+ "I": ("I", None, int),
+ "f": ("f", None, float),
+ "n": ("4s", None, str),
+ "N": ("16s", None, str),
+ "Z": ("64s", None, str),
+ "c": ("h", 0.01, float),
+ "C": ("H", 0.01, float),
+ "e": ("i", 0.01, float),
+ "E": ("I", 0.01, float),
+ "L": ("i", 1.0e-7, float),
+ "d": ("d", None, float),
+ "M": ("b", None, int),
+ "q": ("q", None, long),
+ "Q": ("Q", None, long),
+ }
+
+class DFFormat(object):
+ def __init__(self, type, name, flen, format, columns):
+ self.type = type
+ self.name = name
+ self.len = flen
+ self.format = format
+ self.columns = columns.split(',')
+
+ if self.columns == ['']:
+ self.columns = []
+
+ msg_struct = "<"
+ msg_mults = []
+ msg_types = []
+ for c in format:
+ if ord(c) == 0:
+ break
+ try:
+ (s, mul, type) = FORMAT_TO_STRUCT[c]
+ msg_struct += s
+ msg_mults.append(mul)
+ msg_types.append(type)
+ except KeyError as e:
+ raise Exception("Unsupported format char: '%s' in message %s" % (c, name))
+
+ self.msg_struct = msg_struct
+ self.msg_types = msg_types
+ self.msg_mults = msg_mults
+ self.colhash = {}
+ for i in range(len(self.columns)):
+ self.colhash[self.columns[i]] = i
+
+ def __str__(self):
+ return "DFFormat(%s,%s,%s,%s)" % (self.type, self.name, self.format, self.columns)
+
+def null_term(str):
+ '''null terminate a string'''
+ idx = str.find("\0")
+ if idx != -1:
+ str = str[:idx]
+ return str
+
+class DFMessage(object):
+ def __init__(self, fmt, elements, apply_multiplier):
+ self.fmt = fmt
+ self._elements = elements
+ self._apply_multiplier = apply_multiplier
+ self._fieldnames = fmt.columns
+
+ def __getattr__(self, field):
+ '''override field getter'''
+ try:
+ i = self.fmt.colhash[field]
+ except Exception:
+ raise AttributeError(field)
+ v = self._elements[i]
+ if self.fmt.format[i] != 'M' or self._apply_multiplier:
+ v = self.fmt.msg_types[i](v)
+ if self.fmt.msg_types[i] == str:
+ v = null_term(v)
+ if self.fmt.msg_mults[i] is not None and self._apply_multiplier:
+ v *= self.fmt.msg_mults[i]
+ return v
+
+ def get_type(self):
+ return self.fmt.name
+
+ def __str__(self):
+ ret = "%s {" % self.fmt.name
+ col_count = 0
+ for c in self.fmt.columns:
+ ret += "%s : %s, " % (c, self.__getattr__(c))
+ col_count += 1
+ if col_count != 0:
+ ret = ret[:-2]
+ return ret + '}'
+
+ def get_msgbuf(self):
+ '''create a binary message buffer for a message'''
+ values = []
+ for i in range(len(self.fmt.columns)):
+ if i >= len(self.fmt.msg_mults):
+ continue
+ mul = self.fmt.msg_mults[i]
+ name = self.fmt.columns[i]
+ if name == 'Mode' and 'ModeNum' in self.fmt.columns:
+ name = 'ModeNum'
+ v = self.__getattr__(name)
+ if mul is not None:
+ v /= mul
+ values.append(v)
+ return struct.pack("BBB", 0xA3, 0x95, self.fmt.type) + struct.pack(self.fmt.msg_struct, *values)
+
+
+class DFReaderClock():
+ '''base class for all the different ways we count time in logs'''
+
+ def __init__(self):
+ self.set_timebase(0)
+ self.timestamp = 0
+
+ def _gpsTimeToTime(self, week, msec):
+ '''convert GPS week and TOW to a time in seconds since 1970'''
+ epoch = 86400*(10*365 + (1980-1969)/4 + 1 + 6 - 2)
+ return epoch + 86400*7*week + msec*0.001 - 15
+
+ def set_timebase(self, base):
+ self.timebase = base
+
+ def message_arrived(self, m):
+ pass
+
+ def rewind_event(self):
+ pass
+
+class DFReaderClock_gps_usec(DFReaderClock):
+ '''DFReaderClock_gps_usec - GPS usec - use GPS Week and GPS MS to find base'''
+ def __init__(self):
+ DFReaderClock.__init__(self)
+
+ def find_time_base(self, gps, first_us_stamp):
+ '''work out time basis for the log - even newer style'''
+ t = self._gpsTimeToTime(gps.GWk, gps.GMS)
+ self.set_timebase(t - gps.TimeUS*0.000001)
+ # this ensures FMT messages get appropriate timestamp:
+ self.timestamp = self.timebase + first_us_stamp*0.000001
+
+ def type_has_good_TimeMS(self, type):
+ '''The TimeMS in some messages is not from *our* clock!'''
+ if type.startswith('ACC'):
+ return False;
+ if type.startswith('GYR'):
+ return False;
+ return True
+
+ def should_use_msec_field0(self, m):
+ if not self.type_has_good_TimeMS(m.get_type()):
+ return False
+ if 'TimeMS' != m._fieldnames[0]:
+ return False
+ if self.timebase + m.TimeMS*0.001 < self.timestamp:
+ return False
+ return True;
+
+ def set_message_timestamp(self, m):
+ if 'TimeUS' == m._fieldnames[0]:
+ # only format messages don't have a TimeUS in them...
+ m._timestamp = self.timebase + m.TimeUS*0.000001
+ elif self.should_use_msec_field0(m):
+ # ... in theory. I expect there to be some logs which are not
+ # "pure":
+ m._timestamp = self.timebase + m.TimeMS*0.001
+ else:
+ m._timestamp = self.timestamp
+ self.timestamp = m._timestamp
+
+class DFReaderClock_msec(DFReaderClock):
+ '''DFReaderClock_msec - a format where many messages have TimeMS in their formats, and GPS messages have a "T" field giving msecs '''
+ def find_time_base(self, gps, first_ms_stamp):
+ '''work out time basis for the log - new style'''
+ t = self._gpsTimeToTime(gps.Week, gps.TimeMS)
+ self.set_timebase(t - gps.T*0.001)
+ self.timestamp = self.timebase + first_ms_stamp*0.001
+
+ def set_message_timestamp(self, m):
+ if 'TimeMS' == m._fieldnames[0]:
+ m._timestamp = self.timebase + m.TimeMS*0.001
+ elif m.get_type() in ['GPS','GPS2']:
+ m._timestamp = self.timebase + m.T*0.001
+ else:
+ m._timestamp = self.timestamp
+ self.timestamp = m._timestamp
+
+class DFReaderClock_px4(DFReaderClock):
+ '''DFReaderClock_px4 - a format where a starting time is explicitly given in a message'''
+ def __init__(self):
+ DFReaderClock.__init__(self)
+ self.px4_timebase = 0
+
+ def find_time_base(self, gps):
+ '''work out time basis for the log - PX4 native'''
+ t = gps.GPSTime * 1.0e-6
+ self.timebase = t - self.px4_timebase
+
+ def set_px4_timebase(self, time_msg):
+ self.px4_timebase = time_msg.StartTime * 1.0e-6
+
+ def set_message_timestamp(self, m):
+ m._timestamp = self.timebase + self.px4_timebase
+
+ def message_arrived(self, m):
+ type = m.get_type()
+ if type == 'TIME' and 'StartTime' in m._fieldnames:
+ self.set_px4_timebase(m)
+
+class DFReaderClock_gps_interpolated(DFReaderClock):
+ '''DFReaderClock_gps_interpolated - for when the only real references in a message are GPS timestamps '''
+ def __init__(self):
+ DFReaderClock.__init__(self)
+ self.msg_rate = {}
+ self.counts = {}
+ self.counts_since_gps = {}
+
+ def rewind_event(self):
+ '''reset counters on rewind'''
+ self.counts = {}
+ self.counts_since_gps = {}
+
+ def message_arrived(self, m):
+ type = m.get_type()
+ if not type in self.counts:
+ self.counts[type] = 1
+ else:
+ self.counts[type] += 1
+ # this preserves existing behaviour - but should we be doing this
+ # if type == 'GPS'?
+ if not type in self.counts_since_gps:
+ self.counts_since_gps[type] = 1
+ else:
+ self.counts_since_gps[type] += 1
+
+ if type == 'GPS' or type == 'GPS2':
+ self.gps_message_arrived(m)
+
+ def gps_message_arrived(self, m):
+ '''adjust time base from GPS message'''
+ # msec-style GPS message?
+ gps_week = getattr(m, 'Week', None)
+ gps_timems = getattr(m, 'TimeMS', None)
+ if gps_week is None:
+ # usec-style GPS message?
+ gps_week = getattr(m, 'GWk', None)
+ gps_timems = getattr(m, 'GMS', None)
+ if gps_week is None:
+ if getattr(m, 'GPSTime', None) is not None:
+ # PX4-style timestamp; we've only been called
+ # because we were speculatively created in case no
+ # better clock was found.
+ return;
+
+ t = self._gpsTimeToTime(gps_week, gps_timems)
+
+ deltat = t - self.timebase
+ if deltat <= 0:
+ return
+
+ for type in self.counts_since_gps:
+ rate = self.counts_since_gps[type] / deltat
+ if rate > self.msg_rate.get(type, 0):
+ self.msg_rate[type] = rate
+ self.msg_rate['IMU'] = 50.0
+ self.timebase = t
+ self.counts_since_gps = {}
+
+ def set_message_timestamp(self, m):
+ rate = self.msg_rate.get(m.fmt.name, 50.0)
+ if int(rate) == 0:
+ rate = 50
+ count = self.counts_since_gps.get(m.fmt.name, 0)
+ m._timestamp = self.timebase + count/rate
+
+
+class DFReader(object):
+ '''parse a generic dataflash file'''
+ def __init__(self):
+ # read the whole file into memory for simplicity
+ self.clock = None
+ self.timestamp = 0
+ self.mav_type = mavutil.mavlink.MAV_TYPE_FIXED_WING
+ self.verbose = False
+ self.params = {}
+
+ def _rewind(self):
+ '''reset state on rewind'''
+ self.messages = { 'MAV' : self }
+ self.flightmode = "UNKNOWN"
+ self.percent = 0
+ if self.clock:
+ self.clock.rewind_event()
+
+ def init_clock_px4(self, px4_msg_time, px4_msg_gps):
+ self.clock = DFReaderClock_px4()
+ if not self._zero_time_base:
+ self.clock.set_px4_timebase(px4_msg_time)
+ self.clock.find_time_base(px4_msg_gps)
+ return True
+
+ def init_clock_msec(self, msg_gps, first_ms_stamp):
+ # it is a new style flash log with full timestamps
+ self.clock = DFReaderClock_msec()
+ if not self._zero_time_base:
+ self.clock.find_time_base(msg_gps, first_ms_stamp)
+ return True
+
+ def init_clock_gps_usec(self, msg_gps, first_us_stamp):
+ self.clock = DFReaderClock_gps_usec()
+ if not self._zero_time_base:
+ self.clock.find_time_base(msg_gps, first_us_stamp)
+ return True
+
+ def init_clock_gps_interpolated(self, clock):
+ self.clock = clock
+
+ return True
+
+ def init_clock(self):
+ '''work out time basis for the log'''
+
+ self._rewind()
+
+ # speculatively create a gps clock in case we don't find anything
+ # better
+ gps_clock = DFReaderClock_gps_interpolated()
+ self.clock = gps_clock
+
+ px4_msg_time = None
+ px4_msg_gps = None
+ gps_interp_msg_gps1 = None
+ gps_interp_msg_gps2 = None
+ first_us_stamp = None
+ first_ms_stamp = None
+
+ while True:
+ m = self.recv_msg()
+ if m is None:
+ break;
+
+ type = m.get_type()
+
+ if first_us_stamp is None:
+ first_us_stamp = getattr(m, "TimeUS", None);
+
+ if first_ms_stamp is None and (type != 'GPS' and type != 'GPS2'):
+ # Older GPS messages use TimeMS for msecs past start
+ # of gps week
+ first_ms_stamp = getattr(m, "TimeMS", None);
+
+ if type == 'GPS' or type == 'GPS2':
+ if getattr(m, "TimeUS", 0) != 0 and \
+ getattr(m, "GWk", 0) != 0: # everything-usec-timestamped
+ self.init_clock_gps_usec(m, first_us_stamp)
+ break
+ if getattr(m, "T", 0) != 0 and \
+ getattr(m, "Week", 0) != 0: # GPS is msec-timestamped
+ if first_ms_stamp is None:
+ first_ms_stamp = m.T
+ self.init_clock_msec(m, first_ms_stamp)
+ break
+ if getattr(m, "GPSTime", 0) != 0: # px4-style-only
+ px4_msg_gps = m
+ if getattr(m, "Week", 0) != 0:
+ if gps_interp_msg_gps1 is not None and \
+ (gps_interp_msg_gps1.TimeMS != m.TimeMS or \
+ gps_interp_msg_gps1.Week != m.Week):
+ # we've received two distinct, non-zero GPS
+ # packets without finding a decent clock to
+ # use; fall back to interpolation. Q: should
+ # we wait a few more messages befoe doing
+ # this?
+ self.init_clock_gps_interpolated(gps_clock)
+ break
+ gps_interp_msg_gps1 = m
+
+ elif type == 'TIME':
+ '''only px4-style logs use TIME'''
+ if getattr(m, "StartTime", None) != None:
+ px4_msg_time = m;
+
+ if px4_msg_time is not None and px4_msg_gps is not None:
+ self.init_clock_px4(px4_msg_time, px4_msg_gps)
+ break
+
+# print("clock is " + str(self.clock))
+
+ self._rewind()
+
+ return
+
+ def _set_time(self, m):
+ '''set time for a message'''
+ # really just left here for profiling
+ m._timestamp = self.timestamp
+ if len(m._fieldnames) > 0 and self.clock is not None:
+ self.clock.set_message_timestamp(m)
+
+ def recv_msg(self):
+ return self._parse_next()
+
+ def _add_msg(self, m):
+ '''add a new message'''
+ type = m.get_type()
+ self.messages[type] = m
+
+ if self.clock:
+ self.clock.message_arrived(m)
+
+ if type == 'MSG':
+ if m.Message.find("Rover") != -1:
+ self.mav_type = mavutil.mavlink.MAV_TYPE_GROUND_ROVER
+ elif m.Message.find("Plane") != -1:
+ self.mav_type = mavutil.mavlink.MAV_TYPE_FIXED_WING
+ elif m.Message.find("Copter") != -1:
+ self.mav_type = mavutil.mavlink.MAV_TYPE_QUADROTOR
+ elif m.Message.startswith("Antenna"):
+ self.mav_type = mavutil.mavlink.MAV_TYPE_ANTENNA_TRACKER
+ if type == 'MODE':
+ if isinstance(m.Mode, str):
+ self.flightmode = m.Mode.upper()
+ elif 'ModeNum' in m._fieldnames:
+ mapping = mavutil.mode_mapping_bynumber(self.mav_type)
+ if mapping is not None and m.ModeNum in mapping:
+ self.flightmode = mapping[m.ModeNum]
+ else:
+ self.flightmode = mavutil.mode_string_acm(m.Mode)
+ if type == 'STAT' and 'MainState' in m._fieldnames:
+ self.flightmode = mavutil.mode_string_px4(m.MainState)
+ if type == 'PARM' and getattr(m, 'Name', None) is not None:
+ self.params[m.Name] = m.Value
+ self._set_time(m)
+
+ def recv_match(self, condition=None, type=None, blocking=False):
+ '''recv the next message that matches the given condition
+ type can be a string or a list of strings'''
+ if type is not None and not isinstance(type, list):
+ type = [type]
+ while True:
+ m = self.recv_msg()
+ if m is None:
+ return None
+ if type is not None and not m.get_type() in type:
+ continue
+ if not mavutil.evaluate_condition(condition, self.messages):
+ continue
+ return m
+
+ def check_condition(self, condition):
+ '''check if a condition is true'''
+ return mavutil.evaluate_condition(condition, self.messages)
+
+ def param(self, name, default=None):
+ '''convenient function for returning an arbitrary MAVLink
+ parameter with a default'''
+ if not name in self.params:
+ return default
+ return self.params[name]
+
+class DFReader_binary(DFReader):
+ '''parse a binary dataflash file'''
+ def __init__(self, filename, zero_time_base=False):
+ DFReader.__init__(self)
+ # read the whole file into memory for simplicity
+ f = open(filename, mode='rb')
+ self.data = f.read()
+ self.data_len = len(self.data)
+ f.close()
+ self.HEAD1 = 0xA3
+ self.HEAD2 = 0x95
+ self.formats = {
+ 0x80 : DFFormat(0x80, 'FMT', 89, 'BBnNZ', "Type,Length,Name,Format,Columns")
+ }
+ self._zero_time_base = zero_time_base
+ self.init_clock()
+ self._rewind()
+
+ def _rewind(self):
+ '''rewind to start of log'''
+ DFReader._rewind(self)
+ self.offset = 0
+ self.remaining = self.data_len
+
+ def _parse_next(self):
+ '''read one message, returning it as an object'''
+ if self.data_len - self.offset < 3:
+ return None
+
+ hdr = self.data[self.offset:self.offset+3]
+ skip_bytes = 0
+ skip_type = None
+ # skip over bad messages
+ while (ord(hdr[0]) != self.HEAD1 or ord(hdr[1]) != self.HEAD2 or ord(hdr[2]) not in self.formats):
+ if skip_type is None:
+ skip_type = (ord(hdr[0]), ord(hdr[1]), ord(hdr[2]))
+ skip_bytes += 1
+ self.offset += 1
+ if self.data_len - self.offset < 3:
+ return None
+ hdr = self.data[self.offset:self.offset+3]
+ msg_type = ord(hdr[2])
+ if skip_bytes != 0:
+ if self.remaining < 528:
+ return None
+ print("Skipped %u bad bytes in log %s remaining=%u" % (skip_bytes, skip_type, self.remaining))
+
+ self.offset += 3
+ self.remaining -= 3
+
+ if not msg_type in self.formats:
+ if self.verbose:
+ print("unknown message type %02x" % msg_type)
+ raise Exception("Unknown message type %02x" % msg_type)
+ fmt = self.formats[msg_type]
+ if self.remaining < fmt.len-3:
+ # out of data - can often happen half way through a message
+ if self.verbose:
+ print("out of data")
+ return None
+ body = self.data[self.offset:self.offset+(fmt.len-3)]
+ try:
+ elements = list(struct.unpack(fmt.msg_struct, body))
+ except Exception:
+ if self.remaining < 528:
+ # we can have garbage at the end of an APM2 log
+ return None
+ print("Failed to parse %s/%s with len %u (remaining %u)" % (fmt.name, fmt.msg_struct, len(body), self.remaining))
+ raise
+ name = null_term(fmt.name)
+ if name == 'FMT':
+ # add to formats
+ # name, len, format, headings
+ self.formats[elements[0]] = DFFormat(elements[0],
+ null_term(elements[2]), elements[1],
+ null_term(elements[3]), null_term(elements[4]))
+
+ self.offset += fmt.len-3
+ self.remaining -= fmt.len-3
+ m = DFMessage(fmt, elements, True)
+ self._add_msg(m)
+
+ self.percent = 100.0 * (self.offset / float(self.data_len))
+
+ return m
+
+def DFReader_is_text_log(filename):
+ '''return True if a file appears to be a valid text log'''
+ f = open(filename)
+ ret = (f.read(8000).find('FMT, ') != -1)
+ f.close()
+ return ret
+
+class DFReader_text(DFReader):
+ '''parse a text dataflash file'''
+ def __init__(self, filename, zero_time_base=False):
+ DFReader.__init__(self)
+ # read the whole file into memory for simplicity
+ f = open(filename, mode='r')
+ self.lines = f.readlines()
+ f.close()
+ self.formats = {
+ 'FMT' : DFFormat(0x80, 'FMT', 89, 'BBnNZ', "Type,Length,Name,Format,Columns")
+ }
+ self._rewind()
+ self._zero_time_base = zero_time_base
+ self.init_clock()
+ self._rewind()
+
+ def _rewind(self):
+ '''rewind to start of log'''
+ DFReader._rewind(self)
+ self.line = 0
+ # find the first valid line
+ while self.line < len(self.lines):
+ if self.lines[self.line].startswith("FMT, "):
+ break
+ self.line += 1
+
+ def _parse_next(self):
+ '''read one message, returning it as an object'''
+ while self.line < len(self.lines):
+ s = self.lines[self.line].rstrip()
+ elements = s.split(", ")
+ # move to next line
+ self.line += 1
+ if len(elements) >= 2:
+ break
+
+ if self.line >= len(self.lines):
+ return None
+
+ # cope with empty structures
+ if len(elements) == 5 and elements[-1] == ',':
+ elements[-1] = ''
+ elements.append('')
+
+ self.percent = 100.0 * (self.line / float(len(self.lines)))
+
+ msg_type = elements[0]
+
+ if not msg_type in self.formats:
+ return self._parse_next()
+
+ fmt = self.formats[msg_type]
+
+ if len(elements) < len(fmt.format)+1:
+ # not enough columns
+ return self._parse_next()
+
+ elements = elements[1:]
+
+ name = fmt.name.rstrip('\0')
+ if name == 'FMT':
+ # add to formats
+ # name, len, format, headings
+ self.formats[elements[2]] = DFFormat(int(elements[0]), elements[2], int(elements[1]), elements[3], elements[4])
+
+ try:
+ m = DFMessage(fmt, elements, False)
+ except ValueError:
+ return self._parse_next()
+
+ self._add_msg(m)
+
+ return m
+
+
+if __name__ == "__main__":
+ import sys
+ use_profiler = False
+ if use_profiler:
+ from line_profiler import LineProfiler
+ profiler = LineProfiler()
+ profiler.add_function(DFReader_binary._parse_next)
+ profiler.add_function(DFReader_binary._add_msg)
+ profiler.add_function(DFReader._set_time)
+ profiler.enable_by_count()
+
+ filename = sys.argv[1]
+ if filename.endswith('.log'):
+ log = DFReader_text(filename)
+ else:
+ log = DFReader_binary(filename)
+ while True:
+ m = log.recv_msg()
+ if m is None:
+ break
+ #print(m)
+ if use_profiler:
+ profiler.print_stats()
+
diff --git a/mavlink-solo/pymavlink/README.txt b/mavlink-solo/pymavlink/README.txt
new file mode 100644
index 0000000..a87f257
--- /dev/null
+++ b/mavlink-solo/pymavlink/README.txt
@@ -0,0 +1,9 @@
+This is a python implementation of the MAVLink protocol.
+
+Please see http://www.qgroundcontrol.org/mavlink/pymavlink for
+documentation
+
+License
+-------
+
+pymavlink is released under the GNU Lesser General Public License v3 or later
diff --git a/mavlink-solo/pymavlink/__init__.py b/mavlink-solo/pymavlink/__init__.py
new file mode 100644
index 0000000..27bfa2b
--- /dev/null
+++ b/mavlink-solo/pymavlink/__init__.py
@@ -0,0 +1 @@
+'''Python MAVLink library - see http://www.qgroundcontrol.org/mavlink/mavproxy_startpage'''
diff --git a/mavlink-solo/pymavlink/__init__.pyc b/mavlink-solo/pymavlink/__init__.pyc
new file mode 100644
index 0000000..ae4ef23
Binary files /dev/null and b/mavlink-solo/pymavlink/__init__.pyc differ
diff --git a/mavlink-solo/pymavlink/dialects/__init__.py b/mavlink-solo/pymavlink/dialects/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/mavlink-solo/pymavlink/dialects/v09/__init__.py b/mavlink-solo/pymavlink/dialects/v09/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/mavlink-solo/pymavlink/dialects/v10/__init__.py b/mavlink-solo/pymavlink/dialects/v10/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/mavlink-solo/pymavlink/examples/__init__.py b/mavlink-solo/pymavlink/examples/__init__.py
new file mode 100644
index 0000000..95eeffc
--- /dev/null
+++ b/mavlink-solo/pymavlink/examples/__init__.py
@@ -0,0 +1 @@
+'''This folder contains various example scripts demonstrating MAVLink functionality.'''
diff --git a/mavlink-solo/pymavlink/examples/apmsetrate.py b/mavlink-solo/pymavlink/examples/apmsetrate.py
new file mode 100755
index 0000000..1b98b17
--- /dev/null
+++ b/mavlink-solo/pymavlink/examples/apmsetrate.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+'''
+set stream rate on an APM
+'''
+
+import sys, struct, time, os
+
+from argparse import ArgumentParser
+parser = ArgumentParser(description=__doc__)
+
+parser.add_argument("--baudrate", type=int,
+ help="master port baud rate", default=115200)
+parser.add_argument("--device", required=True, help="serial device")
+parser.add_argument("--rate", default=4, type=int, help="requested stream rate")
+parser.add_argument("--source-system", dest='SOURCE_SYSTEM', type=int,
+ default=255, help='MAVLink source system for this GCS')
+parser.add_argument("--showmessages", action='store_true',
+ help="show incoming messages", default=False)
+args = parser.parse_args()
+
+from pymavlink import mavutil
+
+def wait_heartbeat(m):
+ '''wait for a heartbeat so we know the target system IDs'''
+ print("Waiting for APM heartbeat")
+ m.wait_heartbeat()
+ print("Heartbeat from APM (system %u component %u)" % (m.target_system, m.target_system))
+
+def show_messages(m):
+ '''show incoming mavlink messages'''
+ while True:
+ msg = m.recv_match(blocking=True)
+ if not msg:
+ return
+ if msg.get_type() == "BAD_DATA":
+ if mavutil.all_printable(msg.data):
+ sys.stdout.write(msg.data)
+ sys.stdout.flush()
+ else:
+ print(msg)
+
+# create a mavlink serial instance
+master = mavutil.mavlink_connection(args.device, baud=args.baudrate)
+
+# wait for the heartbeat msg to find the system ID
+wait_heartbeat(master)
+
+print("Sending all stream request for rate %u" % args.rate)
+for i in range(0, 3):
+ master.mav.request_data_stream_send(master.target_system, master.target_component,
+ mavutil.mavlink.MAV_DATA_STREAM_ALL, args.rate, 1)
+if args.showmessages:
+ show_messages(master)
diff --git a/mavlink-solo/pymavlink/examples/bwtest.py b/mavlink-solo/pymavlink/examples/bwtest.py
new file mode 100755
index 0000000..7596161
--- /dev/null
+++ b/mavlink-solo/pymavlink/examples/bwtest.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+'''
+check bandwidth of link
+'''
+
+import sys, struct, time, os
+
+from pymavlink import mavutil
+
+from argparse import ArgumentParser
+parser = ArgumentParser(description=__doc__)
+
+parser.add_argument("--baudrate", type=int,
+ help="master port baud rate", default=115200)
+parser.add_argument("--device", required=True, help="serial device")
+args = parser.parse_args()
+
+# create a mavlink serial instance
+master = mavutil.mavlink_connection(args.device, baud=args.baudrate)
+
+t1 = time.time()
+
+counts = {}
+
+bytes_sent = 0
+bytes_recv = 0
+
+while True:
+ master.mav.heartbeat_send(1, 1)
+ master.mav.sys_status_send(1, 2, 3, 4, 5, 6, 7)
+ master.mav.gps_raw_send(1, 2, 3, 4, 5, 6, 7, 8, 9)
+ master.mav.attitude_send(1, 2, 3, 4, 5, 6, 7)
+ master.mav.vfr_hud_send(1, 2, 3, 4, 5, 6)
+ while master.port.inWaiting() > 0:
+ m = master.recv_msg()
+ if m == None: break
+ if m.get_type() not in counts:
+ counts[m.get_type()] = 0
+ counts[m.get_type()] += 1
+ t2 = time.time()
+ if t2 - t1 > 1.0:
+ print("%u sent, %u received, %u errors bwin=%.1f kB/s bwout=%.1f kB/s" % (
+ master.mav.total_packets_sent,
+ master.mav.total_packets_received,
+ master.mav.total_receive_errors,
+ 0.001*(master.mav.total_bytes_received-bytes_recv)/(t2-t1),
+ 0.001*(master.mav.total_bytes_sent-bytes_sent)/(t2-t1)))
+ bytes_sent = master.mav.total_bytes_sent
+ bytes_recv = master.mav.total_bytes_received
+ t1 = t2
diff --git a/mavlink-solo/pymavlink/examples/magtest.py b/mavlink-solo/pymavlink/examples/magtest.py
new file mode 100755
index 0000000..228254b
--- /dev/null
+++ b/mavlink-solo/pymavlink/examples/magtest.py
@@ -0,0 +1,113 @@
+#!/usr/bin/env python
+
+'''
+rotate APMs on bench to test magnetometers
+
+'''
+
+import sys, os, time
+from math import radians
+
+from pymavlink import mavutil
+
+from argparse import ArgumentParser
+parser = ArgumentParser(description=__doc__)
+
+parser.add_argument("--device1", required=True, help="mavlink device1")
+parser.add_argument("--device2", required=True, help="mavlink device2")
+parser.add_argument("--baudrate", type=int,
+ help="master port baud rate", default=115200)
+args = parser.parse_args()
+
+def set_attitude(rc3, rc4):
+ global mav1, mav2
+ values = [ 65535 ] * 8
+ values[2] = rc3
+ values[3] = rc4
+ mav1.mav.rc_channels_override_send(mav1.target_system, mav1.target_component, *values)
+ mav2.mav.rc_channels_override_send(mav2.target_system, mav2.target_component, *values)
+
+
+# create a mavlink instance
+mav1 = mavutil.mavlink_connection(args.device1, baud=args.baudrate)
+
+# create a mavlink instance
+mav2 = mavutil.mavlink_connection(args.device2, baud=args.baudrate)
+
+print("Waiting for HEARTBEAT")
+mav1.wait_heartbeat()
+mav2.wait_heartbeat()
+print("Heartbeat from APM (system %u component %u)" % (mav1.target_system, mav1.target_system))
+print("Heartbeat from APM (system %u component %u)" % (mav2.target_system, mav2.target_system))
+
+print("Waiting for MANUAL mode")
+mav1.recv_match(type='SYS_STATUS', condition='SYS_STATUS.mode==2 and SYS_STATUS.nav_mode==4', blocking=True)
+mav2.recv_match(type='SYS_STATUS', condition='SYS_STATUS.mode==2 and SYS_STATUS.nav_mode==4', blocking=True)
+
+print("Setting declination")
+mav1.mav.param_set_send(mav1.target_system, mav1.target_component,
+ 'COMPASS_DEC', radians(12.33))
+mav2.mav.param_set_send(mav2.target_system, mav2.target_component,
+ 'COMPASS_DEC', radians(12.33))
+
+
+set_attitude(1060, 1160)
+
+event = mavutil.periodic_event(30)
+pevent = mavutil.periodic_event(0.3)
+rc3_min = 1060
+rc3_max = 1850
+rc4_min = 1080
+rc4_max = 1500
+rc3 = rc3_min
+rc4 = 1160
+delta3 = 2
+delta4 = 1
+use_pitch = 1
+
+MAV_ACTION_CALIBRATE_GYRO = 17
+mav1.mav.action_send(mav1.target_system, mav1.target_component, MAV_ACTION_CALIBRATE_GYRO)
+mav2.mav.action_send(mav2.target_system, mav2.target_component, MAV_ACTION_CALIBRATE_GYRO)
+
+print("Waiting for gyro calibration")
+mav1.recv_match(type='ACTION_ACK')
+mav2.recv_match(type='ACTION_ACK')
+
+print("Resetting mag offsets")
+mav1.mav.set_mag_offsets_send(mav1.target_system, mav1.target_component, 0, 0, 0)
+mav2.mav.set_mag_offsets_send(mav2.target_system, mav2.target_component, 0, 0, 0)
+
+def TrueHeading(SERVO_OUTPUT_RAW):
+ p = float(SERVO_OUTPUT_RAW.servo3_raw - rc3_min) / (rc3_max - rc3_min)
+ return 172 + p*(326 - 172)
+
+while True:
+ mav1.recv_msg()
+ mav2.recv_msg()
+ if event.trigger():
+ if not use_pitch:
+ rc4 = 1160
+ set_attitude(rc3, rc4)
+ rc3 += delta3
+ if rc3 > rc3_max or rc3 < rc3_min:
+ delta3 = -delta3
+ use_pitch ^= 1
+ rc4 += delta4
+ if rc4 > rc4_max or rc4 < rc4_min:
+ delta4 = -delta4
+ if pevent.trigger():
+ print("hdg1: %3u hdg2: %3u ofs1: %4u, %4u, %4u ofs2: %4u, %4u, %4u" % (
+ mav1.messages['VFR_HUD'].heading,
+ mav2.messages['VFR_HUD'].heading,
+ mav1.messages['SENSOR_OFFSETS'].mag_ofs_x,
+ mav1.messages['SENSOR_OFFSETS'].mag_ofs_y,
+ mav1.messages['SENSOR_OFFSETS'].mag_ofs_z,
+ mav2.messages['SENSOR_OFFSETS'].mag_ofs_x,
+ mav2.messages['SENSOR_OFFSETS'].mag_ofs_y,
+ mav2.messages['SENSOR_OFFSETS'].mag_ofs_z,
+ ))
+ time.sleep(0.01)
+
+# 314M 326G
+# 160M 172G
+
diff --git a/mavlink-solo/pymavlink/examples/mav2pcap.py b/mavlink-solo/pymavlink/examples/mav2pcap.py
new file mode 100755
index 0000000..2498db7
--- /dev/null
+++ b/mavlink-solo/pymavlink/examples/mav2pcap.py
@@ -0,0 +1,228 @@
+#!/usr/bin/env python
+
+# Copyright 2012, Holger Steinhaus
+# Released under the GNU GPL version 3 or later
+
+# This program packetizes a binary MAVLink stream. The resulting packets are stored into a PCAP file, which is
+# compatible to tools like Wireshark.
+
+# The program tries to synchronize to the packet structure in a robust way, using the SOF magic, the potential
+# packet length information and the next SOF magic. Additionally the CRC is verified.
+
+# Hint: A MAVLink protocol dissector (parser) for Wireshark may be generated by mavgen.py.
+
+# dependency: Python construct library (python-construct on Debian/Ubuntu), "easy_install construct" elsewhere
+
+
+import sys
+import os
+
+from pymavlink import mavutil
+
+from construct import ULInt16, Struct, Byte, Bytes, Const
+from construct.core import FieldError
+from argparse import ArgumentParser, FileType
+
+
+MAVLINK_MAGIC = 0xfe
+write_junk = True
+
+# copied from ardupilotmega.h (git changeset 694536afb882068f50da1fc296944087aa207f9f, Dec 02 2012
+MAVLINK_MESSAGE_CRCS = (50, 124, 137, 0, 237, 217, 104, 119, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 0, 214, 159, 220, 168, 24, 23, 170, 144, 67, 115, 39, 246, 185, 104, 237, 244, 242, 212, 9, 254, 230, 28, 28, 132, 221, 232, 11, 153, 41, 39, 214, 223, 141, 33, 15, 3, 100, 24, 239, 238, 30, 240, 183, 130, 130, 0, 148, 21, 0, 243, 124, 0, 0, 0, 20, 0, 152, 143, 0, 0, 127, 106, 0, 0, 0, 0, 0, 0, 0, 231, 183, 63, 54, 0, 0, 0, 0, 0, 0, 0, 175, 102, 158, 208, 56, 93, 0, 0, 0, 0, 235, 93, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 241, 15, 134, 219, 208, 188, 84, 22, 19, 21, 134, 0, 78, 68, 189, 127, 111, 21, 21, 144, 1, 234, 73, 181, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 49, 170, 44, 83, 46, 0)
+
+
+import __builtin__
+import struct
+
+# Helper class for writing pcap files
+class pcap:
+ """
+ Used under the terms of GNU GPL v3.
+ Original author: Neale Pickett
+ see http://dirtbags.net/py-pcap.html
+ """
+ _MAGIC = 0xA1B2C3D4
+ def __init__(self, stream, mode='rb', snaplen=65535, linktype=1):
+ try:
+ self.stream = __builtin__.open(stream, mode)
+ except TypeError:
+ self.stream = stream
+ try:
+ # Try reading
+ hdr = self.stream.read(24)
+ except IOError:
+ hdr = None
+
+ if hdr:
+ # We're in read mode
+ self._endian = pcap.None
+ for endian in '<>':
+ (self.magic,) = struct.unpack(endian + 'I', hdr[:4])
+ if self.magic == pcap._MAGIC:
+ self._endian = endian
+ break
+ if not self._endian:
+ raise IOError('Not a pcap file')
+ (self.magic, version_major, version_minor,
+ self.thiszone, self.sigfigs,
+ self.snaplen, self.linktype) = struct.unpack(self._endian + 'IHHIIII', hdr)
+ if (version_major, version_minor) != (2, 4):
+ raise IOError('Cannot handle file version %d.%d' % (version_major,
+ version_minor))
+ else:
+ # We're in write mode
+ self._endian = '='
+ self.magic = pcap._MAGIC
+ version_major = 2
+ version_minor = 4
+ self.thiszone = 0
+ self.sigfigs = 0
+ self.snaplen = snaplen
+ self.linktype = linktype
+ hdr = struct.pack(self._endian + 'IHHIIII',
+ self.magic, version_major, version_minor,
+ self.thiszone, self.sigfigs,
+ self.snaplen, self.linktype)
+ self.stream.write(hdr)
+ self.version = (version_major, version_minor)
+
+ def read(self):
+ hdr = self.stream.read(16)
+ if not hdr:
+ return
+ (tv_sec, tv_usec, caplen, length) = struct.unpack(self._endian + 'IIII', hdr)
+ datum = self.stream.read(caplen)
+ return ((tv_sec, tv_usec, length), datum)
+
+ def write(self, packet):
+ (header, datum) = packet
+ (tv_sec, tv_usec, length) = header
+ hdr = struct.pack(self._endian + 'IIII', tv_sec, tv_usec, length, len(datum))
+ self.stream.write(hdr)
+ self.stream.write(datum)
+
+ def __iter__(self):
+ while True:
+ r = self.read()
+ if not r:
+ break
+ yield r
+
+
+def find_next_frame(data):
+ """
+ find a potential start of frame
+ """
+ return data.find('\xfe')
+
+
+def parse_header(data):
+ """
+ split up header information (using construct)
+ """
+ mavlink_header = Struct('header',
+ Const(Byte('magic'), MAVLINK_MAGIC),
+ Byte('plength'),
+ Byte('sequence'),
+ Byte('sysid'),
+ Byte('compid'),
+ Byte('msgid'),
+ )
+ return mavlink_header.parse(data[0:6])
+
+
+def write_packet(number, data, flags, pkt_length):
+ pcap_header = (number, flags, pkt_length)
+ pcap_file.write((pcap_header, data))
+
+
+def convert_file(mavlink_file, pcap_file):
+ # the whole file is read in a bunch - room for improvement...
+ data = mavlink_file.read()
+
+ i=0
+ done = False
+ skipped_char = None
+ junk = ''
+ cnt_ok = 0
+ cnt_junk = 0
+ cnt_crc = 0
+
+ while not done:
+ i+=1
+ # look for potential start of frame
+ next_sof = find_next_frame(data)
+ if next_sof > 0:
+ print("skipped " + str(next_sof) + " bytes")
+ if write_junk:
+ if skipped_char != None:
+ junk = skipped_char + data[:next_sof]
+ skipped_char = None
+ write_packet(i, junk, 0x03, len(junk))
+ data = data[next_sof:]
+ data[:6]
+ cnt_junk += 1
+
+ # assume, our 0xFE was the start of a packet
+ header = parse_header(data)
+ payload_len = header['plength']
+ pkt_length = 6 + payload_len + 2
+ try:
+ pkt_crc = ULInt16('crc').parse(data[pkt_length-2:pkt_length])
+ except FieldError:
+ # ups, no more data
+ done = True
+ continue
+
+ # peek for the next SOF
+ try:
+ cc = mavutil.x25crc(data[1:6+payload_len])
+ cc.accumulate(chr(MAVLINK_MESSAGE_CRCS[header['msgid']]))
+ x25_crc = cc.crc
+ if x25_crc != pkt_crc:
+ crc_flag = 0x1
+ else:
+ crc_flag = 0
+ next_magic = data[pkt_length]
+ if chr(MAVLINK_MAGIC) != next_magic:
+ # damn, retry
+ print("packet %d has invalid length, crc error: %d" % (i, crc_flag))
+
+ # skip one char to look for a new SOF next round, stow away skipped char
+ skipped_char = data[0]
+ data = data[1:]
+ continue
+
+ # we can consider it a packet now
+ pkt = data[:pkt_length]
+ write_packet(i, pkt, crc_flag, len(pkt))
+ print("packet %d ok, crc error: %d" % (i, crc_flag))
+ data = data[pkt_length:]
+
+ if crc_flag:
+ cnt_crc += 1
+ else:
+ cnt_ok += 1
+
+
+ except IndexError:
+ # ups, no more packets
+ done = True
+ print("converted %d valid packets, %d crc errors, %d junk fragments (total %f%% of junk)" % (cnt_ok, cnt_crc, cnt_junk, 100.*float(cnt_junk+cnt_crc)/(cnt_junk+cnt_ok+cnt_crc)))
+
+###############################################################################
+
+parser = ArgumentParser()
+parser.add_argument("input_file", type=FileType('rb'))
+parser.add_argument("output_file", type=FileType('wb'))
+args = parser.parse_args()
+
+
+mavlink_file = args.input_file
+args.output_file.close()
+pcap_file = pcap(args.output_file.name, args.output_file.mode, linktype=147) # special trick: linktype USER0
+
+convert_file(mavlink_file, pcap_file)
+
+mavlink_file.close()
+#pcap_file.close()
diff --git a/mavlink-solo/pymavlink/examples/mav_accel.py b/mavlink-solo/pymavlink/examples/mav_accel.py
new file mode 100755
index 0000000..b55ee82
--- /dev/null
+++ b/mavlink-solo/pymavlink/examples/mav_accel.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+
+'''
+show accel calibration for a set of logs
+'''
+
+import sys, time, os
+
+from argparse import ArgumentParser
+parser = ArgumentParser()
+parser.add_argument("--no-timestamps", dest="notimestamps", action='store_true', help="Log doesn't have timestamps")
+parser.add_argument("--planner", action='store_true', help="use planner file format")
+parser.add_argument("--robust", action='store_true', help="Enable robust parsing (skip over bad data)")
+parser.add_argument("logs", metavar="LOG", nargs="+")
+
+args = parser.parse_args()
+
+from pymavlink import mavutil
+
+
+def process(logfile):
+ '''display accel cal for a log file'''
+ mlog = mavutil.mavlink_connection(filename,
+ planner_format=args.planner,
+ notimestamps=args.notimestamps,
+ robust_parsing=args.robust)
+
+ m = mlog.recv_match(type='SENSOR_OFFSETS')
+ if m is not None:
+ z_sensor = (m.accel_cal_z - 9.805) * (4096/9.81)
+ print("accel cal %5.2f %5.2f %5.2f %6u %s" % (
+ m.accel_cal_x, m.accel_cal_y, m.accel_cal_z,
+ z_sensor,
+ logfile))
+
+
+total = 0.0
+for filename in args.logs:
+ process(filename)
diff --git a/mavlink-solo/pymavlink/examples/mavgps.py b/mavlink-solo/pymavlink/examples/mavgps.py
new file mode 100755
index 0000000..003d78b
--- /dev/null
+++ b/mavlink-solo/pymavlink/examples/mavgps.py
@@ -0,0 +1,70 @@
+#!/usr/bin/python
+"""
+Allows connection of the uBlox u-Center software to
+a uBlox GPS device connected to a PX4 or Pixhawk device,
+using Mavlink's SERIAL_CONTROL support to route serial
+traffic to/from the GPS, and exposing the data to u-Center
+via a local TCP connection.
+
+@author: Matthew Lloyd (github@matthewlloyd.net)
+"""
+
+from pymavlink import mavutil
+from argparse import ArgumentParser
+import socket
+
+
+def main():
+ parser = ArgumentParser(description=__doc__)
+ parser.add_argument("--mavport", required=True,
+ help="Mavlink port name")
+ parser.add_argument("--mavbaud", type=int,
+ help="Mavlink port baud rate", default=115200)
+ parser.add_argument("--devnum", default=2, type=int,
+ help="PX4 UART device number (defaults to GPS port)")
+ parser.add_argument("--devbaud", default=38400, type=int,
+ help="PX4 UART baud rate (defaults to u-Blox GPS baud)")
+ parser.add_argument("--tcpport", default=1001, type=int,
+ help="local TCP port (defaults to %(default)s)")
+ parser.add_argument("--tcpaddr", default='127.0.0.1', type=str,
+ help="local TCP address (defaults to %(default)s)")
+ parser.add_argument("--debug", default=0, type=int,
+ help="debug level")
+ parser.add_argument("--buffsize", default=128, type=int,
+ help="buffer size")
+ args = parser.parse_args()
+
+ print("Connecting to MAVLINK...")
+ mav_serialport = mavutil.MavlinkSerialPort(
+ args.mavport, args.mavbaud,
+ devnum=args.devnum, devbaud=args.devbaud, debug=args.debug)
+
+ listen_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ listen_sock.bind((args.tcpaddr, args.tcpport))
+ listen_sock.listen(1)
+
+ print("Waiting for a TCP connection.")
+ print("Use tcp://%s:%d in u-Center." % (args.tcpaddr, args.tcpport))
+ conn_sock, addr = listen_sock.accept()
+ conn_sock.setblocking(0) # non-blocking mode
+ print("TCP connection accepted. Use Ctrl+C to exit.")
+
+ while True:
+ try:
+ data = conn_sock.recv(args.buffsize)
+ if data:
+ if args.debug >= 1:
+ print '>', len(data)
+ mav_serialport.write(data)
+ except socket.error:
+ pass
+
+ data = mav_serialport.read(args.buffsize)
+ if data:
+ if args.debug >= 1:
+ print '<', len(data)
+ conn_sock.send(data)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/mavlink-solo/pymavlink/examples/mavtcpsniff.py b/mavlink-solo/pymavlink/examples/mavtcpsniff.py
new file mode 100755
index 0000000..778efed
--- /dev/null
+++ b/mavlink-solo/pymavlink/examples/mavtcpsniff.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python
+
+'''
+connect as a client to two tcpip ports on localhost with mavlink packets. pass them both directions, and show packets in human-readable format on-screen.
+
+this is useful if
+* you have two SITL instances you want to connect to each other and see the comms.
+* you have any tcpip based mavlink happening, and want something better than tcpdump
+
+hint:
+* you can use netcat/nc to do interesting redorection things with each end if you want to.
+
+Copyright Sept 2012 David "Buzz" Bussenschutt
+Released under GNU GPL version 3 or later
+'''
+
+import sys, time, os, struct
+
+from pymavlink import mavutil
+#from pymavlink import mavlinkv10 as mavlink
+
+from argparse import ArgumentParser
+parser = ArgumentParser(description=__doc__)
+parser.add_argument("srcport", type=int)
+parser.add_argument("dstport", type=int)
+
+args = parser.parse_args()
+
+msrc = mavutil.mavlink_connection('tcp:localhost:{}'.format(args.srcport), planner_format=False,
+ notimestamps=True,
+ robust_parsing=True)
+
+mdst = mavutil.mavlink_connection('tcp:localhost:{}'.format(args.dstport), planner_format=False,
+ notimestamps=True,
+ robust_parsing=True)
+
+
+# simple basic byte pass through, no logging or viewing of packets, or analysis etc
+#while True:
+# # L -> R
+# m = msrc.recv();
+# mdst.write(m);
+# # R -> L
+# m2 = mdst.recv();
+# msrc.write(m2);
+
+
+# similar to the above, but with human-readable display of packets on stdout.
+# in this use case we abuse the self.logfile_raw() function to allow
+# us to use the recv_match function ( whch is then calling recv_msg ) , to still get the raw data stream
+# which we pass off to the other mavlink connection without any interference.
+# because internally it will call logfile_raw.write() for us.
+
+# here we hook raw output of one to the raw input of the other, and vice versa:
+msrc.logfile_raw = mdst
+mdst.logfile_raw = msrc
+
+while True:
+ # L -> R
+ l = msrc.recv_match();
+ if l is not None:
+ l_last_timestamp = 0
+ if l.get_type() != 'BAD_DATA':
+ l_timestamp = getattr(l, '_timestamp', None)
+ if not l_timestamp:
+ l_timestamp = l_last_timestamp
+ l_last_timestamp = l_timestamp
+
+ print("--> %s.%02u: %s\n" % (
+ time.strftime("%Y-%m-%d %H:%M:%S",
+ time.localtime(l._timestamp)),
+ int(l._timestamp*100.0)%100, l))
+
+ # R -> L
+ r = mdst.recv_match();
+ if r is not None:
+ r_last_timestamp = 0
+ if r.get_type() != 'BAD_DATA':
+ r_timestamp = getattr(r, '_timestamp', None)
+ if not r_timestamp:
+ r_timestamp = r_last_timestamp
+ r_last_timestamp = r_timestamp
+
+ print("<-- %s.%02u: %s\n" % (
+ time.strftime("%Y-%m-%d %H:%M:%S",
+ time.localtime(r._timestamp)),
+ int(r._timestamp*100.0)%100, r))
+
+
+
diff --git a/mavlink-solo/pymavlink/examples/mavtest.py b/mavlink-solo/pymavlink/examples/mavtest.py
new file mode 100755
index 0000000..f409024
--- /dev/null
+++ b/mavlink-solo/pymavlink/examples/mavtest.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+
+import sys, os
+
+from pymavlink import mavlinkv10 as mavlink
+
+class fifo(object):
+ def __init__(self):
+ self.buf = []
+ def write(self, data):
+ self.buf += data
+ return len(data)
+ def read(self):
+ return self.buf.pop(0)
+
+# we will use a fifo as an encode/decode buffer
+f = fifo()
+
+# create a mavlink instance, which will do IO on file object 'f'
+mav = mavlink.MAVLink(f)
+
+# set the WP_RADIUS parameter on the MAV at the end of the link
+mav.param_set_send(7, 1, "WP_RADIUS", 101, mavlink.MAV_PARAM_TYPE_REAL32)
+
+# alternatively, produce a MAVLink_param_set object
+# this can be sent via your own transport if you like
+m = mav.param_set_encode(7, 1, "WP_RADIUS", 101, mavlink.MAV_PARAM_TYPE_REAL32)
+
+# get the encoded message as a buffer
+b = m.get_msgbuf()
+
+# decode an incoming message
+m2 = mav.decode(b)
+
+# show what fields it has
+print("Got a message with id %u and fields %s" % (m2.get_msgId(), m2.get_fieldnames()))
+
+# print out the fields
+print(m2)
diff --git a/mavlink-solo/pymavlink/examples/mavtester.py b/mavlink-solo/pymavlink/examples/mavtester.py
new file mode 100755
index 0000000..b73e03c
--- /dev/null
+++ b/mavlink-solo/pymavlink/examples/mavtester.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+
+'''
+test mavlink messages
+'''
+
+import sys, struct, time, os
+from curses import ascii
+
+from pymavlink import mavtest, mavutil
+
+from argparse import ArgumentParser
+parser = ArgumentParser(description=__doc__)
+
+parser.add_argument("--baudrate", type=int,
+ help="master port baud rate", default=115200)
+parser.add_argument("--device", required=True, help="serial device")
+parser.add_argument("--source-system", dest='SOURCE_SYSTEM', type=int,
+ default=255, help='MAVLink source system for this GCS')
+args = parser.parse_args()
+
+def wait_heartbeat(m):
+ '''wait for a heartbeat so we know the target system IDs'''
+ print("Waiting for APM heartbeat")
+ msg = m.recv_match(type='HEARTBEAT', blocking=True)
+ print("Heartbeat from APM (system %u component %u)" % (m.target_system, m.target_system))
+
+# create a mavlink serial instance
+master = mavutil.mavlink_connection(args.device, baud=args.baudrate, source_system=args.SOURCE_SYSTEM)
+
+# wait for the heartbeat msg to find the system ID
+wait_heartbeat(master)
+
+print("Sending all message types")
+mavtest.generate_outputs(master.mav)
+
diff --git a/mavlink-solo/pymavlink/examples/wptogpx.py b/mavlink-solo/pymavlink/examples/wptogpx.py
new file mode 100755
index 0000000..e31ef5e
--- /dev/null
+++ b/mavlink-solo/pymavlink/examples/wptogpx.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+
+'''
+example program to extract GPS data from a waypoint file, and create a GPX
+file, for loading into google earth
+'''
+
+import sys, struct, time, os
+
+from argparse import ArgumentParser
+parser = ArgumentParser(description=__doc__)
+parser.add_argument("wpfiles", metavar="WP_FILE", nargs="+")
+args = parser.parse_args()
+
+from pymavlink import mavutil, mavwp
+
+
+def wp_to_gpx(infilename, outfilename):
+ '''convert a wp file to a GPX file'''
+
+ wp = mavwp.MAVWPLoader()
+ wp.load(infilename)
+ outf = open(outfilename, mode='w')
+
+ def process_wp(w, i):
+ t = time.localtime(i)
+ outf.write('''
+ %s
+ WP %u
+
+''' % (w.x, w.y, w.z, i))
+
+ def add_header():
+ outf.write('''
+
+''')
+
+ def add_footer():
+ outf.write('''
+
+''')
+
+ add_header()
+
+ count = 0
+ for i in range(wp.count()):
+ w = wp.wp(i)
+ if w.frame == 3:
+ w.z += wp.wp(0).z
+ if w.command == 16:
+ process_wp(w, i)
+ count += 1
+ add_footer()
+ print("Created %s with %u points" % (outfilename, count))
+
+
+for infilename in args.wpfiles:
+ outfilename = infilename + '.gpx'
+ wp_to_gpx(infilename, outfilename)
diff --git a/mavlink-solo/pymavlink/fgFDM.py b/mavlink-solo/pymavlink/fgFDM.py
new file mode 100644
index 0000000..d381afa
--- /dev/null
+++ b/mavlink-solo/pymavlink/fgFDM.py
@@ -0,0 +1,212 @@
+#!/usr/bin/env python
+# parse and construct FlightGear NET FDM packets
+# Andrew Tridgell, November 2011
+# released under GNU GPL version 2 or later
+
+import struct, math
+
+class fgFDMError(Exception):
+ '''fgFDM error class'''
+ def __init__(self, msg):
+ Exception.__init__(self, msg)
+ self.message = 'fgFDMError: ' + msg
+
+class fgFDMVariable(object):
+ '''represent a single fgFDM variable'''
+ def __init__(self, index, arraylength, units):
+ self.index = index
+ self.arraylength = arraylength
+ self.units = units
+
+class fgFDMVariableList(object):
+ '''represent a list of fgFDM variable'''
+ def __init__(self):
+ self.vars = {}
+ self._nextidx = 0
+
+ def add(self, varname, arraylength=1, units=None):
+ self.vars[varname] = fgFDMVariable(self._nextidx, arraylength, units=units)
+ self._nextidx += arraylength
+
+class fgFDM(object):
+ '''a flightgear native FDM parser/generator'''
+ def __init__(self):
+ '''init a fgFDM object'''
+ self.FG_NET_FDM_VERSION = 24
+ self.pack_string = '>I 4x 3d 6f 11f 3f 2f I 4I 4f 4f 4f 4f 4f 4f 4f 4f 4f I 4f I 3I 3f 3f 3f I i f 10f'
+ self.values = [0]*98
+
+ self.FG_MAX_ENGINES = 4
+ self.FG_MAX_WHEELS = 3
+ self.FG_MAX_TANKS = 4
+
+ # supported unit mappings
+ self.unitmap = {
+ ('radians', 'degrees') : math.degrees(1),
+ ('rps', 'dps') : math.degrees(1),
+ ('feet', 'meters') : 0.3048,
+ ('fps', 'mps') : 0.3048,
+ ('knots', 'mps') : 0.514444444,
+ ('knots', 'fps') : 0.514444444/0.3048,
+ ('fpss', 'mpss') : 0.3048,
+ ('seconds', 'minutes') : 60,
+ ('seconds', 'hours') : 3600,
+ }
+
+ # build a mapping between variable name and index in the values array
+ # note that the order of this initialisation is critical - it must
+ # match the wire structure
+ self.mapping = fgFDMVariableList()
+ self.mapping.add('version')
+
+ # position
+ self.mapping.add('longitude', units='radians') # geodetic (radians)
+ self.mapping.add('latitude', units='radians') # geodetic (radians)
+ self.mapping.add('altitude', units='meters') # above sea level (meters)
+ self.mapping.add('agl', units='meters') # above ground level (meters)
+
+ # attitude
+ self.mapping.add('phi', units='radians') # roll (radians)
+ self.mapping.add('theta', units='radians') # pitch (radians)
+ self.mapping.add('psi', units='radians') # yaw or true heading (radians)
+ self.mapping.add('alpha', units='radians') # angle of attack (radians)
+ self.mapping.add('beta', units='radians') # side slip angle (radians)
+
+ # Velocities
+ self.mapping.add('phidot', units='rps') # roll rate (radians/sec)
+ self.mapping.add('thetadot', units='rps') # pitch rate (radians/sec)
+ self.mapping.add('psidot', units='rps') # yaw rate (radians/sec)
+ self.mapping.add('vcas', units='fps') # calibrated airspeed
+ self.mapping.add('climb_rate', units='fps') # feet per second
+ self.mapping.add('v_north', units='fps') # north velocity in local/body frame, fps
+ self.mapping.add('v_east', units='fps') # east velocity in local/body frame, fps
+ self.mapping.add('v_down', units='fps') # down/vertical velocity in local/body frame, fps
+ self.mapping.add('v_wind_body_north', units='fps') # north velocity in local/body frame
+ self.mapping.add('v_wind_body_east', units='fps') # east velocity in local/body frame
+ self.mapping.add('v_wind_body_down', units='fps') # down/vertical velocity in local/body
+
+ # Accelerations
+ self.mapping.add('A_X_pilot', units='fpss') # X accel in body frame ft/sec^2
+ self.mapping.add('A_Y_pilot', units='fpss') # Y accel in body frame ft/sec^2
+ self.mapping.add('A_Z_pilot', units='fpss') # Z accel in body frame ft/sec^2
+
+ # Stall
+ self.mapping.add('stall_warning') # 0.0 - 1.0 indicating the amount of stall
+ self.mapping.add('slip_deg', units='degrees') # slip ball deflection
+
+ # Engine status
+ self.mapping.add('num_engines') # Number of valid engines
+ self.mapping.add('eng_state', self.FG_MAX_ENGINES) # Engine state (off, cranking, running)
+ self.mapping.add('rpm', self.FG_MAX_ENGINES) # Engine RPM rev/min
+ self.mapping.add('fuel_flow', self.FG_MAX_ENGINES) # Fuel flow gallons/hr
+ self.mapping.add('fuel_px', self.FG_MAX_ENGINES) # Fuel pressure psi
+ self.mapping.add('egt', self.FG_MAX_ENGINES) # Exhuast gas temp deg F
+ self.mapping.add('cht', self.FG_MAX_ENGINES) # Cylinder head temp deg F
+ self.mapping.add('mp_osi', self.FG_MAX_ENGINES) # Manifold pressure
+ self.mapping.add('tit', self.FG_MAX_ENGINES) # Turbine Inlet Temperature
+ self.mapping.add('oil_temp', self.FG_MAX_ENGINES) # Oil temp deg F
+ self.mapping.add('oil_px', self.FG_MAX_ENGINES) # Oil pressure psi
+
+ # Consumables
+ self.mapping.add('num_tanks') # Max number of fuel tanks
+ self.mapping.add('fuel_quantity', self.FG_MAX_TANKS)
+
+ # Gear status
+ self.mapping.add('num_wheels')
+ self.mapping.add('wow', self.FG_MAX_WHEELS)
+ self.mapping.add('gear_pos', self.FG_MAX_WHEELS)
+ self.mapping.add('gear_steer', self.FG_MAX_WHEELS)
+ self.mapping.add('gear_compression', self.FG_MAX_WHEELS)
+
+ # Environment
+ self.mapping.add('cur_time', units='seconds') # current unix time
+ self.mapping.add('warp', units='seconds') # offset in seconds to unix time
+ self.mapping.add('visibility', units='meters') # visibility in meters (for env. effects)
+
+ # Control surface positions (normalized values)
+ self.mapping.add('elevator')
+ self.mapping.add('elevator_trim_tab')
+ self.mapping.add('left_flap')
+ self.mapping.add('right_flap')
+ self.mapping.add('left_aileron')
+ self.mapping.add('right_aileron')
+ self.mapping.add('rudder')
+ self.mapping.add('nose_wheel')
+ self.mapping.add('speedbrake')
+ self.mapping.add('spoilers')
+
+ self._packet_size = struct.calcsize(self.pack_string)
+
+ self.set('version', self.FG_NET_FDM_VERSION)
+
+ if len(self.values) != self.mapping._nextidx:
+ raise fgFDMError('Invalid variable list in initialisation')
+
+ def packet_size(self):
+ '''return expected size of FG FDM packets'''
+ return self._packet_size
+
+ def convert(self, value, fromunits, tounits):
+ '''convert a value from one set of units to another'''
+ if fromunits == tounits:
+ return value
+ if (fromunits,tounits) in self.unitmap:
+ return value * self.unitmap[(fromunits,tounits)]
+ if (tounits,fromunits) in self.unitmap:
+ return value / self.unitmap[(tounits,fromunits)]
+ raise fgFDMError("unknown unit mapping (%s,%s)" % (fromunits, tounits))
+
+
+ def units(self, varname):
+ '''return the default units of a variable'''
+ if not varname in self.mapping.vars:
+ raise fgFDMError('Unknown variable %s' % varname)
+ return self.mapping.vars[varname].units
+
+
+ def variables(self):
+ '''return a list of available variables'''
+ return sorted(list(self.mapping.vars.keys()),
+ key = lambda v : self.mapping.vars[v].index)
+
+
+ def get(self, varname, idx=0, units=None):
+ '''get a variable value'''
+ if not varname in self.mapping.vars:
+ raise fgFDMError('Unknown variable %s' % varname)
+ if idx >= self.mapping.vars[varname].arraylength:
+ raise fgFDMError('index of %s beyond end of array idx=%u arraylength=%u' % (
+ varname, idx, self.mapping.vars[varname].arraylength))
+ value = self.values[self.mapping.vars[varname].index + idx]
+ if units:
+ value = self.convert(value, self.mapping.vars[varname].units, units)
+ return value
+
+ def set(self, varname, value, idx=0, units=None):
+ '''set a variable value'''
+ if not varname in self.mapping.vars:
+ raise fgFDMError('Unknown variable %s' % varname)
+ if idx >= self.mapping.vars[varname].arraylength:
+ raise fgFDMError('index of %s beyond end of array idx=%u arraylength=%u' % (
+ varname, idx, self.mapping.vars[varname].arraylength))
+ if units:
+ value = self.convert(value, units, self.mapping.vars[varname].units)
+ # avoid range errors when packing into 4 byte floats
+ if math.isinf(value) or math.isnan(value) or math.fabs(value) > 3.4e38:
+ value = 0
+ self.values[self.mapping.vars[varname].index + idx] = value
+
+ def parse(self, buf):
+ '''parse a FD FDM buffer'''
+ try:
+ t = struct.unpack(self.pack_string, buf)
+ except struct.error as msg:
+ raise fgFDMError('unable to parse - %s' % msg)
+ self.values = list(t)
+
+ def pack(self):
+ '''pack a FD FDM buffer from current values'''
+ for i in range(len(self.values)):
+ if math.isnan(self.values[i]):
+ self.values[i] = 0
+ return struct.pack(self.pack_string, *self.values)
diff --git a/mavlink-solo/pymavlink/files/archlinux/PKGBUILD b/mavlink-solo/pymavlink/files/archlinux/PKGBUILD
new file mode 100644
index 0000000..ef38225
--- /dev/null
+++ b/mavlink-solo/pymavlink/files/archlinux/PKGBUILD
@@ -0,0 +1,52 @@
+# Maintainer: Thomas Gubler
+pkgname=python2-mavlink-git
+pkgver=20140119
+pkgrel=1
+pkgdesc="Python implementation of the MAVLink protocol"
+arch=(any)
+url="http://qgroundcontrol.org/mavlink/pymavlink"
+license=('LGPL3')
+depends=('python2')
+makedepends=('git' 'python2' 'python2-setuptools')
+optdepends=()
+provides=('python2-mavlink-git')
+conflicts=()
+options=(!emptydirs)
+
+_gitroot="https://github.com/mavlink/mavlink/"
+_gitname="mavlink"
+_subfoldername="pymavlink"
+
+build() {
+ cd "$srcdir"
+ msg "Connecting to GIT server..."
+
+ if [ -d $_gitname ] ; then
+ cd $_gitname && git pull origin
+ msg "The local files are updated."
+ else
+ git clone $_gitroot $_gitname
+ fi
+
+ msg "GIT checkout done or server timeout"
+
+ cd "$srcdir/$_gitname/$_subfoldername"
+ git clean -fdx
+
+ msg "Starting make..."
+ python2 setup.py build
+}
+
+package() {
+ cd "$srcdir/$_gitname/$_subfoldername"
+ python2 setup.py install --prefix=/usr --root=$pkgdir/ --optimize=1
+
+ install -Dm644 "$srcdir/$_gitname/$_subfoldername/README.txt" "$pkgdir/usr/share/licenses/$pkgname/README.txt"
+}
+
+pkgver() {
+ cd "$pkgname"
+ printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
+}
+
+# vim:set ts=2 sw=2 et:
diff --git a/mavlink-solo/pymavlink/generator/.gitignore b/mavlink-solo/pymavlink/generator/.gitignore
new file mode 100644
index 0000000..0d20b64
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/mavlink-solo/pymavlink/generator/C/include_v0.9/checksum.h b/mavlink-solo/pymavlink/generator/C/include_v0.9/checksum.h
new file mode 100644
index 0000000..32bf6e4
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/include_v0.9/checksum.h
@@ -0,0 +1,95 @@
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _CHECKSUM_H_
+#define _CHECKSUM_H_
+
+// Visual Studio versions before 2010 don't have stdint.h, so we just error out.
+#if (defined _MSC_VER) && (_MSC_VER < 1600)
+#error "The C-MAVLink implementation requires Visual Studio 2010 or greater"
+#endif
+
+#include
+
+/**
+ *
+ * CALCULATE THE CHECKSUM
+ *
+ */
+
+#define X25_INIT_CRC 0xffff
+#define X25_VALIDATE_CRC 0xf0b8
+
+/**
+ * @brief Accumulate the X.25 CRC by adding one char at a time.
+ *
+ * The checksum function adds the hash of one char at a time to the
+ * 16 bit checksum (uint16_t).
+ *
+ * @param data new char to hash
+ * @param crcAccum the already accumulated checksum
+ **/
+static inline void crc_accumulate(uint8_t data, uint16_t *crcAccum)
+{
+ /*Accumulate one byte of data into the CRC*/
+ uint8_t tmp;
+
+ tmp = data ^ (uint8_t)(*crcAccum &0xff);
+ tmp ^= (tmp<<4);
+ *crcAccum = (*crcAccum>>8) ^ (tmp<<8) ^ (tmp <<3) ^ (tmp>>4);
+}
+
+/**
+ * @brief Initiliaze the buffer for the X.25 CRC
+ *
+ * @param crcAccum the 16 bit X.25 CRC
+ */
+static inline void crc_init(uint16_t* crcAccum)
+{
+ *crcAccum = X25_INIT_CRC;
+}
+
+
+/**
+ * @brief Calculates the X.25 checksum on a byte buffer
+ *
+ * @param pBuffer buffer containing the byte array to hash
+ * @param length length of the byte array
+ * @return the checksum over the buffer bytes
+ **/
+static inline uint16_t crc_calculate(const uint8_t* pBuffer, uint16_t length)
+{
+ uint16_t crcTmp;
+ crc_init(&crcTmp);
+ while (length--) {
+ crc_accumulate(*pBuffer++, &crcTmp);
+ }
+ return crcTmp;
+}
+
+/**
+ * @brief Accumulate the X.25 CRC by adding an array of bytes
+ *
+ * The checksum function adds the hash of one char at a time to the
+ * 16 bit checksum (uint16_t).
+ *
+ * @param data new bytes to hash
+ * @param crcAccum the already accumulated checksum
+ **/
+static inline void crc_accumulate_buffer(uint16_t *crcAccum, const char *pBuffer, uint8_t length)
+{
+ const uint8_t *p = (const uint8_t *)pBuffer;
+ while (length--) {
+ crc_accumulate(*p++, crcAccum);
+ }
+}
+
+
+
+
+#endif /* _CHECKSUM_H_ */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/mavlink-solo/pymavlink/generator/C/include_v0.9/mavlink_helpers.h b/mavlink-solo/pymavlink/generator/C/include_v0.9/mavlink_helpers.h
new file mode 100644
index 0000000..f3eac41
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/include_v0.9/mavlink_helpers.h
@@ -0,0 +1,550 @@
+#ifndef _MAVLINK_HELPERS_H_
+#define _MAVLINK_HELPERS_H_
+
+#include "string.h"
+#include "checksum.h"
+#include "mavlink_types.h"
+
+#ifndef MAVLINK_HELPER
+#define MAVLINK_HELPER
+#endif
+
+/*
+ internal function to give access to the channel status for each channel
+ */
+MAVLINK_HELPER mavlink_status_t* mavlink_get_channel_status(uint8_t chan)
+{
+ static mavlink_status_t m_mavlink_status[MAVLINK_COMM_NUM_BUFFERS];
+ return &m_mavlink_status[chan];
+}
+
+/*
+ internal function to give access to the channel buffer for each channel
+ */
+MAVLINK_HELPER mavlink_message_t* mavlink_get_channel_buffer(uint8_t chan)
+{
+
+#if MAVLINK_EXTERNAL_RX_BUFFER
+ // No m_mavlink_message array defined in function,
+ // has to be defined externally
+#ifndef m_mavlink_message
+#error ERROR: IF #define MAVLINK_EXTERNAL_RX_BUFFER IS SET, THE BUFFER HAS TO BE ALLOCATED OUTSIDE OF THIS FUNCTION (mavlink_message_t m_mavlink_buffer[MAVLINK_COMM_NUM_BUFFERS];)
+#endif
+#else
+ static mavlink_message_t m_mavlink_buffer[MAVLINK_COMM_NUM_BUFFERS];
+#endif
+ return &m_mavlink_buffer[chan];
+}
+
+/**
+ * @brief Finalize a MAVLink message with channel assignment
+ *
+ * This function calculates the checksum and sets length and aircraft id correctly.
+ * It assumes that the message id and the payload are already correctly set. This function
+ * can also be used if the message header has already been written before (as in mavlink_msg_xxx_pack
+ * instead of mavlink_msg_xxx_pack_headerless), it just introduces little extra overhead.
+ *
+ * @param msg Message to finalize
+ * @param system_id Id of the sending (this) system, 1-127
+ * @param length Message length
+ */
+#if MAVLINK_CRC_EXTRA
+MAVLINK_HELPER uint16_t mavlink_finalize_message_chan(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
+ uint8_t chan, uint8_t length, uint8_t crc_extra)
+#else
+MAVLINK_HELPER uint16_t mavlink_finalize_message_chan(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
+ uint8_t chan, uint8_t length)
+#endif
+{
+ // This code part is the same for all messages;
+ uint16_t checksum;
+ msg->magic = MAVLINK_STX;
+ msg->len = length;
+ msg->sysid = system_id;
+ msg->compid = component_id;
+ // One sequence number per channel
+ msg->seq = mavlink_get_channel_status(chan)->current_tx_seq;
+ mavlink_get_channel_status(chan)->current_tx_seq = mavlink_get_channel_status(chan)->current_tx_seq+1;
+ checksum = crc_calculate((uint8_t*)&msg->len, length + MAVLINK_CORE_HEADER_LEN);
+#if MAVLINK_CRC_EXTRA
+ crc_accumulate(crc_extra, &checksum);
+#endif
+ mavlink_ck_a(msg) = (uint8_t)(checksum & 0xFF);
+ mavlink_ck_b(msg) = (uint8_t)(checksum >> 8);
+
+ return length + MAVLINK_NUM_NON_PAYLOAD_BYTES;
+}
+
+
+/**
+ * @brief Finalize a MAVLink message with MAVLINK_COMM_0 as default channel
+ */
+#if MAVLINK_CRC_EXTRA
+MAVLINK_HELPER uint16_t mavlink_finalize_message(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
+ uint8_t length, uint8_t crc_extra)
+{
+ return mavlink_finalize_message_chan(msg, system_id, component_id, MAVLINK_COMM_0, length, crc_extra);
+}
+#else
+MAVLINK_HELPER uint16_t mavlink_finalize_message(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
+ uint8_t length)
+{
+ return mavlink_finalize_message_chan(msg, system_id, component_id, MAVLINK_COMM_0, length);
+}
+#endif
+
+#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS
+MAVLINK_HELPER void _mavlink_send_uart(mavlink_channel_t chan, const char *buf, uint16_t len);
+
+/**
+ * @brief Finalize a MAVLink message with channel assignment and send
+ */
+#if MAVLINK_CRC_EXTRA
+MAVLINK_HELPER void _mav_finalize_message_chan_send(mavlink_channel_t chan, uint8_t msgid, const char *packet,
+ uint8_t length, uint8_t crc_extra)
+#else
+MAVLINK_HELPER void _mav_finalize_message_chan_send(mavlink_channel_t chan, uint8_t msgid, const char *packet, uint8_t length)
+#endif
+{
+ uint16_t checksum;
+ uint8_t buf[MAVLINK_NUM_HEADER_BYTES];
+ uint8_t ck[2];
+ mavlink_status_t *status = mavlink_get_channel_status(chan);
+ buf[0] = MAVLINK_STX;
+ buf[1] = length;
+ buf[2] = status->current_tx_seq;
+ buf[3] = mavlink_system.sysid;
+ buf[4] = mavlink_system.compid;
+ buf[5] = msgid;
+ status->current_tx_seq++;
+ checksum = crc_calculate((uint8_t*)&buf[1], MAVLINK_CORE_HEADER_LEN);
+ crc_accumulate_buffer(&checksum, packet, length);
+#if MAVLINK_CRC_EXTRA
+ crc_accumulate(crc_extra, &checksum);
+#endif
+ ck[0] = (uint8_t)(checksum & 0xFF);
+ ck[1] = (uint8_t)(checksum >> 8);
+
+ MAVLINK_START_UART_SEND(chan, MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)length);
+ _mavlink_send_uart(chan, (const char *)buf, MAVLINK_NUM_HEADER_BYTES);
+ _mavlink_send_uart(chan, packet, length);
+ _mavlink_send_uart(chan, (const char *)ck, 2);
+ MAVLINK_END_UART_SEND(chan, MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)length);
+}
+
+/**
+ * @brief re-send a message over a uart channel
+ * this is more stack efficient than re-marshalling the message
+ */
+MAVLINK_HELPER void _mavlink_resend_uart(mavlink_channel_t chan, const mavlink_message_t *msg)
+{
+ uint8_t ck[2];
+
+ ck[0] = (uint8_t)(msg->checksum & 0xFF);
+ ck[1] = (uint8_t)(msg->checksum >> 8);
+
+ MAVLINK_START_UART_SEND(chan, MAVLINK_NUM_NON_PAYLOAD_BYTES + msg->len);
+ _mavlink_send_uart(chan, (const char *)&msg->magic, MAVLINK_NUM_HEADER_BYTES);
+ _mavlink_send_uart(chan, _MAV_PAYLOAD(msg), msg->len);
+ _mavlink_send_uart(chan, (const char *)ck, 2);
+ MAVLINK_END_UART_SEND(chan, MAVLINK_NUM_NON_PAYLOAD_BYTES + msg->len);
+}
+#endif // MAVLINK_USE_CONVENIENCE_FUNCTIONS
+
+/**
+ * @brief Pack a message to send it over a serial byte stream
+ */
+MAVLINK_HELPER uint16_t mavlink_msg_to_send_buffer(uint8_t *buffer, const mavlink_message_t *msg)
+{
+ memcpy(buffer, (const uint8_t *)&msg->magic, MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)msg->len);
+ return MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)msg->len;
+}
+
+union __mavlink_bitfield {
+ uint8_t uint8;
+ int8_t int8;
+ uint16_t uint16;
+ int16_t int16;
+ uint32_t uint32;
+ int32_t int32;
+};
+
+
+MAVLINK_HELPER void mavlink_start_checksum(mavlink_message_t* msg)
+{
+ crc_init(&msg->checksum);
+}
+
+MAVLINK_HELPER void mavlink_update_checksum(mavlink_message_t* msg, uint8_t c)
+{
+ crc_accumulate(c, &msg->checksum);
+}
+
+/**
+ * This is a convenience function which handles the complete MAVLink parsing.
+ * the function will parse one byte at a time and return the complete packet once
+ * it could be successfully decoded. Checksum and other failures will be silently
+ * ignored.
+ *
+ * @param chan ID of the current channel. This allows to parse different channels with this function.
+ * a channel is not a physical message channel like a serial port, but a logic partition of
+ * the communication streams in this case. COMM_NB is the limit for the number of channels
+ * on MCU (e.g. ARM7), while COMM_NB_HIGH is the limit for the number of channels in Linux/Windows
+ * @param c The char to barse
+ *
+ * @param returnMsg NULL if no message could be decoded, the message data else
+ * @return 0 if no message could be decoded, 1 else
+ *
+ * A typical use scenario of this function call is:
+ *
+ * @code
+ * #include // For fixed-width uint8_t type
+ *
+ * mavlink_message_t msg;
+ * int chan = 0;
+ *
+ *
+ * while(serial.bytesAvailable > 0)
+ * {
+ * uint8_t byte = serial.getNextByte();
+ * if (mavlink_parse_char(chan, byte, &msg))
+ * {
+ * printf("Received message with ID %d, sequence: %d from component %d of system %d", msg.msgid, msg.seq, msg.compid, msg.sysid);
+ * }
+ * }
+ *
+ *
+ * @endcode
+ */
+MAVLINK_HELPER uint8_t mavlink_parse_char(uint8_t chan, uint8_t c, mavlink_message_t* r_message, mavlink_status_t* r_mavlink_status)
+{
+ /*
+ default message crc function. You can override this per-system to
+ put this data in a different memory segment
+ */
+#if MAVLINK_CRC_EXTRA
+#ifndef MAVLINK_MESSAGE_CRC
+ static const uint8_t mavlink_message_crcs[256] = MAVLINK_MESSAGE_CRCS;
+#define MAVLINK_MESSAGE_CRC(msgid) mavlink_message_crcs[msgid]
+#endif
+#endif
+
+
+/* Enable this option to check the length of each message.
+This allows invalid messages to be caught much sooner. Use if the transmission
+medium is prone to missing (or extra) characters (e.g. a radio that fades in
+and out). Only use if the channel will only contain messages types listed in
+the headers.
+*/
+#if MAVLINK_CHECK_MESSAGE_LENGTH
+#ifndef MAVLINK_MESSAGE_LENGTH
+ static const uint8_t mavlink_message_lengths[256] = MAVLINK_MESSAGE_LENGTHS;
+#define MAVLINK_MESSAGE_LENGTH(msgid) mavlink_message_lengths[msgid]
+#endif
+#endif
+
+ mavlink_message_t* rxmsg = mavlink_get_channel_buffer(chan); ///< The currently decoded message
+ mavlink_status_t* status = mavlink_get_channel_status(chan); ///< The current decode status
+ int bufferIndex = 0;
+
+ status->msg_received = 0;
+
+ switch (status->parse_state)
+ {
+ case MAVLINK_PARSE_STATE_UNINIT:
+ case MAVLINK_PARSE_STATE_IDLE:
+ if (c == MAVLINK_STX)
+ {
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_STX;
+ rxmsg->len = 0;
+ rxmsg->magic = c;
+ mavlink_start_checksum(rxmsg);
+ }
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_STX:
+ if (status->msg_received
+/* Support shorter buffers than the
+ default maximum packet size */
+#if (MAVLINK_MAX_PAYLOAD_LEN < 255)
+ || c > MAVLINK_MAX_PAYLOAD_LEN
+#endif
+ )
+ {
+ status->buffer_overrun++;
+ status->parse_error++;
+ status->msg_received = 0;
+ status->parse_state = MAVLINK_PARSE_STATE_IDLE;
+ }
+ else
+ {
+ // NOT counting STX, LENGTH, SEQ, SYSID, COMPID, MSGID, CRC1 and CRC2
+ rxmsg->len = c;
+ status->packet_idx = 0;
+ mavlink_update_checksum(rxmsg, c);
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_LENGTH;
+ }
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_LENGTH:
+ rxmsg->seq = c;
+ mavlink_update_checksum(rxmsg, c);
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_SEQ;
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_SEQ:
+ rxmsg->sysid = c;
+ mavlink_update_checksum(rxmsg, c);
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_SYSID;
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_SYSID:
+ rxmsg->compid = c;
+ mavlink_update_checksum(rxmsg, c);
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_COMPID;
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_COMPID:
+#if MAVLINK_CHECK_MESSAGE_LENGTH
+ if (rxmsg->len != MAVLINK_MESSAGE_LENGTH(c))
+ {
+ status->parse_error++;
+ status->parse_state = MAVLINK_PARSE_STATE_IDLE;
+ break;
+ }
+#endif
+ rxmsg->msgid = c;
+ mavlink_update_checksum(rxmsg, c);
+ if (rxmsg->len == 0)
+ {
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_PAYLOAD;
+ }
+ else
+ {
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_MSGID;
+ }
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_MSGID:
+ _MAV_PAYLOAD_NON_CONST(rxmsg)[status->packet_idx++] = (char)c;
+ mavlink_update_checksum(rxmsg, c);
+ if (status->packet_idx == rxmsg->len)
+ {
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_PAYLOAD;
+ }
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_PAYLOAD:
+#if MAVLINK_CRC_EXTRA
+ mavlink_update_checksum(rxmsg, MAVLINK_MESSAGE_CRC(rxmsg->msgid));
+#endif
+ if (c != (rxmsg->checksum & 0xFF)) {
+ // Check first checksum byte
+ status->parse_error++;
+ status->msg_received = 0;
+ status->parse_state = MAVLINK_PARSE_STATE_IDLE;
+ if (c == MAVLINK_STX)
+ {
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_STX;
+ rxmsg->len = 0;
+ mavlink_start_checksum(rxmsg);
+ }
+ }
+ else
+ {
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_CRC1;
+ _MAV_PAYLOAD_NON_CONST(rxmsg)[status->packet_idx] = (char)c;
+ }
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_CRC1:
+ if (c != (rxmsg->checksum >> 8)) {
+ // Check second checksum byte
+ status->parse_error++;
+ status->msg_received = 0;
+ status->parse_state = MAVLINK_PARSE_STATE_IDLE;
+ if (c == MAVLINK_STX)
+ {
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_STX;
+ rxmsg->len = 0;
+ mavlink_start_checksum(rxmsg);
+ }
+ }
+ else
+ {
+ // Successfully got message
+ status->msg_received = 1;
+ status->parse_state = MAVLINK_PARSE_STATE_IDLE;
+ _MAV_PAYLOAD_NON_CONST(rxmsg)[status->packet_idx+1] = (char)c;
+ memcpy(r_message, rxmsg, sizeof(mavlink_message_t));
+ }
+ break;
+ }
+
+ bufferIndex++;
+ // If a message has been sucessfully decoded, check index
+ if (status->msg_received == 1)
+ {
+ //while(status->current_seq != rxmsg->seq)
+ //{
+ // status->packet_rx_drop_count++;
+ // status->current_seq++;
+ //}
+ status->current_rx_seq = rxmsg->seq;
+ // Initial condition: If no packet has been received so far, drop count is undefined
+ if (status->packet_rx_success_count == 0) status->packet_rx_drop_count = 0;
+ // Count this packet as received
+ status->packet_rx_success_count++;
+ }
+
+ r_message->len = rxmsg->len; // Provide visibility on how far we are into current msg
+ r_mavlink_status->parse_state = status->parse_state;
+ r_mavlink_status->packet_idx = status->packet_idx;
+ r_mavlink_status->current_rx_seq = status->current_rx_seq+1;
+ r_mavlink_status->packet_rx_success_count = status->packet_rx_success_count;
+ r_mavlink_status->packet_rx_drop_count = status->parse_error;
+ status->parse_error = 0;
+ return status->msg_received;
+}
+
+/**
+ * @brief Put a bitfield of length 1-32 bit into the buffer
+ *
+ * @param b the value to add, will be encoded in the bitfield
+ * @param bits number of bits to use to encode b, e.g. 1 for boolean, 2, 3, etc.
+ * @param packet_index the position in the packet (the index of the first byte to use)
+ * @param bit_index the position in the byte (the index of the first bit to use)
+ * @param buffer packet buffer to write into
+ * @return new position of the last used byte in the buffer
+ */
+MAVLINK_HELPER uint8_t put_bitfield_n_by_index(int32_t b, uint8_t bits, uint8_t packet_index, uint8_t bit_index, uint8_t* r_bit_index, uint8_t* buffer)
+{
+ uint16_t bits_remain = bits;
+ // Transform number into network order
+ int32_t v;
+ uint8_t i_bit_index, i_byte_index, curr_bits_n;
+#if MAVLINK_NEED_BYTE_SWAP
+ union {
+ int32_t i;
+ uint8_t b[4];
+ } bin, bout;
+ bin.i = b;
+ bout.b[0] = bin.b[3];
+ bout.b[1] = bin.b[2];
+ bout.b[2] = bin.b[1];
+ bout.b[3] = bin.b[0];
+ v = bout.i;
+#else
+ v = b;
+#endif
+
+ // buffer in
+ // 01100000 01000000 00000000 11110001
+ // buffer out
+ // 11110001 00000000 01000000 01100000
+
+ // Existing partly filled byte (four free slots)
+ // 0111xxxx
+
+ // Mask n free bits
+ // 00001111 = 2^0 + 2^1 + 2^2 + 2^3 = 2^n - 1
+ // = ((uint32_t)(1 << n)) - 1; // = 2^n - 1
+
+ // Shift n bits into the right position
+ // out = in >> n;
+
+ // Mask and shift bytes
+ i_bit_index = bit_index;
+ i_byte_index = packet_index;
+ if (bit_index > 0)
+ {
+ // If bits were available at start, they were available
+ // in the byte before the current index
+ i_byte_index--;
+ }
+
+ // While bits have not been packed yet
+ while (bits_remain > 0)
+ {
+ // Bits still have to be packed
+ // there can be more than 8 bits, so
+ // we might have to pack them into more than one byte
+
+ // First pack everything we can into the current 'open' byte
+ //curr_bits_n = bits_remain << 3; // Equals bits_remain mod 8
+ //FIXME
+ if (bits_remain <= (uint8_t)(8 - i_bit_index))
+ {
+ // Enough space
+ curr_bits_n = (uint8_t)bits_remain;
+ }
+ else
+ {
+ curr_bits_n = (8 - i_bit_index);
+ }
+
+ // Pack these n bits into the current byte
+ // Mask out whatever was at that position with ones (xxx11111)
+ buffer[i_byte_index] &= (0xFF >> (8 - curr_bits_n));
+ // Put content to this position, by masking out the non-used part
+ buffer[i_byte_index] |= ((0x00 << curr_bits_n) & v);
+
+ // Increment the bit index
+ i_bit_index += curr_bits_n;
+
+ // Now proceed to the next byte, if necessary
+ bits_remain -= curr_bits_n;
+ if (bits_remain > 0)
+ {
+ // Offer another 8 bits / one byte
+ i_byte_index++;
+ i_bit_index = 0;
+ }
+ }
+
+ *r_bit_index = i_bit_index;
+ // If a partly filled byte is present, mark this as consumed
+ if (i_bit_index != 7) i_byte_index++;
+ return i_byte_index - packet_index;
+}
+
+#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS
+
+// To make MAVLink work on your MCU, define comm_send_ch() if you wish
+// to send 1 byte at a time, or MAVLINK_SEND_UART_BYTES() to send a
+// whole packet at a time
+
+/*
+
+#include "mavlink_types.h"
+
+void comm_send_ch(mavlink_channel_t chan, uint8_t ch)
+{
+ if (chan == MAVLINK_COMM_0)
+ {
+ uart0_transmit(ch);
+ }
+ if (chan == MAVLINK_COMM_1)
+ {
+ uart1_transmit(ch);
+ }
+}
+ */
+
+MAVLINK_HELPER void _mavlink_send_uart(mavlink_channel_t chan, const char *buf, uint16_t len)
+{
+#ifdef MAVLINK_SEND_UART_BYTES
+ /* this is the more efficient approach, if the platform
+ defines it */
+ MAVLINK_SEND_UART_BYTES(chan, (uint8_t *)buf, len);
+#else
+ /* fallback to one byte at a time */
+ uint16_t i;
+ for (i = 0; i < len; i++) {
+ comm_send_ch(chan, (uint8_t)buf[i]);
+ }
+#endif
+}
+#endif // MAVLINK_USE_CONVENIENCE_FUNCTIONS
+
+#endif /* _MAVLINK_HELPERS_H_ */
diff --git a/mavlink-solo/pymavlink/generator/C/include_v0.9/mavlink_types.h b/mavlink-solo/pymavlink/generator/C/include_v0.9/mavlink_types.h
new file mode 100644
index 0000000..9d04155
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/include_v0.9/mavlink_types.h
@@ -0,0 +1,323 @@
+#ifndef MAVLINK_TYPES_H_
+#define MAVLINK_TYPES_H_
+
+#include "inttypes.h"
+
+enum MAV_CLASS
+{
+ MAV_CLASS_GENERIC = 0, ///< Generic autopilot, full support for everything
+ MAV_CLASS_PIXHAWK = 1, ///< PIXHAWK autopilot, http://pixhawk.ethz.ch
+ MAV_CLASS_SLUGS = 2, ///< SLUGS autopilot, http://slugsuav.soe.ucsc.edu
+ MAV_CLASS_ARDUPILOTMEGA = 3, ///< ArduPilotMega / ArduCopter, http://diydrones.com
+ MAV_CLASS_OPENPILOT = 4, ///< OpenPilot, http://openpilot.org
+ MAV_CLASS_GENERIC_MISSION_WAYPOINTS_ONLY = 5, ///< Generic autopilot only supporting simple waypoints
+ MAV_CLASS_GENERIC_MISSION_NAVIGATION_ONLY = 6, ///< Generic autopilot supporting waypoints and other simple navigation commands
+ MAV_CLASS_GENERIC_MISSION_FULL = 7, ///< Generic autopilot supporting the full mission command set
+ MAV_CLASS_NONE = 8, ///< No valid autopilot
+ MAV_CLASS_NB ///< Number of autopilot classes
+};
+
+enum MAV_ACTION
+{
+ MAV_ACTION_HOLD = 0,
+ MAV_ACTION_MOTORS_START = 1,
+ MAV_ACTION_LAUNCH = 2,
+ MAV_ACTION_RETURN = 3,
+ MAV_ACTION_EMCY_LAND = 4,
+ MAV_ACTION_EMCY_KILL = 5,
+ MAV_ACTION_CONFIRM_KILL = 6,
+ MAV_ACTION_CONTINUE = 7,
+ MAV_ACTION_MOTORS_STOP = 8,
+ MAV_ACTION_HALT = 9,
+ MAV_ACTION_SHUTDOWN = 10,
+ MAV_ACTION_REBOOT = 11,
+ MAV_ACTION_SET_MANUAL = 12,
+ MAV_ACTION_SET_AUTO = 13,
+ MAV_ACTION_STORAGE_READ = 14,
+ MAV_ACTION_STORAGE_WRITE = 15,
+ MAV_ACTION_CALIBRATE_RC = 16,
+ MAV_ACTION_CALIBRATE_GYRO = 17,
+ MAV_ACTION_CALIBRATE_MAG = 18,
+ MAV_ACTION_CALIBRATE_ACC = 19,
+ MAV_ACTION_CALIBRATE_PRESSURE = 20,
+ MAV_ACTION_REC_START = 21,
+ MAV_ACTION_REC_PAUSE = 22,
+ MAV_ACTION_REC_STOP = 23,
+ MAV_ACTION_TAKEOFF = 24,
+ MAV_ACTION_NAVIGATE = 25,
+ MAV_ACTION_LAND = 26,
+ MAV_ACTION_LOITER = 27,
+ MAV_ACTION_SET_ORIGIN = 28,
+ MAV_ACTION_RELAY_ON = 29,
+ MAV_ACTION_RELAY_OFF = 30,
+ MAV_ACTION_GET_IMAGE = 31,
+ MAV_ACTION_VIDEO_START = 32,
+ MAV_ACTION_VIDEO_STOP = 33,
+ MAV_ACTION_RESET_MAP = 34,
+ MAV_ACTION_RESET_PLAN = 35,
+ MAV_ACTION_DELAY_BEFORE_COMMAND = 36,
+ MAV_ACTION_ASCEND_AT_RATE = 37,
+ MAV_ACTION_CHANGE_MODE = 38,
+ MAV_ACTION_LOITER_MAX_TURNS = 39,
+ MAV_ACTION_LOITER_MAX_TIME = 40,
+ MAV_ACTION_START_HILSIM = 41,
+ MAV_ACTION_STOP_HILSIM = 42,
+ MAV_ACTION_NB ///< Number of MAV actions
+};
+
+enum MAV_MODE
+{
+ MAV_MODE_UNINIT = 0, ///< System is in undefined state
+ MAV_MODE_LOCKED = 1, ///< Motors are blocked, system is safe
+ MAV_MODE_MANUAL = 2, ///< System is allowed to be active, under manual (RC) control
+ MAV_MODE_GUIDED = 3, ///< System is allowed to be active, under autonomous control, manual setpoint
+ MAV_MODE_AUTO = 4, ///< System is allowed to be active, under autonomous control and navigation
+ MAV_MODE_TEST1 = 5, ///< Generic test mode, for custom use
+ MAV_MODE_TEST2 = 6, ///< Generic test mode, for custom use
+ MAV_MODE_TEST3 = 7, ///< Generic test mode, for custom use
+ MAV_MODE_READY = 8, ///< System is ready, motors are unblocked, but controllers are inactive
+ MAV_MODE_RC_TRAINING = 9 ///< System is blocked, only RC valued are read and reported back
+};
+
+enum MAV_STATE
+{
+ MAV_STATE_UNINIT = 0,
+ MAV_STATE_BOOT,
+ MAV_STATE_CALIBRATING,
+ MAV_STATE_STANDBY,
+ MAV_STATE_ACTIVE,
+ MAV_STATE_CRITICAL,
+ MAV_STATE_EMERGENCY,
+ MAV_STATE_HILSIM,
+ MAV_STATE_POWEROFF
+};
+
+enum MAV_NAV
+{
+ MAV_NAV_GROUNDED = 0,
+ MAV_NAV_LIFTOFF,
+ MAV_NAV_HOLD,
+ MAV_NAV_WAYPOINT,
+ MAV_NAV_VECTOR,
+ MAV_NAV_RETURNING,
+ MAV_NAV_LANDING,
+ MAV_NAV_LOST,
+ MAV_NAV_LOITER,
+ MAV_NAV_FREE_DRIFT
+};
+
+enum MAV_TYPE
+{
+ MAV_GENERIC = 0,
+ MAV_FIXED_WING = 1,
+ MAV_QUADROTOR = 2,
+ MAV_COAXIAL = 3,
+ MAV_HELICOPTER = 4,
+ MAV_GROUND = 5,
+ OCU = 6,
+ MAV_AIRSHIP = 7,
+ MAV_FREE_BALLOON = 8,
+ MAV_ROCKET = 9,
+ UGV_GROUND_ROVER = 10,
+ UGV_SURFACE_SHIP = 11
+};
+
+enum MAV_AUTOPILOT_TYPE
+{
+ MAV_AUTOPILOT_GENERIC = 0,
+ MAV_AUTOPILOT_PIXHAWK = 1,
+ MAV_AUTOPILOT_SLUGS = 2,
+ MAV_AUTOPILOT_ARDUPILOTMEGA = 3,
+ MAV_AUTOPILOT_NONE = 4
+};
+
+enum MAV_COMPONENT
+{
+ MAV_COMP_ID_GPS,
+ MAV_COMP_ID_WAYPOINTPLANNER,
+ MAV_COMP_ID_BLOBTRACKER,
+ MAV_COMP_ID_PATHPLANNER,
+ MAV_COMP_ID_AIRSLAM,
+ MAV_COMP_ID_MAPPER,
+ MAV_COMP_ID_CAMERA,
+ MAV_COMP_ID_RADIO = 68,
+ MAV_COMP_ID_IMU = 200,
+ MAV_COMP_ID_IMU_2 = 201,
+ MAV_COMP_ID_IMU_3 = 202,
+ MAV_COMP_ID_UDP_BRIDGE = 240,
+ MAV_COMP_ID_UART_BRIDGE = 241,
+ MAV_COMP_ID_SYSTEM_CONTROL = 250
+};
+
+enum MAV_FRAME
+{
+ MAV_FRAME_GLOBAL = 0,
+ MAV_FRAME_LOCAL = 1,
+ MAV_FRAME_MISSION = 2,
+ MAV_FRAME_GLOBAL_RELATIVE_ALT = 3,
+ MAV_FRAME_LOCAL_ENU = 4
+};
+
+enum MAVLINK_DATA_STREAM_TYPE
+{
+ MAVLINK_DATA_STREAM_IMG_JPEG,
+ MAVLINK_DATA_STREAM_IMG_BMP,
+ MAVLINK_DATA_STREAM_IMG_RAW8U,
+ MAVLINK_DATA_STREAM_IMG_RAW32U,
+ MAVLINK_DATA_STREAM_IMG_PGM,
+ MAVLINK_DATA_STREAM_IMG_PNG
+};
+
+#ifndef MAVLINK_MAX_PAYLOAD_LEN
+// it is possible to override this, but be careful!
+#define MAVLINK_MAX_PAYLOAD_LEN 255 ///< Maximum payload length
+#endif
+
+#define MAVLINK_CORE_HEADER_LEN 5 ///< Length of core header (of the comm. layer): message length (1 byte) + message sequence (1 byte) + message system id (1 byte) + message component id (1 byte) + message type id (1 byte)
+#define MAVLINK_NUM_HEADER_BYTES (MAVLINK_CORE_HEADER_LEN + 1) ///< Length of all header bytes, including core and checksum
+#define MAVLINK_NUM_CHECKSUM_BYTES 2
+#define MAVLINK_NUM_NON_PAYLOAD_BYTES (MAVLINK_NUM_HEADER_BYTES + MAVLINK_NUM_CHECKSUM_BYTES)
+
+#define MAVLINK_MAX_PACKET_LEN (MAVLINK_MAX_PAYLOAD_LEN + MAVLINK_NUM_NON_PAYLOAD_BYTES) ///< Maximum packet length
+
+#define MAVLINK_MSG_ID_EXTENDED_MESSAGE 255
+#define MAVLINK_EXTENDED_HEADER_LEN 14
+
+#if (defined _MSC_VER) | ((defined __APPLE__) & (defined __MACH__)) | (defined __linux__)
+ /* full fledged 32bit++ OS */
+ #define MAVLINK_MAX_EXTENDED_PACKET_LEN 65507
+#else
+ /* small microcontrollers */
+ #define MAVLINK_MAX_EXTENDED_PACKET_LEN 2048
+#endif
+
+#define MAVLINK_MAX_EXTENDED_PAYLOAD_LEN (MAVLINK_MAX_EXTENDED_PACKET_LEN - MAVLINK_EXTENDED_HEADER_LEN - MAVLINK_NUM_NON_PAYLOAD_BYTES)
+
+typedef struct param_union {
+ union {
+ float param_float;
+ int32_t param_int32;
+ uint32_t param_uint32;
+ uint8_t param_uint8;
+ uint8_t bytes[4];
+ };
+ uint8_t type;
+} mavlink_param_union_t;
+
+typedef struct __mavlink_system {
+ uint8_t sysid; ///< Used by the MAVLink message_xx_send() convenience function
+ uint8_t compid; ///< Used by the MAVLink message_xx_send() convenience function
+ uint8_t type; ///< Unused, can be used by user to store the system's type
+ uint8_t state; ///< Unused, can be used by user to store the system's state
+ uint8_t mode; ///< Unused, can be used by user to store the system's mode
+ uint8_t nav_mode; ///< Unused, can be used by user to store the system's navigation mode
+} mavlink_system_t;
+
+typedef struct __mavlink_message {
+ uint16_t checksum; /// sent at end of packet
+ uint8_t magic; ///< protocol magic marker
+ uint8_t len; ///< Length of payload
+ uint8_t seq; ///< Sequence of packet
+ uint8_t sysid; ///< ID of message sender system/aircraft
+ uint8_t compid; ///< ID of the message sender component
+ uint8_t msgid; ///< ID of message in payload
+ uint64_t payload64[(MAVLINK_MAX_PAYLOAD_LEN+MAVLINK_NUM_CHECKSUM_BYTES+7)/8];
+} mavlink_message_t;
+
+
+typedef struct __mavlink_extended_message {
+ mavlink_message_t base_msg;
+ int32_t extended_payload_len; ///< Length of extended payload if any
+ uint8_t extended_payload[MAVLINK_MAX_EXTENDED_PAYLOAD_LEN];
+} mavlink_extended_message_t;
+
+
+typedef enum {
+ MAVLINK_TYPE_CHAR = 0,
+ MAVLINK_TYPE_UINT8_T = 1,
+ MAVLINK_TYPE_INT8_T = 2,
+ MAVLINK_TYPE_UINT16_T = 3,
+ MAVLINK_TYPE_INT16_T = 4,
+ MAVLINK_TYPE_UINT32_T = 5,
+ MAVLINK_TYPE_INT32_T = 6,
+ MAVLINK_TYPE_UINT64_T = 7,
+ MAVLINK_TYPE_INT64_T = 8,
+ MAVLINK_TYPE_FLOAT = 9,
+ MAVLINK_TYPE_DOUBLE = 10
+} mavlink_message_type_t;
+
+#define MAVLINK_MAX_FIELDS 64
+
+typedef struct __mavlink_field_info {
+ const char *name; // name of this field
+ const char *print_format; // printing format hint, or NULL
+ mavlink_message_type_t type; // type of this field
+ unsigned int array_length; // if non-zero, field is an array
+ unsigned int wire_offset; // offset of each field in the payload
+ unsigned int structure_offset; // offset in a C structure
+} mavlink_field_info_t;
+
+// note that in this structure the order of fields is the order
+// in the XML file, not necessary the wire order
+typedef struct __mavlink_message_info {
+ const char *name; // name of the message
+ unsigned num_fields; // how many fields in this message
+ mavlink_field_info_t fields[MAVLINK_MAX_FIELDS]; // field information
+} mavlink_message_info_t;
+
+#define _MAV_PAYLOAD(msg) ((const char *)(&((msg)->payload64[0])))
+#define _MAV_PAYLOAD_NON_CONST(msg) ((char *)(&((msg)->payload64[0])))
+
+// checksum is immediately after the payload bytes
+#define mavlink_ck_a(msg) *((msg)->len + (uint8_t *)_MAV_PAYLOAD_NON_CONST(msg))
+#define mavlink_ck_b(msg) *(((msg)->len+(uint16_t)1) + (uint8_t *)_MAV_PAYLOAD_NON_CONST(msg))
+
+typedef enum {
+ MAVLINK_COMM_0,
+ MAVLINK_COMM_1,
+ MAVLINK_COMM_2,
+ MAVLINK_COMM_3
+} mavlink_channel_t;
+
+/*
+ * applications can set MAVLINK_COMM_NUM_BUFFERS to the maximum number
+ * of buffers they will use. If more are used, then the result will be
+ * a stack overrun
+ */
+#ifndef MAVLINK_COMM_NUM_BUFFERS
+#if (defined linux) | (defined __linux) | (defined __MACH__) | (defined _WIN32)
+# define MAVLINK_COMM_NUM_BUFFERS 16
+#else
+# define MAVLINK_COMM_NUM_BUFFERS 4
+#endif
+#endif
+
+typedef enum {
+ MAVLINK_PARSE_STATE_UNINIT=0,
+ MAVLINK_PARSE_STATE_IDLE,
+ MAVLINK_PARSE_STATE_GOT_STX,
+ MAVLINK_PARSE_STATE_GOT_SEQ,
+ MAVLINK_PARSE_STATE_GOT_LENGTH,
+ MAVLINK_PARSE_STATE_GOT_SYSID,
+ MAVLINK_PARSE_STATE_GOT_COMPID,
+ MAVLINK_PARSE_STATE_GOT_MSGID,
+ MAVLINK_PARSE_STATE_GOT_PAYLOAD,
+ MAVLINK_PARSE_STATE_GOT_CRC1
+} mavlink_parse_state_t; ///< The state machine for the comm parser
+
+typedef struct __mavlink_status {
+ uint8_t msg_received; ///< Number of received messages
+ uint8_t buffer_overrun; ///< Number of buffer overruns
+ uint8_t parse_error; ///< Number of parse errors
+ mavlink_parse_state_t parse_state; ///< Parsing state machine
+ uint8_t packet_idx; ///< Index in current packet
+ uint8_t current_rx_seq; ///< Sequence number of last packet received
+ uint8_t current_tx_seq; ///< Sequence number of last packet sent
+ uint16_t packet_rx_success_count; ///< Received packets
+ uint16_t packet_rx_drop_count; ///< Number of packet drops
+} mavlink_status_t;
+
+#define MAVLINK_BIG_ENDIAN 0
+#define MAVLINK_LITTLE_ENDIAN 1
+
+#endif /* MAVLINK_TYPES_H_ */
diff --git a/mavlink-solo/pymavlink/generator/C/include_v0.9/protocol.h b/mavlink-solo/pymavlink/generator/C/include_v0.9/protocol.h
new file mode 100644
index 0000000..5283779
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/include_v0.9/protocol.h
@@ -0,0 +1,323 @@
+#ifndef _MAVLINK_PROTOCOL_H_
+#define _MAVLINK_PROTOCOL_H_
+
+#include "string.h"
+#include "mavlink_types.h"
+
+/*
+ If you want MAVLink on a system that is native big-endian,
+ you need to define NATIVE_BIG_ENDIAN
+*/
+#ifdef NATIVE_BIG_ENDIAN
+# define MAVLINK_NEED_BYTE_SWAP (MAVLINK_ENDIAN == MAVLINK_LITTLE_ENDIAN)
+#else
+# define MAVLINK_NEED_BYTE_SWAP (MAVLINK_ENDIAN != MAVLINK_LITTLE_ENDIAN)
+#endif
+
+#ifndef MAVLINK_STACK_BUFFER
+#define MAVLINK_STACK_BUFFER 0
+#endif
+
+#ifndef MAVLINK_AVOID_GCC_STACK_BUG
+# define MAVLINK_AVOID_GCC_STACK_BUG defined(__GNUC__)
+#endif
+
+#ifndef MAVLINK_ASSERT
+#define MAVLINK_ASSERT(x)
+#endif
+
+#ifndef MAVLINK_START_UART_SEND
+#define MAVLINK_START_UART_SEND(chan, length)
+#endif
+
+#ifndef MAVLINK_END_UART_SEND
+#define MAVLINK_END_UART_SEND(chan, length)
+#endif
+
+#ifdef MAVLINK_SEPARATE_HELPERS
+#define MAVLINK_HELPER
+#else
+#define MAVLINK_HELPER static inline
+#include "mavlink_helpers.h"
+#endif // MAVLINK_SEPARATE_HELPERS
+
+/* always include the prototypes to ensure we don't get out of sync */
+MAVLINK_HELPER mavlink_status_t* mavlink_get_channel_status(uint8_t chan);
+#if MAVLINK_CRC_EXTRA
+MAVLINK_HELPER uint16_t mavlink_finalize_message_chan(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
+ uint8_t chan, uint8_t length, uint8_t crc_extra);
+MAVLINK_HELPER uint16_t mavlink_finalize_message(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
+ uint8_t length, uint8_t crc_extra);
+#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS
+MAVLINK_HELPER void _mav_finalize_message_chan_send(mavlink_channel_t chan, uint8_t msgid, const char *packet,
+ uint8_t length, uint8_t crc_extra);
+#endif
+#else
+MAVLINK_HELPER uint16_t mavlink_finalize_message_chan(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
+ uint8_t chan, uint8_t length);
+MAVLINK_HELPER uint16_t mavlink_finalize_message(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
+ uint8_t length);
+MAVLINK_HELPER void _mav_finalize_message_chan_send(mavlink_channel_t chan, uint8_t msgid, const char *packet, uint8_t length);
+#endif // MAVLINK_CRC_EXTRA
+MAVLINK_HELPER uint16_t mavlink_msg_to_send_buffer(uint8_t *buffer, const mavlink_message_t *msg);
+MAVLINK_HELPER void mavlink_start_checksum(mavlink_message_t* msg);
+MAVLINK_HELPER void mavlink_update_checksum(mavlink_message_t* msg, uint8_t c);
+MAVLINK_HELPER uint8_t mavlink_parse_char(uint8_t chan, uint8_t c, mavlink_message_t* r_message, mavlink_status_t* r_mavlink_status);
+MAVLINK_HELPER uint8_t put_bitfield_n_by_index(int32_t b, uint8_t bits, uint8_t packet_index, uint8_t bit_index,
+ uint8_t* r_bit_index, uint8_t* buffer);
+#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS
+MAVLINK_HELPER void _mavlink_send_uart(mavlink_channel_t chan, const char *buf, uint16_t len);
+MAVLINK_HELPER void _mavlink_resend_uart(mavlink_channel_t chan, const mavlink_message_t *msg);
+#endif
+
+/**
+ * @brief Get the required buffer size for this message
+ */
+static inline uint16_t mavlink_msg_get_send_buffer_length(const mavlink_message_t* msg)
+{
+ return msg->len + MAVLINK_NUM_NON_PAYLOAD_BYTES;
+}
+
+#if MAVLINK_NEED_BYTE_SWAP
+static inline void byte_swap_2(char *dst, const char *src)
+{
+ dst[0] = src[1];
+ dst[1] = src[0];
+}
+static inline void byte_swap_4(char *dst, const char *src)
+{
+ dst[0] = src[3];
+ dst[1] = src[2];
+ dst[2] = src[1];
+ dst[3] = src[0];
+}
+static inline void byte_swap_8(char *dst, const char *src)
+{
+ dst[0] = src[7];
+ dst[1] = src[6];
+ dst[2] = src[5];
+ dst[3] = src[4];
+ dst[4] = src[3];
+ dst[5] = src[2];
+ dst[6] = src[1];
+ dst[7] = src[0];
+}
+#elif !MAVLINK_ALIGNED_FIELDS
+static inline void byte_copy_2(char *dst, const char *src)
+{
+ dst[0] = src[0];
+ dst[1] = src[1];
+}
+static inline void byte_copy_4(char *dst, const char *src)
+{
+ dst[0] = src[0];
+ dst[1] = src[1];
+ dst[2] = src[2];
+ dst[3] = src[3];
+}
+static inline void byte_copy_8(char *dst, const char *src)
+{
+ memcpy(dst, src, 8);
+}
+#endif
+
+#define _mav_put_uint8_t(buf, wire_offset, b) buf[wire_offset] = (uint8_t)b
+#define _mav_put_int8_t(buf, wire_offset, b) buf[wire_offset] = (int8_t)b
+#define _mav_put_char(buf, wire_offset, b) buf[wire_offset] = b
+
+#if MAVLINK_NEED_BYTE_SWAP
+#define _mav_put_uint16_t(buf, wire_offset, b) byte_swap_2(&buf[wire_offset], (const char *)&b)
+#define _mav_put_int16_t(buf, wire_offset, b) byte_swap_2(&buf[wire_offset], (const char *)&b)
+#define _mav_put_uint32_t(buf, wire_offset, b) byte_swap_4(&buf[wire_offset], (const char *)&b)
+#define _mav_put_int32_t(buf, wire_offset, b) byte_swap_4(&buf[wire_offset], (const char *)&b)
+#define _mav_put_uint64_t(buf, wire_offset, b) byte_swap_8(&buf[wire_offset], (const char *)&b)
+#define _mav_put_int64_t(buf, wire_offset, b) byte_swap_8(&buf[wire_offset], (const char *)&b)
+#define _mav_put_float(buf, wire_offset, b) byte_swap_4(&buf[wire_offset], (const char *)&b)
+#define _mav_put_double(buf, wire_offset, b) byte_swap_8(&buf[wire_offset], (const char *)&b)
+#elif !MAVLINK_ALIGNED_FIELDS
+#define _mav_put_uint16_t(buf, wire_offset, b) byte_copy_2(&buf[wire_offset], (const char *)&b)
+#define _mav_put_int16_t(buf, wire_offset, b) byte_copy_2(&buf[wire_offset], (const char *)&b)
+#define _mav_put_uint32_t(buf, wire_offset, b) byte_copy_4(&buf[wire_offset], (const char *)&b)
+#define _mav_put_int32_t(buf, wire_offset, b) byte_copy_4(&buf[wire_offset], (const char *)&b)
+#define _mav_put_uint64_t(buf, wire_offset, b) byte_copy_8(&buf[wire_offset], (const char *)&b)
+#define _mav_put_int64_t(buf, wire_offset, b) byte_copy_8(&buf[wire_offset], (const char *)&b)
+#define _mav_put_float(buf, wire_offset, b) byte_copy_4(&buf[wire_offset], (const char *)&b)
+#define _mav_put_double(buf, wire_offset, b) byte_copy_8(&buf[wire_offset], (const char *)&b)
+#else
+#define _mav_put_uint16_t(buf, wire_offset, b) *(uint16_t *)&buf[wire_offset] = b
+#define _mav_put_int16_t(buf, wire_offset, b) *(int16_t *)&buf[wire_offset] = b
+#define _mav_put_uint32_t(buf, wire_offset, b) *(uint32_t *)&buf[wire_offset] = b
+#define _mav_put_int32_t(buf, wire_offset, b) *(int32_t *)&buf[wire_offset] = b
+#define _mav_put_uint64_t(buf, wire_offset, b) *(uint64_t *)&buf[wire_offset] = b
+#define _mav_put_int64_t(buf, wire_offset, b) *(int64_t *)&buf[wire_offset] = b
+#define _mav_put_float(buf, wire_offset, b) *(float *)&buf[wire_offset] = b
+#define _mav_put_double(buf, wire_offset, b) *(double *)&buf[wire_offset] = b
+#endif
+
+/*
+ like memcpy(), but if src is NULL, do a memset to zero
+*/
+static void mav_array_memcpy(void *dest, const void *src, size_t n)
+{
+ if (src == NULL) {
+ memset(dest, 0, n);
+ } else {
+ memcpy(dest, src, n);
+ }
+}
+
+/*
+ * Place a char array into a buffer
+ */
+static inline void _mav_put_char_array(char *buf, uint8_t wire_offset, const char *b, uint8_t array_length)
+{
+ mav_array_memcpy(&buf[wire_offset], b, array_length);
+
+}
+
+/*
+ * Place a uint8_t array into a buffer
+ */
+static inline void _mav_put_uint8_t_array(char *buf, uint8_t wire_offset, const uint8_t *b, uint8_t array_length)
+{
+ mav_array_memcpy(&buf[wire_offset], b, array_length);
+
+}
+
+/*
+ * Place a int8_t array into a buffer
+ */
+static inline void _mav_put_int8_t_array(char *buf, uint8_t wire_offset, const int8_t *b, uint8_t array_length)
+{
+ mav_array_memcpy(&buf[wire_offset], b, array_length);
+
+}
+
+#if MAVLINK_NEED_BYTE_SWAP
+#define _MAV_PUT_ARRAY(TYPE, V) \
+static inline void _mav_put_ ## TYPE ##_array(char *buf, uint8_t wire_offset, const TYPE *b, uint8_t array_length) \
+{ \
+ if (b == NULL) { \
+ memset(&buf[wire_offset], 0, array_length*sizeof(TYPE)); \
+ } else { \
+ uint16_t i; \
+ for (i=0; imsgid = MAVLINK_MSG_ID_TEST_TYPES;
+#if MAVLINK_CRC_EXTRA
+ return mavlink_finalize_message(msg, system_id, component_id, MAVLINK_MSG_ID_TEST_TYPES_LEN, MAVLINK_MSG_ID_TEST_TYPES_CRC);
+#else
+ return mavlink_finalize_message(msg, system_id, component_id, MAVLINK_MSG_ID_TEST_TYPES_LEN);
+#endif
+}
+
+/**
+ * @brief Pack a test_types message on a channel
+ * @param system_id ID of this system
+ * @param component_id ID of this component (e.g. 200 for IMU)
+ * @param chan The MAVLink channel this message was sent over
+ * @param msg The MAVLink message to compress the data into
+ * @param c char
+ * @param s string
+ * @param u8 uint8_t
+ * @param u16 uint16_t
+ * @param u32 uint32_t
+ * @param u64 uint64_t
+ * @param s8 int8_t
+ * @param s16 int16_t
+ * @param s32 int32_t
+ * @param s64 int64_t
+ * @param f float
+ * @param d double
+ * @param u8_array uint8_t_array
+ * @param u16_array uint16_t_array
+ * @param u32_array uint32_t_array
+ * @param u64_array uint64_t_array
+ * @param s8_array int8_t_array
+ * @param s16_array int16_t_array
+ * @param s32_array int32_t_array
+ * @param s64_array int64_t_array
+ * @param f_array float_array
+ * @param d_array double_array
+ * @return length of the message in bytes (excluding serial stream start sign)
+ */
+static inline uint16_t mavlink_msg_test_types_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan,
+ mavlink_message_t* msg,
+ char c,const char *s,uint8_t u8,uint16_t u16,uint32_t u32,uint64_t u64,int8_t s8,int16_t s16,int32_t s32,int64_t s64,float f,double d,const uint8_t *u8_array,const uint16_t *u16_array,const uint32_t *u32_array,const uint64_t *u64_array,const int8_t *s8_array,const int16_t *s16_array,const int32_t *s32_array,const int64_t *s64_array,const float *f_array,const double *d_array)
+{
+#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS
+ char buf[MAVLINK_MSG_ID_TEST_TYPES_LEN];
+ _mav_put_char(buf, 0, c);
+ _mav_put_uint8_t(buf, 11, u8);
+ _mav_put_uint16_t(buf, 12, u16);
+ _mav_put_uint32_t(buf, 14, u32);
+ _mav_put_uint64_t(buf, 18, u64);
+ _mav_put_int8_t(buf, 26, s8);
+ _mav_put_int16_t(buf, 27, s16);
+ _mav_put_int32_t(buf, 29, s32);
+ _mav_put_int64_t(buf, 33, s64);
+ _mav_put_float(buf, 41, f);
+ _mav_put_double(buf, 45, d);
+ _mav_put_char_array(buf, 1, s, 10);
+ _mav_put_uint8_t_array(buf, 53, u8_array, 3);
+ _mav_put_uint16_t_array(buf, 56, u16_array, 3);
+ _mav_put_uint32_t_array(buf, 62, u32_array, 3);
+ _mav_put_uint64_t_array(buf, 74, u64_array, 3);
+ _mav_put_int8_t_array(buf, 98, s8_array, 3);
+ _mav_put_int16_t_array(buf, 101, s16_array, 3);
+ _mav_put_int32_t_array(buf, 107, s32_array, 3);
+ _mav_put_int64_t_array(buf, 119, s64_array, 3);
+ _mav_put_float_array(buf, 143, f_array, 3);
+ _mav_put_double_array(buf, 155, d_array, 3);
+ memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, MAVLINK_MSG_ID_TEST_TYPES_LEN);
+#else
+ mavlink_test_types_t packet;
+ packet.c = c;
+ packet.u8 = u8;
+ packet.u16 = u16;
+ packet.u32 = u32;
+ packet.u64 = u64;
+ packet.s8 = s8;
+ packet.s16 = s16;
+ packet.s32 = s32;
+ packet.s64 = s64;
+ packet.f = f;
+ packet.d = d;
+ mav_array_memcpy(packet.s, s, sizeof(char)*10);
+ mav_array_memcpy(packet.u8_array, u8_array, sizeof(uint8_t)*3);
+ mav_array_memcpy(packet.u16_array, u16_array, sizeof(uint16_t)*3);
+ mav_array_memcpy(packet.u32_array, u32_array, sizeof(uint32_t)*3);
+ mav_array_memcpy(packet.u64_array, u64_array, sizeof(uint64_t)*3);
+ mav_array_memcpy(packet.s8_array, s8_array, sizeof(int8_t)*3);
+ mav_array_memcpy(packet.s16_array, s16_array, sizeof(int16_t)*3);
+ mav_array_memcpy(packet.s32_array, s32_array, sizeof(int32_t)*3);
+ mav_array_memcpy(packet.s64_array, s64_array, sizeof(int64_t)*3);
+ mav_array_memcpy(packet.f_array, f_array, sizeof(float)*3);
+ mav_array_memcpy(packet.d_array, d_array, sizeof(double)*3);
+ memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, MAVLINK_MSG_ID_TEST_TYPES_LEN);
+#endif
+
+ msg->msgid = MAVLINK_MSG_ID_TEST_TYPES;
+#if MAVLINK_CRC_EXTRA
+ return mavlink_finalize_message_chan(msg, system_id, component_id, chan, MAVLINK_MSG_ID_TEST_TYPES_LEN, MAVLINK_MSG_ID_TEST_TYPES_CRC);
+#else
+ return mavlink_finalize_message_chan(msg, system_id, component_id, chan, MAVLINK_MSG_ID_TEST_TYPES_LEN);
+#endif
+}
+
+/**
+ * @brief Encode a test_types struct into a message
+ *
+ * @param system_id ID of this system
+ * @param component_id ID of this component (e.g. 200 for IMU)
+ * @param msg The MAVLink message to compress the data into
+ * @param test_types C-struct to read the message contents from
+ */
+static inline uint16_t mavlink_msg_test_types_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg, const mavlink_test_types_t* test_types)
+{
+ return mavlink_msg_test_types_pack(system_id, component_id, msg, test_types->c, test_types->s, test_types->u8, test_types->u16, test_types->u32, test_types->u64, test_types->s8, test_types->s16, test_types->s32, test_types->s64, test_types->f, test_types->d, test_types->u8_array, test_types->u16_array, test_types->u32_array, test_types->u64_array, test_types->s8_array, test_types->s16_array, test_types->s32_array, test_types->s64_array, test_types->f_array, test_types->d_array);
+}
+
+/**
+ * @brief Send a test_types message
+ * @param chan MAVLink channel to send the message
+ *
+ * @param c char
+ * @param s string
+ * @param u8 uint8_t
+ * @param u16 uint16_t
+ * @param u32 uint32_t
+ * @param u64 uint64_t
+ * @param s8 int8_t
+ * @param s16 int16_t
+ * @param s32 int32_t
+ * @param s64 int64_t
+ * @param f float
+ * @param d double
+ * @param u8_array uint8_t_array
+ * @param u16_array uint16_t_array
+ * @param u32_array uint32_t_array
+ * @param u64_array uint64_t_array
+ * @param s8_array int8_t_array
+ * @param s16_array int16_t_array
+ * @param s32_array int32_t_array
+ * @param s64_array int64_t_array
+ * @param f_array float_array
+ * @param d_array double_array
+ */
+#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS
+
+static inline void mavlink_msg_test_types_send(mavlink_channel_t chan, char c, const char *s, uint8_t u8, uint16_t u16, uint32_t u32, uint64_t u64, int8_t s8, int16_t s16, int32_t s32, int64_t s64, float f, double d, const uint8_t *u8_array, const uint16_t *u16_array, const uint32_t *u32_array, const uint64_t *u64_array, const int8_t *s8_array, const int16_t *s16_array, const int32_t *s32_array, const int64_t *s64_array, const float *f_array, const double *d_array)
+{
+#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS
+ char buf[MAVLINK_MSG_ID_TEST_TYPES_LEN];
+ _mav_put_char(buf, 0, c);
+ _mav_put_uint8_t(buf, 11, u8);
+ _mav_put_uint16_t(buf, 12, u16);
+ _mav_put_uint32_t(buf, 14, u32);
+ _mav_put_uint64_t(buf, 18, u64);
+ _mav_put_int8_t(buf, 26, s8);
+ _mav_put_int16_t(buf, 27, s16);
+ _mav_put_int32_t(buf, 29, s32);
+ _mav_put_int64_t(buf, 33, s64);
+ _mav_put_float(buf, 41, f);
+ _mav_put_double(buf, 45, d);
+ _mav_put_char_array(buf, 1, s, 10);
+ _mav_put_uint8_t_array(buf, 53, u8_array, 3);
+ _mav_put_uint16_t_array(buf, 56, u16_array, 3);
+ _mav_put_uint32_t_array(buf, 62, u32_array, 3);
+ _mav_put_uint64_t_array(buf, 74, u64_array, 3);
+ _mav_put_int8_t_array(buf, 98, s8_array, 3);
+ _mav_put_int16_t_array(buf, 101, s16_array, 3);
+ _mav_put_int32_t_array(buf, 107, s32_array, 3);
+ _mav_put_int64_t_array(buf, 119, s64_array, 3);
+ _mav_put_float_array(buf, 143, f_array, 3);
+ _mav_put_double_array(buf, 155, d_array, 3);
+#if MAVLINK_CRC_EXTRA
+ _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_TEST_TYPES, buf, MAVLINK_MSG_ID_TEST_TYPES_LEN, MAVLINK_MSG_ID_TEST_TYPES_CRC);
+#else
+ _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_TEST_TYPES, buf, MAVLINK_MSG_ID_TEST_TYPES_LEN);
+#endif
+#else
+ mavlink_test_types_t packet;
+ packet.c = c;
+ packet.u8 = u8;
+ packet.u16 = u16;
+ packet.u32 = u32;
+ packet.u64 = u64;
+ packet.s8 = s8;
+ packet.s16 = s16;
+ packet.s32 = s32;
+ packet.s64 = s64;
+ packet.f = f;
+ packet.d = d;
+ mav_array_memcpy(packet.s, s, sizeof(char)*10);
+ mav_array_memcpy(packet.u8_array, u8_array, sizeof(uint8_t)*3);
+ mav_array_memcpy(packet.u16_array, u16_array, sizeof(uint16_t)*3);
+ mav_array_memcpy(packet.u32_array, u32_array, sizeof(uint32_t)*3);
+ mav_array_memcpy(packet.u64_array, u64_array, sizeof(uint64_t)*3);
+ mav_array_memcpy(packet.s8_array, s8_array, sizeof(int8_t)*3);
+ mav_array_memcpy(packet.s16_array, s16_array, sizeof(int16_t)*3);
+ mav_array_memcpy(packet.s32_array, s32_array, sizeof(int32_t)*3);
+ mav_array_memcpy(packet.s64_array, s64_array, sizeof(int64_t)*3);
+ mav_array_memcpy(packet.f_array, f_array, sizeof(float)*3);
+ mav_array_memcpy(packet.d_array, d_array, sizeof(double)*3);
+#if MAVLINK_CRC_EXTRA
+ _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_TEST_TYPES, (const char *)&packet, MAVLINK_MSG_ID_TEST_TYPES_LEN, MAVLINK_MSG_ID_TEST_TYPES_CRC);
+#else
+ _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_TEST_TYPES, (const char *)&packet, MAVLINK_MSG_ID_TEST_TYPES_LEN);
+#endif
+#endif
+}
+
+#endif
+
+// MESSAGE TEST_TYPES UNPACKING
+
+
+/**
+ * @brief Get field c from test_types message
+ *
+ * @return char
+ */
+static inline char mavlink_msg_test_types_get_c(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_char(msg, 0);
+}
+
+/**
+ * @brief Get field s from test_types message
+ *
+ * @return string
+ */
+static inline uint16_t mavlink_msg_test_types_get_s(const mavlink_message_t* msg, char *s)
+{
+ return _MAV_RETURN_char_array(msg, s, 10, 1);
+}
+
+/**
+ * @brief Get field u8 from test_types message
+ *
+ * @return uint8_t
+ */
+static inline uint8_t mavlink_msg_test_types_get_u8(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_uint8_t(msg, 11);
+}
+
+/**
+ * @brief Get field u16 from test_types message
+ *
+ * @return uint16_t
+ */
+static inline uint16_t mavlink_msg_test_types_get_u16(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_uint16_t(msg, 12);
+}
+
+/**
+ * @brief Get field u32 from test_types message
+ *
+ * @return uint32_t
+ */
+static inline uint32_t mavlink_msg_test_types_get_u32(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_uint32_t(msg, 14);
+}
+
+/**
+ * @brief Get field u64 from test_types message
+ *
+ * @return uint64_t
+ */
+static inline uint64_t mavlink_msg_test_types_get_u64(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_uint64_t(msg, 18);
+}
+
+/**
+ * @brief Get field s8 from test_types message
+ *
+ * @return int8_t
+ */
+static inline int8_t mavlink_msg_test_types_get_s8(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_int8_t(msg, 26);
+}
+
+/**
+ * @brief Get field s16 from test_types message
+ *
+ * @return int16_t
+ */
+static inline int16_t mavlink_msg_test_types_get_s16(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_int16_t(msg, 27);
+}
+
+/**
+ * @brief Get field s32 from test_types message
+ *
+ * @return int32_t
+ */
+static inline int32_t mavlink_msg_test_types_get_s32(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_int32_t(msg, 29);
+}
+
+/**
+ * @brief Get field s64 from test_types message
+ *
+ * @return int64_t
+ */
+static inline int64_t mavlink_msg_test_types_get_s64(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_int64_t(msg, 33);
+}
+
+/**
+ * @brief Get field f from test_types message
+ *
+ * @return float
+ */
+static inline float mavlink_msg_test_types_get_f(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_float(msg, 41);
+}
+
+/**
+ * @brief Get field d from test_types message
+ *
+ * @return double
+ */
+static inline double mavlink_msg_test_types_get_d(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_double(msg, 45);
+}
+
+/**
+ * @brief Get field u8_array from test_types message
+ *
+ * @return uint8_t_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_u8_array(const mavlink_message_t* msg, uint8_t *u8_array)
+{
+ return _MAV_RETURN_uint8_t_array(msg, u8_array, 3, 53);
+}
+
+/**
+ * @brief Get field u16_array from test_types message
+ *
+ * @return uint16_t_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_u16_array(const mavlink_message_t* msg, uint16_t *u16_array)
+{
+ return _MAV_RETURN_uint16_t_array(msg, u16_array, 3, 56);
+}
+
+/**
+ * @brief Get field u32_array from test_types message
+ *
+ * @return uint32_t_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_u32_array(const mavlink_message_t* msg, uint32_t *u32_array)
+{
+ return _MAV_RETURN_uint32_t_array(msg, u32_array, 3, 62);
+}
+
+/**
+ * @brief Get field u64_array from test_types message
+ *
+ * @return uint64_t_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_u64_array(const mavlink_message_t* msg, uint64_t *u64_array)
+{
+ return _MAV_RETURN_uint64_t_array(msg, u64_array, 3, 74);
+}
+
+/**
+ * @brief Get field s8_array from test_types message
+ *
+ * @return int8_t_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_s8_array(const mavlink_message_t* msg, int8_t *s8_array)
+{
+ return _MAV_RETURN_int8_t_array(msg, s8_array, 3, 98);
+}
+
+/**
+ * @brief Get field s16_array from test_types message
+ *
+ * @return int16_t_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_s16_array(const mavlink_message_t* msg, int16_t *s16_array)
+{
+ return _MAV_RETURN_int16_t_array(msg, s16_array, 3, 101);
+}
+
+/**
+ * @brief Get field s32_array from test_types message
+ *
+ * @return int32_t_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_s32_array(const mavlink_message_t* msg, int32_t *s32_array)
+{
+ return _MAV_RETURN_int32_t_array(msg, s32_array, 3, 107);
+}
+
+/**
+ * @brief Get field s64_array from test_types message
+ *
+ * @return int64_t_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_s64_array(const mavlink_message_t* msg, int64_t *s64_array)
+{
+ return _MAV_RETURN_int64_t_array(msg, s64_array, 3, 119);
+}
+
+/**
+ * @brief Get field f_array from test_types message
+ *
+ * @return float_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_f_array(const mavlink_message_t* msg, float *f_array)
+{
+ return _MAV_RETURN_float_array(msg, f_array, 3, 143);
+}
+
+/**
+ * @brief Get field d_array from test_types message
+ *
+ * @return double_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_d_array(const mavlink_message_t* msg, double *d_array)
+{
+ return _MAV_RETURN_double_array(msg, d_array, 3, 155);
+}
+
+/**
+ * @brief Decode a test_types message into a struct
+ *
+ * @param msg The message to decode
+ * @param test_types C-struct to decode the message contents into
+ */
+static inline void mavlink_msg_test_types_decode(const mavlink_message_t* msg, mavlink_test_types_t* test_types)
+{
+#if MAVLINK_NEED_BYTE_SWAP
+ test_types->c = mavlink_msg_test_types_get_c(msg);
+ mavlink_msg_test_types_get_s(msg, test_types->s);
+ test_types->u8 = mavlink_msg_test_types_get_u8(msg);
+ test_types->u16 = mavlink_msg_test_types_get_u16(msg);
+ test_types->u32 = mavlink_msg_test_types_get_u32(msg);
+ test_types->u64 = mavlink_msg_test_types_get_u64(msg);
+ test_types->s8 = mavlink_msg_test_types_get_s8(msg);
+ test_types->s16 = mavlink_msg_test_types_get_s16(msg);
+ test_types->s32 = mavlink_msg_test_types_get_s32(msg);
+ test_types->s64 = mavlink_msg_test_types_get_s64(msg);
+ test_types->f = mavlink_msg_test_types_get_f(msg);
+ test_types->d = mavlink_msg_test_types_get_d(msg);
+ mavlink_msg_test_types_get_u8_array(msg, test_types->u8_array);
+ mavlink_msg_test_types_get_u16_array(msg, test_types->u16_array);
+ mavlink_msg_test_types_get_u32_array(msg, test_types->u32_array);
+ mavlink_msg_test_types_get_u64_array(msg, test_types->u64_array);
+ mavlink_msg_test_types_get_s8_array(msg, test_types->s8_array);
+ mavlink_msg_test_types_get_s16_array(msg, test_types->s16_array);
+ mavlink_msg_test_types_get_s32_array(msg, test_types->s32_array);
+ mavlink_msg_test_types_get_s64_array(msg, test_types->s64_array);
+ mavlink_msg_test_types_get_f_array(msg, test_types->f_array);
+ mavlink_msg_test_types_get_d_array(msg, test_types->d_array);
+#else
+ memcpy(test_types, _MAV_PAYLOAD(msg), MAVLINK_MSG_ID_TEST_TYPES_LEN);
+#endif
+}
diff --git a/mavlink-solo/pymavlink/generator/C/include_v0.9/test/test.h b/mavlink-solo/pymavlink/generator/C/include_v0.9/test/test.h
new file mode 100644
index 0000000..46b47be
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/include_v0.9/test/test.h
@@ -0,0 +1,53 @@
+/** @file
+ * @brief MAVLink comm protocol generated from test.xml
+ * @see http://qgroundcontrol.org/mavlink/
+ */
+#ifndef TEST_H
+#define TEST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// MESSAGE LENGTHS AND CRCS
+
+#ifndef MAVLINK_MESSAGE_LENGTHS
+#define MAVLINK_MESSAGE_LENGTHS {179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#endif
+
+#ifndef MAVLINK_MESSAGE_CRCS
+#define MAVLINK_MESSAGE_CRCS {91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#endif
+
+#ifndef MAVLINK_MESSAGE_INFO
+#define MAVLINK_MESSAGE_INFO {MAVLINK_MESSAGE_INFO_TEST_TYPES, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}}
+#endif
+
+#include "../protocol.h"
+
+#define MAVLINK_ENABLED_TEST
+
+// ENUM DEFINITIONS
+
+
+
+
+
+// MAVLINK VERSION
+
+#ifndef MAVLINK_VERSION
+#define MAVLINK_VERSION 3
+#endif
+
+#if (MAVLINK_VERSION == 0)
+#undef MAVLINK_VERSION
+#define MAVLINK_VERSION 3
+#endif
+
+// MESSAGE DEFINITIONS
+#include "./mavlink_msg_test_types.h"
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif // TEST_H
diff --git a/mavlink-solo/pymavlink/generator/C/include_v0.9/test/testsuite.h b/mavlink-solo/pymavlink/generator/C/include_v0.9/test/testsuite.h
new file mode 100644
index 0000000..9b0fc04
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/include_v0.9/test/testsuite.h
@@ -0,0 +1,120 @@
+/** @file
+ * @brief MAVLink comm protocol testsuite generated from test.xml
+ * @see http://qgroundcontrol.org/mavlink/
+ */
+#ifndef TEST_TESTSUITE_H
+#define TEST_TESTSUITE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MAVLINK_TEST_ALL
+#define MAVLINK_TEST_ALL
+
+static void mavlink_test_test(uint8_t, uint8_t, mavlink_message_t *last_msg);
+
+static void mavlink_test_all(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg)
+{
+
+ mavlink_test_test(system_id, component_id, last_msg);
+}
+#endif
+
+
+
+
+static void mavlink_test_test_types(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg)
+{
+ mavlink_message_t msg;
+ uint8_t buffer[MAVLINK_MAX_PACKET_LEN];
+ uint16_t i;
+ mavlink_test_types_t packet_in = {
+ 'A',
+ "BCDEFGHIJ",
+ 230,
+ 17859,
+ 963498192,
+ 93372036854776941ULL,
+ 211,
+ 18639,
+ 963498972,
+ 93372036854777886LL,
+ 304.0,
+ 438.0,
+ { 228, 229, 230 },
+ { 20147, 20148, 20149 },
+ { 963500688, 963500689, 963500690 },
+ { 93372036854780469, 93372036854780470, 93372036854780471 },
+ { 171, 172, 173 },
+ { 22487, 22488, 22489 },
+ { 963503028, 963503029, 963503030 },
+ { 93372036854783304, 93372036854783305, 93372036854783306 },
+ { 1018.0, 1019.0, 1020.0 },
+ { 1208.0, 1209.0, 1210.0 },
+ };
+ mavlink_test_types_t packet1, packet2;
+ memset(&packet1, 0, sizeof(packet1));
+ packet1.c = packet_in.c;
+ packet1.u8 = packet_in.u8;
+ packet1.u16 = packet_in.u16;
+ packet1.u32 = packet_in.u32;
+ packet1.u64 = packet_in.u64;
+ packet1.s8 = packet_in.s8;
+ packet1.s16 = packet_in.s16;
+ packet1.s32 = packet_in.s32;
+ packet1.s64 = packet_in.s64;
+ packet1.f = packet_in.f;
+ packet1.d = packet_in.d;
+
+ mav_array_memcpy(packet1.s, packet_in.s, sizeof(char)*10);
+ mav_array_memcpy(packet1.u8_array, packet_in.u8_array, sizeof(uint8_t)*3);
+ mav_array_memcpy(packet1.u16_array, packet_in.u16_array, sizeof(uint16_t)*3);
+ mav_array_memcpy(packet1.u32_array, packet_in.u32_array, sizeof(uint32_t)*3);
+ mav_array_memcpy(packet1.u64_array, packet_in.u64_array, sizeof(uint64_t)*3);
+ mav_array_memcpy(packet1.s8_array, packet_in.s8_array, sizeof(int8_t)*3);
+ mav_array_memcpy(packet1.s16_array, packet_in.s16_array, sizeof(int16_t)*3);
+ mav_array_memcpy(packet1.s32_array, packet_in.s32_array, sizeof(int32_t)*3);
+ mav_array_memcpy(packet1.s64_array, packet_in.s64_array, sizeof(int64_t)*3);
+ mav_array_memcpy(packet1.f_array, packet_in.f_array, sizeof(float)*3);
+ mav_array_memcpy(packet1.d_array, packet_in.d_array, sizeof(double)*3);
+
+
+ memset(&packet2, 0, sizeof(packet2));
+ mavlink_msg_test_types_encode(system_id, component_id, &msg, &packet1);
+ mavlink_msg_test_types_decode(&msg, &packet2);
+ MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0);
+
+ memset(&packet2, 0, sizeof(packet2));
+ mavlink_msg_test_types_pack(system_id, component_id, &msg , packet1.c , packet1.s , packet1.u8 , packet1.u16 , packet1.u32 , packet1.u64 , packet1.s8 , packet1.s16 , packet1.s32 , packet1.s64 , packet1.f , packet1.d , packet1.u8_array , packet1.u16_array , packet1.u32_array , packet1.u64_array , packet1.s8_array , packet1.s16_array , packet1.s32_array , packet1.s64_array , packet1.f_array , packet1.d_array );
+ mavlink_msg_test_types_decode(&msg, &packet2);
+ MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0);
+
+ memset(&packet2, 0, sizeof(packet2));
+ mavlink_msg_test_types_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg , packet1.c , packet1.s , packet1.u8 , packet1.u16 , packet1.u32 , packet1.u64 , packet1.s8 , packet1.s16 , packet1.s32 , packet1.s64 , packet1.f , packet1.d , packet1.u8_array , packet1.u16_array , packet1.u32_array , packet1.u64_array , packet1.s8_array , packet1.s16_array , packet1.s32_array , packet1.s64_array , packet1.f_array , packet1.d_array );
+ mavlink_msg_test_types_decode(&msg, &packet2);
+ MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0);
+
+ memset(&packet2, 0, sizeof(packet2));
+ mavlink_msg_to_send_buffer(buffer, &msg);
+ for (i=0; i
+
+/**
+ *
+ * CALCULATE THE CHECKSUM
+ *
+ */
+
+#define X25_INIT_CRC 0xffff
+#define X25_VALIDATE_CRC 0xf0b8
+
+#ifndef HAVE_CRC_ACCUMULATE
+/**
+ * @brief Accumulate the X.25 CRC by adding one char at a time.
+ *
+ * The checksum function adds the hash of one char at a time to the
+ * 16 bit checksum (uint16_t).
+ *
+ * @param data new char to hash
+ * @param crcAccum the already accumulated checksum
+ **/
+static inline void crc_accumulate(uint8_t data, uint16_t *crcAccum)
+{
+ /*Accumulate one byte of data into the CRC*/
+ uint8_t tmp;
+
+ tmp = data ^ (uint8_t)(*crcAccum &0xff);
+ tmp ^= (tmp<<4);
+ *crcAccum = (*crcAccum>>8) ^ (tmp<<8) ^ (tmp <<3) ^ (tmp>>4);
+}
+#endif
+
+
+/**
+ * @brief Initiliaze the buffer for the X.25 CRC
+ *
+ * @param crcAccum the 16 bit X.25 CRC
+ */
+static inline void crc_init(uint16_t* crcAccum)
+{
+ *crcAccum = X25_INIT_CRC;
+}
+
+
+/**
+ * @brief Calculates the X.25 checksum on a byte buffer
+ *
+ * @param pBuffer buffer containing the byte array to hash
+ * @param length length of the byte array
+ * @return the checksum over the buffer bytes
+ **/
+static inline uint16_t crc_calculate(const uint8_t* pBuffer, uint16_t length)
+{
+ uint16_t crcTmp;
+ crc_init(&crcTmp);
+ while (length--) {
+ crc_accumulate(*pBuffer++, &crcTmp);
+ }
+ return crcTmp;
+}
+
+
+/**
+ * @brief Accumulate the X.25 CRC by adding an array of bytes
+ *
+ * The checksum function adds the hash of one char at a time to the
+ * 16 bit checksum (uint16_t).
+ *
+ * @param data new bytes to hash
+ * @param crcAccum the already accumulated checksum
+ **/
+static inline void crc_accumulate_buffer(uint16_t *crcAccum, const char *pBuffer, uint16_t length)
+{
+ const uint8_t *p = (const uint8_t *)pBuffer;
+ while (length--) {
+ crc_accumulate(*p++, crcAccum);
+ }
+}
+
+#endif /* _CHECKSUM_H_ */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/mavlink-solo/pymavlink/generator/C/include_v1.0/mavlink_conversions.h b/mavlink-solo/pymavlink/generator/C/include_v1.0/mavlink_conversions.h
new file mode 100644
index 0000000..63bcfa3
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/include_v1.0/mavlink_conversions.h
@@ -0,0 +1,211 @@
+#ifndef _MAVLINK_CONVERSIONS_H_
+#define _MAVLINK_CONVERSIONS_H_
+
+/* enable math defines on Windows */
+#ifdef _MSC_VER
+#ifndef _USE_MATH_DEFINES
+#define _USE_MATH_DEFINES
+#endif
+#endif
+#include
+
+#ifndef M_PI_2
+ #define M_PI_2 ((float)asin(1))
+#endif
+
+/**
+ * @file mavlink_conversions.h
+ *
+ * These conversion functions follow the NASA rotation standards definition file
+ * available online.
+ *
+ * Their intent is to lower the barrier for MAVLink adopters to use gimbal-lock free
+ * (both rotation matrices, sometimes called DCM, and quaternions are gimbal-lock free)
+ * rotation representations. Euler angles (roll, pitch, yaw) will be phased out of the
+ * protocol as widely as possible.
+ *
+ * @author James Goppert
+ * @author Thomas Gubler
+ */
+
+
+/**
+ * Converts a quaternion to a rotation matrix
+ *
+ * @param quaternion a [w, x, y, z] ordered quaternion (null-rotation being 1 0 0 0)
+ * @param dcm a 3x3 rotation matrix
+ */
+MAVLINK_HELPER void mavlink_quaternion_to_dcm(const float quaternion[4], float dcm[3][3])
+{
+ double a = quaternion[0];
+ double b = quaternion[1];
+ double c = quaternion[2];
+ double d = quaternion[3];
+ double aSq = a * a;
+ double bSq = b * b;
+ double cSq = c * c;
+ double dSq = d * d;
+ dcm[0][0] = aSq + bSq - cSq - dSq;
+ dcm[0][1] = 2 * (b * c - a * d);
+ dcm[0][2] = 2 * (a * c + b * d);
+ dcm[1][0] = 2 * (b * c + a * d);
+ dcm[1][1] = aSq - bSq + cSq - dSq;
+ dcm[1][2] = 2 * (c * d - a * b);
+ dcm[2][0] = 2 * (b * d - a * c);
+ dcm[2][1] = 2 * (a * b + c * d);
+ dcm[2][2] = aSq - bSq - cSq + dSq;
+}
+
+
+/**
+ * Converts a rotation matrix to euler angles
+ *
+ * @param dcm a 3x3 rotation matrix
+ * @param roll the roll angle in radians
+ * @param pitch the pitch angle in radians
+ * @param yaw the yaw angle in radians
+ */
+MAVLINK_HELPER void mavlink_dcm_to_euler(const float dcm[3][3], float* roll, float* pitch, float* yaw)
+{
+ float phi, theta, psi;
+ theta = asin(-dcm[2][0]);
+
+ if (fabsf(theta - (float)M_PI_2) < 1.0e-3f) {
+ phi = 0.0f;
+ psi = (atan2f(dcm[1][2] - dcm[0][1],
+ dcm[0][2] + dcm[1][1]) + phi);
+
+ } else if (fabsf(theta + (float)M_PI_2) < 1.0e-3f) {
+ phi = 0.0f;
+ psi = atan2f(dcm[1][2] - dcm[0][1],
+ dcm[0][2] + dcm[1][1] - phi);
+
+ } else {
+ phi = atan2f(dcm[2][1], dcm[2][2]);
+ psi = atan2f(dcm[1][0], dcm[0][0]);
+ }
+
+ *roll = phi;
+ *pitch = theta;
+ *yaw = psi;
+}
+
+
+/**
+ * Converts a quaternion to euler angles
+ *
+ * @param quaternion a [w, x, y, z] ordered quaternion (null-rotation being 1 0 0 0)
+ * @param roll the roll angle in radians
+ * @param pitch the pitch angle in radians
+ * @param yaw the yaw angle in radians
+ */
+MAVLINK_HELPER void mavlink_quaternion_to_euler(const float quaternion[4], float* roll, float* pitch, float* yaw)
+{
+ float dcm[3][3];
+ mavlink_quaternion_to_dcm(quaternion, dcm);
+ mavlink_dcm_to_euler((const float(*)[3])dcm, roll, pitch, yaw);
+}
+
+
+/**
+ * Converts euler angles to a quaternion
+ *
+ * @param roll the roll angle in radians
+ * @param pitch the pitch angle in radians
+ * @param yaw the yaw angle in radians
+ * @param quaternion a [w, x, y, z] ordered quaternion (null-rotation being 1 0 0 0)
+ */
+MAVLINK_HELPER void mavlink_euler_to_quaternion(float roll, float pitch, float yaw, float quaternion[4])
+{
+ float cosPhi_2 = cosf(roll / 2);
+ float sinPhi_2 = sinf(roll / 2);
+ float cosTheta_2 = cosf(pitch / 2);
+ float sinTheta_2 = sinf(pitch / 2);
+ float cosPsi_2 = cosf(yaw / 2);
+ float sinPsi_2 = sinf(yaw / 2);
+ quaternion[0] = (cosPhi_2 * cosTheta_2 * cosPsi_2 +
+ sinPhi_2 * sinTheta_2 * sinPsi_2);
+ quaternion[1] = (sinPhi_2 * cosTheta_2 * cosPsi_2 -
+ cosPhi_2 * sinTheta_2 * sinPsi_2);
+ quaternion[2] = (cosPhi_2 * sinTheta_2 * cosPsi_2 +
+ sinPhi_2 * cosTheta_2 * sinPsi_2);
+ quaternion[3] = (cosPhi_2 * cosTheta_2 * sinPsi_2 -
+ sinPhi_2 * sinTheta_2 * cosPsi_2);
+}
+
+
+/**
+ * Converts a rotation matrix to a quaternion
+ * Reference:
+ * - Shoemake, Quaternions,
+ * http://www.cs.ucr.edu/~vbz/resources/quatut.pdf
+ *
+ * @param dcm a 3x3 rotation matrix
+ * @param quaternion a [w, x, y, z] ordered quaternion (null-rotation being 1 0 0 0)
+ */
+MAVLINK_HELPER void mavlink_dcm_to_quaternion(const float dcm[3][3], float quaternion[4])
+{
+ float tr = dcm[0][0] + dcm[1][1] + dcm[2][2];
+ if (tr > 0.0f) {
+ float s = sqrtf(tr + 1.0f);
+ quaternion[0] = s * 0.5f;
+ s = 0.5f / s;
+ quaternion[1] = (dcm[2][1] - dcm[1][2]) * s;
+ quaternion[2] = (dcm[0][2] - dcm[2][0]) * s;
+ quaternion[3] = (dcm[1][0] - dcm[0][1]) * s;
+ } else {
+ /* Find maximum diagonal element in dcm
+ * store index in dcm_i */
+ int dcm_i = 0;
+ int i;
+ for (i = 1; i < 3; i++) {
+ if (dcm[i][i] > dcm[dcm_i][dcm_i]) {
+ dcm_i = i;
+ }
+ }
+
+ int dcm_j = (dcm_i + 1) % 3;
+ int dcm_k = (dcm_i + 2) % 3;
+
+ float s = sqrtf((dcm[dcm_i][dcm_i] - dcm[dcm_j][dcm_j] -
+ dcm[dcm_k][dcm_k]) + 1.0f);
+ quaternion[dcm_i + 1] = s * 0.5f;
+ s = 0.5f / s;
+ quaternion[dcm_j + 1] = (dcm[dcm_i][dcm_j] + dcm[dcm_j][dcm_i]) * s;
+ quaternion[dcm_k + 1] = (dcm[dcm_k][dcm_i] + dcm[dcm_i][dcm_k]) * s;
+ quaternion[0] = (dcm[dcm_k][dcm_j] - dcm[dcm_j][dcm_k]) * s;
+ }
+}
+
+
+/**
+ * Converts euler angles to a rotation matrix
+ *
+ * @param roll the roll angle in radians
+ * @param pitch the pitch angle in radians
+ * @param yaw the yaw angle in radians
+ * @param dcm a 3x3 rotation matrix
+ */
+MAVLINK_HELPER void mavlink_euler_to_dcm(float roll, float pitch, float yaw, float dcm[3][3])
+{
+ float cosPhi = cosf(roll);
+ float sinPhi = sinf(roll);
+ float cosThe = cosf(pitch);
+ float sinThe = sinf(pitch);
+ float cosPsi = cosf(yaw);
+ float sinPsi = sinf(yaw);
+
+ dcm[0][0] = cosThe * cosPsi;
+ dcm[0][1] = -cosPhi * sinPsi + sinPhi * sinThe * cosPsi;
+ dcm[0][2] = sinPhi * sinPsi + cosPhi * sinThe * cosPsi;
+
+ dcm[1][0] = cosThe * sinPsi;
+ dcm[1][1] = cosPhi * cosPsi + sinPhi * sinThe * sinPsi;
+ dcm[1][2] = -sinPhi * cosPsi + cosPhi * sinThe * sinPsi;
+
+ dcm[2][0] = -sinThe;
+ dcm[2][1] = sinPhi * cosThe;
+ dcm[2][2] = cosPhi * cosThe;
+}
+
+#endif
diff --git a/mavlink-solo/pymavlink/generator/C/include_v1.0/mavlink_helpers.h b/mavlink-solo/pymavlink/generator/C/include_v1.0/mavlink_helpers.h
new file mode 100644
index 0000000..0fa87fc
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/include_v1.0/mavlink_helpers.h
@@ -0,0 +1,676 @@
+#ifndef _MAVLINK_HELPERS_H_
+#define _MAVLINK_HELPERS_H_
+
+#include "string.h"
+#include "checksum.h"
+#include "mavlink_types.h"
+#include "mavlink_conversions.h"
+
+#ifndef MAVLINK_HELPER
+#define MAVLINK_HELPER
+#endif
+
+/*
+ * Internal function to give access to the channel status for each channel
+ */
+#ifndef MAVLINK_GET_CHANNEL_STATUS
+MAVLINK_HELPER mavlink_status_t* mavlink_get_channel_status(uint8_t chan)
+{
+#ifdef MAVLINK_EXTERNAL_RX_STATUS
+ // No m_mavlink_status array defined in function,
+ // has to be defined externally
+#else
+ static mavlink_status_t m_mavlink_status[MAVLINK_COMM_NUM_BUFFERS];
+#endif
+ return &m_mavlink_status[chan];
+}
+#endif
+
+/*
+ * Internal function to give access to the channel buffer for each channel
+ */
+#ifndef MAVLINK_GET_CHANNEL_BUFFER
+MAVLINK_HELPER mavlink_message_t* mavlink_get_channel_buffer(uint8_t chan)
+{
+
+#ifdef MAVLINK_EXTERNAL_RX_BUFFER
+ // No m_mavlink_buffer array defined in function,
+ // has to be defined externally
+#else
+ static mavlink_message_t m_mavlink_buffer[MAVLINK_COMM_NUM_BUFFERS];
+#endif
+ return &m_mavlink_buffer[chan];
+}
+#endif
+
+/**
+ * @brief Reset the status of a channel.
+ */
+MAVLINK_HELPER void mavlink_reset_channel_status(uint8_t chan)
+{
+ mavlink_status_t *status = mavlink_get_channel_status(chan);
+ status->parse_state = MAVLINK_PARSE_STATE_IDLE;
+}
+
+/**
+ * @brief Finalize a MAVLink message with channel assignment
+ *
+ * This function calculates the checksum and sets length and aircraft id correctly.
+ * It assumes that the message id and the payload are already correctly set. This function
+ * can also be used if the message header has already been written before (as in mavlink_msg_xxx_pack
+ * instead of mavlink_msg_xxx_pack_headerless), it just introduces little extra overhead.
+ *
+ * @param msg Message to finalize
+ * @param system_id Id of the sending (this) system, 1-127
+ * @param length Message length
+ */
+#if MAVLINK_CRC_EXTRA
+MAVLINK_HELPER uint16_t mavlink_finalize_message_chan(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
+ uint8_t chan, uint8_t length, uint8_t crc_extra)
+#else
+MAVLINK_HELPER uint16_t mavlink_finalize_message_chan(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
+ uint8_t chan, uint8_t length)
+#endif
+{
+ // This code part is the same for all messages;
+ msg->magic = MAVLINK_STX;
+ msg->len = length;
+ msg->sysid = system_id;
+ msg->compid = component_id;
+ // One sequence number per channel
+ msg->seq = mavlink_get_channel_status(chan)->current_tx_seq;
+ mavlink_get_channel_status(chan)->current_tx_seq = mavlink_get_channel_status(chan)->current_tx_seq+1;
+ msg->checksum = crc_calculate(((const uint8_t*)(msg)) + 3, MAVLINK_CORE_HEADER_LEN);
+ crc_accumulate_buffer(&msg->checksum, _MAV_PAYLOAD(msg), msg->len);
+#if MAVLINK_CRC_EXTRA
+ crc_accumulate(crc_extra, &msg->checksum);
+#endif
+ mavlink_ck_a(msg) = (uint8_t)(msg->checksum & 0xFF);
+ mavlink_ck_b(msg) = (uint8_t)(msg->checksum >> 8);
+
+ return length + MAVLINK_NUM_NON_PAYLOAD_BYTES;
+}
+
+
+/**
+ * @brief Finalize a MAVLink message with MAVLINK_COMM_0 as default channel
+ */
+#if MAVLINK_CRC_EXTRA
+MAVLINK_HELPER uint16_t mavlink_finalize_message(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
+ uint8_t length, uint8_t crc_extra)
+{
+ return mavlink_finalize_message_chan(msg, system_id, component_id, MAVLINK_COMM_0, length, crc_extra);
+}
+#else
+MAVLINK_HELPER uint16_t mavlink_finalize_message(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
+ uint8_t length)
+{
+ return mavlink_finalize_message_chan(msg, system_id, component_id, MAVLINK_COMM_0, length);
+}
+#endif
+
+#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS
+MAVLINK_HELPER void _mavlink_send_uart(mavlink_channel_t chan, const char *buf, uint16_t len);
+
+/**
+ * @brief Finalize a MAVLink message with channel assignment and send
+ */
+#if MAVLINK_CRC_EXTRA
+MAVLINK_HELPER void _mav_finalize_message_chan_send(mavlink_channel_t chan, uint8_t msgid, const char *packet,
+ uint8_t length, uint8_t crc_extra)
+#else
+MAVLINK_HELPER void _mav_finalize_message_chan_send(mavlink_channel_t chan, uint8_t msgid, const char *packet, uint8_t length)
+#endif
+{
+ uint16_t checksum;
+ uint8_t buf[MAVLINK_NUM_HEADER_BYTES];
+ uint8_t ck[2];
+ mavlink_status_t *status = mavlink_get_channel_status(chan);
+ buf[0] = MAVLINK_STX;
+ buf[1] = length;
+ buf[2] = status->current_tx_seq;
+ buf[3] = mavlink_system.sysid;
+ buf[4] = mavlink_system.compid;
+ buf[5] = msgid;
+ status->current_tx_seq++;
+ checksum = crc_calculate((const uint8_t*)&buf[1], MAVLINK_CORE_HEADER_LEN);
+ crc_accumulate_buffer(&checksum, packet, length);
+#if MAVLINK_CRC_EXTRA
+ crc_accumulate(crc_extra, &checksum);
+#endif
+ ck[0] = (uint8_t)(checksum & 0xFF);
+ ck[1] = (uint8_t)(checksum >> 8);
+
+ MAVLINK_START_UART_SEND(chan, MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)length);
+ _mavlink_send_uart(chan, (const char *)buf, MAVLINK_NUM_HEADER_BYTES);
+ _mavlink_send_uart(chan, packet, length);
+ _mavlink_send_uart(chan, (const char *)ck, 2);
+ MAVLINK_END_UART_SEND(chan, MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)length);
+}
+
+/**
+ * @brief re-send a message over a uart channel
+ * this is more stack efficient than re-marshalling the message
+ */
+MAVLINK_HELPER void _mavlink_resend_uart(mavlink_channel_t chan, const mavlink_message_t *msg)
+{
+ uint8_t ck[2];
+
+ ck[0] = (uint8_t)(msg->checksum & 0xFF);
+ ck[1] = (uint8_t)(msg->checksum >> 8);
+ // XXX use the right sequence here
+
+ MAVLINK_START_UART_SEND(chan, MAVLINK_NUM_NON_PAYLOAD_BYTES + msg->len);
+ _mavlink_send_uart(chan, (const char *)&msg->magic, MAVLINK_NUM_HEADER_BYTES);
+ _mavlink_send_uart(chan, _MAV_PAYLOAD(msg), msg->len);
+ _mavlink_send_uart(chan, (const char *)ck, 2);
+ MAVLINK_END_UART_SEND(chan, MAVLINK_NUM_NON_PAYLOAD_BYTES + msg->len);
+}
+#endif // MAVLINK_USE_CONVENIENCE_FUNCTIONS
+
+/**
+ * @brief Pack a message to send it over a serial byte stream
+ */
+MAVLINK_HELPER uint16_t mavlink_msg_to_send_buffer(uint8_t *buffer, const mavlink_message_t *msg)
+{
+ memcpy(buffer, (const uint8_t *)&msg->magic, MAVLINK_NUM_HEADER_BYTES + (uint16_t)msg->len);
+
+ uint8_t *ck = buffer + (MAVLINK_NUM_HEADER_BYTES + (uint16_t)msg->len);
+
+ ck[0] = (uint8_t)(msg->checksum & 0xFF);
+ ck[1] = (uint8_t)(msg->checksum >> 8);
+
+ return MAVLINK_NUM_NON_PAYLOAD_BYTES + (uint16_t)msg->len;
+}
+
+union __mavlink_bitfield {
+ uint8_t uint8;
+ int8_t int8;
+ uint16_t uint16;
+ int16_t int16;
+ uint32_t uint32;
+ int32_t int32;
+};
+
+
+MAVLINK_HELPER void mavlink_start_checksum(mavlink_message_t* msg)
+{
+ crc_init(&msg->checksum);
+}
+
+MAVLINK_HELPER void mavlink_update_checksum(mavlink_message_t* msg, uint8_t c)
+{
+ crc_accumulate(c, &msg->checksum);
+}
+
+/**
+ * This is a varient of mavlink_frame_char() but with caller supplied
+ * parsing buffers. It is useful when you want to create a MAVLink
+ * parser in a library that doesn't use any global variables
+ *
+ * @param rxmsg parsing message buffer
+ * @param status parsing starus buffer
+ * @param c The char to parse
+ *
+ * @param returnMsg NULL if no message could be decoded, the message data else
+ * @param returnStats if a message was decoded, this is filled with the channel's stats
+ * @return 0 if no message could be decoded, 1 on good message and CRC, 2 on bad CRC
+ *
+ * A typical use scenario of this function call is:
+ *
+ * @code
+ * #include
+ *
+ * mavlink_message_t msg;
+ * int chan = 0;
+ *
+ *
+ * while(serial.bytesAvailable > 0)
+ * {
+ * uint8_t byte = serial.getNextByte();
+ * if (mavlink_frame_char(chan, byte, &msg) != MAVLINK_FRAMING_INCOMPLETE)
+ * {
+ * printf("Received message with ID %d, sequence: %d from component %d of system %d", msg.msgid, msg.seq, msg.compid, msg.sysid);
+ * }
+ * }
+ *
+ *
+ * @endcode
+ */
+MAVLINK_HELPER uint8_t mavlink_frame_char_buffer(mavlink_message_t* rxmsg,
+ mavlink_status_t* status,
+ uint8_t c,
+ mavlink_message_t* r_message,
+ mavlink_status_t* r_mavlink_status)
+{
+ /*
+ default message crc function. You can override this per-system to
+ put this data in a different memory segment
+ */
+#if MAVLINK_CRC_EXTRA
+#ifndef MAVLINK_MESSAGE_CRC
+ static const uint8_t mavlink_message_crcs[256] = MAVLINK_MESSAGE_CRCS;
+#define MAVLINK_MESSAGE_CRC(msgid) mavlink_message_crcs[msgid]
+#endif
+#endif
+
+ /* Enable this option to check the length of each message.
+ This allows invalid messages to be caught much sooner. Use if the transmission
+ medium is prone to missing (or extra) characters (e.g. a radio that fades in
+ and out). Only use if the channel will only contain messages types listed in
+ the headers.
+ */
+#ifdef MAVLINK_CHECK_MESSAGE_LENGTH
+#ifndef MAVLINK_MESSAGE_LENGTH
+ static const uint8_t mavlink_message_lengths[256] = MAVLINK_MESSAGE_LENGTHS;
+#define MAVLINK_MESSAGE_LENGTH(msgid) mavlink_message_lengths[msgid]
+#endif
+#endif
+
+ int bufferIndex = 0;
+
+ status->msg_received = MAVLINK_FRAMING_INCOMPLETE;
+
+ switch (status->parse_state)
+ {
+ case MAVLINK_PARSE_STATE_UNINIT:
+ case MAVLINK_PARSE_STATE_IDLE:
+ if (c == MAVLINK_STX)
+ {
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_STX;
+ rxmsg->len = 0;
+ rxmsg->magic = c;
+ mavlink_start_checksum(rxmsg);
+ }
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_STX:
+ if (status->msg_received
+/* Support shorter buffers than the
+ default maximum packet size */
+#if (MAVLINK_MAX_PAYLOAD_LEN < 255)
+ || c > MAVLINK_MAX_PAYLOAD_LEN
+#endif
+ )
+ {
+ status->buffer_overrun++;
+ status->parse_error++;
+ status->msg_received = 0;
+ status->parse_state = MAVLINK_PARSE_STATE_IDLE;
+ }
+ else
+ {
+ // NOT counting STX, LENGTH, SEQ, SYSID, COMPID, MSGID, CRC1 and CRC2
+ rxmsg->len = c;
+ status->packet_idx = 0;
+ mavlink_update_checksum(rxmsg, c);
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_LENGTH;
+ }
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_LENGTH:
+ rxmsg->seq = c;
+ mavlink_update_checksum(rxmsg, c);
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_SEQ;
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_SEQ:
+ rxmsg->sysid = c;
+ mavlink_update_checksum(rxmsg, c);
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_SYSID;
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_SYSID:
+ rxmsg->compid = c;
+ mavlink_update_checksum(rxmsg, c);
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_COMPID;
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_COMPID:
+#ifdef MAVLINK_CHECK_MESSAGE_LENGTH
+ if (rxmsg->len != MAVLINK_MESSAGE_LENGTH(c))
+ {
+ status->parse_error++;
+ status->parse_state = MAVLINK_PARSE_STATE_IDLE;
+ break;
+ }
+#endif
+ rxmsg->msgid = c;
+ mavlink_update_checksum(rxmsg, c);
+ if (rxmsg->len == 0)
+ {
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_PAYLOAD;
+ }
+ else
+ {
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_MSGID;
+ }
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_MSGID:
+ _MAV_PAYLOAD_NON_CONST(rxmsg)[status->packet_idx++] = (char)c;
+ mavlink_update_checksum(rxmsg, c);
+ if (status->packet_idx == rxmsg->len)
+ {
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_PAYLOAD;
+ }
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_PAYLOAD:
+#if MAVLINK_CRC_EXTRA
+ mavlink_update_checksum(rxmsg, MAVLINK_MESSAGE_CRC(rxmsg->msgid));
+#endif
+ if (c != (rxmsg->checksum & 0xFF)) {
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_BAD_CRC1;
+ } else {
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_CRC1;
+ }
+ _MAV_PAYLOAD_NON_CONST(rxmsg)[status->packet_idx] = (char)c;
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_CRC1:
+ case MAVLINK_PARSE_STATE_GOT_BAD_CRC1:
+ if (status->parse_state == MAVLINK_PARSE_STATE_GOT_BAD_CRC1 || c != (rxmsg->checksum >> 8)) {
+ // got a bad CRC message
+ status->msg_received = MAVLINK_FRAMING_BAD_CRC;
+ } else {
+ // Successfully got message
+ status->msg_received = MAVLINK_FRAMING_OK;
+ }
+ status->parse_state = MAVLINK_PARSE_STATE_IDLE;
+ _MAV_PAYLOAD_NON_CONST(rxmsg)[status->packet_idx+1] = (char)c;
+ memcpy(r_message, rxmsg, sizeof(mavlink_message_t));
+ break;
+ }
+
+ bufferIndex++;
+ // If a message has been sucessfully decoded, check index
+ if (status->msg_received == MAVLINK_FRAMING_OK)
+ {
+ //while(status->current_seq != rxmsg->seq)
+ //{
+ // status->packet_rx_drop_count++;
+ // status->current_seq++;
+ //}
+ status->current_rx_seq = rxmsg->seq;
+ // Initial condition: If no packet has been received so far, drop count is undefined
+ if (status->packet_rx_success_count == 0) status->packet_rx_drop_count = 0;
+ // Count this packet as received
+ status->packet_rx_success_count++;
+ }
+
+ r_message->len = rxmsg->len; // Provide visibility on how far we are into current msg
+ r_mavlink_status->parse_state = status->parse_state;
+ r_mavlink_status->packet_idx = status->packet_idx;
+ r_mavlink_status->current_rx_seq = status->current_rx_seq+1;
+ r_mavlink_status->packet_rx_success_count = status->packet_rx_success_count;
+ r_mavlink_status->packet_rx_drop_count = status->parse_error;
+ status->parse_error = 0;
+
+ if (status->msg_received == MAVLINK_FRAMING_BAD_CRC) {
+ /*
+ the CRC came out wrong. We now need to overwrite the
+ msg CRC with the one on the wire so that if the
+ caller decides to forward the message anyway that
+ mavlink_msg_to_send_buffer() won't overwrite the
+ checksum
+ */
+ r_message->checksum = _MAV_PAYLOAD(rxmsg)[status->packet_idx] | (_MAV_PAYLOAD(rxmsg)[status->packet_idx+1]<<8);
+ }
+
+ return status->msg_received;
+}
+
+/**
+ * This is a convenience function which handles the complete MAVLink parsing.
+ * the function will parse one byte at a time and return the complete packet once
+ * it could be successfully decoded. This function will return 0, 1 or
+ * 2 (MAVLINK_FRAMING_INCOMPLETE, MAVLINK_FRAMING_OK or MAVLINK_FRAMING_BAD_CRC)
+ *
+ * Messages are parsed into an internal buffer (one for each channel). When a complete
+ * message is received it is copies into *returnMsg and the channel's status is
+ * copied into *returnStats.
+ *
+ * @param chan ID of the current channel. This allows to parse different channels with this function.
+ * a channel is not a physical message channel like a serial port, but a logic partition of
+ * the communication streams in this case. COMM_NB is the limit for the number of channels
+ * on MCU (e.g. ARM7), while COMM_NB_HIGH is the limit for the number of channels in Linux/Windows
+ * @param c The char to parse
+ *
+ * @param returnMsg NULL if no message could be decoded, the message data else
+ * @param returnStats if a message was decoded, this is filled with the channel's stats
+ * @return 0 if no message could be decoded, 1 on good message and CRC, 2 on bad CRC
+ *
+ * A typical use scenario of this function call is:
+ *
+ * @code
+ * #include
+ *
+ * mavlink_message_t msg;
+ * int chan = 0;
+ *
+ *
+ * while(serial.bytesAvailable > 0)
+ * {
+ * uint8_t byte = serial.getNextByte();
+ * if (mavlink_frame_char(chan, byte, &msg) != MAVLINK_FRAMING_INCOMPLETE)
+ * {
+ * printf("Received message with ID %d, sequence: %d from component %d of system %d", msg.msgid, msg.seq, msg.compid, msg.sysid);
+ * }
+ * }
+ *
+ *
+ * @endcode
+ */
+MAVLINK_HELPER uint8_t mavlink_frame_char(uint8_t chan, uint8_t c, mavlink_message_t* r_message, mavlink_status_t* r_mavlink_status)
+{
+ return mavlink_frame_char_buffer(mavlink_get_channel_buffer(chan),
+ mavlink_get_channel_status(chan),
+ c,
+ r_message,
+ r_mavlink_status);
+}
+
+
+/**
+ * This is a convenience function which handles the complete MAVLink parsing.
+ * the function will parse one byte at a time and return the complete packet once
+ * it could be successfully decoded. This function will return 0 or 1.
+ *
+ * Messages are parsed into an internal buffer (one for each channel). When a complete
+ * message is received it is copies into *returnMsg and the channel's status is
+ * copied into *returnStats.
+ *
+ * @param chan ID of the current channel. This allows to parse different channels with this function.
+ * a channel is not a physical message channel like a serial port, but a logic partition of
+ * the communication streams in this case. COMM_NB is the limit for the number of channels
+ * on MCU (e.g. ARM7), while COMM_NB_HIGH is the limit for the number of channels in Linux/Windows
+ * @param c The char to parse
+ *
+ * @param returnMsg NULL if no message could be decoded, the message data else
+ * @param returnStats if a message was decoded, this is filled with the channel's stats
+ * @return 0 if no message could be decoded or bad CRC, 1 on good message and CRC
+ *
+ * A typical use scenario of this function call is:
+ *
+ * @code
+ * #include
+ *
+ * mavlink_message_t msg;
+ * int chan = 0;
+ *
+ *
+ * while(serial.bytesAvailable > 0)
+ * {
+ * uint8_t byte = serial.getNextByte();
+ * if (mavlink_parse_char(chan, byte, &msg))
+ * {
+ * printf("Received message with ID %d, sequence: %d from component %d of system %d", msg.msgid, msg.seq, msg.compid, msg.sysid);
+ * }
+ * }
+ *
+ *
+ * @endcode
+ */
+MAVLINK_HELPER uint8_t mavlink_parse_char(uint8_t chan, uint8_t c, mavlink_message_t* r_message, mavlink_status_t* r_mavlink_status)
+{
+ uint8_t msg_received = mavlink_frame_char(chan, c, r_message, r_mavlink_status);
+ if (msg_received == MAVLINK_FRAMING_BAD_CRC) {
+ // we got a bad CRC. Treat as a parse failure
+ mavlink_message_t* rxmsg = mavlink_get_channel_buffer(chan);
+ mavlink_status_t* status = mavlink_get_channel_status(chan);
+ status->parse_error++;
+ status->msg_received = MAVLINK_FRAMING_INCOMPLETE;
+ status->parse_state = MAVLINK_PARSE_STATE_IDLE;
+ if (c == MAVLINK_STX)
+ {
+ status->parse_state = MAVLINK_PARSE_STATE_GOT_STX;
+ rxmsg->len = 0;
+ mavlink_start_checksum(rxmsg);
+ }
+ return 0;
+ }
+ return msg_received;
+}
+
+/**
+ * @brief Put a bitfield of length 1-32 bit into the buffer
+ *
+ * @param b the value to add, will be encoded in the bitfield
+ * @param bits number of bits to use to encode b, e.g. 1 for boolean, 2, 3, etc.
+ * @param packet_index the position in the packet (the index of the first byte to use)
+ * @param bit_index the position in the byte (the index of the first bit to use)
+ * @param buffer packet buffer to write into
+ * @return new position of the last used byte in the buffer
+ */
+MAVLINK_HELPER uint8_t put_bitfield_n_by_index(int32_t b, uint8_t bits, uint8_t packet_index, uint8_t bit_index, uint8_t* r_bit_index, uint8_t* buffer)
+{
+ uint16_t bits_remain = bits;
+ // Transform number into network order
+ int32_t v;
+ uint8_t i_bit_index, i_byte_index, curr_bits_n;
+#if MAVLINK_NEED_BYTE_SWAP
+ union {
+ int32_t i;
+ uint8_t b[4];
+ } bin, bout;
+ bin.i = b;
+ bout.b[0] = bin.b[3];
+ bout.b[1] = bin.b[2];
+ bout.b[2] = bin.b[1];
+ bout.b[3] = bin.b[0];
+ v = bout.i;
+#else
+ v = b;
+#endif
+
+ // buffer in
+ // 01100000 01000000 00000000 11110001
+ // buffer out
+ // 11110001 00000000 01000000 01100000
+
+ // Existing partly filled byte (four free slots)
+ // 0111xxxx
+
+ // Mask n free bits
+ // 00001111 = 2^0 + 2^1 + 2^2 + 2^3 = 2^n - 1
+ // = ((uint32_t)(1 << n)) - 1; // = 2^n - 1
+
+ // Shift n bits into the right position
+ // out = in >> n;
+
+ // Mask and shift bytes
+ i_bit_index = bit_index;
+ i_byte_index = packet_index;
+ if (bit_index > 0)
+ {
+ // If bits were available at start, they were available
+ // in the byte before the current index
+ i_byte_index--;
+ }
+
+ // While bits have not been packed yet
+ while (bits_remain > 0)
+ {
+ // Bits still have to be packed
+ // there can be more than 8 bits, so
+ // we might have to pack them into more than one byte
+
+ // First pack everything we can into the current 'open' byte
+ //curr_bits_n = bits_remain << 3; // Equals bits_remain mod 8
+ //FIXME
+ if (bits_remain <= (uint8_t)(8 - i_bit_index))
+ {
+ // Enough space
+ curr_bits_n = (uint8_t)bits_remain;
+ }
+ else
+ {
+ curr_bits_n = (8 - i_bit_index);
+ }
+
+ // Pack these n bits into the current byte
+ // Mask out whatever was at that position with ones (xxx11111)
+ buffer[i_byte_index] &= (0xFF >> (8 - curr_bits_n));
+ // Put content to this position, by masking out the non-used part
+ buffer[i_byte_index] |= ((0x00 << curr_bits_n) & v);
+
+ // Increment the bit index
+ i_bit_index += curr_bits_n;
+
+ // Now proceed to the next byte, if necessary
+ bits_remain -= curr_bits_n;
+ if (bits_remain > 0)
+ {
+ // Offer another 8 bits / one byte
+ i_byte_index++;
+ i_bit_index = 0;
+ }
+ }
+
+ *r_bit_index = i_bit_index;
+ // If a partly filled byte is present, mark this as consumed
+ if (i_bit_index != 7) i_byte_index++;
+ return i_byte_index - packet_index;
+}
+
+#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS
+
+// To make MAVLink work on your MCU, define comm_send_ch() if you wish
+// to send 1 byte at a time, or MAVLINK_SEND_UART_BYTES() to send a
+// whole packet at a time
+
+/*
+
+#include "mavlink_types.h"
+
+void comm_send_ch(mavlink_channel_t chan, uint8_t ch)
+{
+ if (chan == MAVLINK_COMM_0)
+ {
+ uart0_transmit(ch);
+ }
+ if (chan == MAVLINK_COMM_1)
+ {
+ uart1_transmit(ch);
+ }
+}
+ */
+
+MAVLINK_HELPER void _mavlink_send_uart(mavlink_channel_t chan, const char *buf, uint16_t len)
+{
+#ifdef MAVLINK_SEND_UART_BYTES
+ /* this is the more efficient approach, if the platform
+ defines it */
+ MAVLINK_SEND_UART_BYTES(chan, (const uint8_t *)buf, len);
+#else
+ /* fallback to one byte at a time */
+ uint16_t i;
+ for (i = 0; i < len; i++) {
+ comm_send_ch(chan, (uint8_t)buf[i]);
+ }
+#endif
+}
+#endif // MAVLINK_USE_CONVENIENCE_FUNCTIONS
+
+#endif /* _MAVLINK_HELPERS_H_ */
diff --git a/mavlink-solo/pymavlink/generator/C/include_v1.0/mavlink_types.h b/mavlink-solo/pymavlink/generator/C/include_v1.0/mavlink_types.h
new file mode 100644
index 0000000..0a98ccc
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/include_v1.0/mavlink_types.h
@@ -0,0 +1,228 @@
+#ifndef MAVLINK_TYPES_H_
+#define MAVLINK_TYPES_H_
+
+// Visual Studio versions before 2010 don't have stdint.h, so we just error out.
+#if (defined _MSC_VER) && (_MSC_VER < 1600)
+#error "The C-MAVLink implementation requires Visual Studio 2010 or greater"
+#endif
+
+#include
+
+// Macro to define packed structures
+#ifdef __GNUC__
+ #define MAVPACKED( __Declaration__ ) __Declaration__ __attribute__((packed))
+#else
+ #define MAVPACKED( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop) )
+#endif
+
+#ifndef MAVLINK_MAX_PAYLOAD_LEN
+// it is possible to override this, but be careful!
+#define MAVLINK_MAX_PAYLOAD_LEN 255 ///< Maximum payload length
+#endif
+
+#define MAVLINK_CORE_HEADER_LEN 5 ///< Length of core header (of the comm. layer): message length (1 byte) + message sequence (1 byte) + message system id (1 byte) + message component id (1 byte) + message type id (1 byte)
+#define MAVLINK_NUM_HEADER_BYTES (MAVLINK_CORE_HEADER_LEN + 1) ///< Length of all header bytes, including core and checksum
+#define MAVLINK_NUM_CHECKSUM_BYTES 2
+#define MAVLINK_NUM_NON_PAYLOAD_BYTES (MAVLINK_NUM_HEADER_BYTES + MAVLINK_NUM_CHECKSUM_BYTES)
+
+#define MAVLINK_MAX_PACKET_LEN (MAVLINK_MAX_PAYLOAD_LEN + MAVLINK_NUM_NON_PAYLOAD_BYTES) ///< Maximum packet length
+
+#define MAVLINK_MSG_ID_EXTENDED_MESSAGE 255
+#define MAVLINK_EXTENDED_HEADER_LEN 14
+
+#if (defined _MSC_VER) || ((defined __APPLE__) && (defined __MACH__)) || (defined __linux__)
+ /* full fledged 32bit++ OS */
+ #define MAVLINK_MAX_EXTENDED_PACKET_LEN 65507
+#else
+ /* small microcontrollers */
+ #define MAVLINK_MAX_EXTENDED_PACKET_LEN 2048
+#endif
+
+#define MAVLINK_MAX_EXTENDED_PAYLOAD_LEN (MAVLINK_MAX_EXTENDED_PACKET_LEN - MAVLINK_EXTENDED_HEADER_LEN - MAVLINK_NUM_NON_PAYLOAD_BYTES)
+
+
+/**
+ * Old-style 4 byte param union
+ *
+ * This struct is the data format to be used when sending
+ * parameters. The parameter should be copied to the native
+ * type (without type conversion)
+ * and re-instanted on the receiving side using the
+ * native type as well.
+ */
+MAVPACKED(
+typedef struct param_union {
+ union {
+ float param_float;
+ int32_t param_int32;
+ uint32_t param_uint32;
+ int16_t param_int16;
+ uint16_t param_uint16;
+ int8_t param_int8;
+ uint8_t param_uint8;
+ uint8_t bytes[4];
+ };
+ uint8_t type;
+}) mavlink_param_union_t;
+
+
+/**
+ * New-style 8 byte param union
+ * mavlink_param_union_double_t will be 8 bytes long, and treated as needing 8 byte alignment for the purposes of MAVLink 1.0 field ordering.
+ * The mavlink_param_union_double_t will be treated as a little-endian structure.
+ *
+ * If is_double is 1 then the type is a double, and the remaining 63 bits are the double, with the lowest bit of the mantissa zero.
+ * The intention is that by replacing the is_double bit with 0 the type can be directly used as a double (as the is_double bit corresponds to the
+ * lowest mantissa bit of a double). If is_double is 0 then mavlink_type gives the type in the union.
+ * The mavlink_types.h header will also need to have shifts/masks to define the bit boundaries in the above,
+ * as bitfield ordering isn’t consistent between platforms. The above is intended to be for gcc on x86,
+ * which should be the same as gcc on little-endian arm. When using shifts/masks the value will be treated as a 64 bit unsigned number,
+ * and the bits pulled out using the shifts/masks.
+*/
+MAVPACKED(
+typedef struct param_union_extended {
+ union {
+ struct {
+ uint8_t is_double:1;
+ uint8_t mavlink_type:7;
+ union {
+ char c;
+ uint8_t uint8;
+ int8_t int8;
+ uint16_t uint16;
+ int16_t int16;
+ uint32_t uint32;
+ int32_t int32;
+ float f;
+ uint8_t align[7];
+ };
+ };
+ uint8_t data[8];
+ };
+}) mavlink_param_union_double_t;
+
+/**
+ * This structure is required to make the mavlink_send_xxx convenience functions
+ * work, as it tells the library what the current system and component ID are.
+ */
+MAVPACKED(
+typedef struct __mavlink_system {
+ uint8_t sysid; ///< Used by the MAVLink message_xx_send() convenience function
+ uint8_t compid; ///< Used by the MAVLink message_xx_send() convenience function
+}) mavlink_system_t;
+
+MAVPACKED(
+typedef struct __mavlink_message {
+ uint16_t checksum; ///< sent at end of packet
+ uint8_t magic; ///< protocol magic marker
+ uint8_t len; ///< Length of payload
+ uint8_t seq; ///< Sequence of packet
+ uint8_t sysid; ///< ID of message sender system/aircraft
+ uint8_t compid; ///< ID of the message sender component
+ uint8_t msgid; ///< ID of message in payload
+ uint64_t payload64[(MAVLINK_MAX_PAYLOAD_LEN+MAVLINK_NUM_CHECKSUM_BYTES+7)/8];
+}) mavlink_message_t;
+
+MAVPACKED(
+typedef struct __mavlink_extended_message {
+ mavlink_message_t base_msg;
+ int32_t extended_payload_len; ///< Length of extended payload if any
+ uint8_t extended_payload[MAVLINK_MAX_EXTENDED_PAYLOAD_LEN];
+}) mavlink_extended_message_t;
+
+typedef enum {
+ MAVLINK_TYPE_CHAR = 0,
+ MAVLINK_TYPE_UINT8_T = 1,
+ MAVLINK_TYPE_INT8_T = 2,
+ MAVLINK_TYPE_UINT16_T = 3,
+ MAVLINK_TYPE_INT16_T = 4,
+ MAVLINK_TYPE_UINT32_T = 5,
+ MAVLINK_TYPE_INT32_T = 6,
+ MAVLINK_TYPE_UINT64_T = 7,
+ MAVLINK_TYPE_INT64_T = 8,
+ MAVLINK_TYPE_FLOAT = 9,
+ MAVLINK_TYPE_DOUBLE = 10
+} mavlink_message_type_t;
+
+#define MAVLINK_MAX_FIELDS 64
+
+typedef struct __mavlink_field_info {
+ const char *name; // name of this field
+ const char *print_format; // printing format hint, or NULL
+ mavlink_message_type_t type; // type of this field
+ unsigned int array_length; // if non-zero, field is an array
+ unsigned int wire_offset; // offset of each field in the payload
+ unsigned int structure_offset; // offset in a C structure
+} mavlink_field_info_t;
+
+// note that in this structure the order of fields is the order
+// in the XML file, not necessary the wire order
+typedef struct __mavlink_message_info {
+ const char *name; // name of the message
+ unsigned num_fields; // how many fields in this message
+ mavlink_field_info_t fields[MAVLINK_MAX_FIELDS]; // field information
+} mavlink_message_info_t;
+
+#define _MAV_PAYLOAD(msg) ((const char *)(&((msg)->payload64[0])))
+#define _MAV_PAYLOAD_NON_CONST(msg) ((char *)(&((msg)->payload64[0])))
+
+// checksum is immediately after the payload bytes
+#define mavlink_ck_a(msg) *((msg)->len + (uint8_t *)_MAV_PAYLOAD_NON_CONST(msg))
+#define mavlink_ck_b(msg) *(((msg)->len+(uint16_t)1) + (uint8_t *)_MAV_PAYLOAD_NON_CONST(msg))
+
+typedef enum {
+ MAVLINK_COMM_0,
+ MAVLINK_COMM_1,
+ MAVLINK_COMM_2,
+ MAVLINK_COMM_3
+} mavlink_channel_t;
+
+/*
+ * applications can set MAVLINK_COMM_NUM_BUFFERS to the maximum number
+ * of buffers they will use. If more are used, then the result will be
+ * a stack overrun
+ */
+#ifndef MAVLINK_COMM_NUM_BUFFERS
+#if (defined linux) | (defined __linux) | (defined __MACH__) | (defined _WIN32)
+# define MAVLINK_COMM_NUM_BUFFERS 16
+#else
+# define MAVLINK_COMM_NUM_BUFFERS 4
+#endif
+#endif
+
+typedef enum {
+ MAVLINK_PARSE_STATE_UNINIT=0,
+ MAVLINK_PARSE_STATE_IDLE,
+ MAVLINK_PARSE_STATE_GOT_STX,
+ MAVLINK_PARSE_STATE_GOT_SEQ,
+ MAVLINK_PARSE_STATE_GOT_LENGTH,
+ MAVLINK_PARSE_STATE_GOT_SYSID,
+ MAVLINK_PARSE_STATE_GOT_COMPID,
+ MAVLINK_PARSE_STATE_GOT_MSGID,
+ MAVLINK_PARSE_STATE_GOT_PAYLOAD,
+ MAVLINK_PARSE_STATE_GOT_CRC1,
+ MAVLINK_PARSE_STATE_GOT_BAD_CRC1
+} mavlink_parse_state_t; ///< The state machine for the comm parser
+
+typedef enum {
+ MAVLINK_FRAMING_INCOMPLETE=0,
+ MAVLINK_FRAMING_OK=1,
+ MAVLINK_FRAMING_BAD_CRC=2
+} mavlink_framing_t;
+
+typedef struct __mavlink_status {
+ uint8_t msg_received; ///< Number of received messages
+ uint8_t buffer_overrun; ///< Number of buffer overruns
+ uint8_t parse_error; ///< Number of parse errors
+ mavlink_parse_state_t parse_state; ///< Parsing state machine
+ uint8_t packet_idx; ///< Index in current packet
+ uint8_t current_rx_seq; ///< Sequence number of last packet received
+ uint8_t current_tx_seq; ///< Sequence number of last packet sent
+ uint16_t packet_rx_success_count; ///< Received packets
+ uint16_t packet_rx_drop_count; ///< Number of packet drops
+} mavlink_status_t;
+
+#define MAVLINK_BIG_ENDIAN 0
+#define MAVLINK_LITTLE_ENDIAN 1
+
+#endif /* MAVLINK_TYPES_H_ */
diff --git a/mavlink-solo/pymavlink/generator/C/include_v1.0/protocol.h b/mavlink-solo/pymavlink/generator/C/include_v1.0/protocol.h
new file mode 100644
index 0000000..bf20708
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/include_v1.0/protocol.h
@@ -0,0 +1,339 @@
+#ifndef _MAVLINK_PROTOCOL_H_
+#define _MAVLINK_PROTOCOL_H_
+
+#include "string.h"
+#include "mavlink_types.h"
+
+/*
+ If you want MAVLink on a system that is native big-endian,
+ you need to define NATIVE_BIG_ENDIAN
+*/
+#ifdef NATIVE_BIG_ENDIAN
+# define MAVLINK_NEED_BYTE_SWAP (MAVLINK_ENDIAN == MAVLINK_LITTLE_ENDIAN)
+#else
+# define MAVLINK_NEED_BYTE_SWAP (MAVLINK_ENDIAN != MAVLINK_LITTLE_ENDIAN)
+#endif
+
+#ifndef MAVLINK_STACK_BUFFER
+#define MAVLINK_STACK_BUFFER 0
+#endif
+
+#ifndef MAVLINK_AVOID_GCC_STACK_BUG
+# define MAVLINK_AVOID_GCC_STACK_BUG defined(__GNUC__)
+#endif
+
+#ifndef MAVLINK_ASSERT
+#define MAVLINK_ASSERT(x)
+#endif
+
+#ifndef MAVLINK_START_UART_SEND
+#define MAVLINK_START_UART_SEND(chan, length)
+#endif
+
+#ifndef MAVLINK_END_UART_SEND
+#define MAVLINK_END_UART_SEND(chan, length)
+#endif
+
+/* option to provide alternative implementation of mavlink_helpers.h */
+#ifdef MAVLINK_SEPARATE_HELPERS
+
+ #define MAVLINK_HELPER
+
+ /* decls in sync with those in mavlink_helpers.h */
+ #ifndef MAVLINK_GET_CHANNEL_STATUS
+ MAVLINK_HELPER mavlink_status_t* mavlink_get_channel_status(uint8_t chan);
+ #endif
+ MAVLINK_HELPER void mavlink_reset_channel_status(uint8_t chan);
+ #if MAVLINK_CRC_EXTRA
+ MAVLINK_HELPER uint16_t mavlink_finalize_message_chan(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
+ uint8_t chan, uint8_t length, uint8_t crc_extra);
+ MAVLINK_HELPER uint16_t mavlink_finalize_message(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
+ uint8_t length, uint8_t crc_extra);
+ #ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS
+ MAVLINK_HELPER void _mav_finalize_message_chan_send(mavlink_channel_t chan, uint8_t msgid, const char *packet,
+ uint8_t length, uint8_t crc_extra);
+ #endif
+ #else
+ MAVLINK_HELPER uint16_t mavlink_finalize_message_chan(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
+ uint8_t chan, uint8_t length);
+ MAVLINK_HELPER uint16_t mavlink_finalize_message(mavlink_message_t* msg, uint8_t system_id, uint8_t component_id,
+ uint8_t length);
+ #ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS
+ MAVLINK_HELPER void _mav_finalize_message_chan_send(mavlink_channel_t chan, uint8_t msgid, const char *packet, uint8_t length);
+ #endif
+ #endif // MAVLINK_CRC_EXTRA
+ MAVLINK_HELPER uint16_t mavlink_msg_to_send_buffer(uint8_t *buffer, const mavlink_message_t *msg);
+ MAVLINK_HELPER void mavlink_start_checksum(mavlink_message_t* msg);
+ MAVLINK_HELPER void mavlink_update_checksum(mavlink_message_t* msg, uint8_t c);
+ MAVLINK_HELPER uint8_t mavlink_frame_char_buffer(mavlink_message_t* rxmsg,
+ mavlink_status_t* status,
+ uint8_t c,
+ mavlink_message_t* r_message,
+ mavlink_status_t* r_mavlink_status);
+ MAVLINK_HELPER uint8_t mavlink_frame_char(uint8_t chan, uint8_t c, mavlink_message_t* r_message, mavlink_status_t* r_mavlink_status);
+ MAVLINK_HELPER uint8_t mavlink_parse_char(uint8_t chan, uint8_t c, mavlink_message_t* r_message, mavlink_status_t* r_mavlink_status);
+ MAVLINK_HELPER uint8_t put_bitfield_n_by_index(int32_t b, uint8_t bits, uint8_t packet_index, uint8_t bit_index,
+ uint8_t* r_bit_index, uint8_t* buffer);
+ #ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS
+ MAVLINK_HELPER void _mavlink_send_uart(mavlink_channel_t chan, const char *buf, uint16_t len);
+ MAVLINK_HELPER void _mavlink_resend_uart(mavlink_channel_t chan, const mavlink_message_t *msg);
+ #endif
+
+#else
+
+ #define MAVLINK_HELPER static inline
+ #include "mavlink_helpers.h"
+
+#endif // MAVLINK_SEPARATE_HELPERS
+
+/**
+ * @brief Get the required buffer size for this message
+ */
+static inline uint16_t mavlink_msg_get_send_buffer_length(const mavlink_message_t* msg)
+{
+ return msg->len + MAVLINK_NUM_NON_PAYLOAD_BYTES;
+}
+
+#if MAVLINK_NEED_BYTE_SWAP
+static inline void byte_swap_2(char *dst, const char *src)
+{
+ dst[0] = src[1];
+ dst[1] = src[0];
+}
+static inline void byte_swap_4(char *dst, const char *src)
+{
+ dst[0] = src[3];
+ dst[1] = src[2];
+ dst[2] = src[1];
+ dst[3] = src[0];
+}
+static inline void byte_swap_8(char *dst, const char *src)
+{
+ dst[0] = src[7];
+ dst[1] = src[6];
+ dst[2] = src[5];
+ dst[3] = src[4];
+ dst[4] = src[3];
+ dst[5] = src[2];
+ dst[6] = src[1];
+ dst[7] = src[0];
+}
+#elif !MAVLINK_ALIGNED_FIELDS
+static inline void byte_copy_2(char *dst, const char *src)
+{
+ dst[0] = src[0];
+ dst[1] = src[1];
+}
+static inline void byte_copy_4(char *dst, const char *src)
+{
+ dst[0] = src[0];
+ dst[1] = src[1];
+ dst[2] = src[2];
+ dst[3] = src[3];
+}
+static inline void byte_copy_8(char *dst, const char *src)
+{
+ memcpy(dst, src, 8);
+}
+#endif
+
+#define _mav_put_uint8_t(buf, wire_offset, b) buf[wire_offset] = (uint8_t)b
+#define _mav_put_int8_t(buf, wire_offset, b) buf[wire_offset] = (int8_t)b
+#define _mav_put_char(buf, wire_offset, b) buf[wire_offset] = b
+
+#if MAVLINK_NEED_BYTE_SWAP
+#define _mav_put_uint16_t(buf, wire_offset, b) byte_swap_2(&buf[wire_offset], (const char *)&b)
+#define _mav_put_int16_t(buf, wire_offset, b) byte_swap_2(&buf[wire_offset], (const char *)&b)
+#define _mav_put_uint32_t(buf, wire_offset, b) byte_swap_4(&buf[wire_offset], (const char *)&b)
+#define _mav_put_int32_t(buf, wire_offset, b) byte_swap_4(&buf[wire_offset], (const char *)&b)
+#define _mav_put_uint64_t(buf, wire_offset, b) byte_swap_8(&buf[wire_offset], (const char *)&b)
+#define _mav_put_int64_t(buf, wire_offset, b) byte_swap_8(&buf[wire_offset], (const char *)&b)
+#define _mav_put_float(buf, wire_offset, b) byte_swap_4(&buf[wire_offset], (const char *)&b)
+#define _mav_put_double(buf, wire_offset, b) byte_swap_8(&buf[wire_offset], (const char *)&b)
+#elif !MAVLINK_ALIGNED_FIELDS
+#define _mav_put_uint16_t(buf, wire_offset, b) byte_copy_2(&buf[wire_offset], (const char *)&b)
+#define _mav_put_int16_t(buf, wire_offset, b) byte_copy_2(&buf[wire_offset], (const char *)&b)
+#define _mav_put_uint32_t(buf, wire_offset, b) byte_copy_4(&buf[wire_offset], (const char *)&b)
+#define _mav_put_int32_t(buf, wire_offset, b) byte_copy_4(&buf[wire_offset], (const char *)&b)
+#define _mav_put_uint64_t(buf, wire_offset, b) byte_copy_8(&buf[wire_offset], (const char *)&b)
+#define _mav_put_int64_t(buf, wire_offset, b) byte_copy_8(&buf[wire_offset], (const char *)&b)
+#define _mav_put_float(buf, wire_offset, b) byte_copy_4(&buf[wire_offset], (const char *)&b)
+#define _mav_put_double(buf, wire_offset, b) byte_copy_8(&buf[wire_offset], (const char *)&b)
+#else
+#define _mav_put_uint16_t(buf, wire_offset, b) *(uint16_t *)&buf[wire_offset] = b
+#define _mav_put_int16_t(buf, wire_offset, b) *(int16_t *)&buf[wire_offset] = b
+#define _mav_put_uint32_t(buf, wire_offset, b) *(uint32_t *)&buf[wire_offset] = b
+#define _mav_put_int32_t(buf, wire_offset, b) *(int32_t *)&buf[wire_offset] = b
+#define _mav_put_uint64_t(buf, wire_offset, b) *(uint64_t *)&buf[wire_offset] = b
+#define _mav_put_int64_t(buf, wire_offset, b) *(int64_t *)&buf[wire_offset] = b
+#define _mav_put_float(buf, wire_offset, b) *(float *)&buf[wire_offset] = b
+#define _mav_put_double(buf, wire_offset, b) *(double *)&buf[wire_offset] = b
+#endif
+
+/*
+ like memcpy(), but if src is NULL, do a memset to zero
+*/
+static inline void mav_array_memcpy(void *dest, const void *src, size_t n)
+{
+ if (src == NULL) {
+ memset(dest, 0, n);
+ } else {
+ memcpy(dest, src, n);
+ }
+}
+
+/*
+ * Place a char array into a buffer
+ */
+static inline void _mav_put_char_array(char *buf, uint8_t wire_offset, const char *b, uint8_t array_length)
+{
+ mav_array_memcpy(&buf[wire_offset], b, array_length);
+
+}
+
+/*
+ * Place a uint8_t array into a buffer
+ */
+static inline void _mav_put_uint8_t_array(char *buf, uint8_t wire_offset, const uint8_t *b, uint8_t array_length)
+{
+ mav_array_memcpy(&buf[wire_offset], b, array_length);
+
+}
+
+/*
+ * Place a int8_t array into a buffer
+ */
+static inline void _mav_put_int8_t_array(char *buf, uint8_t wire_offset, const int8_t *b, uint8_t array_length)
+{
+ mav_array_memcpy(&buf[wire_offset], b, array_length);
+
+}
+
+#if MAVLINK_NEED_BYTE_SWAP
+#define _MAV_PUT_ARRAY(TYPE, V) \
+static inline void _mav_put_ ## TYPE ##_array(char *buf, uint8_t wire_offset, const TYPE *b, uint8_t array_length) \
+{ \
+ if (b == NULL) { \
+ memset(&buf[wire_offset], 0, array_length*sizeof(TYPE)); \
+ } else { \
+ uint16_t i; \
+ for (i=0; imsgid = MAVLINK_MSG_ID_TEST_TYPES;
+#if MAVLINK_CRC_EXTRA
+ return mavlink_finalize_message(msg, system_id, component_id, MAVLINK_MSG_ID_TEST_TYPES_LEN, MAVLINK_MSG_ID_TEST_TYPES_CRC);
+#else
+ return mavlink_finalize_message(msg, system_id, component_id, MAVLINK_MSG_ID_TEST_TYPES_LEN);
+#endif
+}
+
+/**
+ * @brief Pack a test_types message on a channel
+ * @param system_id ID of this system
+ * @param component_id ID of this component (e.g. 200 for IMU)
+ * @param chan The MAVLink channel this message was sent over
+ * @param msg The MAVLink message to compress the data into
+ * @param c char
+ * @param s string
+ * @param u8 uint8_t
+ * @param u16 uint16_t
+ * @param u32 uint32_t
+ * @param u64 uint64_t
+ * @param s8 int8_t
+ * @param s16 int16_t
+ * @param s32 int32_t
+ * @param s64 int64_t
+ * @param f float
+ * @param d double
+ * @param u8_array uint8_t_array
+ * @param u16_array uint16_t_array
+ * @param u32_array uint32_t_array
+ * @param u64_array uint64_t_array
+ * @param s8_array int8_t_array
+ * @param s16_array int16_t_array
+ * @param s32_array int32_t_array
+ * @param s64_array int64_t_array
+ * @param f_array float_array
+ * @param d_array double_array
+ * @return length of the message in bytes (excluding serial stream start sign)
+ */
+static inline uint16_t mavlink_msg_test_types_pack_chan(uint8_t system_id, uint8_t component_id, uint8_t chan,
+ mavlink_message_t* msg,
+ char c,const char *s,uint8_t u8,uint16_t u16,uint32_t u32,uint64_t u64,int8_t s8,int16_t s16,int32_t s32,int64_t s64,float f,double d,const uint8_t *u8_array,const uint16_t *u16_array,const uint32_t *u32_array,const uint64_t *u64_array,const int8_t *s8_array,const int16_t *s16_array,const int32_t *s32_array,const int64_t *s64_array,const float *f_array,const double *d_array)
+{
+#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS
+ char buf[MAVLINK_MSG_ID_TEST_TYPES_LEN];
+ _mav_put_uint64_t(buf, 0, u64);
+ _mav_put_int64_t(buf, 8, s64);
+ _mav_put_double(buf, 16, d);
+ _mav_put_uint32_t(buf, 96, u32);
+ _mav_put_int32_t(buf, 100, s32);
+ _mav_put_float(buf, 104, f);
+ _mav_put_uint16_t(buf, 144, u16);
+ _mav_put_int16_t(buf, 146, s16);
+ _mav_put_char(buf, 160, c);
+ _mav_put_uint8_t(buf, 171, u8);
+ _mav_put_int8_t(buf, 172, s8);
+ _mav_put_uint64_t_array(buf, 24, u64_array, 3);
+ _mav_put_int64_t_array(buf, 48, s64_array, 3);
+ _mav_put_double_array(buf, 72, d_array, 3);
+ _mav_put_uint32_t_array(buf, 108, u32_array, 3);
+ _mav_put_int32_t_array(buf, 120, s32_array, 3);
+ _mav_put_float_array(buf, 132, f_array, 3);
+ _mav_put_uint16_t_array(buf, 148, u16_array, 3);
+ _mav_put_int16_t_array(buf, 154, s16_array, 3);
+ _mav_put_char_array(buf, 161, s, 10);
+ _mav_put_uint8_t_array(buf, 173, u8_array, 3);
+ _mav_put_int8_t_array(buf, 176, s8_array, 3);
+ memcpy(_MAV_PAYLOAD_NON_CONST(msg), buf, MAVLINK_MSG_ID_TEST_TYPES_LEN);
+#else
+ mavlink_test_types_t packet;
+ packet.u64 = u64;
+ packet.s64 = s64;
+ packet.d = d;
+ packet.u32 = u32;
+ packet.s32 = s32;
+ packet.f = f;
+ packet.u16 = u16;
+ packet.s16 = s16;
+ packet.c = c;
+ packet.u8 = u8;
+ packet.s8 = s8;
+ mav_array_memcpy(packet.u64_array, u64_array, sizeof(uint64_t)*3);
+ mav_array_memcpy(packet.s64_array, s64_array, sizeof(int64_t)*3);
+ mav_array_memcpy(packet.d_array, d_array, sizeof(double)*3);
+ mav_array_memcpy(packet.u32_array, u32_array, sizeof(uint32_t)*3);
+ mav_array_memcpy(packet.s32_array, s32_array, sizeof(int32_t)*3);
+ mav_array_memcpy(packet.f_array, f_array, sizeof(float)*3);
+ mav_array_memcpy(packet.u16_array, u16_array, sizeof(uint16_t)*3);
+ mav_array_memcpy(packet.s16_array, s16_array, sizeof(int16_t)*3);
+ mav_array_memcpy(packet.s, s, sizeof(char)*10);
+ mav_array_memcpy(packet.u8_array, u8_array, sizeof(uint8_t)*3);
+ mav_array_memcpy(packet.s8_array, s8_array, sizeof(int8_t)*3);
+ memcpy(_MAV_PAYLOAD_NON_CONST(msg), &packet, MAVLINK_MSG_ID_TEST_TYPES_LEN);
+#endif
+
+ msg->msgid = MAVLINK_MSG_ID_TEST_TYPES;
+#if MAVLINK_CRC_EXTRA
+ return mavlink_finalize_message_chan(msg, system_id, component_id, chan, MAVLINK_MSG_ID_TEST_TYPES_LEN, MAVLINK_MSG_ID_TEST_TYPES_CRC);
+#else
+ return mavlink_finalize_message_chan(msg, system_id, component_id, chan, MAVLINK_MSG_ID_TEST_TYPES_LEN);
+#endif
+}
+
+/**
+ * @brief Encode a test_types struct into a message
+ *
+ * @param system_id ID of this system
+ * @param component_id ID of this component (e.g. 200 for IMU)
+ * @param msg The MAVLink message to compress the data into
+ * @param test_types C-struct to read the message contents from
+ */
+static inline uint16_t mavlink_msg_test_types_encode(uint8_t system_id, uint8_t component_id, mavlink_message_t* msg, const mavlink_test_types_t* test_types)
+{
+ return mavlink_msg_test_types_pack(system_id, component_id, msg, test_types->c, test_types->s, test_types->u8, test_types->u16, test_types->u32, test_types->u64, test_types->s8, test_types->s16, test_types->s32, test_types->s64, test_types->f, test_types->d, test_types->u8_array, test_types->u16_array, test_types->u32_array, test_types->u64_array, test_types->s8_array, test_types->s16_array, test_types->s32_array, test_types->s64_array, test_types->f_array, test_types->d_array);
+}
+
+/**
+ * @brief Send a test_types message
+ * @param chan MAVLink channel to send the message
+ *
+ * @param c char
+ * @param s string
+ * @param u8 uint8_t
+ * @param u16 uint16_t
+ * @param u32 uint32_t
+ * @param u64 uint64_t
+ * @param s8 int8_t
+ * @param s16 int16_t
+ * @param s32 int32_t
+ * @param s64 int64_t
+ * @param f float
+ * @param d double
+ * @param u8_array uint8_t_array
+ * @param u16_array uint16_t_array
+ * @param u32_array uint32_t_array
+ * @param u64_array uint64_t_array
+ * @param s8_array int8_t_array
+ * @param s16_array int16_t_array
+ * @param s32_array int32_t_array
+ * @param s64_array int64_t_array
+ * @param f_array float_array
+ * @param d_array double_array
+ */
+#ifdef MAVLINK_USE_CONVENIENCE_FUNCTIONS
+
+static inline void mavlink_msg_test_types_send(mavlink_channel_t chan, char c, const char *s, uint8_t u8, uint16_t u16, uint32_t u32, uint64_t u64, int8_t s8, int16_t s16, int32_t s32, int64_t s64, float f, double d, const uint8_t *u8_array, const uint16_t *u16_array, const uint32_t *u32_array, const uint64_t *u64_array, const int8_t *s8_array, const int16_t *s16_array, const int32_t *s32_array, const int64_t *s64_array, const float *f_array, const double *d_array)
+{
+#if MAVLINK_NEED_BYTE_SWAP || !MAVLINK_ALIGNED_FIELDS
+ char buf[MAVLINK_MSG_ID_TEST_TYPES_LEN];
+ _mav_put_uint64_t(buf, 0, u64);
+ _mav_put_int64_t(buf, 8, s64);
+ _mav_put_double(buf, 16, d);
+ _mav_put_uint32_t(buf, 96, u32);
+ _mav_put_int32_t(buf, 100, s32);
+ _mav_put_float(buf, 104, f);
+ _mav_put_uint16_t(buf, 144, u16);
+ _mav_put_int16_t(buf, 146, s16);
+ _mav_put_char(buf, 160, c);
+ _mav_put_uint8_t(buf, 171, u8);
+ _mav_put_int8_t(buf, 172, s8);
+ _mav_put_uint64_t_array(buf, 24, u64_array, 3);
+ _mav_put_int64_t_array(buf, 48, s64_array, 3);
+ _mav_put_double_array(buf, 72, d_array, 3);
+ _mav_put_uint32_t_array(buf, 108, u32_array, 3);
+ _mav_put_int32_t_array(buf, 120, s32_array, 3);
+ _mav_put_float_array(buf, 132, f_array, 3);
+ _mav_put_uint16_t_array(buf, 148, u16_array, 3);
+ _mav_put_int16_t_array(buf, 154, s16_array, 3);
+ _mav_put_char_array(buf, 161, s, 10);
+ _mav_put_uint8_t_array(buf, 173, u8_array, 3);
+ _mav_put_int8_t_array(buf, 176, s8_array, 3);
+#if MAVLINK_CRC_EXTRA
+ _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_TEST_TYPES, buf, MAVLINK_MSG_ID_TEST_TYPES_LEN, MAVLINK_MSG_ID_TEST_TYPES_CRC);
+#else
+ _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_TEST_TYPES, buf, MAVLINK_MSG_ID_TEST_TYPES_LEN);
+#endif
+#else
+ mavlink_test_types_t packet;
+ packet.u64 = u64;
+ packet.s64 = s64;
+ packet.d = d;
+ packet.u32 = u32;
+ packet.s32 = s32;
+ packet.f = f;
+ packet.u16 = u16;
+ packet.s16 = s16;
+ packet.c = c;
+ packet.u8 = u8;
+ packet.s8 = s8;
+ mav_array_memcpy(packet.u64_array, u64_array, sizeof(uint64_t)*3);
+ mav_array_memcpy(packet.s64_array, s64_array, sizeof(int64_t)*3);
+ mav_array_memcpy(packet.d_array, d_array, sizeof(double)*3);
+ mav_array_memcpy(packet.u32_array, u32_array, sizeof(uint32_t)*3);
+ mav_array_memcpy(packet.s32_array, s32_array, sizeof(int32_t)*3);
+ mav_array_memcpy(packet.f_array, f_array, sizeof(float)*3);
+ mav_array_memcpy(packet.u16_array, u16_array, sizeof(uint16_t)*3);
+ mav_array_memcpy(packet.s16_array, s16_array, sizeof(int16_t)*3);
+ mav_array_memcpy(packet.s, s, sizeof(char)*10);
+ mav_array_memcpy(packet.u8_array, u8_array, sizeof(uint8_t)*3);
+ mav_array_memcpy(packet.s8_array, s8_array, sizeof(int8_t)*3);
+#if MAVLINK_CRC_EXTRA
+ _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_TEST_TYPES, (const char *)&packet, MAVLINK_MSG_ID_TEST_TYPES_LEN, MAVLINK_MSG_ID_TEST_TYPES_CRC);
+#else
+ _mav_finalize_message_chan_send(chan, MAVLINK_MSG_ID_TEST_TYPES, (const char *)&packet, MAVLINK_MSG_ID_TEST_TYPES_LEN);
+#endif
+#endif
+}
+
+#endif
+
+// MESSAGE TEST_TYPES UNPACKING
+
+
+/**
+ * @brief Get field c from test_types message
+ *
+ * @return char
+ */
+static inline char mavlink_msg_test_types_get_c(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_char(msg, 160);
+}
+
+/**
+ * @brief Get field s from test_types message
+ *
+ * @return string
+ */
+static inline uint16_t mavlink_msg_test_types_get_s(const mavlink_message_t* msg, char *s)
+{
+ return _MAV_RETURN_char_array(msg, s, 10, 161);
+}
+
+/**
+ * @brief Get field u8 from test_types message
+ *
+ * @return uint8_t
+ */
+static inline uint8_t mavlink_msg_test_types_get_u8(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_uint8_t(msg, 171);
+}
+
+/**
+ * @brief Get field u16 from test_types message
+ *
+ * @return uint16_t
+ */
+static inline uint16_t mavlink_msg_test_types_get_u16(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_uint16_t(msg, 144);
+}
+
+/**
+ * @brief Get field u32 from test_types message
+ *
+ * @return uint32_t
+ */
+static inline uint32_t mavlink_msg_test_types_get_u32(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_uint32_t(msg, 96);
+}
+
+/**
+ * @brief Get field u64 from test_types message
+ *
+ * @return uint64_t
+ */
+static inline uint64_t mavlink_msg_test_types_get_u64(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_uint64_t(msg, 0);
+}
+
+/**
+ * @brief Get field s8 from test_types message
+ *
+ * @return int8_t
+ */
+static inline int8_t mavlink_msg_test_types_get_s8(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_int8_t(msg, 172);
+}
+
+/**
+ * @brief Get field s16 from test_types message
+ *
+ * @return int16_t
+ */
+static inline int16_t mavlink_msg_test_types_get_s16(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_int16_t(msg, 146);
+}
+
+/**
+ * @brief Get field s32 from test_types message
+ *
+ * @return int32_t
+ */
+static inline int32_t mavlink_msg_test_types_get_s32(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_int32_t(msg, 100);
+}
+
+/**
+ * @brief Get field s64 from test_types message
+ *
+ * @return int64_t
+ */
+static inline int64_t mavlink_msg_test_types_get_s64(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_int64_t(msg, 8);
+}
+
+/**
+ * @brief Get field f from test_types message
+ *
+ * @return float
+ */
+static inline float mavlink_msg_test_types_get_f(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_float(msg, 104);
+}
+
+/**
+ * @brief Get field d from test_types message
+ *
+ * @return double
+ */
+static inline double mavlink_msg_test_types_get_d(const mavlink_message_t* msg)
+{
+ return _MAV_RETURN_double(msg, 16);
+}
+
+/**
+ * @brief Get field u8_array from test_types message
+ *
+ * @return uint8_t_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_u8_array(const mavlink_message_t* msg, uint8_t *u8_array)
+{
+ return _MAV_RETURN_uint8_t_array(msg, u8_array, 3, 173);
+}
+
+/**
+ * @brief Get field u16_array from test_types message
+ *
+ * @return uint16_t_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_u16_array(const mavlink_message_t* msg, uint16_t *u16_array)
+{
+ return _MAV_RETURN_uint16_t_array(msg, u16_array, 3, 148);
+}
+
+/**
+ * @brief Get field u32_array from test_types message
+ *
+ * @return uint32_t_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_u32_array(const mavlink_message_t* msg, uint32_t *u32_array)
+{
+ return _MAV_RETURN_uint32_t_array(msg, u32_array, 3, 108);
+}
+
+/**
+ * @brief Get field u64_array from test_types message
+ *
+ * @return uint64_t_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_u64_array(const mavlink_message_t* msg, uint64_t *u64_array)
+{
+ return _MAV_RETURN_uint64_t_array(msg, u64_array, 3, 24);
+}
+
+/**
+ * @brief Get field s8_array from test_types message
+ *
+ * @return int8_t_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_s8_array(const mavlink_message_t* msg, int8_t *s8_array)
+{
+ return _MAV_RETURN_int8_t_array(msg, s8_array, 3, 176);
+}
+
+/**
+ * @brief Get field s16_array from test_types message
+ *
+ * @return int16_t_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_s16_array(const mavlink_message_t* msg, int16_t *s16_array)
+{
+ return _MAV_RETURN_int16_t_array(msg, s16_array, 3, 154);
+}
+
+/**
+ * @brief Get field s32_array from test_types message
+ *
+ * @return int32_t_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_s32_array(const mavlink_message_t* msg, int32_t *s32_array)
+{
+ return _MAV_RETURN_int32_t_array(msg, s32_array, 3, 120);
+}
+
+/**
+ * @brief Get field s64_array from test_types message
+ *
+ * @return int64_t_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_s64_array(const mavlink_message_t* msg, int64_t *s64_array)
+{
+ return _MAV_RETURN_int64_t_array(msg, s64_array, 3, 48);
+}
+
+/**
+ * @brief Get field f_array from test_types message
+ *
+ * @return float_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_f_array(const mavlink_message_t* msg, float *f_array)
+{
+ return _MAV_RETURN_float_array(msg, f_array, 3, 132);
+}
+
+/**
+ * @brief Get field d_array from test_types message
+ *
+ * @return double_array
+ */
+static inline uint16_t mavlink_msg_test_types_get_d_array(const mavlink_message_t* msg, double *d_array)
+{
+ return _MAV_RETURN_double_array(msg, d_array, 3, 72);
+}
+
+/**
+ * @brief Decode a test_types message into a struct
+ *
+ * @param msg The message to decode
+ * @param test_types C-struct to decode the message contents into
+ */
+static inline void mavlink_msg_test_types_decode(const mavlink_message_t* msg, mavlink_test_types_t* test_types)
+{
+#if MAVLINK_NEED_BYTE_SWAP
+ test_types->u64 = mavlink_msg_test_types_get_u64(msg);
+ test_types->s64 = mavlink_msg_test_types_get_s64(msg);
+ test_types->d = mavlink_msg_test_types_get_d(msg);
+ mavlink_msg_test_types_get_u64_array(msg, test_types->u64_array);
+ mavlink_msg_test_types_get_s64_array(msg, test_types->s64_array);
+ mavlink_msg_test_types_get_d_array(msg, test_types->d_array);
+ test_types->u32 = mavlink_msg_test_types_get_u32(msg);
+ test_types->s32 = mavlink_msg_test_types_get_s32(msg);
+ test_types->f = mavlink_msg_test_types_get_f(msg);
+ mavlink_msg_test_types_get_u32_array(msg, test_types->u32_array);
+ mavlink_msg_test_types_get_s32_array(msg, test_types->s32_array);
+ mavlink_msg_test_types_get_f_array(msg, test_types->f_array);
+ test_types->u16 = mavlink_msg_test_types_get_u16(msg);
+ test_types->s16 = mavlink_msg_test_types_get_s16(msg);
+ mavlink_msg_test_types_get_u16_array(msg, test_types->u16_array);
+ mavlink_msg_test_types_get_s16_array(msg, test_types->s16_array);
+ test_types->c = mavlink_msg_test_types_get_c(msg);
+ mavlink_msg_test_types_get_s(msg, test_types->s);
+ test_types->u8 = mavlink_msg_test_types_get_u8(msg);
+ test_types->s8 = mavlink_msg_test_types_get_s8(msg);
+ mavlink_msg_test_types_get_u8_array(msg, test_types->u8_array);
+ mavlink_msg_test_types_get_s8_array(msg, test_types->s8_array);
+#else
+ memcpy(test_types, _MAV_PAYLOAD(msg), MAVLINK_MSG_ID_TEST_TYPES_LEN);
+#endif
+}
diff --git a/mavlink-solo/pymavlink/generator/C/include_v1.0/test/test.h b/mavlink-solo/pymavlink/generator/C/include_v1.0/test/test.h
new file mode 100644
index 0000000..06192f0
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/include_v1.0/test/test.h
@@ -0,0 +1,53 @@
+/** @file
+ * @brief MAVLink comm protocol generated from test.xml
+ * @see http://qgroundcontrol.org/mavlink/
+ */
+#ifndef TEST_H
+#define TEST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// MESSAGE LENGTHS AND CRCS
+
+#ifndef MAVLINK_MESSAGE_LENGTHS
+#define MAVLINK_MESSAGE_LENGTHS {179, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#endif
+
+#ifndef MAVLINK_MESSAGE_CRCS
+#define MAVLINK_MESSAGE_CRCS {103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#endif
+
+#ifndef MAVLINK_MESSAGE_INFO
+#define MAVLINK_MESSAGE_INFO {MAVLINK_MESSAGE_INFO_TEST_TYPES, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}, {"EMPTY",0,{{"","",MAVLINK_TYPE_CHAR,0,0,0}}}}
+#endif
+
+#include "../protocol.h"
+
+#define MAVLINK_ENABLED_TEST
+
+// ENUM DEFINITIONS
+
+
+
+
+
+// MAVLINK VERSION
+
+#ifndef MAVLINK_VERSION
+#define MAVLINK_VERSION 3
+#endif
+
+#if (MAVLINK_VERSION == 0)
+#undef MAVLINK_VERSION
+#define MAVLINK_VERSION 3
+#endif
+
+// MESSAGE DEFINITIONS
+#include "./mavlink_msg_test_types.h"
+
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+#endif // TEST_H
diff --git a/mavlink-solo/pymavlink/generator/C/include_v1.0/test/testsuite.h b/mavlink-solo/pymavlink/generator/C/include_v1.0/test/testsuite.h
new file mode 100644
index 0000000..658e1ae
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/include_v1.0/test/testsuite.h
@@ -0,0 +1,120 @@
+/** @file
+ * @brief MAVLink comm protocol testsuite generated from test.xml
+ * @see http://qgroundcontrol.org/mavlink/
+ */
+#ifndef TEST_TESTSUITE_H
+#define TEST_TESTSUITE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MAVLINK_TEST_ALL
+#define MAVLINK_TEST_ALL
+
+static void mavlink_test_test(uint8_t, uint8_t, mavlink_message_t *last_msg);
+
+static void mavlink_test_all(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg)
+{
+
+ mavlink_test_test(system_id, component_id, last_msg);
+}
+#endif
+
+
+
+
+static void mavlink_test_test_types(uint8_t system_id, uint8_t component_id, mavlink_message_t *last_msg)
+{
+ mavlink_message_t msg;
+ uint8_t buffer[MAVLINK_MAX_PACKET_LEN];
+ uint16_t i;
+ mavlink_test_types_t packet_in = {
+ 93372036854775807ULL,
+ 93372036854776311LL,
+ 235.0,
+ { 93372036854777319, 93372036854777320, 93372036854777321 },
+ { 93372036854778831, 93372036854778832, 93372036854778833 },
+ { 627.0, 628.0, 629.0 },
+ 963502456,
+ 963502664,
+ 745.0,
+ { 963503080, 963503081, 963503082 },
+ { 963503704, 963503705, 963503706 },
+ { 941.0, 942.0, 943.0 },
+ 24723,
+ 24827,
+ { 24931, 24932, 24933 },
+ { 25243, 25244, 25245 },
+ 'E',
+ "FGHIJKLMN",
+ 198,
+ 9,
+ { 76, 77, 78 },
+ { 21, 22, 23 },
+ };
+ mavlink_test_types_t packet1, packet2;
+ memset(&packet1, 0, sizeof(packet1));
+ packet1.u64 = packet_in.u64;
+ packet1.s64 = packet_in.s64;
+ packet1.d = packet_in.d;
+ packet1.u32 = packet_in.u32;
+ packet1.s32 = packet_in.s32;
+ packet1.f = packet_in.f;
+ packet1.u16 = packet_in.u16;
+ packet1.s16 = packet_in.s16;
+ packet1.c = packet_in.c;
+ packet1.u8 = packet_in.u8;
+ packet1.s8 = packet_in.s8;
+
+ mav_array_memcpy(packet1.u64_array, packet_in.u64_array, sizeof(uint64_t)*3);
+ mav_array_memcpy(packet1.s64_array, packet_in.s64_array, sizeof(int64_t)*3);
+ mav_array_memcpy(packet1.d_array, packet_in.d_array, sizeof(double)*3);
+ mav_array_memcpy(packet1.u32_array, packet_in.u32_array, sizeof(uint32_t)*3);
+ mav_array_memcpy(packet1.s32_array, packet_in.s32_array, sizeof(int32_t)*3);
+ mav_array_memcpy(packet1.f_array, packet_in.f_array, sizeof(float)*3);
+ mav_array_memcpy(packet1.u16_array, packet_in.u16_array, sizeof(uint16_t)*3);
+ mav_array_memcpy(packet1.s16_array, packet_in.s16_array, sizeof(int16_t)*3);
+ mav_array_memcpy(packet1.s, packet_in.s, sizeof(char)*10);
+ mav_array_memcpy(packet1.u8_array, packet_in.u8_array, sizeof(uint8_t)*3);
+ mav_array_memcpy(packet1.s8_array, packet_in.s8_array, sizeof(int8_t)*3);
+
+
+ memset(&packet2, 0, sizeof(packet2));
+ mavlink_msg_test_types_encode(system_id, component_id, &msg, &packet1);
+ mavlink_msg_test_types_decode(&msg, &packet2);
+ MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0);
+
+ memset(&packet2, 0, sizeof(packet2));
+ mavlink_msg_test_types_pack(system_id, component_id, &msg , packet1.c , packet1.s , packet1.u8 , packet1.u16 , packet1.u32 , packet1.u64 , packet1.s8 , packet1.s16 , packet1.s32 , packet1.s64 , packet1.f , packet1.d , packet1.u8_array , packet1.u16_array , packet1.u32_array , packet1.u64_array , packet1.s8_array , packet1.s16_array , packet1.s32_array , packet1.s64_array , packet1.f_array , packet1.d_array );
+ mavlink_msg_test_types_decode(&msg, &packet2);
+ MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0);
+
+ memset(&packet2, 0, sizeof(packet2));
+ mavlink_msg_test_types_pack_chan(system_id, component_id, MAVLINK_COMM_0, &msg , packet1.c , packet1.s , packet1.u8 , packet1.u16 , packet1.u32 , packet1.u64 , packet1.s8 , packet1.s16 , packet1.s32 , packet1.s64 , packet1.f , packet1.d , packet1.u8_array , packet1.u16_array , packet1.u32_array , packet1.u64_array , packet1.s8_array , packet1.s16_array , packet1.s32_array , packet1.s64_array , packet1.f_array , packet1.d_array );
+ mavlink_msg_test_types_decode(&msg, &packet2);
+ MAVLINK_ASSERT(memcmp(&packet1, &packet2, sizeof(packet1)) == 0);
+
+ memset(&packet2, 0, sizeof(packet2));
+ mavlink_msg_to_send_buffer(buffer, &msg);
+ for (i=0; i
+#include
+#include
+#include
+#include
+
+#define MAVLINK_USE_CONVENIENCE_FUNCTIONS
+#define MAVLINK_COMM_NUM_BUFFERS 2
+
+// this trick allows us to make mavlink_message_t as small as possible
+// for this dialect, which saves some memory
+#include
+#define MAVLINK_MAX_PAYLOAD_LEN MAVLINK_MAX_DIALECT_PAYLOAD_SIZE
+
+#include
+static mavlink_system_t mavlink_system = {42,11,};
+
+#define MAVLINK_ASSERT(x) assert(x)
+static void comm_send_ch(mavlink_channel_t chan, uint8_t c);
+
+static mavlink_message_t last_msg;
+
+#include
+#include
+
+static unsigned chan_counts[MAVLINK_COMM_NUM_BUFFERS];
+
+static const unsigned message_lengths[] = MAVLINK_MESSAGE_LENGTHS;
+static unsigned error_count;
+
+static const mavlink_message_info_t message_info[256] = MAVLINK_MESSAGE_INFO;
+
+static void print_one_field(mavlink_message_t *msg, const mavlink_field_info_t *f, int idx)
+{
+#define PRINT_FORMAT(f, def) (f->print_format?f->print_format:def)
+ switch (f->type) {
+ case MAVLINK_TYPE_CHAR:
+ printf(PRINT_FORMAT(f, "%c"), _MAV_RETURN_char(msg, f->wire_offset+idx*1));
+ break;
+ case MAVLINK_TYPE_UINT8_T:
+ printf(PRINT_FORMAT(f, "%u"), _MAV_RETURN_uint8_t(msg, f->wire_offset+idx*1));
+ break;
+ case MAVLINK_TYPE_INT8_T:
+ printf(PRINT_FORMAT(f, "%d"), _MAV_RETURN_int8_t(msg, f->wire_offset+idx*1));
+ break;
+ case MAVLINK_TYPE_UINT16_T:
+ printf(PRINT_FORMAT(f, "%u"), _MAV_RETURN_uint16_t(msg, f->wire_offset+idx*2));
+ break;
+ case MAVLINK_TYPE_INT16_T:
+ printf(PRINT_FORMAT(f, "%d"), _MAV_RETURN_int16_t(msg, f->wire_offset+idx*2));
+ break;
+ case MAVLINK_TYPE_UINT32_T:
+ printf(PRINT_FORMAT(f, "%lu"), (unsigned long)_MAV_RETURN_uint32_t(msg, f->wire_offset+idx*4));
+ break;
+ case MAVLINK_TYPE_INT32_T:
+ printf(PRINT_FORMAT(f, "%ld"), (long)_MAV_RETURN_int32_t(msg, f->wire_offset+idx*4));
+ break;
+ case MAVLINK_TYPE_UINT64_T:
+ printf(PRINT_FORMAT(f, "%llu"), (unsigned long long)_MAV_RETURN_uint64_t(msg, f->wire_offset+idx*8));
+ break;
+ case MAVLINK_TYPE_INT64_T:
+ printf(PRINT_FORMAT(f, "%lld"), (long long)_MAV_RETURN_int64_t(msg, f->wire_offset+idx*8));
+ break;
+ case MAVLINK_TYPE_FLOAT:
+ printf(PRINT_FORMAT(f, "%f"), (double)_MAV_RETURN_float(msg, f->wire_offset+idx*4));
+ break;
+ case MAVLINK_TYPE_DOUBLE:
+ printf(PRINT_FORMAT(f, "%f"), _MAV_RETURN_double(msg, f->wire_offset+idx*8));
+ break;
+ }
+}
+
+static void print_field(mavlink_message_t *msg, const mavlink_field_info_t *f)
+{
+ printf("%s: ", f->name);
+ if (f->array_length == 0) {
+ print_one_field(msg, f, 0);
+ printf(" ");
+ } else {
+ unsigned i;
+ /* print an array */
+ if (f->type == MAVLINK_TYPE_CHAR) {
+ printf("'%.*s'", f->array_length,
+ f->wire_offset+(const char *)_MAV_PAYLOAD(msg));
+
+ } else {
+ printf("[ ");
+ for (i=0; iarray_length; i++) {
+ print_one_field(msg, f, i);
+ if (i < f->array_length) {
+ printf(", ");
+ }
+ }
+ printf("]");
+ }
+ }
+ printf(" ");
+}
+
+static void print_message(mavlink_message_t *msg)
+{
+ const mavlink_message_info_t *m = &message_info[msg->msgid];
+ const mavlink_field_info_t *f = m->fields;
+ unsigned i;
+ printf("%s { ", m->name);
+ for (i=0; inum_fields; i++) {
+ print_field(msg, &f[i]);
+ }
+ printf("}\n");
+}
+
+static void comm_send_ch(mavlink_channel_t chan, uint8_t c)
+{
+ mavlink_status_t status;
+ if (mavlink_parse_char(chan, c, &last_msg, &status)) {
+ print_message(&last_msg);
+ chan_counts[chan]++;
+ /* channel 0 gets 3 messages per message, because of
+ the channel defaults for _pack() and _encode() */
+ if (chan == MAVLINK_COMM_0 && status.current_rx_seq != (uint8_t)(chan_counts[chan]*3)) {
+ printf("Channel 0 sequence mismatch error at packet %u (rx_seq=%u)\n",
+ chan_counts[chan], status.current_rx_seq);
+ error_count++;
+ } else if (chan > MAVLINK_COMM_0 && status.current_rx_seq != (uint8_t)chan_counts[chan]) {
+ printf("Channel %u sequence mismatch error at packet %u (rx_seq=%u)\n",
+ (unsigned)chan, chan_counts[chan], status.current_rx_seq);
+ error_count++;
+ }
+ if (message_lengths[last_msg.msgid] != last_msg.len) {
+ printf("Incorrect message length %u for message %u - expected %u\n",
+ (unsigned)last_msg.len, (unsigned)last_msg.msgid, message_lengths[last_msg.msgid]);
+ error_count++;
+ }
+ }
+ if (status.packet_rx_drop_count != 0) {
+ printf("Parse error at packet %u\n", chan_counts[chan]);
+ error_count++;
+ }
+}
+
+int main(void)
+{
+ mavlink_channel_t chan;
+ mavlink_test_all(11, 10, &last_msg);
+ for (chan=MAVLINK_COMM_0; chan<=MAVLINK_COMM_1; chan++) {
+ printf("Received %u messages on channel %u OK\n",
+ chan_counts[chan], (unsigned)chan);
+ }
+ if (error_count != 0) {
+ printf("Error count %u\n", error_count);
+ exit(1);
+ }
+ printf("No errors detected\n");
+ return 0;
+}
+
diff --git a/mavlink-solo/pymavlink/generator/C/test/windows/stdafx.cpp b/mavlink-solo/pymavlink/generator/C/test/windows/stdafx.cpp
new file mode 100644
index 0000000..98b4abf
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/test/windows/stdafx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// testmav.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/mavlink-solo/pymavlink/generator/C/test/windows/stdafx.h b/mavlink-solo/pymavlink/generator/C/test/windows/stdafx.h
new file mode 100644
index 0000000..47a0d02
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/test/windows/stdafx.h
@@ -0,0 +1,15 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#pragma once
+
+#include "targetver.h"
+
+#include
+#include
+
+
+
+// TODO: reference additional headers your program requires here
diff --git a/mavlink-solo/pymavlink/generator/C/test/windows/targetver.h b/mavlink-solo/pymavlink/generator/C/test/windows/targetver.h
new file mode 100644
index 0000000..90e767b
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/test/windows/targetver.h
@@ -0,0 +1,8 @@
+#pragma once
+
+// Including SDKDDKVer.h defines the highest available Windows platform.
+
+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
+
+#include
diff --git a/mavlink-solo/pymavlink/generator/C/test/windows/testmav.cpp b/mavlink-solo/pymavlink/generator/C/test/windows/testmav.cpp
new file mode 100644
index 0000000..aa83cac
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/test/windows/testmav.cpp
@@ -0,0 +1,154 @@
+// testmav.cpp : Defines the entry point for the console application.
+//
+
+#include "stdafx.h"
+#include "stdio.h"
+#include "stdint.h"
+#include "stddef.h"
+#include "assert.h"
+
+
+#define MAVLINK_USE_CONVENIENCE_FUNCTIONS
+#define MAVLINK_COMM_NUM_BUFFERS 2
+
+#include
+static mavlink_system_t mavlink_system = {42,11,};
+
+#define MAVLINK_ASSERT(x) assert(x)
+static void comm_send_ch(mavlink_channel_t chan, uint8_t c);
+
+static mavlink_message_t last_msg;
+
+#include
+#include
+
+static unsigned chan_counts[MAVLINK_COMM_NUM_BUFFERS];
+
+static const unsigned message_lengths[] = MAVLINK_MESSAGE_LENGTHS;
+static unsigned error_count;
+
+static const mavlink_message_info_t message_info[256] = MAVLINK_MESSAGE_INFO;
+
+static void print_one_field(mavlink_message_t *msg, const mavlink_field_info_t *f, int idx)
+{
+#define PRINT_FORMAT(f, def) (f->print_format?f->print_format:def)
+ switch (f->type) {
+ case MAVLINK_TYPE_CHAR:
+ printf(PRINT_FORMAT(f, "%c"), _MAV_RETURN_char(msg, f->wire_offset+idx*1));
+ break;
+ case MAVLINK_TYPE_UINT8_T:
+ printf(PRINT_FORMAT(f, "%u"), _MAV_RETURN_uint8_t(msg, f->wire_offset+idx*1));
+ break;
+ case MAVLINK_TYPE_INT8_T:
+ printf(PRINT_FORMAT(f, "%d"), _MAV_RETURN_int8_t(msg, f->wire_offset+idx*1));
+ break;
+ case MAVLINK_TYPE_UINT16_T:
+ printf(PRINT_FORMAT(f, "%u"), _MAV_RETURN_uint16_t(msg, f->wire_offset+idx*2));
+ break;
+ case MAVLINK_TYPE_INT16_T:
+ printf(PRINT_FORMAT(f, "%d"), _MAV_RETURN_int16_t(msg, f->wire_offset+idx*2));
+ break;
+ case MAVLINK_TYPE_UINT32_T:
+ printf(PRINT_FORMAT(f, "%lu"), (unsigned long)_MAV_RETURN_uint32_t(msg, f->wire_offset+idx*4));
+ break;
+ case MAVLINK_TYPE_INT32_T:
+ printf(PRINT_FORMAT(f, "%ld"), (long)_MAV_RETURN_int32_t(msg, f->wire_offset+idx*4));
+ break;
+ case MAVLINK_TYPE_UINT64_T:
+ printf(PRINT_FORMAT(f, "%llu"), (unsigned long long)_MAV_RETURN_uint64_t(msg, f->wire_offset+idx*8));
+ break;
+ case MAVLINK_TYPE_INT64_T:
+ printf(PRINT_FORMAT(f, "%lld"), (long long)_MAV_RETURN_int64_t(msg, f->wire_offset+idx*8));
+ break;
+ case MAVLINK_TYPE_FLOAT:
+ printf(PRINT_FORMAT(f, "%f"), (double)_MAV_RETURN_float(msg, f->wire_offset+idx*4));
+ break;
+ case MAVLINK_TYPE_DOUBLE:
+ printf(PRINT_FORMAT(f, "%f"), _MAV_RETURN_double(msg, f->wire_offset+idx*8));
+ break;
+ }
+}
+
+static void print_field(mavlink_message_t *msg, const mavlink_field_info_t *f)
+{
+ printf("%s: ", f->name);
+ if (f->array_length == 0) {
+ print_one_field(msg, f, 0);
+ printf(" ");
+ } else {
+ unsigned i;
+ /* print an array */
+ if (f->type == MAVLINK_TYPE_CHAR) {
+ printf("'%.*s'", f->array_length,
+ f->wire_offset+(const char *)_MAV_PAYLOAD(msg));
+
+ } else {
+ printf("[ ");
+ for (i=0; iarray_length; i++) {
+ print_one_field(msg, f, i);
+ if (i < f->array_length) {
+ printf(", ");
+ }
+ }
+ printf("]");
+ }
+ }
+ printf(" ");
+}
+
+static void print_message(mavlink_message_t *msg)
+{
+ const mavlink_message_info_t *m = &message_info[msg->msgid];
+ const mavlink_field_info_t *f = m->fields;
+ unsigned i;
+ printf("%s { ", m->name);
+ for (i=0; inum_fields; i++) {
+ print_field(msg, &f[i]);
+ }
+ printf("}\n");
+}
+
+static void comm_send_ch(mavlink_channel_t chan, uint8_t c)
+{
+ mavlink_status_t status;
+ if (mavlink_parse_char(chan, c, &last_msg, &status)) {
+ print_message(&last_msg);
+ chan_counts[chan]++;
+ /* channel 0 gets 3 messages per message, because of
+ the channel defaults for _pack() and _encode() */
+ if (chan == MAVLINK_COMM_0 && status.current_rx_seq != (uint8_t)(chan_counts[chan]*3)) {
+ printf("Channel 0 sequence mismatch error at packet %u (rx_seq=%u)\n",
+ chan_counts[chan], status.current_rx_seq);
+ error_count++;
+ } else if (chan > MAVLINK_COMM_0 && status.current_rx_seq != (uint8_t)chan_counts[chan]) {
+ printf("Channel %u sequence mismatch error at packet %u (rx_seq=%u)\n",
+ (unsigned)chan, chan_counts[chan], status.current_rx_seq);
+ error_count++;
+ }
+ if (message_lengths[last_msg.msgid] != last_msg.len) {
+ printf("Incorrect message length %u for message %u - expected %u\n",
+ (unsigned)last_msg.len, (unsigned)last_msg.msgid, message_lengths[last_msg.msgid]);
+ error_count++;
+ }
+ }
+ if (status.packet_rx_drop_count != 0) {
+ printf("Parse error at packet %u\n", chan_counts[chan]);
+ error_count++;
+ }
+}
+
+int _tmain(int argc, _TCHAR* argv[])
+{
+ int chan;
+ mavlink_test_all(11, 10, &last_msg);
+ for (chan=MAVLINK_COMM_0; chan<=MAVLINK_COMM_1; chan++) {
+ printf("Received %u messages on channel %u OK\n",
+ chan_counts[chan], (unsigned)chan);
+ }
+ if (error_count != 0) {
+ printf("Error count %u\n", error_count);
+ return(1);
+ }
+ printf("No errors detected\n");
+ return 0;
+}
diff --git a/mavlink-solo/pymavlink/generator/C/test/windows/testmav.sln b/mavlink-solo/pymavlink/generator/C/test/windows/testmav.sln
new file mode 100644
index 0000000..37a3056
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/test/windows/testmav.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual C++ Express 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testmav", "testmav\testmav.vcxproj", "{02C30EBC-DF41-4C36-B2F3-79BED7E6EF9F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {02C30EBC-DF41-4C36-B2F3-79BED7E6EF9F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {02C30EBC-DF41-4C36-B2F3-79BED7E6EF9F}.Debug|Win32.Build.0 = Debug|Win32
+ {02C30EBC-DF41-4C36-B2F3-79BED7E6EF9F}.Release|Win32.ActiveCfg = Release|Win32
+ {02C30EBC-DF41-4C36-B2F3-79BED7E6EF9F}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/mavlink-solo/pymavlink/generator/C/test/windows/testmav.suo b/mavlink-solo/pymavlink/generator/C/test/windows/testmav.suo
new file mode 100644
index 0000000..9b2e18c
Binary files /dev/null and b/mavlink-solo/pymavlink/generator/C/test/windows/testmav.suo differ
diff --git a/mavlink-solo/pymavlink/generator/C/test/windows/testmav.vcxproj b/mavlink-solo/pymavlink/generator/C/test/windows/testmav.vcxproj
new file mode 100644
index 0000000..7181b3a
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/C/test/windows/testmav.vcxproj
@@ -0,0 +1,91 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {02C30EBC-DF41-4C36-B2F3-79BED7E6EF9F}
+ Win32Proj
+ testmav
+
+
+
+ Application
+ true
+ Unicode
+
+
+ Application
+ false
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ false
+
+
+
+
+
+ Level3
+ Disabled
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ E:\pymavlink\generator\C\include_v1.0
+
+
+ Console
+ true
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mavlink-solo/pymavlink/generator/CS/common/ByteArrayUtil.cs b/mavlink-solo/pymavlink/generator/CS/common/ByteArrayUtil.cs
new file mode 100644
index 0000000..2fa246e
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/CS/common/ByteArrayUtil.cs
@@ -0,0 +1,198 @@
+using System;
+using System.Text;
+
+namespace MavLink
+{
+ internal static class ByteArrayUtil
+ {
+#if MF_FRAMEWORK_VERSION_V4_1
+ private static readonly MavBitConverter bitConverter = new MavBitConverter();
+#else
+ private static readonly FrameworkBitConverter bitConverter = new FrameworkBitConverter();
+#endif
+
+ public static byte[] ToChar(byte[] source, int sourceOffset, int size)
+ {
+ var bytes = new byte[size];
+
+ for (int i = 0; i < size; i++)
+ bytes[i] = source[i + sourceOffset];
+
+ return bytes;
+ }
+
+ public static byte[] ToUInt8(byte[] source, int sourceOffset, int size)
+ {
+ var bytes = new byte[size];
+ Array.Copy(source, sourceOffset, bytes, 0, size);
+ return bytes;
+ }
+
+ public static sbyte[] ToInt8(byte[] source, int sourceOffset, int size)
+ {
+ var bytes = new sbyte[size];
+
+ for (int i = 0; i < size; i++)
+ bytes[i] = unchecked((sbyte)source[i + sourceOffset]);
+
+ return bytes;
+ }
+
+ public static UInt16[] ToUInt16(byte[] source, int sourceOffset, int size)
+ {
+ var arr = new UInt16[size];
+ for (int i = 0; i < size; i++)
+ arr[i] = bitConverter.ToUInt16(source, sourceOffset + (i * sizeof (UInt16)));
+ return arr;
+ }
+
+ public static Int16[] ToInt16(byte[] source, int sourceOffset, int size)
+ {
+ var arr = new Int16[size];
+ for (int i = 0; i < size; i++)
+ arr[i] = bitConverter.ToInt16(source, sourceOffset + (i * sizeof(Int16)));
+ return arr;
+ }
+
+ public static UInt32[] ToUInt32(byte[] source, int sourceOffset, int size)
+ {
+ var arr = new UInt32[size];
+ for (int i = 0; i < size; i++)
+ arr[i] = bitConverter.ToUInt16(source, sourceOffset + (i * sizeof(UInt32)));
+ return arr;
+ }
+
+ public static Int32[] ToInt32(byte[] source, int sourceOffset, int size)
+ {
+ var arr = new Int32[size];
+ for (int i = 0; i < size; i++)
+ arr[i] = bitConverter.ToInt16(source, sourceOffset + (i * sizeof(Int32)));
+ return arr;
+ }
+
+ public static UInt64[] ToUInt64(byte[] source, int sourceOffset, int size)
+ {
+ var arr = new UInt64[size];
+ for (int i = 0; i < size; i++)
+ arr[i] = bitConverter.ToUInt16(source, sourceOffset + (i * sizeof(UInt64)));
+ return arr;
+ }
+
+ public static Int64[] ToInt64(byte[] source, int sourceOffset, int size)
+ {
+ var arr = new Int64[size];
+ for (int i = 0; i < size; i++)
+ arr[i] = bitConverter.ToInt16(source, sourceOffset + (i * sizeof(Int64)));
+ return arr;
+ }
+
+ public static Single[] ToSingle(byte[] source, int sourceOffset, int size)
+ {
+ var arr = new Single[size];
+ for (int i = 0; i < size; i++)
+ arr[i] = bitConverter.ToUInt16(source, sourceOffset + (i * sizeof(Single)));
+ return arr;
+ }
+
+ public static Double[] ToDouble(byte[] source, int sourceOffset, int size)
+ {
+ var arr = new Double[size];
+ for (int i = 0; i < size; i++)
+ arr[i] = bitConverter.ToInt16(source, sourceOffset + (i * sizeof(Double)));
+ return arr;
+ }
+
+ public static void ToByteArray(byte[] src, byte[] dst, int offset, int size)
+ {
+ int i;
+ for (i = 0; i < src.Length; i++)
+ dst[offset + i] = src[i];
+ while (i++ < size)
+ dst[offset + i] = 0;
+ }
+
+ public static void ToByteArray(sbyte[] src, byte[] dst, int offset, int size)
+ {
+ int i;
+ for (i = 0; i < size && i
+ /// converter from byte[] => primitive CLR types
+ /// delegates to the .Net framework bitconverter for speed, and to avoid using unsafe pointer
+ /// casting for Silverlight.
+ ///
+ internal class FrameworkBitConverter
+ {
+ private bool _shouldReverse = false;
+
+ public void SetDataIsLittleEndian(bool islittle)
+ {
+ _shouldReverse = islittle == !BitConverter.IsLittleEndian;
+ }
+
+ public UInt16 ToUInt16(byte[] value, int startIndex)
+ {
+ if (_shouldReverse)
+ {
+ var bytes = new[] {value[startIndex + 1], value[startIndex]};
+ return BitConverter.ToUInt16(bytes,0);
+ }
+ return BitConverter.ToUInt16(value, startIndex);
+ }
+
+ public Int16 ToInt16(byte[] value, int startIndex)
+ {
+ if (_shouldReverse)
+ {
+ var bytes = new[] { value[startIndex + 1], value[startIndex] };
+ return BitConverter.ToInt16(bytes, 0);
+ }
+ return BitConverter.ToInt16(value, startIndex);
+ }
+
+ public sbyte ToInt8(byte[] value, int startIndex)
+ {
+ return unchecked((sbyte)value[startIndex]);
+ }
+
+ public Int32 ToInt32(byte[] value, int startIndex)
+ {
+ if (_shouldReverse)
+ {
+ var bytes = new byte[4];
+ Array.Copy(value,startIndex,bytes,0,4);
+ Array.Reverse(bytes);
+ return BitConverter.ToInt32(bytes, 0);
+ }
+ return BitConverter.ToInt32(value, startIndex);
+ }
+
+ public UInt32 ToUInt32(byte[] value, int startIndex)
+ {
+ if (_shouldReverse)
+ {
+ var bytes = new byte[4];
+ Array.Copy(value, startIndex, bytes, 0, 4);
+ Array.Reverse(bytes);
+ return BitConverter.ToUInt32(bytes, 0);
+ }
+ return BitConverter.ToUInt32(value, startIndex);
+ }
+
+ public UInt64 ToUInt64(byte[] value, int startIndex)
+ {
+ if (_shouldReverse)
+ {
+ var bytes = new byte[8];
+ Array.Copy(value, startIndex, bytes, 0, bytes.Length);
+ Array.Reverse(bytes);
+ return BitConverter.ToUInt64(bytes, 0);
+ }
+ return BitConverter.ToUInt64(value, startIndex);
+ }
+
+ public Int64 ToInt64(byte[] value, int startIndex)
+ {
+ if (_shouldReverse)
+ {
+ var bytes = new byte[8];
+ Array.Copy(value, startIndex, bytes, 0, bytes.Length);
+ Array.Reverse(bytes);
+ return BitConverter.ToInt64(bytes, 0);
+ }
+ return BitConverter.ToInt64(value, startIndex);
+ }
+
+ public Single ToSingle(byte[] value, int startIndex)
+ {
+ if (_shouldReverse)
+ {
+ var bytes = new byte[4];
+ Array.Copy(value, startIndex, bytes, 0, bytes.Length);
+ Array.Reverse(bytes);
+ return BitConverter.ToSingle(bytes, 0);
+ }
+ return BitConverter.ToSingle(value, startIndex);
+ }
+
+ public Double ToDouble(byte[] value, int startIndex)
+ {
+ if (_shouldReverse)
+ {
+ var bytes = new byte[8];
+ Array.Copy(value, startIndex, bytes, 0, bytes.Length);
+ Array.Reverse(bytes);
+ return BitConverter.ToDouble(bytes, 0);
+ }
+ return BitConverter.ToDouble(value, startIndex);
+ }
+
+ public void GetBytes(Double value, byte[] dst, int offset)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ if (_shouldReverse) Array.Reverse(bytes);
+ Array.Copy(bytes, 0, dst, offset, bytes.Length);
+
+ }
+
+ public void GetBytes(Single value, byte[] dst, int offset)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ if (_shouldReverse) Array.Reverse(bytes);
+
+ Array.Copy(bytes, 0, dst, offset, bytes.Length);
+ }
+
+ public void GetBytes(UInt64 value, byte[] dst, int offset)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ if (_shouldReverse) Array.Reverse(bytes);
+
+ Array.Copy(bytes, 0, dst, offset, bytes.Length);
+ }
+
+ public void GetBytes(Int64 value, byte[] dst, int offset)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ if (_shouldReverse) Array.Reverse(bytes);
+
+ Array.Copy(bytes, 0, dst, offset, bytes.Length);
+ }
+
+ public void GetBytes(UInt32 value, byte[] dst, int offset)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ if (_shouldReverse) Array.Reverse(bytes);
+
+ Array.Copy(bytes, 0, dst, offset, bytes.Length);
+ }
+
+ public void GetBytes(Int16 value, byte[] dst, int offset)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ if (_shouldReverse) Array.Reverse(bytes);
+
+ Array.Copy(bytes, 0, dst, offset, bytes.Length);
+ }
+
+ public void GetBytes(Int32 value, byte[] dst, int offset)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ if (_shouldReverse) Array.Reverse(bytes);
+
+ Array.Copy(bytes, 0, dst, offset, bytes.Length);
+ }
+
+ public void GetBytes(UInt16 value, byte[] dst, int offset)
+ {
+ var bytes = BitConverter.GetBytes(value);
+ if (_shouldReverse) Array.Reverse(bytes);
+
+ Array.Copy(bytes, 0, dst, offset, bytes.Length);
+ }
+
+ public byte[] GetBytes(sbyte value)
+ {
+ return new byte[1]
+ {
+ (byte)value,
+ };
+ }
+ }
+}
\ No newline at end of file
diff --git a/mavlink-solo/pymavlink/generator/CS/common/Mavlink.cs b/mavlink-solo/pymavlink/generator/CS/common/Mavlink.cs
new file mode 100644
index 0000000..299728d
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/CS/common/Mavlink.cs
@@ -0,0 +1,437 @@
+using System;
+using MavLink;
+
+namespace MavLink
+{
+ ///
+ /// Mavlink communication class.
+ ///
+ ///
+ /// Keeps track of state across send and receive of packets.
+ /// User of this class can just send Mavlink Messsages, and
+ /// receive them by feeding this class bytes off the wire as
+ /// they arrive
+ ///
+ public class Mavlink
+ {
+ private byte[] leftovers;
+
+ ///
+ /// Event raised when a message is decoded successfully
+ ///
+ public event PacketReceivedEventHandler PacketReceived;
+
+ ///
+ /// Total number of packets successfully received so far
+ ///
+ public UInt32 PacketsReceived { get; private set; }
+
+ ///
+ /// Total number of packets which have been rejected due to a failed crc
+ ///
+ public UInt32 BadCrcPacketsReceived { get; private set; }
+
+ ///
+ /// Raised when a packet does not pass CRC
+ ///
+ public event PacketCRCFailEventHandler PacketFailedCRC;
+
+ ///
+ /// Raised when a number of bytes are passed over and cannot
+ /// be used to decode a packet
+ ///
+ public event PacketCRCFailEventHandler BytesUnused;
+
+ // The current packet sequence number for transmission
+ // public so it can be manipulated for testing
+ // Normal usage would only read this
+ public byte txPacketSequence;
+
+ ///
+ /// Create a new MavlinkLink Object
+ ///
+ public Mavlink()
+ {
+ MavLinkSerializer.SetDataIsLittleEndian(MavlinkSettings.IsLittleEndian);
+ leftovers = new byte[] {};
+ }
+
+
+ ///
+ /// Process latest bytes from the stream. Received packets will be raised in the event
+ ///
+ public void ParseBytes(byte[] newlyReceived)
+ {
+ uint i = 0;
+
+ // copy the old and new into a contiguous array
+ // This is pretty inefficient...
+ var bytesToProcess = new byte[newlyReceived.Length + leftovers.Length];
+ int j = 0;
+
+ for (i = 0; i < leftovers.Length; i++)
+ bytesToProcess[j++] = leftovers[i];
+
+ for (i = 0; i < newlyReceived.Length; i++)
+ bytesToProcess[j++] = newlyReceived[i];
+
+ i = 0;
+
+ // we are going to loop and decode packets until we use up the data
+ // at which point we will return. Hence one call to this method could
+ // result in multiple packet decode events
+ while (true)
+ {
+ // Hunt for the start char
+ int huntStartPos = (int)i;
+
+ while (i < bytesToProcess.Length && bytesToProcess[i] != MavlinkSettings.ProtocolMarker)
+ i++;
+
+ if (i == bytesToProcess.Length)
+ {
+ // No start byte found in all our bytes. Dump them, Exit.
+ leftovers = new byte[] { };
+ return;
+ }
+
+ if (i > huntStartPos)
+ {
+ // if we get here then are some bytes which this code thinks are
+ // not interesting and would be dumped. For diagnostics purposes,
+ // lets pop these bytes up in an event.
+ if (BytesUnused != null)
+ {
+ var badBytes = new byte[i - huntStartPos];
+ Array.Copy(bytesToProcess, huntStartPos, badBytes, 0, (int)(i - huntStartPos));
+ BytesUnused(this, new PacketCRCFailEventArgs(badBytes, bytesToProcess.Length - huntStartPos));
+ }
+ }
+
+ // We need at least the minimum length of a packet to process it.
+ // The minimum packet length is 8 bytes for acknowledgement packets without payload
+ // if we don't have the minimum now, go round again
+ if (bytesToProcess.Length - i < 8)
+ {
+ leftovers = new byte[bytesToProcess.Length - i];
+ j = 0;
+ while (i < bytesToProcess.Length)
+ leftovers[j++] = bytesToProcess[i++];
+ return;
+ }
+
+ /*
+ * Byte order:
+ *
+ * 0 Packet start sign
+ * 1 Payload length 0 - 255
+ * 2 Packet sequence 0 - 255
+ * 3 System ID 1 - 255
+ * 4 Component ID 0 - 255
+ * 5 Message ID 0 - 255
+ * 6 to (n+6) Data (0 - 255) bytes
+ * (n+7) to (n+8) Checksum (high byte, low byte) for v0.9, lowbyte, highbyte for 1.0
+ *
+ */
+ UInt16 payLoadLength = bytesToProcess[i + 1];
+
+ // Now we know the packet length,
+ // If we don't have enough bytes in this packet to satisfy that packet lenghth,
+ // then dump the whole lot in the leftovers and do nothing else - go round again
+ if (payLoadLength > (bytesToProcess.Length - i - 8)) // payload + 'overhead' bytes (crc, system etc)
+ {
+ // back up to the start char for next cycle
+ j = 0;
+
+ leftovers = new byte[bytesToProcess.Length - i];
+
+ for (; i < bytesToProcess.Length; i++)
+ {
+ leftovers[j++] = bytesToProcess[i];
+ }
+ return;
+ }
+
+ i++;
+
+ // Check the CRC. Does not include the starting 'U' byte but does include the length
+ var crc1 = Mavlink_Crc.Calculate(bytesToProcess, (UInt16)(i), (UInt16)(payLoadLength + 5));
+
+ if (MavlinkSettings.CrcExtra)
+ {
+ var possibleMsgId = bytesToProcess[i + 4];
+
+ if (!MavLinkSerializer.Lookup.ContainsKey(possibleMsgId))
+ {
+ // we have received an unknown message. In this case we don't know the special
+ // CRC extra, so we have no choice but to fail.
+
+ // The way we do this is to just let the procedure continue
+ // There will be a natural failure of the main packet CRC
+ }
+ else
+ {
+ var extra = MavLinkSerializer.Lookup[possibleMsgId];
+ crc1 = Mavlink_Crc.CrcAccumulate(extra.CrcExtra, crc1);
+ }
+ }
+
+ byte crcHigh = (byte)(crc1 & 0xFF);
+ byte crcLow = (byte)(crc1 >> 8);
+
+ byte messageCrcHigh = bytesToProcess[i + 5 + payLoadLength];
+ byte messageCrcLow = bytesToProcess[i + 6 + payLoadLength];
+
+ if (messageCrcHigh == crcHigh && messageCrcLow == crcLow)
+ {
+ // This is used for data drop outs metrics, not packet windows
+ // so we should consider this here.
+ // We pass up to subscribers only as an advisory thing
+ var rxPacketSequence = bytesToProcess[++i];
+ i++;
+ var packet = new byte[payLoadLength + 3]; // +3 because we are going to send up the sys and comp id and msg type with the data
+
+ for (j = 0; j < packet.Length; j++)
+ packet[j] = bytesToProcess[i + j];
+
+ var debugArray = new byte[payLoadLength + 7];
+ Array.Copy(bytesToProcess, (int)(i - 3), debugArray, 0, debugArray.Length);
+
+ //OnPacketDecoded(packet, rxPacketSequence, debugArray);
+
+ ProcessPacketBytes(packet, rxPacketSequence);
+
+ PacketsReceived++;
+
+ // clear leftovers, just incase this is the last packet
+ leftovers = new byte[] { };
+
+ // advance i here by j to avoid unecessary hunting
+ // todo: could advance by j + 2 I think?
+ i = i + (uint)(j + 2);
+ }
+ else
+ {
+ var badBytes = new byte[i + 7 + payLoadLength];
+ Array.Copy(bytesToProcess, (int)(i - 1), badBytes, 0, payLoadLength + 7);
+
+ if (PacketFailedCRC != null)
+ {
+ PacketFailedCRC(this, new PacketCRCFailEventArgs(badBytes, (int)(bytesToProcess.Length - i - 1)));
+ }
+
+ BadCrcPacketsReceived++;
+ }
+ }
+ }
+
+ public byte[] Send(MavlinkPacket mavlinkPacket)
+ {
+ var bytes = this.Serialize(mavlinkPacket.Message, mavlinkPacket.SystemId, mavlinkPacket.ComponentId);
+ return SendPacketLinkLayer(bytes);
+ }
+
+ // Send a raw message over the link -
+ // this will add start byte, lenghth, crc and other link layer stuff
+ private byte[] SendPacketLinkLayer(byte[] packetData)
+ {
+ /*
+ * Byte order:
+ *
+ * 0 Packet start sign
+ * 1 Payload length 0 - 255
+ * 2 Packet sequence 0 - 255
+ * 3 System ID 1 - 255
+ * 4 Component ID 0 - 255
+ * 5 Message ID 0 - 255
+ * 6 to (n+6) Data (0 - 255) bytes
+ * (n+7) to (n+8) Checksum (high byte, low byte)
+ *
+ */
+ var outBytes = new byte[packetData.Length + 5];
+
+ outBytes[0] = MavlinkSettings.ProtocolMarker;
+ outBytes[1] = (byte)(packetData.Length-3); // 3 bytes for sequence, id, msg type which this
+ // layer does not concern itself with
+ outBytes[2] = unchecked(txPacketSequence++);
+
+ int i;
+
+ for ( i = 0; i < packetData.Length; i++)
+ {
+ outBytes[i + 3] = packetData[i];
+ }
+
+ // Check the CRC. Does not include the starting byte but does include the length
+ var crc1 = Mavlink_Crc.Calculate(outBytes, 1, (UInt16)(packetData.Length + 2));
+
+ if (MavlinkSettings.CrcExtra)
+ {
+ var possibleMsgId = outBytes[5];
+ var extra = MavLinkSerializer.Lookup[possibleMsgId];
+ crc1 = Mavlink_Crc.CrcAccumulate(extra.CrcExtra, crc1);
+ }
+
+ byte crc_high = (byte)(crc1 & 0xFF);
+ byte crc_low = (byte)(crc1 >> 8);
+
+ outBytes[i + 3] = crc_high;
+ outBytes[i + 4] = crc_low;
+
+ return outBytes;
+ }
+
+
+ // Process a raw packet in it's entirety in the given byte array
+ // if deserialization is successful, then the packetdecoded event will be raised
+ private void ProcessPacketBytes(byte[] packetBytes, byte rxPacketSequence)
+ {
+ // System ID 1 - 255
+ // Component ID 0 - 255
+ // Message ID 0 - 255
+ // 6 to (n+6) Data (0 - 255) bytes
+ var packet = new MavlinkPacket
+ {
+ SystemId = packetBytes[0],
+ ComponentId = packetBytes[1],
+ SequenceNumber = rxPacketSequence,
+ Message = this.Deserialize(packetBytes, 2)
+ };
+
+ if (PacketReceived != null)
+ {
+ PacketReceived(this, packet);
+ }
+
+ // else do what?
+ }
+
+
+ public MavlinkMessage Deserialize(byte[] bytes, int offset)
+ {
+ // first byte is the mavlink
+ var packetNum = (int)bytes[offset + 0];
+ var packetGen = MavLinkSerializer.Lookup[packetNum].Deserializer;
+ return packetGen.Invoke(bytes, offset + 1);
+ }
+
+ public byte[] Serialize(MavlinkMessage message, int systemId, int componentId)
+ {
+ var buff = new byte[256];
+
+ buff[0] = (byte)systemId;
+ buff[1] = (byte)componentId;
+
+ var endPos = 3;
+
+ var msgId = message.Serialize(buff, ref endPos);
+
+ buff[2] = (byte)msgId;
+
+ var resultBytes = new byte[endPos];
+ Array.Copy(buff, resultBytes, endPos);
+
+ return resultBytes;
+ }
+ }
+
+
+ ///
+ /// Describes an occurance when a packet fails CRC
+ ///
+ public class PacketCRCFailEventArgs : EventArgs
+ {
+ ///
+ ///
+ public PacketCRCFailEventArgs(byte[] badPacket, int offset)
+ {
+ BadPacket = badPacket;
+ Offset = offset;
+ }
+
+ ///
+ /// The bytes that filed the CRC, including the starting character
+ ///
+ public byte[] BadPacket;
+
+ ///
+ /// The offset in bytes where the start of the block begins, e.g
+ /// 50 would mean the block of badbytes would start 50 bytes ago
+ /// in the stread. No negative sign is necessary
+ ///
+ public int Offset;
+ }
+
+ ///
+ /// Handler for an PacketFailedCRC Event
+ ///
+ public delegate void PacketCRCFailEventHandler(object sender, PacketCRCFailEventArgs e);
+
+
+ public delegate void PacketReceivedEventHandler(object sender, MavlinkPacket e);
+
+
+ ///
+ /// Represents a Mavlink message - both the message object itself
+ /// and the identified sending party
+ ///
+ public class MavlinkPacket
+ {
+ ///
+ /// The sender's system ID
+ ///
+ public int SystemId;
+
+ ///
+ /// The sender's component ID
+ ///
+ public int ComponentId;
+
+ ///
+ /// The sequence number received for this packet
+ ///
+ public byte SequenceNumber;
+
+
+ ///
+ /// Time of receipt
+ ///
+ public DateTime TimeStamp;
+
+ ///
+ /// Object which is the mavlink message
+ ///
+ public MavlinkMessage Message;
+ }
+
+ ///
+ /// Crc code copied/adapted from ardumega planner code
+ ///
+ internal static class Mavlink_Crc
+ {
+ const UInt16 X25_INIT_CRC = 0xffff;
+
+ public static UInt16 CrcAccumulate(byte b, UInt16 crc)
+ {
+ unchecked
+ {
+ byte ch = (byte)(b ^ (byte)(crc & 0x00ff));
+ ch = (byte)(ch ^ (ch << 4));
+ return (UInt16)((crc >> 8) ^ (ch << 8) ^ (ch << 3) ^ (ch >> 4));
+ }
+ }
+
+
+ // For a "message" of length bytes contained in the byte array
+ // pointed to by buffer, calculate the CRC
+ public static UInt16 Calculate(byte[] buffer, UInt16 start, UInt16 length)
+ {
+ UInt16 crcTmp = X25_INIT_CRC;
+
+ for (int i = start; i < start + length; i++)
+ crcTmp = CrcAccumulate(buffer[i], crcTmp);
+
+ return crcTmp;
+ }
+ }
+}
diff --git a/mavlink-solo/pymavlink/generator/__init__.py b/mavlink-solo/pymavlink/generator/__init__.py
new file mode 100644
index 0000000..2910a8f
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/__init__.py
@@ -0,0 +1 @@
+'''pymavlink code generator'''
diff --git a/mavlink-solo/pymavlink/generator/gen_js.sh b/mavlink-solo/pymavlink/generator/gen_js.sh
new file mode 100755
index 0000000..3b444b4
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/gen_js.sh
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+for protocol in 0.9 1.0; do
+ for xml in ../../message_definitions/v$protocol/*.xml; do
+ base=$(basename $xml .xml)
+ mkdir -p javascript/implementations/mavlink_${base}_v${protocol}
+
+ # Generate MAVLink implementation
+ ../tools/mavgen.py --lang=JavaScript --wire-protocol=$protocol --output=javascript/implementations/mavlink_${base}_v${protocol}/mavlink.js $xml || exit 1
+
+ # Create package.json file
+ cat >javascript/implementations/mavlink_${base}_v${protocol}/package.json <"],
+ "main" : "mavlink.js",
+ "repository" : {
+ "type" : "git",
+ "url" : "https://github.com/mavlink/mavlink"
+ },
+ "dependencies" : {
+ "underscore" : "",
+ "jspack":"",
+ "winston": ""
+ },
+ "devDependencies" : {
+ "should" : "",
+ "mocha" : "",
+ "sinon" : ""
+ }
+}
+EOF
+
+ done
+done
diff --git a/mavlink-solo/pymavlink/generator/java/lib/Messages/MAVLinkMessage.java b/mavlink-solo/pymavlink/generator/java/lib/Messages/MAVLinkMessage.java
new file mode 100644
index 0000000..dde64d3
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/java/lib/Messages/MAVLinkMessage.java
@@ -0,0 +1,23 @@
+
+package com.MAVLink.Messages;
+
+import java.io.Serializable;
+
+import com.MAVLink.MAVLinkPacket;
+
+public abstract class MAVLinkMessage implements Serializable {
+ private static final long serialVersionUID = -7754622750478538539L;
+ // The MAVLink message classes have been changed to implement Serializable,
+ // this way is possible to pass a mavlink message trought the Service-Acctivity interface
+
+ /**
+ * Simply a common interface for all MAVLink Messages
+ */
+
+ public int sysid;
+ public int compid;
+ public int msgid;
+ public abstract MAVLinkPacket pack();
+ public abstract void unpack(MAVLinkPayload payload);
+}
+
\ No newline at end of file
diff --git a/mavlink-solo/pymavlink/generator/java/lib/Messages/MAVLinkPayload.java b/mavlink-solo/pymavlink/generator/java/lib/Messages/MAVLinkPayload.java
new file mode 100644
index 0000000..8bece83
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/java/lib/Messages/MAVLinkPayload.java
@@ -0,0 +1,121 @@
+package com.MAVLink.Messages;
+
+import java.nio.ByteBuffer;
+
+public class MAVLinkPayload {
+
+ public static final int MAX_PAYLOAD_SIZE = 512;
+
+ public ByteBuffer payload;
+ public int index;
+
+ public MAVLinkPayload() {
+ payload = ByteBuffer.allocate(MAX_PAYLOAD_SIZE);
+ }
+
+ public ByteBuffer getData() {
+ return payload;
+ }
+
+ public int size() {
+ return payload.position();
+ }
+
+ public void add(byte c) {
+ payload.put(c);
+ }
+
+ public void resetIndex() {
+ index = 0;
+ }
+
+ public byte getByte() {
+ byte result = 0;
+ result |= (payload.get(index + 0) & 0xFF);
+ index += 1;
+ return (byte) result;
+ }
+
+ public short getShort() {
+ short result = 0;
+ result |= (payload.get(index + 1) & 0xFF) << 8;
+ result |= (payload.get(index + 0) & 0xFF);
+ index += 2;
+ return (short) result;
+ }
+
+ public int getInt() {
+ int result = 0;
+ result |= (payload.get(index + 3) & (int)0xFF) << 24;
+ result |= (payload.get(index + 2) & (int)0xFF) << 16;
+ result |= (payload.get(index + 1) & (int)0xFF) << 8;
+ result |= (payload.get(index + 0) & (int)0xFF);
+ index += 4;
+ return (int) result;
+ }
+
+ public long getLong() {
+ long result = 0;
+ result |= (payload.get(index + 7) & (long)0xFF) << 56;
+ result |= (payload.get(index + 6) & (long)0xFF) << 48;
+ result |= (payload.get(index + 5) & (long)0xFF) << 40;
+ result |= (payload.get(index + 4) & (long)0xFF) << 32;
+ result |= (payload.get(index + 3) & (long)0xFF) << 24;
+ result |= (payload.get(index + 2) & (long)0xFF) << 16;
+ result |= (payload.get(index + 1) & (long)0xFF) << 8;
+ result |= (payload.get(index + 0) & (long)0xFF);
+ index += 8;
+ return (long) result;
+ }
+
+
+ public long getLongReverse() {
+ long result = 0;
+ result |= (payload.get(index + 0) & (long)0xFF) << 56;
+ result |= (payload.get(index + 1) & (long)0xFF) << 48;
+ result |= (payload.get(index + 2) & (long)0xFF) << 40;
+ result |= (payload.get(index + 3) & (long)0xFF) << 32;
+ result |= (payload.get(index + 4) & (long)0xFF) << 24;
+ result |= (payload.get(index + 5) & (long)0xFF) << 16;
+ result |= (payload.get(index + 6) & (long)0xFF) << 8;
+ result |= (payload.get(index + 7) & (long)0xFF);
+ index += 8;
+ return (long) result;
+ }
+
+ public float getFloat() {
+ return Float.intBitsToFloat(getInt());
+ }
+
+ public void putByte(byte data) {
+ add(data);
+ }
+
+ public void putShort(short data) {
+ add((byte) (data >> 0));
+ add((byte) (data >> 8));
+ }
+
+ public void putInt(int data) {
+ add((byte) (data >> 0));
+ add((byte) (data >> 8));
+ add((byte) (data >> 16));
+ add((byte) (data >> 24));
+ }
+
+ public void putLong(long data) {
+ add((byte) (data >> 0));
+ add((byte) (data >> 8));
+ add((byte) (data >> 16));
+ add((byte) (data >> 24));
+ add((byte) (data >> 32));
+ add((byte) (data >> 40));
+ add((byte) (data >> 48));
+ add((byte) (data >> 56));
+ }
+
+ public void putFloat(float data) {
+ putInt(Float.floatToIntBits(data));
+ }
+
+}
diff --git a/mavlink-solo/pymavlink/generator/java/lib/Messages/MAVLinkStats.java b/mavlink-solo/pymavlink/generator/java/lib/Messages/MAVLinkStats.java
new file mode 100644
index 0000000..e9fa36e
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/java/lib/Messages/MAVLinkStats.java
@@ -0,0 +1,71 @@
+package com.MAVLink.Messages;
+
+import com.MAVLink.MAVLinkPacket;
+
+/**
+ * Storage for MAVLink Packet and Error statistics
+ *
+ */
+public class MAVLinkStats /* implements Serializable */{
+
+ public int receivedPacketCount;
+
+ public int crcErrorCount;
+
+ public int lostPacketCount;
+
+ private int lastPacketSeq;
+
+ /**
+ * Check the new received packet to see if has lost someone between this and
+ * the last packet
+ *
+ * @param packet
+ * Packet that should be checked
+ */
+ public void newPacket(MAVLinkPacket packet) {
+ advanceLastPacketSequence();
+ if (hasLostPackets(packet)) {
+ updateLostPacketCount(packet);
+ }
+ lastPacketSeq = packet.seq;
+ receivedPacketCount++;
+ }
+
+ private void updateLostPacketCount(MAVLinkPacket packet) {
+ int lostPackets;
+ if (packet.seq - lastPacketSeq < 0) {
+ lostPackets = (packet.seq - lastPacketSeq) + 255;
+ } else {
+ lostPackets = (packet.seq - lastPacketSeq);
+ }
+ lostPacketCount += lostPackets;
+ }
+
+ private boolean hasLostPackets(MAVLinkPacket packet) {
+ return lastPacketSeq > 0 && packet.seq != lastPacketSeq;
+ }
+
+ private void advanceLastPacketSequence() {
+ // wrap from 255 to 0 if necessary
+ lastPacketSeq = (lastPacketSeq + 1) & 0xFF;
+ }
+
+ /**
+ * Called when a CRC error happens on the parser
+ */
+ public void crcError() {
+ crcErrorCount++;
+ }
+
+ /**
+ * Resets statistics for this MAVLink.
+ */
+ public void mavlinkResetStats() {
+ lastPacketSeq = -1;
+ lostPacketCount = 0;
+ crcErrorCount = 0;
+ receivedPacketCount = 0;
+ }
+
+}
\ No newline at end of file
diff --git a/mavlink-solo/pymavlink/generator/java/lib/Parser.java b/mavlink-solo/pymavlink/generator/java/lib/Parser.java
new file mode 100644
index 0000000..cb31512
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/java/lib/Parser.java
@@ -0,0 +1,127 @@
+package com.MAVLink;
+
+import com.MAVLink.MAVLinkPacket;
+import com.MAVLink.Messages.MAVLinkStats;
+
+public class Parser {
+
+ /**
+ * States from the parsing state machine
+ */
+ enum MAV_states {
+ MAVLINK_PARSE_STATE_UNINIT, MAVLINK_PARSE_STATE_IDLE, MAVLINK_PARSE_STATE_GOT_STX, MAVLINK_PARSE_STATE_GOT_LENGTH, MAVLINK_PARSE_STATE_GOT_SEQ, MAVLINK_PARSE_STATE_GOT_SYSID, MAVLINK_PARSE_STATE_GOT_COMPID, MAVLINK_PARSE_STATE_GOT_MSGID, MAVLINK_PARSE_STATE_GOT_CRC1, MAVLINK_PARSE_STATE_GOT_PAYLOAD
+ }
+
+ MAV_states state = MAV_states.MAVLINK_PARSE_STATE_UNINIT;
+
+ static boolean msg_received;
+
+ public MAVLinkStats stats = new MAVLinkStats();
+ private MAVLinkPacket m;
+
+ /**
+ * This is a convenience function which handles the complete MAVLink
+ * parsing. the function will parse one byte at a time and return the
+ * complete packet once it could be successfully decoded. Checksum and other
+ * failures will be silently ignored.
+ *
+ * @param c
+ * The char to parse
+ */
+ public MAVLinkPacket mavlink_parse_char(int c) {
+ msg_received = false;
+
+ switch (state) {
+ case MAVLINK_PARSE_STATE_UNINIT:
+ case MAVLINK_PARSE_STATE_IDLE:
+
+ if (c == MAVLinkPacket.MAVLINK_STX) {
+ state = MAV_states.MAVLINK_PARSE_STATE_GOT_STX;
+ m = new MAVLinkPacket();
+ }
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_STX:
+ if (msg_received) {
+ msg_received = false;
+ state = MAV_states.MAVLINK_PARSE_STATE_IDLE;
+ } else {
+ m.len = c;
+ state = MAV_states.MAVLINK_PARSE_STATE_GOT_LENGTH;
+ }
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_LENGTH:
+ m.seq = c;
+ state = MAV_states.MAVLINK_PARSE_STATE_GOT_SEQ;
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_SEQ:
+ m.sysid = c;
+ state = MAV_states.MAVLINK_PARSE_STATE_GOT_SYSID;
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_SYSID:
+ m.compid = c;
+ state = MAV_states.MAVLINK_PARSE_STATE_GOT_COMPID;
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_COMPID:
+ m.msgid = c;
+ if (m.len == 0) {
+ state = MAV_states.MAVLINK_PARSE_STATE_GOT_PAYLOAD;
+ } else {
+ state = MAV_states.MAVLINK_PARSE_STATE_GOT_MSGID;
+ }
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_MSGID:
+ m.payload.add((byte) c);
+ if (m.payloadIsFilled()) {
+ state = MAV_states.MAVLINK_PARSE_STATE_GOT_PAYLOAD;
+ }
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_PAYLOAD:
+ m.generateCRC();
+ // Check first checksum byte
+ if (c != m.crc.getLSB()) {
+ msg_received = false;
+ state = MAV_states.MAVLINK_PARSE_STATE_IDLE;
+ if (c == MAVLinkPacket.MAVLINK_STX) {
+ state = MAV_states.MAVLINK_PARSE_STATE_GOT_STX;
+ m.crc.start_checksum();
+ }
+ stats.crcError();
+ } else {
+ state = MAV_states.MAVLINK_PARSE_STATE_GOT_CRC1;
+ }
+ break;
+
+ case MAVLINK_PARSE_STATE_GOT_CRC1:
+ // Check second checksum byte
+ if (c != m.crc.getMSB()) {
+ msg_received = false;
+ state = MAV_states.MAVLINK_PARSE_STATE_IDLE;
+ if (c == MAVLinkPacket.MAVLINK_STX) {
+ state = MAV_states.MAVLINK_PARSE_STATE_GOT_STX;
+ m.crc.start_checksum();
+ }
+ stats.crcError();
+ } else { // Successfully received the message
+ stats.newPacket(m);
+ msg_received = true;
+ state = MAV_states.MAVLINK_PARSE_STATE_IDLE;
+ }
+
+ break;
+
+ }
+ if (msg_received) {
+ return m;
+ } else {
+ return null;
+ }
+ }
+
+}
diff --git a/mavlink-solo/pymavlink/generator/javascript/.gitignore b/mavlink-solo/pymavlink/generator/javascript/.gitignore
new file mode 100644
index 0000000..6223d45
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/javascript/.gitignore
@@ -0,0 +1,3 @@
+implementations
+node_modules
+mocha.xml
diff --git a/mavlink-solo/pymavlink/generator/javascript/Makefile b/mavlink-solo/pymavlink/generator/javascript/Makefile
new file mode 100644
index 0000000..b8fbedf
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/javascript/Makefile
@@ -0,0 +1,11 @@
+all: clean
+ npm install
+
+test: all
+ mocha test
+
+ci: all
+ mocha --reporter xunit test > mocha.xml
+
+clean:
+ rm -rf implementations
\ No newline at end of file
diff --git a/mavlink-solo/pymavlink/generator/javascript/README.md b/mavlink-solo/pymavlink/generator/javascript/README.md
new file mode 100644
index 0000000..182dda2
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/javascript/README.md
@@ -0,0 +1,140 @@
+## Javascript MAVLink implementation ##
+
+This code generates ```npm``` modules that can be used with Node.js. As with the other implementations in Python and C, the MAVLink protocol is specified in XML manifests which can be modified to add custom messages.
+
+*See the gotcha's and todo's section below* for some important caveats. This implementation should be considered pre-beta: it creates a working MAVLink parser, but there's plenty of rough edges in terms of API.
+
+### Generating the JS implementation ###
+
+Folders in the ```implementations/``` directory are ```npm``` modules, automatically generated from XML manifests that are in the [mavlink/mavlink](https://github.com/mavlink/mavlink) project. If you wish to generate custom MAVLink packets, you would need to follow the directions there.
+
+You need to have Node.js and npm installed to build.
+
+To build the Javascript implementations:
+
+```bash
+npm install
+```
+
+or
+
+```bash
+make
+```
+
+(which calls npm)
+
+### Usage in Node.js ###
+
+The generated modules emit events when valid MAVLink messages are encountered. The name of the event is the same as the name of the message: ```HEARTBEAT```, ```FETCH_PARAM_LIST```, ```REQUEST_DATA_STREAM```, etc. In addition, a generic ```message``` event is emitted whenever a message is successfully decoded.
+
+The below code is a rough sketch of how to use the generated module in Node.js. A somewhat more complete (though early, early alpha) example can be found [here](https://github.com/acuasi/ground-control-station).
+
+#### Generating the parser
+
+After running the generator, copy the version of the MAVLink protocol you need into your project's ```node_modules``` folder, then enter that directory and install its dependencies using ```npm install```:
+
+```bash
+cp -R javascript/implementations/mavlink_ardupilotmega_v1.0 /path/to/my/project/node_modules/
+cd /path/to/my/project/node_modules/mavlink_ardupilotmega_v1.0 && npm install
+```
+
+Then, you can use the MAVLink module, as sketched below.
+
+#### Initializing the parser
+
+In your ```server.js``` script, you need to include the generated parser and instantiate it; you also need some kind of binary stream library that can read/write binary data and emit an event when new data is ready to be parsed (TCP, UDP, serial port all have appropriate libraries in the npm-o-sphere). The connection's "data is ready" event is bound to invoke the MAVLink parser to try and extract a valid message.
+
+```javascript
+// requires Underscore.js, can use Winston for logging ,
+// see package.json for dependencies for the implementation
+var mavlink = require('mavlink_ardupilotmega_v1.0'),
+ net = require('net');
+
+// Instantiate the parser
+// logger: pass a Winston logger or null if not used
+// 1: source system id
+// 50: source component id
+mavlinkParser = new MAVLink(logger, 1, 50);
+
+// Create a connection -- can be anything that can receive/send binary
+connection = net.createConnection(5760, '127.0.0.1');
+
+// When the connection issues a "got data" event, try and parse it
+connection.on('data', function(data) {
+ mavlinkParser.parseBuffer(data);
+});
+```
+
+#### Receiving MAVLink messages
+
+If the serial buffer has a valid MAVLink message, the message is removed from the buffer and parsed. Upon parsing a valid message, the MAVLink implementation emits two events: ```message``` (for any message) and the specific message name that was parsed, so you can listen for specific messages and handle them.
+
+```javascript
+// Attach an event handler for any valid MAVLink message
+mavlinkParser.on('message', function(message) {
+ console.log('Got a message of any type!');
+ console.log(message);
+});
+
+// Attach an event handler for a specific MAVLink message
+mavlinkParser.on('HEARTBEAT', function(message) {
+ console.log('Got a heartbeat message!');
+ console.log(message); // message is a HEARTBEAT message
+});
+```
+
+#### Sending MAVLink messages
+
+*See the gotcha's and todo's section below* for some important caveats. The below code is preliminary and *will* change to be more direct. At this point, the MAVLink parser doesn't manage any state information about the UAV or the connection itself, so a few fields need to be fudged, as indicated below.
+
+Sending a MAVLink message is done by creating the message object, populating its fields, and packing/sending it across the wire. Messages are defined in the generated code, and you can look up the parameter list/docs for each message type there. For example, the message ```REQUEST_DATA_STREAM``` has this signature:
+
+```javascript
+mavlink.messages.request_data_stream = function(target_system, target_component, req_stream_id, req_message_rate, start_stop) //...
+```
+
+Creating the message is done like this:
+
+```javascript
+request = new mavlink.messages.request_data_stream(1, 1, mavlink.MAV_DATA_STREAM_ALL, 1, 1);
+
+// Create a buffer consisting of the packed message, and send it across the wire.
+// You need to pass a MAVLink instance to pack. It will then take care of setting sequence number, system and component id.
+// Hack alert: the MAVLink connection could/should encapsulate this.
+p = new Buffer(request.pack(mavlinkParser));
+connection.write(p);
+```
+
+### Gotchas and todo's ###
+
+JavaScript doesn't have 64bit integers (long). The library that replaces Pythons struct converts ```q``` and ```Q``` into 3 part arrays: ```[lowBits, highBits, unsignedFlag]```. These arrays can be used with int64 libraries such as [Long.js](https://github.com/dcodeIO/Long.js). See [int64.js](https://github.com/AndreasAntener/node-jspack/blob/master/test/int64.js) for examples.
+
+Current implementation tries to be as robust as possible. It doesn't throw errors but emits bad_data messages. Also it discards the buffer of a possible message as soon as if finds a valid prefix. Future improvements:
+* Implement not so robust parsing: throw errors (similar to the Python version)
+* Implement trying hard: parse buffer char by char and don't just discard the expected length buffer if there is an error
+
+This code isn't great idiomatic Javascript (yet!), instead, it's more of a line-by-line translation from Python as much as possible.
+
+The Python MAVLink code manages some information about the connection status (system/component attached, bad packets, durations/times, etc), and that work isn't completely present in this code yet.
+
+Code to create/send MAVLink messages to a client is very clumsy at this point in time *and will change* to make it more direct.
+
+Publish generated scripts as npm module.
+
+### Development ###
+
+Unit tests cover basic packing/unpacking functionality against mock binary buffers representing valid MAVlink generated by the Python implementation. You need to have [mocha](http://visionmedia.github.com/mocha/) installed to run the unit tests.
+
+To run tests, use npm:
+
+```bash
+npm test
+```
+
+Specific instructions for generating Jenkins-friendly output is done through the makefile as well:
+
+```bash
+make ci
+```
+
diff --git a/mavlink-solo/pymavlink/generator/javascript/package.json b/mavlink-solo/pymavlink/generator/javascript/package.json
new file mode 100644
index 0000000..f464459
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/javascript/package.json
@@ -0,0 +1,22 @@
+{
+ "name" : "mavlink",
+ "version" : "0.0.1",
+ "description" : "Implementation of the MAVLink protocol for various platforms and both 0.9 and 1.0 revisions of MAVLink",
+ "repository": "private",
+ "dependencies" : {
+ "underscore" : "",
+ "winston": ""
+ },
+ "devDependencies" : {
+ "should" : "",
+ "mocha" : "",
+ "sinon" : ""
+ },
+ "scripts": {
+ "preinstall": "rm -rf implementations",
+ "install": "cd .. && ./gen_js.sh",
+
+ "pretest": "npm install",
+ "test": "mocha test"
+ }
+}
\ No newline at end of file
diff --git a/mavlink-solo/pymavlink/generator/javascript/test/capture.mavlink b/mavlink-solo/pymavlink/generator/javascript/test/capture.mavlink
new file mode 100644
index 0000000..08cd169
Binary files /dev/null and b/mavlink-solo/pymavlink/generator/javascript/test/capture.mavlink differ
diff --git a/mavlink-solo/pymavlink/generator/javascript/test/mavlink.js b/mavlink-solo/pymavlink/generator/javascript/test/mavlink.js
new file mode 100644
index 0000000..a4e3d37
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/javascript/test/mavlink.js
@@ -0,0 +1,302 @@
+var mavlink = require('../implementations/mavlink_common_v1.0/mavlink.js'),
+ should = require('should'),
+ sinon = require('sinon'),
+ fs = require('fs');
+
+// Actual data stream taken from APM.
+global.fixtures = global.fixtures || {};
+global.fixtures.serialStream = fs.readFileSync("test/capture.mavlink");
+//global.fixtures.heartbeatBinaryStream = fs.readFileSync("javascript/test/heartbeat-data-fixture");
+
+describe("Generated MAVLink protocol handler object", function() {
+
+ beforeEach(function() {
+ this.m = new MAVLink();
+
+ // Valid heartbeat payload
+ this.heartbeatPayload = new Buffer([0xfe, 0x09, 0x03, 0xff , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x06 , 0x08 , 0x00 , 0x00 , 0x03, 0x9f, 0x5c]);
+
+ // Complete but invalid message
+ this.completeInvalidMessage = new Buffer([0xfe, 0x00, 0xfe, 0x00, 0x00, 0xe0, 0x00, 0x00]);
+ });
+
+ describe("message header handling", function() {
+
+ it("IDs and sequence numbers are set on send", function(){
+ var mav = new MAVLink(null, 42, 99);
+ var writer = {
+ write: function(){}
+ };
+ mav.file = writer;
+ var spy = sinon.spy(writer, 'write');
+
+ var msg = new mavlink.messages['heartbeat']();
+ mav.send(msg);
+
+ spy.calledOnce.should.be.true;
+ spy.getCall(0).args[0][2].should.be.eql(0); // seq
+ spy.getCall(0).args[0][3].should.be.eql(42); // sys
+ spy.getCall(0).args[0][4].should.be.eql(99); // comp
+ });
+
+ it("sequence number increases on send", function(){
+ var mav = new MAVLink(null, 42, 99);
+ var writer = {
+ write: function(){}
+ };
+ mav.file = writer;
+ var spy = sinon.spy(writer, 'write');
+
+ var msg = new mavlink.messages['heartbeat']();
+ mav.send(msg);
+ mav.send(msg);
+
+ spy.callCount.should.be.eql(2);
+ spy.getCall(0).args[0][2].should.be.eql(0); // seq
+ spy.getCall(0).args[0][3].should.be.eql(42); // sys
+ spy.getCall(0).args[0][4].should.be.eql(99); // comp
+ spy.getCall(1).args[0][2].should.be.eql(1); // seq
+ spy.getCall(1).args[0][3].should.be.eql(42); // sys
+ spy.getCall(1).args[0][4].should.be.eql(99); // comp
+ });
+
+ it("sequence number turns over at 256", function(){
+ var mav = new MAVLink(null, 42, 99);
+ var writer = {
+ write: function(){}
+ };
+ mav.file = writer;
+ var spy = sinon.spy(writer, 'write');
+
+ var msg = new mavlink.messages['heartbeat']();
+
+ for(var i = 0; i < 258; i++){
+ mav.send(msg);
+ var seq = i % 256;
+ spy.getCall(i).args[0][2].should.be.eql(seq); // seq
+ }
+ });
+
+ });
+
+ describe("buffer decoder (parseBuffer)", function() {
+
+ // This test prepopulates a single message as a binary buffer.
+ it("decodes a binary stream representation of a single message correctly", function() {
+ this.m.pushBuffer(global.fixtures.heartbeatBinaryStream);
+ var messages = this.m.parseBuffer();
+
+ });
+
+ // This test includes a "noisy" signal, with non-mavlink data/messages/noise.
+ it("decodes a real serial binary stream into an array of MAVLink messages", function() {
+ this.m.pushBuffer(global.fixtures.serialStream);
+ var messages = this.m.parseBuffer();
+ });
+
+ it("decodes at most one message, even if there are more in its buffer", function() {
+
+ });
+
+ it("returns null while no packet is available", function() {
+ (this.m.parseBuffer() === null).should.equal(true); // should's a bit tortured here
+ });
+
+ });
+
+ describe("decoding chain (parseChar)", function() {
+
+ it("returns a bad_data message if a borked message is encountered", function() {
+ var b = new Buffer([3, 0, 1, 2, 3, 4, 5]); // invalid message
+ var message = this.m.parseChar(b);
+ message.should.be.an.instanceof(mavlink.messages.bad_data);
+ });
+
+ it("emits a 'message' event, provisioning callbacks with the message", function(done) {
+ this.m.on('message', function(message) {
+ message.should.be.an.instanceof(mavlink.messages.heartbeat);
+ done();
+ });
+ this.m.parseChar(this.heartbeatPayload);
+ });
+
+ it("emits a 'message' event for bad messages, provisioning callbacks with the message", function(done) {
+ var b = new Buffer([3, 0, 1, 2, 3, 4, 5]); // invalid message
+ this.m.on('message', function(message) {
+ message.should.be.an.instanceof(mavlink.messages.bad_data);
+ done();
+ });
+ this.m.parseChar(b);
+ });
+
+ it("on bad prefix: cuts-off first char in buffer and returns correct bad data", function() {
+ var b = new Buffer([3, 0, 1, 2, 3, 4, 5]); // invalid message
+ var message = this.m.parseChar(b);
+ message.msgbuf.length.should.be.eql(1);
+ message.msgbuf[0].should.be.eql(3);
+ this.m.buf.length.should.be.eql(6);
+ // should process next char
+ message = this.m.parseChar();
+ message.msgbuf.length.should.be.eql(1);
+ message.msgbuf[0].should.be.eql(0);
+ this.m.buf.length.should.be.eql(5);
+ });
+
+ it("on bad message: cuts-off message length and returns correct bad data", function() {
+ var message = this.m.parseChar(this.completeInvalidMessage);
+ message.msgbuf.length.should.be.eql(8);
+ message.msgbuf.should.be.eql(this.completeInvalidMessage);
+ this.m.buf.length.should.be.eql(0);
+ });
+
+ it("error counter is raised on error", function() {
+ var message = this.m.parseChar(this.completeInvalidMessage);
+ this.m.total_receive_errors.should.equal(1);
+ var message = this.m.parseChar(this.completeInvalidMessage);
+ this.m.total_receive_errors.should.equal(2);
+ });
+
+ // TODO: there is a option in python: robust_parsing. Maybe we should port this as well.
+ // If robust_parsing is off, the following should be tested:
+ // - (maybe) not returning subsequent errors for prefix errors
+ // - errors are thrown instead of catched inside
+
+ // TODO: add tests for "try hard" parsing when implemented
+
+ });
+
+ describe("stream buffer accumulator", function() {
+
+ it("increments total bytes received", function() {
+ this.m.total_bytes_received.should.equal(0);
+ var b = new Buffer(16);
+ b.fill("h");
+ this.m.pushBuffer(b);
+ this.m.total_bytes_received.should.equal(16);
+ });
+
+ it("appends data to its local buffer", function() {
+ this.m.buf.length.should.equal(0);
+ var b = new Buffer(16);
+ b.fill("h");
+ this.m.pushBuffer(b);
+ this.m.buf.should.eql(b); // eql = wiggly equality
+ });
+ });
+
+ describe("prefix decoder", function() {
+
+ it("consumes, unretrievably, the first byte of the buffer, if its a bad prefix", function() {
+
+ var b = new Buffer([1, 254]);
+ this.m.pushBuffer(b);
+
+ // eat the exception here.
+ try {
+ this.m.parsePrefix();
+ } catch (e) {
+ this.m.buf.length.should.equal(1);
+ this.m.buf[0].should.equal(254);
+ }
+
+ });
+
+ it("throws an exception if a malformed prefix is encountered", function() {
+
+ var b = new Buffer([15, 254, 1, 7, 7]); // borked system status packet, invalid
+ this.m.pushBuffer(b);
+ var m = this.m;
+ (function() { m.parsePrefix(); }).should.throw('Bad prefix (15)');
+
+ });
+
+ });
+
+ describe("length decoder", function() {
+ it("updates the expected length to the size of the expected full message", function() {
+ this.m.expected_length.should.equal(6); // default, header size
+ var b = new Buffer([254, 1, 1]); // packet length = 1
+ this.m.pushBuffer(b);
+ this.m.parseLength();
+ this.m.expected_length.should.equal(9); // 1+8 bytes for the message header
+ });
+ });
+
+ describe("payload decoder", function() {
+
+ it("resets the expected length of the next packet to 6 (header)", function() {
+ this.m.pushBuffer(this.heartbeatPayload);
+ this.m.parseLength(); // expected length should now be 9 (message) + 8 bytes (header) = 17
+ this.m.expected_length.should.equal(17);
+ this.m.parsePayload();
+ this.m.expected_length.should.equal(6);
+ });
+
+ it("submits a candidate message to the mavlink decode function", function() {
+
+ var spy = sinon.spy(this.m, 'decode');
+
+ this.m.pushBuffer(this.heartbeatPayload);
+ this.m.parseLength();
+ this.m.parsePayload();
+
+ // could improve this to check the args more closely.
+ // It'd be better but tricky because the type comparison doesn't quite work.
+ spy.called.should.be.true;
+
+ });
+
+ // invalid data should return bad_data message
+ it("parsePayload throws exception if a borked message is encountered", function() {
+ var b = new Buffer([3, 0, 1, 2, 3, 4, 5]); // invalid message
+ this.m.pushBuffer(b);
+ var message;
+ (function(){
+ message = this.m.parsePayload();
+ }).should.throw();
+ });
+
+ it("returns a valid mavlink packet if everything is OK", function() {
+ this.m.pushBuffer(this.heartbeatPayload);
+ this.m.parseLength();
+ var message = this.m.parsePayload();
+ message.should.be.an.instanceof(mavlink.messages.heartbeat);
+ });
+
+ it("increments the total packets received if a good packet is decoded", function() {
+ this.m.total_packets_received.should.equal(0);
+ this.m.pushBuffer(this.heartbeatPayload);
+ this.m.parseLength();
+ var message = this.m.parsePayload();
+ this.m.total_packets_received.should.equal(1);
+ });
+
+
+
+ });
+
+});
+
+
+describe("MAVLink X25CRC Decoder", function() {
+
+ beforeEach(function() {
+ // Message header + payload, lacks initial MAVLink flag (FE) and CRC.
+ this.heartbeatMessage = new Buffer([0x09, 0x03, 0xff , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x06 , 0x08 , 0x00 , 0x00 , 0x03]);
+
+ });
+
+ // This test matches the output directly taken by inspecting what the Python implementation
+ // generated for the above packet.
+ it('implements x25crc function', function() {
+ mavlink.x25Crc(this.heartbeatMessage).should.equal(27276);
+ });
+
+ // Heartbeat crc_extra value is 50.
+ it('can accumulate further bytes as needed (crc_extra)', function() {
+ var crc = mavlink.x25Crc(this.heartbeatMessage);
+ crc = mavlink.x25Crc([50], crc);
+ crc.should.eql(23711)
+ });
+
+});
\ No newline at end of file
diff --git a/mavlink-solo/pymavlink/generator/javascript/test/message.js b/mavlink-solo/pymavlink/generator/javascript/test/message.js
new file mode 100644
index 0000000..fae68c1
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/javascript/test/message.js
@@ -0,0 +1,252 @@
+var mavlink = require('../implementations/mavlink_common_v1.0/mavlink.js'),
+ should = require('should');
+
+describe('MAVLink message registry', function() {
+
+ it('defines constructors for every message', function() {
+ mavlink.messages['gps_raw_int'].should.be.a.function;
+ });
+
+ it('assigns message properties, format with int64 (q), gps_raw_int', function() {
+ var m = new mavlink.messages['gps_raw_int']();
+ m.format.should.equal(""
+__date__ = "08. August 2008"
+__version__ = "0.9.0"
+
+import string
+import os
+import re
+import copy
+from types import TupleType, StringTypes
+from xml.dom import EMPTY_PREFIX, EMPTY_NAMESPACE
+from xmlifUtils import processWhitespaceAction, NsNameTupleFactory, splitQName, nsNameToQName, escapeCdata, escapeAttribute
+
+
+########################################
+# XML interface base class
+# All not implemented methods have to be overloaded by the derived class!!
+#
+
+class XmlInterfaceBase:
+ """XML interface base class.
+
+ All not implemented methods have to be overloaded by the derived class!!
+ """
+
+ def __init__(self, verbose, useCaching, processXInclude):
+ """Constructor of class XmlInterfaceBase.
+
+ Input parameter:
+ 'verbose': 0 or 1: controls verbose print output for module genxmlif
+ 'useCaching': 0 or 1: controls usage of caching for module genxmlif
+ 'processXInclude': 0 or 1: controls XInclude processing during parsing
+ """
+
+ self.verbose = verbose
+ self.useCaching = useCaching
+ self.processXInclude = processXInclude
+
+ # set default wrapper classes
+ self.setTreeWrapperClass (XmlTreeWrapper)
+ self.setElementWrapperClass (XmlElementWrapper)
+
+
+ def createXmlTree (self, namespace, xmlRootTagName, attributeDict={}, publicId=None, systemId=None):
+ """Create a new XML TreeWrapper object (wrapper for DOM document or elementtree).
+
+ Input parameter:
+ 'namespace': not yet handled (for future use)
+ 'xmlRootTagName': specifies the tag name of the root element
+ 'attributeDict': contains the attributes of the root node (optional)
+ 'publicId': forwarded to contained DOM tree (unused for elementtree)
+ 'systemId': forwarded to contained DOM tree (unused for elementtree)
+ Returns the created XML tree wrapper object.
+ Method has to be implemented by derived classes!
+ """
+
+ raise NotImplementedError
+
+
+ def parse (self, filePath, baseUrl="", ownerDoc=None):
+ """Call the XML parser for 'file'.
+
+ Input parameter:
+ 'filePath': a file path or an URI
+ 'baseUrl': if specified, it is used e.g. as base path for schema files referenced inside the XML file.
+ 'ownerDoc': only used in case of 4DOM (forwarded to 4DOM parser).
+ Returns the respective XML tree wrapper object for the parsed XML file.
+ Method has to be implemented by derived classes!
+ """
+
+ raise NotImplementedError
+
+
+ def parseString (self, text, baseUrl="", ownerDoc=None):
+ """Call the XML parser for 'text'.
+
+ Input parameter:
+ 'text': contains the XML string to be parsed
+ 'baseUrl': if specified, it is used e.g. as base path for schema files referenced inside the XML string.
+ 'ownerDoc': only used in case of 4DOM (forwarded to 4DOM parser).
+ Returns the respective XML tree wrapper object for the parsed XML 'text' string.
+ Method has to be implemented by derived classes!
+ """
+ raise NotImplementedError
+
+
+ def setTreeWrapperClass (self, treeWrapperClass):
+ """Set the tree wrapper class which shall be used by this interface.
+
+ Input parameter:
+ treeWrapperClass: tree wrapper class
+ """
+ self.treeWrapperClass = treeWrapperClass
+
+
+ def setElementWrapperClass (self, elementWrapperClass):
+ """Set the element wrapper classes which shall be used by this interface.
+
+ Input parameter:
+ elementWrapperClass: element wrapper class
+ """
+ self.elementWrapperClass = elementWrapperClass
+
+
+ def getXmlIfType (self):
+ """Retrieve the type of the XML interface."""
+ return self.xmlIfType
+
+
+########################################
+# Tree wrapper API (interface class)
+#
+
+class XmlTreeWrapper:
+ """XML tree wrapper API.
+
+ Contains a DOM tree or an elementtree (depending on used XML parser)
+ """
+
+ def __init__(self, xmlIf, tree, useCaching):
+ """Constructor of wrapper class XmlTreeWrapper.
+
+ Input parameter:
+ 'xmlIf': used XML interface class
+ 'tree': DOM tree or elementtree which is wrapped by this object
+ 'useCaching': 1 if caching shall be used inside genxmlif, otherwise 0
+ """
+ self.xmlIf = xmlIf
+ self.__tree = tree
+ self.__useCaching = useCaching
+
+
+ def createElement (self, tupleOrLocalName, attributeDict=None, curNs=[]):
+ """Create an ElementWrapper object.
+
+ Input parameter:
+ tupleOrLocalName: tag name of element node to be created
+ (tuple of namespace and localName or only localName if no namespace is used)
+ attributeDict: attributes for this elements
+ curNs: namespaces for scope of this element
+ Returns an ElementWrapper object containing the created element node.
+ """
+ nsName = NsNameTupleFactory(tupleOrLocalName)
+ elementNode = self.__tree.xmlIfExtCreateElement(nsName, attributeDict, curNs)
+ return self.xmlIf.elementWrapperClass(elementNode, self, curNs)
+
+
+ def cloneTree (self):
+ """Creates a copy of a whole XML DOM tree."""
+ rootElementWrapperCopy = self.getRootNode().cloneNode(deep=1)
+ treeWrapperCopy = self.__class__(self.xmlIf,
+ self.__tree.xmlIfExtCloneTree(rootElementWrapperCopy.element),
+ self.__useCaching)
+ for elementWrapper in rootElementWrapperCopy.getIterator():
+ elementWrapper.treeWrapper = treeWrapperCopy
+ return treeWrapperCopy
+
+
+ def getRootNode (self):
+ """Retrieve the wrapper object of the root element of the contained XML tree.
+
+ Returns the ElementWrapper object of the root element.
+ """
+ return self.__tree.xmlIfExtGetRootNode().xmlIfExtElementWrapper
+
+
+ def getTree (self):
+ """Retrieve the contained XML tree.
+
+ Returns the contained XML tree object (internal DOM tree wrapper or elementtree).
+ """
+ return self.__tree
+
+
+ def printTree (self, prettyPrint=0, printElementValue=1, encoding=None):
+ """Return the string representation of the contained XML tree.
+
+ Input parameter:
+ 'prettyPrint': aligns the columns of the attributes of childNodes
+ 'printElementValue': controls if the lement values are printed or not.
+ Returns a string with the string representation of the whole XML tree.
+ """
+ if not encoding:
+ encoding = "utf-8"
+ if encoding != "utf-8" and encoding != "us-ascii":
+ text = "\n" % encoding
+ else:
+ text = ""
+ return text + self.getRootNode().printNode(deep=1, prettyPrint=prettyPrint, printElementValue=printElementValue, encoding=encoding)
+
+
+ def useCaching (self):
+ """Return 1 if caching should be used for the contained XML tree."""
+ return self.__useCaching
+
+
+ def setExternalCacheUsage (self, used):
+ """Set external cache usage for the whole tree
+ unlink commands are ignored if used by an external cache
+
+ Input parameter:
+ used: 0 or 1 (used by external cache)
+ """
+ self.getRootNode().setExternalCacheUsage (used, deep=1)
+
+
+ def unlink (self):
+ """Break circular references of the complete XML tree.
+
+ To be called if the XML tree is not longer used => garbage collection!
+ """
+ self.getRootNode().unlink()
+
+
+ def __str__ (self):
+ """Return the string representation of the contained XML tree."""
+ return self.printTree()
+
+
+
+########################################
+# Element wrapper API (interface class)
+#
+
+class XmlElementWrapper:
+ """XML element wrapper API.
+
+ Contains a XML element node
+ All not implemented methods have to be overloaded by the derived class!!
+ """
+
+ def __init__(self, element, treeWrapper, curNs=[], initAttrSeq=1):
+ """Constructor of wrapper class XmlElementWrapper.
+
+ Input parameter:
+ element: XML element node which is wrapped by this object
+ treeWrapper: XML tree wrapper class the current element belongs to
+ curNs: namespaces for scope of this element
+ """
+ self.element = element
+ self.element.xmlIfExtElementWrapper = self
+ self.treeWrapper = treeWrapper
+ self.nodeUsedByExternalCache = 0
+
+ if self.__useCaching():
+ self.__childrenCache = {}
+ self.__firstChildCache = {}
+ self.__qNameAttrCache = {}
+
+ self.baseUrl = None
+ self.absUrl = None
+ self.filePath = None
+ self.startLineNumber = None
+ self.endLineNumber = None
+ self.curNs = curNs[:]
+ self.attributeSequence = []
+
+ if initAttrSeq:
+ self.attributeSequence = self.getAttributeDict().keys()
+
+
+ def unlink (self):
+ """Break circular references of this element and its children."""
+ for childWrapper in self.getChildren():
+ childWrapper.unlink()
+ if not self.isUsedByExternalCache():
+ self.element.xmlIfExtUnlink()
+
+
+ def cloneNode (self, deep, cloneCallback=None):
+ """Create a copy of the current element wrapper.
+ The reference to the parent node is set to None!"""
+ elementCopy = self.element.xmlIfExtCloneNode()
+ elementWrapperCopy = self.__class__(elementCopy, self.treeWrapper, initAttrSeq=0)
+ elementWrapperCopy.treeWrapper = None
+ elementWrapperCopy.baseUrl = self.baseUrl
+ elementWrapperCopy.absUrl = self.absUrl
+ elementWrapperCopy.filePath = self.filePath
+ elementWrapperCopy.startLineNumber = self.startLineNumber
+ elementWrapperCopy.endLineNumber = self.endLineNumber
+ elementWrapperCopy.curNs = self.curNs[:]
+ elementWrapperCopy.attributeSequence = self.attributeSequence[:]
+ if cloneCallback: cloneCallback(elementWrapperCopy)
+ if deep:
+ for childElement in self.element.xmlIfExtGetChildren():
+ childWrapperElementCopy = childElement.xmlIfExtElementWrapper.cloneNode(deep, cloneCallback)
+ childWrapperElementCopy.element.xmlIfExtSetParentNode(elementWrapperCopy.element)
+ elementWrapperCopy.element.xmlIfExtAppendChild(childWrapperElementCopy.element)
+ return elementWrapperCopy
+
+
+ def clearNodeCache (self):
+ """Clear all caches used by this element wrapper which contains element wrapper references."""
+ self.__clearChildrenCache()
+
+
+ def isUsedByExternalCache (self):
+ """Check if this node is used by an external cache.
+ unlink commands are ignored if used by an external cache"""
+ return self.nodeUsedByExternalCache
+
+
+ def setExternalCacheUsage (self, used, deep=1):
+ """Set external cache usage for this node and its children
+ unlink commands are ignored if used by an external cache
+
+ Input parameter:
+ used: 0 or 1 (used by external cache)
+ deep: 0 or 1: controls if the child elements are also marked as used by external cache
+ """
+ self.nodeUsedByExternalCache = used
+ if deep:
+ for childWrapper in self.getChildren():
+ childWrapper.setExternalCacheUsage (used, deep)
+
+
+
+ ##########################################################
+ # attributes of the current node can be accessed via key operator
+
+ def __getitem__(self, tupleOrAttrName):
+ """Attributes of the contained element node can be accessed via key operator.
+
+ Input parameter:
+ tupleOrAttrName: name of the attribute (tuple of namespace and attributeName or only attributeName)
+ Returns the attribute value.
+ """
+ attrValue = self.getAttribute (tupleOrAttrName)
+ if attrValue != None:
+ return attrValue
+ else:
+ raise AttributeError, "Attribute %s not found!" %(repr(tupleOrAttrName))
+
+
+ def __setitem__(self, tupleOrAttrName, attributeValue):
+ """Attributes of the contained element node can be accessed via key operator.
+
+ Input parameter:
+ tupleOrAttrName: name of the attribute (tuple of namespace and attributeName or only attributeName)
+ attributeValue: attribute value to be set
+ """
+ self.setAttribute (tupleOrAttrName, attributeValue)
+
+
+#++++++++++++ methods concerning the tag name ++++++++++++++++++++++++
+
+ def getTagName (self):
+ """Retrieve the (complete) tag name of the contained element node
+
+ Returns the (complete) tag name of the contained element node
+ """
+ return self.element.xmlIfExtGetTagName()
+
+
+ def getLocalName (self):
+ """Retrieve the local name (without namespace) of the contained element node
+
+ Returns the local name (without namespace) of the contained element node
+ """
+
+ try:
+ return self.__localNameCache
+ except:
+ prefix, localName = splitQName (self.getTagName())
+ if self.__useCaching():
+ self.__localNameCache = localName
+ return localName
+
+
+ def getNamespaceURI (self):
+ """Retrieve the namespace URI of the contained element node
+
+ Returns the namespace URI of the contained element node (None if no namespace is used).
+ """
+ try:
+ return self.__nsUriCache
+ except:
+ prefix = self.element.xmlIfExtGetNamespaceURI()
+ if self.__useCaching():
+ self.__nsUriCache = prefix
+ return prefix
+
+
+ def getNsName (self):
+ """Retrieve a tuple (namespace, localName) of the contained element node
+
+ Returns a tuple (namespace, localName) of the contained element node (namespace is None if no namespace is used).
+ """
+ try:
+ return self.__nsNameCache
+ except:
+ nsName = NsNameTupleFactory( (self.getNamespaceURI(), self.getLocalName()) )
+ if self.__useCaching():
+ self.__nsNameCache = nsName
+ return nsName
+
+
+ def getQName (self):
+ """Retrieve a string prefix and localName of the contained element node
+
+ Returns a string "prefix:localName" of the contained element node
+ """
+ return self.nsName2QName(self.getNsName())
+
+
+ def getPrefix (self):
+ """Retrieve the namespace prefix of the contained element node
+
+ Returns the namespace prefix of the contained element node (None if no namespace is used).
+ """
+ return self.getNsPrefix(self.getNsName())
+
+
+#++++++++++++ methods concerning print support ++++++++++++++++++++++++
+
+ def __str__ (self):
+ """Retrieve the textual representation of the contained element node."""
+ return self.printNode()
+
+
+ def printNode (self, indent="", deep=0, prettyPrint=0, attrMaxLengthDict={}, printElementValue=1, encoding=None):
+ """Retrieve the textual representation of the contained element node.
+
+ Input parameter:
+ indent: indentation to be used for string representation
+ deep: 0 or 1: controls if the child element nodes are also printed
+ prettyPrint: aligns the columns of the attributes of childNodes
+ attrMaxLengthDict: dictionary containing the length of the attribute values (used for prettyprint)
+ printElementValue: 0 or 1: controls if the element value is printed
+ Returns the string representation
+ """
+ patternXmlTagShort = '''\
+%(indent)s<%(qName)s%(attributeString)s/>%(tailText)s%(lf)s'''
+
+ patternXmlTagLong = '''\
+%(indent)s<%(qName)s%(attributeString)s>%(elementValueString)s\
+%(lf)s%(subTreeString)s\
+%(indent)s%(qName)s>%(tailText)s%(lf)s'''
+
+ subTreeStringList = []
+ tailText = ""
+ addIndent = ""
+ lf = ""
+ if deep:
+ childAttrMaxLengthDict = {}
+ if prettyPrint:
+ for childNode in self.getChildren():
+ childNode.__updateAttrMaxLengthDict(childAttrMaxLengthDict)
+ lf = "\n"
+ addIndent = " "
+ for childNode in self.getChildren():
+ subTreeStringList.append (childNode.printNode(indent + addIndent, deep, prettyPrint, childAttrMaxLengthDict, printElementValue))
+ tailText = escapeCdata(self.element.xmlIfExtGetElementTailText(), encoding)
+
+ attributeStringList = []
+ for attrName in self.getAttributeList():
+ attrValue = escapeAttribute(self.getAttribute(attrName), encoding)
+ if prettyPrint:
+ try:
+ align = attrMaxLengthDict[attrName]
+ except:
+ align = len(attrValue)
+ else:
+ align = len(attrValue)
+ qName = self.nsName2QName(attrName)
+ attributeStringList.append (' %s="%s"%*s' %(qName, attrValue, align - len(attrValue), ""))
+ attributeString = string.join (attributeStringList, "")
+
+ qName = self.getQName()
+ if printElementValue:
+ if deep:
+ elementValueString = escapeCdata(self.element.xmlIfExtGetElementText(), encoding)
+ else:
+ elementValueString = escapeCdata(self.getElementValue(ignoreEmtpyStringFragments=1), encoding)
+ else:
+ elementValueString = ""
+
+ if subTreeStringList == [] and elementValueString == "":
+ printPattern = patternXmlTagShort
+ else:
+ if subTreeStringList != []:
+ subTreeString = string.join (subTreeStringList, "")
+ else:
+ subTreeString = ""
+ printPattern = patternXmlTagLong
+ return printPattern % vars()
+
+
+#++++++++++++ methods concerning the parent of the current node ++++++++++++++++++++++++
+
+ def getParentNode (self):
+ """Retrieve the ElementWrapper object of the parent element node.
+
+ Returns the ElementWrapper object of the parent element node.
+ """
+ parent = self.element.xmlIfExtGetParentNode()
+ if parent != None:
+ return parent.xmlIfExtElementWrapper
+ else:
+ return None
+
+
+#++++++++++++ methods concerning the children of the current node ++++++++++++++++++++++++
+
+
+ def getChildren (self, tagFilter=None):
+ """Retrieve the ElementWrapper objects of the children element nodes.
+
+ Input parameter:
+ tagFilter: retrieve only the children with this tag name ('*' or None returns all children)
+ Returns all children of this element node which match 'tagFilter' (list)
+ """
+ if tagFilter in (None, '*', (None, '*')):
+ children = self.element.xmlIfExtGetChildren()
+ elif tagFilter[1] == '*':
+ # handle (namespace, '*')
+ children = filter(lambda child:child.xmlIfExtElementWrapper.getNamespaceURI() == tagFilter[0],
+ self.element.xmlIfExtGetChildren())
+ else:
+ nsNameFilter = NsNameTupleFactory(tagFilter)
+ try:
+ children = self.__childrenCache[nsNameFilter]
+ except:
+ children = self.element.xmlIfExtGetChildren(nsNameFilter)
+ if self.__useCaching():
+ self.__childrenCache[nsNameFilter] = children
+
+ return map(lambda child: child.xmlIfExtElementWrapper, children)
+
+
+ def getChildrenNS (self, namespaceURI, tagFilter=None):
+ """Retrieve the ElementWrapper objects of the children element nodes using a namespace.
+
+ Input parameter:
+ namespaceURI: the namespace URI of the children or None
+ tagFilter: retrieve only the children with this localName ('*' or None returns all children)
+ Returns all children of this element node which match 'namespaceURI' and 'tagFilter' (list)
+ """
+ return self.getChildren((namespaceURI, tagFilter))
+
+
+ def getChildrenWithKey (self, tagFilter=None, keyAttr=None, keyValue=None):
+ """Retrieve the ElementWrapper objects of the children element nodes.
+
+ Input parameter:
+ tagFilter: retrieve only the children with this tag name ('*' or None returns all children)
+ keyAttr: name of the key attribute
+ keyValue: value of the key
+ Returns all children of this element node which match 'tagFilter' (list)
+ """
+ children = self.getChildren(tagFilter)
+ return filter(lambda child:child[keyAttr]==keyValue, children)
+
+
+ def getFirstChild (self, tagFilter=None):
+ """Retrieve the ElementWrapper objects of the first child element node.
+
+ Input parameter:
+ tagFilter: retrieve only the first child with this tag name ('*' or None: no filter)
+ Returns the first child of this element node which match 'tagFilter'
+ or None if no suitable child element was found
+ """
+ if tagFilter in (None, '*', (None, '*')):
+ element = self.element.xmlIfExtGetFirstChild()
+ elif tagFilter[1] == '*':
+ # handle (namespace, '*')
+ children = filter(lambda child:child.xmlIfExtElementWrapper.getNamespaceURI() == tagFilter[0],
+ self.element.xmlIfExtGetChildren())
+ try:
+ element = children[0]
+ except:
+ element = None
+ else:
+ nsNameFilter = NsNameTupleFactory(tagFilter)
+ try:
+ element = self.__firstChildCache[nsNameFilter]
+ except:
+ element = self.element.xmlIfExtGetFirstChild(nsNameFilter)
+ if self.__useCaching():
+ self.__firstChildCache[nsNameFilter] = element
+
+ if element != None:
+ return element.xmlIfExtElementWrapper
+ else:
+ return None
+
+
+ def getFirstChildNS (self, namespaceURI, tagFilter=None):
+ """Retrieve the ElementWrapper objects of the first child element node using a namespace.
+
+ Input parameter:
+ namespaceURI: the namespace URI of the children or None
+ tagFilter: retrieve only the first child with this localName ('*' or None: no filter)
+ Returns the first child of this element node which match 'namespaceURI' and 'tagFilter'
+ or None if no suitable child element was found
+ """
+ return self.getFirstChild ((namespaceURI, tagFilter))
+
+
+ def getFirstChildWithKey (self, tagFilter=None, keyAttr=None, keyValue=None):
+ """Retrieve the ElementWrapper objects of the children element nodes.
+
+ Input parameter:
+ tagFilter: retrieve only the children with this tag name ('*' or None returns all children)
+ keyAttr: name of the key attribute
+ keyValue: value of the key
+ Returns all children of this element node which match 'tagFilter' (list)
+ """
+ children = self.getChildren(tagFilter)
+ childrenWithKey = filter(lambda child:child[keyAttr]==keyValue, children)
+ if childrenWithKey != []:
+ return childrenWithKey[0]
+ else:
+ return None
+
+
+ def getElementsByTagName (self, tagFilter=None):
+ """Retrieve all descendant ElementWrapper object of current node whose tag name match 'tagFilter'.
+
+ Input parameter:
+ tagFilter: retrieve only the children with this tag name ('*' or None returns all descendants)
+ Returns all descendants of this element node which match 'tagFilter' (list)
+ """
+ if tagFilter in (None, '*', (None, '*'), (None, None)):
+ descendants = self.element.xmlIfExtGetElementsByTagName()
+
+ elif tagFilter[1] == '*':
+ # handle (namespace, '*')
+ descendants = filter(lambda desc:desc.xmlIfExtElementWrapper.getNamespaceURI() == tagFilter[0],
+ self.element.xmlIfExtGetElementsByTagName())
+ else:
+ nsNameFilter = NsNameTupleFactory(tagFilter)
+ descendants = self.element.xmlIfExtGetElementsByTagName(nsNameFilter)
+
+ return map(lambda descendant: descendant.xmlIfExtElementWrapper, descendants)
+
+
+ def getElementsByTagNameNS (self, namespaceURI, tagFilter=None):
+ """Retrieve all descendant ElementWrapper object of current node whose tag name match 'namespaceURI' and 'tagFilter'.
+
+ Input parameter:
+ namespaceURI: the namespace URI of the descendants or None
+ tagFilter: retrieve only the descendants with this localName ('*' or None returns all descendants)
+ Returns all descendants of this element node which match 'namespaceURI' and 'tagFilter' (list)
+ """
+ return self.getElementsByTagName((namespaceURI, tagFilter))
+
+
+ def getIterator (self, tagFilter=None):
+ """Creates a tree iterator. The iterator loops over this element
+ and all subelements, in document order, and returns all elements
+ whose tag name match 'tagFilter'.
+
+ Input parameter:
+ tagFilter: retrieve only the children with this tag name ('*' or None returns all descendants)
+ Returns all element nodes which match 'tagFilter' (list)
+ """
+ if tagFilter in (None, '*', (None, '*'), (None, None)):
+ matchingElements = self.element.xmlIfExtGetIterator()
+ elif tagFilter[1] == '*':
+ # handle (namespace, '*')
+ matchingElements = filter(lambda desc:desc.xmlIfExtElementWrapper.getNamespaceURI() == tagFilter[0],
+ self.element.xmlIfExtGetIterator())
+ else:
+ nsNameFilter = NsNameTupleFactory(tagFilter)
+ matchingElements = self.element.xmlIfExtGetIterator(nsNameFilter)
+
+ return map(lambda e: e.xmlIfExtElementWrapper, matchingElements)
+
+
+ def appendChild (self, tupleOrLocalNameOrElement, attributeDict={}):
+ """Append an element node to the children of the current node.
+
+ Input parameter:
+ tupleOrLocalNameOrElement: (namespace, localName) or tagName or ElementWrapper object of the new child
+ attributeDict: attribute dictionary containing the attributes of the new child (optional)
+ If not an ElementWrapper object is given, a new ElementWrapper object is created with tupleOrLocalName
+ Returns the ElementWrapper object of the new child.
+ """
+ if not isinstance(tupleOrLocalNameOrElement, self.__class__):
+ childElementWrapper = self.__createElement (tupleOrLocalNameOrElement, attributeDict)
+ else:
+ childElementWrapper = tupleOrLocalNameOrElement
+ self.element.xmlIfExtAppendChild (childElementWrapper.element)
+ self.__clearChildrenCache(childElementWrapper.getNsName())
+ return childElementWrapper
+
+
+ def insertBefore (self, tupleOrLocalNameOrElement, refChild, attributeDict={}):
+ """Insert an child element node before the given reference child of the current node.
+
+ Input parameter:
+ tupleOrLocalNameOrElement: (namespace, localName) or tagName or ElementWrapper object of the new child
+ refChild: reference child ElementWrapper object
+ attributeDict: attribute dictionary containing the attributes of the new child (optional)
+ If not an ElementWrapper object is given, a new ElementWrapper object is created with tupleOrLocalName
+ Returns the ElementWrapper object of the new child.
+ """
+ if not isinstance(tupleOrLocalNameOrElement, self.__class__):
+ childElementWrapper = self.__createElement (tupleOrLocalNameOrElement, attributeDict)
+ else:
+ childElementWrapper = tupleOrLocalNameOrElement
+ if refChild == None:
+ self.appendChild (childElementWrapper)
+ else:
+ self.element.xmlIfExtInsertBefore(childElementWrapper.element, refChild.element)
+ self.__clearChildrenCache(childElementWrapper.getNsName())
+ return childElementWrapper
+
+
+ def removeChild (self, childElementWrapper):
+ """Remove the given child element node from the children of the current node.
+
+ Input parameter:
+ childElementWrapper: ElementWrapper object to be removed
+ """
+ self.element.xmlIfExtRemoveChild(childElementWrapper.element)
+ self.__clearChildrenCache(childElementWrapper.getNsName())
+
+
+ def insertSubtree (self, refChildWrapper, subTreeWrapper, insertSubTreeRootNode=1):
+ """Insert the given subtree before 'refChildWrapper' ('refChildWrapper' is not removed!)
+
+ Input parameter:
+ refChildWrapper: reference child ElementWrapper object
+ subTreeWrapper: subtree wrapper object which contains the subtree to be inserted
+ insertSubTreeRootNode: if 1, root node of subtree is inserted into parent tree, otherwise not
+ """
+ if refChildWrapper != None:
+ self.element.xmlIfExtInsertSubtree (refChildWrapper.element, subTreeWrapper.getTree(), insertSubTreeRootNode)
+ else:
+ self.element.xmlIfExtInsertSubtree (None, subTreeWrapper.getTree(), insertSubTreeRootNode)
+ self.__clearChildrenCache()
+
+
+
+ def replaceChildBySubtree (self, childElementWrapper, subTreeWrapper, insertSubTreeRootNode=1):
+ """Replace child element node by XML subtree (e.g. expanding included XML files)
+
+ Input parameter:
+ childElementWrapper: ElementWrapper object to be replaced
+ subTreeWrapper: XML subtree wrapper object to be inserted
+ insertSubTreeRootNode: if 1, root node of subtree is inserted into parent tree, otherwise not
+ """
+ self.insertSubtree (childElementWrapper, subTreeWrapper, insertSubTreeRootNode)
+ self.removeChild(childElementWrapper)
+
+
+#++++++++++++ methods concerning the attributes of the current node ++++++++++++++++++++++++
+
+ def getAttributeDict (self):
+ """Retrieve a dictionary containing all attributes of the current element node.
+
+ Returns a dictionary (copy) containing all attributes of the current element node.
+ """
+ return self.element.xmlIfExtGetAttributeDict()
+
+
+ def getAttributeList (self):
+ """Retrieve a list containing all attributes of the current element node
+ in the sequence specified in the input XML file.
+
+ Returns a list (copy) containing all attributes of the current element node
+ in the sequence specified in the input XML file (TODO: does currently not work for 4DOM/pyXML interface).
+ """
+ attrList = map(lambda a: NsNameTupleFactory(a), self.attributeSequence)
+ return attrList
+
+
+ def getAttribute (self, tupleOrAttrName):
+ """Retrieve an attribute value of the current element node.
+
+ Input parameter:
+ tupleOrAttrName: tuple '(namespace, attributeName)' or 'attributeName' if no namespace is used
+ Returns the value of the specified attribute.
+ """
+ nsName = NsNameTupleFactory(tupleOrAttrName)
+ return self.element.xmlIfExtGetAttribute(nsName)
+
+
+ def getAttributeOrDefault (self, tupleOrAttrName, defaultValue):
+ """Retrieve an attribute value of the current element node or the given default value if the attribute doesn't exist.
+
+ Input parameter:
+ tupleOrAttrName: tuple '(namespace, attributeName)' or 'attributeName' if no namespace is used
+ Returns the value of the specified attribute or the given default value if the attribute doesn't exist.
+ """
+ attributeValue = self.getAttribute (tupleOrAttrName)
+ if attributeValue == None:
+ attributeValue = defaultValue
+ return attributeValue
+
+
+ def getQNameAttribute (self, tupleOrAttrName):
+ """Retrieve a QName attribute value of the current element node.
+
+ Input parameter:
+ tupleOrAttrName: tuple '(namespace, attributeName)' or 'attributeName' if no namespace is used
+ Returns the value of the specified QName attribute as tuple (namespace, localName),
+ i.e. the prefix is converted into the corresponding namespace value.
+ """
+ nsNameAttrName = NsNameTupleFactory(tupleOrAttrName)
+ try:
+ return self.__qNameAttrCache[nsNameAttrName]
+ except:
+ qNameValue = self.getAttribute (nsNameAttrName)
+ nsNameValue = self.qName2NsName(qNameValue, useDefaultNs=1)
+ if self.__useCaching():
+ self.__qNameAttrCache[nsNameAttrName] = nsNameValue
+ return nsNameValue
+
+
+ def hasAttribute (self, tupleOrAttrName):
+ """Checks if the requested attribute exist for the current element node.
+
+ Returns 1 if the attribute exists, otherwise 0.
+ """
+ nsName = NsNameTupleFactory(tupleOrAttrName)
+ attrValue = self.element.xmlIfExtGetAttribute(nsName)
+ if attrValue != None:
+ return 1
+ else:
+ return 0
+
+
+ def setAttribute (self, tupleOrAttrName, attributeValue):
+ """Sets an attribute value of the current element node.
+ If the attribute does not yet exist, it will be created.
+
+ Input parameter:
+ tupleOrAttrName: tuple '(namespace, attributeName)' or 'attributeName' if no namespace is used
+ attributeValue: attribute value to be set
+ """
+ if not isinstance(attributeValue, StringTypes):
+ raise TypeError, "%s (attribute %s) must be a string!" %(repr(attributeValue), repr(tupleOrAttrName))
+
+ nsNameAttrName = NsNameTupleFactory(tupleOrAttrName)
+ if nsNameAttrName not in self.attributeSequence:
+ self.attributeSequence.append(nsNameAttrName)
+
+ if self.__useCaching():
+ if self.__qNameAttrCache.has_key(nsNameAttrName):
+ del self.__qNameAttrCache[nsNameAttrName]
+
+ self.element.xmlIfExtSetAttribute(nsNameAttrName, attributeValue, self.getCurrentNamespaces())
+
+
+ def setAttributeDefault (self, tupleOrAttrName, defaultValue):
+ """Create attribute and set value to default if it does not yet exist for the current element node.
+ If the attribute is already existing nothing is done.
+
+ Input parameter:
+ tupleOrAttrName: tuple '(namespace, attributeName)' or 'attributeName' if no namespace is used
+ defaultValue: default attribute value to be set
+ """
+ if not self.hasAttribute(tupleOrAttrName):
+ self.setAttribute(tupleOrAttrName, defaultValue)
+
+
+ def removeAttribute (self, tupleOrAttrName):
+ """Removes an attribute from the current element node.
+ No exception is raised if there is no matching attribute.
+
+ Input parameter:
+ tupleOrAttrName: tuple '(namespace, attributeName)' or 'attributeName' if no namespace is used
+ """
+ nsNameAttrName = NsNameTupleFactory(tupleOrAttrName)
+
+ if self.__useCaching():
+ if self.__qNameAttrCache.has_key(nsNameAttrName):
+ del self.__qNameAttrCache[nsNameAttrName]
+
+ self.element.xmlIfExtRemoveAttribute(nsNameAttrName)
+
+
+ def processWsAttribute (self, tupleOrAttrName, wsAction):
+ """Process white space action for the specified attribute according to requested 'wsAction'.
+
+ Input parameter:
+ tupleOrAttrName: tuple '(namespace, attributeName)' or 'attributeName' if no namespace is used
+ wsAction: 'collapse': substitute multiple whitespace characters by a single ' '
+ 'replace': substitute each whitespace characters by a single ' '
+ """
+ attributeValue = self.getAttribute(tupleOrAttrName)
+ newValue = processWhitespaceAction (attributeValue, wsAction)
+ if newValue != attributeValue:
+ self.setAttribute(tupleOrAttrName, newValue)
+ return newValue
+
+
+#++++++++++++ methods concerning the content of the current node ++++++++++++++++++++++++
+
+ def getElementValue (self, ignoreEmtpyStringFragments=0):
+ """Retrieve the content of the current element node.
+
+ Returns the content of the current element node as string.
+ The content of multiple text nodes / CDATA nodes are concatenated to one string.
+
+ Input parameter:
+ ignoreEmtpyStringFragments: if 1, text nodes containing only whitespaces are ignored
+ """
+ return "".join (self.getElementValueFragments(ignoreEmtpyStringFragments))
+
+
+ def getElementValueFragments (self, ignoreEmtpyStringFragments=0):
+ """Retrieve the content of the current element node as value fragment list.
+
+ Returns the content of the current element node as list of string fragments.
+ Each list element represents one text nodes / CDATA node.
+
+ Input parameter:
+ ignoreEmtpyStringFragments: if 1, text nodes containing only whitespaces are ignored
+
+ Method has to be implemented by derived classes!
+ """
+ return self.element.xmlIfExtGetElementValueFragments (ignoreEmtpyStringFragments)
+
+
+ def setElementValue (self, elementValue):
+ """Set the content of the current element node.
+
+ Input parameter:
+ elementValue: string containing the new element value
+ If multiple text nodes / CDATA nodes are existing, 'elementValue' is set
+ for the first text node / CDATA node. All other text nodes /CDATA nodes are set to ''.
+ """
+ self.element.xmlIfExtSetElementValue(elementValue)
+
+
+ def processWsElementValue (self, wsAction):
+ """Process white space action for the content of the current element node according to requested 'wsAction'.
+
+ Input parameter:
+ wsAction: 'collapse': substitute multiple whitespace characters by a single ' '
+ 'replace': substitute each whitespace characters by a single ' '
+ """
+ self.element.xmlIfExtProcessWsElementValue(wsAction)
+ return self.getElementValue()
+
+
+#++++++++++++ methods concerning the info about the current node in the XML file ++++++++++++++++++++
+
+
+ def getStartLineNumber (self):
+ """Retrieve the start line number of the current element node.
+
+ Returns the start line number of the current element node in the XML file
+ """
+ return self.startLineNumber
+
+
+ def getEndLineNumber (self):
+ """Retrieve the end line number of the current element node.
+
+ Returns the end line number of the current element node in the XML file
+ """
+ return self.endLineNumber
+
+
+ def getAbsUrl (self):
+ """Retrieve the absolute URL of the XML file the current element node belongs to.
+
+ Returns the absolute URL of the XML file the current element node belongs to.
+ """
+ return self.absUrl
+
+
+ def getBaseUrl (self):
+ """Retrieve the base URL of the XML file the current element node belongs to.
+
+ Returns the base URL of the XML file the current element node belongs to.
+ """
+ return self.baseUrl
+
+
+ def getFilePath (self):
+ """Retrieve the file path of the XML file the current element node belongs to.
+
+ Returns the file path of the XML file the current element node belongs to.
+ """
+ return self.filePath
+
+
+ def getLocation (self, end=0, fullpath=0):
+ """Retrieve a string containing file name and line number of the current element node.
+
+ Input parameter:
+ end: 1 if end line number shall be shown, 0 for start line number
+ fullpath: 1 if the full path of the XML file shall be shown, 0 for only the file name
+ Returns a string containing file name and line number of the current element node.
+ (e.g. to be used for traces or error messages)
+ """
+ lineMethod = (self.getStartLineNumber, self.getEndLineNumber)
+ pathFunc = (os.path.basename, os.path.abspath)
+ return "%s, %d" % (pathFunc[fullpath](self.getFilePath()), lineMethod[end]())
+
+
+#++++++++++++ miscellaneous methods concerning namespaces ++++++++++++++++++++
+
+
+ def getCurrentNamespaces (self):
+ """Retrieve the namespace prefixes visible for the current element node
+
+ Returns a list of the namespace prefixes visible for the current node.
+ """
+ return self.curNs
+
+
+ def qName2NsName (self, qName, useDefaultNs):
+ """Convert a qName 'prefix:localName' to a tuple '(namespace, localName)'.
+
+ Input parameter:
+ qName: qName to be converted
+ useDefaultNs: 1 if default namespace shall be used
+ Returns the corresponding tuple '(namespace, localName)' for 'qName'.
+ """
+ if qName != None:
+ qNamePrefix, qNameLocalName = splitQName (qName)
+ for prefix, namespaceURI in self.getCurrentNamespaces():
+ if qNamePrefix == prefix:
+ if prefix != EMPTY_PREFIX or useDefaultNs:
+ nsName = (namespaceURI, qNameLocalName)
+ break
+ else:
+ if qNamePrefix == None:
+ nsName = (EMPTY_NAMESPACE, qNameLocalName)
+ else:
+ raise ValueError, "Namespace prefix '%s' not bound to a namespace!" % (qNamePrefix)
+ else:
+ nsName = (None, None)
+ return NsNameTupleFactory(nsName)
+
+
+ def nsName2QName (self, nsLocalName):
+ """Convert a tuple '(namespace, localName)' to a string 'prefix:localName'
+
+ Input parameter:
+ nsLocalName: tuple '(namespace, localName)' to be converted
+ Returns the corresponding string 'prefix:localName' for 'nsLocalName'.
+ """
+ qName = nsNameToQName (nsLocalName, self.getCurrentNamespaces())
+ if qName == "xmlns:None": qName = "xmlns"
+ return qName
+
+
+ def getNamespace (self, qName):
+ """Retrieve namespace for a qName 'prefix:localName'.
+
+ Input parameter:
+ qName: qName 'prefix:localName'
+ Returns the corresponding namespace for the prefix of 'qName'.
+ """
+ if qName != None:
+ qNamePrefix, qNameLocalName = splitQName (qName)
+ for prefix, namespaceURI in self.getCurrentNamespaces():
+ if qNamePrefix == prefix:
+ namespace = namespaceURI
+ break
+ else:
+ if qNamePrefix == None:
+ namespace = EMPTY_NAMESPACE
+ else:
+ raise LookupError, "Namespace for QName '%s' not found!" % (qName)
+ else:
+ namespace = EMPTY_NAMESPACE
+ return namespace
+
+
+ def getNsPrefix (self, nsLocalName):
+ """Retrieve prefix for a tuple '(namespace, localName)'.
+
+ Input parameter:
+ nsLocalName: tuple '(namespace, localName)'
+ Returns the corresponding prefix for the namespace of 'nsLocalName'.
+ """
+ ns = nsLocalName[0]
+ for prefix, namespace in self.getCurrentNamespaces():
+ if ns == namespace:
+ return prefix
+ else:
+ if ns == None:
+ return None
+ else:
+ raise LookupError, "Prefix for namespaceURI '%s' not found!" % (ns)
+
+
+#++++++++++++ limited XPath support ++++++++++++++++++++
+
+ def getXPath (self, xPath, namespaceRef=None, useDefaultNs=1, attrIgnoreList=[]):
+ """Retrieve node list or attribute list for specified XPath
+
+ Input parameter:
+ xPath: string containing xPath specification
+ namespaceRef: scope for namespaces (default is own element node)
+ useDefaultNs: 1, if default namespace shall be used if no prefix is available
+ attrIgnoreList: list of attributes to be ignored if wildcard is specified for attributes
+
+ Returns all nodes which match xPath specification or
+ list of attribute values if xPath specifies an attribute
+ """
+ return self.getXPathList(xPath, namespaceRef, useDefaultNs, attrIgnoreList)[0]
+
+
+ def getXPathList (self, xPath, namespaceRef=None, useDefaultNs=1, attrIgnoreList=[]):
+ """Retrieve node list or attribute list for specified XPath
+
+ Input parameter:
+ xPath: string containing xPath specification
+ namespaceRef: scope for namespaces (default is own element node)
+ useDefaultNs: 1, if default namespace shall be used if no prefix is available
+ attrIgnoreList: list of attributes to be ignored if wildcard is specified for attributes
+
+ Returns tuple (completeChildList, attrNodeList, attrNsNameFirst).
+ completeChildList: contains all child node which match xPath specification or
+ list of attribute values if xPath specifies an attribute
+ attrNodeList: contains all child nodes where the specified attribute was found
+ attrNsNameFirst: contains the name of the first attribute which was found
+ TODO: Re-design namespace and attribute handling of this method
+ """
+ reChild = re.compile('child *::')
+ reAttribute = re.compile('attribute *::')
+ if namespaceRef == None: namespaceRef = self
+ xPath = reChild.sub('./', xPath)
+ xPath = reAttribute.sub('@', xPath)
+ xPathList = string.split (xPath, "|")
+ completeChildDict = {}
+ completeChildList = []
+ attrNodeList = []
+ attrNsNameFirst = None
+ for xRelPath in xPathList:
+ xRelPath = string.strip(xRelPath)
+ descendantOrSelf = 0
+ if xRelPath[:3] == ".//":
+ descendantOrSelf = 1
+ xRelPath = xRelPath[3:]
+ xPathLocalStepList = string.split (xRelPath, "/")
+ childList = [self, ]
+ for localStep in xPathLocalStepList:
+ localStep = string.strip(localStep)
+ stepChildList = []
+ if localStep == "":
+ raise IOError ("Invalid xPath '%s'!" %(xRelPath))
+ elif localStep == ".":
+ continue
+ elif localStep[0] == '@':
+ if len(localStep) == 1:
+ raise ValueError ("Attribute name is missing in xPath!")
+ if descendantOrSelf:
+ childList = self.getElementsByTagName()
+ attrName = localStep[1:]
+ for childNode in childList:
+ if attrName == '*':
+ attrNodeList.append (childNode)
+ attrDict = childNode.getAttributeDict()
+ for attrIgnore in attrIgnoreList:
+ if attrDict.has_key(attrIgnore):
+ del attrDict[attrIgnore]
+ stepChildList.extend(attrDict.values())
+ try:
+ attrNsNameFirst = attrDict.keys()[0]
+ except:
+ pass
+ else:
+ attrNsName = namespaceRef.qName2NsName (attrName, useDefaultNs=0)
+ if attrNsName[1] == '*':
+ for attr in childNode.getAttributeDict().keys():
+ if attr[0] == attrNsName[0]:
+ if attrNodeList == []:
+ attrNsNameFirst = attrNsName
+ attrNodeList.append (childNode)
+ stepChildList.append (childNode.getAttribute(attr))
+ elif childNode.hasAttribute(attrNsName):
+ if attrNodeList == []:
+ attrNsNameFirst = attrNsName
+ attrNodeList.append (childNode)
+ stepChildList.append (childNode.getAttribute(attrNsName))
+ childList = stepChildList
+ else:
+ nsLocalName = namespaceRef.qName2NsName (localStep, useDefaultNs=useDefaultNs)
+ if descendantOrSelf:
+ descendantOrSelf = 0
+ if localStep == "*":
+ stepChildList = self.getElementsByTagName()
+ else:
+ stepChildList = self.getElementsByTagName(nsLocalName)
+ else:
+ for childNode in childList:
+ if localStep == "*":
+ stepChildList.extend (childNode.getChildren())
+ else:
+ stepChildList.extend (childNode.getChildrenNS(nsLocalName[0], nsLocalName[1]))
+ childList = stepChildList
+ # filter duplicated childs
+ for child in childList:
+ try:
+ childKey = child.element
+ except:
+ childKey = child
+ if not completeChildDict.has_key(childKey):
+ completeChildList.append(child)
+ completeChildDict[childKey] = 1
+ return completeChildList, attrNodeList, attrNsNameFirst
+
+
+ ###############################################################
+ # PRIVATE methods
+ ###############################################################
+
+ def __createElement (self, tupleOrLocalName, attributeDict):
+ """Create a new ElementWrapper object.
+
+ Input parameter:
+ tupleOrLocalName: tuple '(namespace, localName)' or 'localName' if no namespace is used
+ attributeDict: dictionary which contains the attributes and their values of the element node to be created
+ Returns the created ElementWrapper object
+ """
+ childElementWrapper = self.treeWrapper.createElement (tupleOrLocalName, attributeDict, self.curNs[:]) # TODO: when to be adapted???)
+ childElementWrapper.element.xmlIfExtSetParentNode(self.element)
+ return childElementWrapper
+
+
+ def __updateAttrMaxLengthDict (self, attrMaxLengthDict):
+ """Update dictionary which contains the maximum length of node attributes.
+
+ Used for pretty print to align the attributes of child nodes.
+ attrMaxLengthDict is in/out parameter.
+ """
+ for attrName, attrValue in self.getAttributeDict().items():
+ attrLength = len(attrValue)
+ if not attrMaxLengthDict.has_key(attrName):
+ attrMaxLengthDict[attrName] = attrLength
+ else:
+ attrMaxLengthDict[attrName] = max(attrMaxLengthDict[attrName], attrLength)
+
+
+ def __clearChildrenCache (self, childNsName=None):
+ """Clear children cache.
+ """
+ if self.__useCaching():
+ if childNsName != None:
+ if self.__childrenCache.has_key(childNsName):
+ del self.__childrenCache[childNsName]
+ if self.__firstChildCache.has_key(childNsName):
+ del self.__firstChildCache[childNsName]
+ else:
+ self.__childrenCache.clear()
+ self.__firstChildCache.clear()
+
+
+ def __useCaching(self):
+ return self.treeWrapper.useCaching()
+
+
diff --git a/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifBase.py b/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifBase.py
new file mode 100644
index 0000000..ca2d93f
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifBase.py
@@ -0,0 +1,130 @@
+#
+# genxmlif, Release 0.9.0
+# file: xmlifbase.py
+#
+# XML interface base classes
+#
+# history:
+# 2005-04-25 rl created
+# 2006-08-18 rl some methods for XML schema validation support added
+# 2007-05-25 rl performance optimization (caching) added, bugfixes for XPath handling
+# 2007-07-04 rl complete re-design, API classes moved to xmlifApi.py
+#
+# Copyright (c) 2005-2008 by Roland Leuthe. All rights reserved.
+#
+# --------------------------------------------------------------------
+# The generic XML interface is
+#
+# Copyright (c) 2005-2008 by Roland Leuthe
+#
+# By obtaining, using, and/or copying this software and/or its
+# associated documentation, you agree that you have read, understood,
+# and will comply with the following terms and conditions:
+#
+# Permission to use, copy, modify, and distribute this software and
+# its associated documentation for any purpose and without fee is
+# hereby granted, provided that the above copyright notice appears in
+# all copies, and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of
+# the author not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
+# ABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+# --------------------------------------------------------------------
+
+__author__ = "Roland Leuthe "
+__date__ = "28 July 2008"
+__version__ = "0.9"
+
+from xml.dom import XML_NAMESPACE, XMLNS_NAMESPACE
+from xmlifUtils import NsNameTupleFactory, convertToAbsUrl
+
+
+
+########################################
+# XmlIf builder extension base class
+# All not implemented methods have to be overloaded by the derived class!!
+#
+
+class XmlIfBuilderExtensionBase:
+ """XmlIf builder extension base class.
+
+ This class provides additional data (e.g. line numbers or caches)
+ for an element node which are stored in the element node object during parsing.
+ """
+
+ def __init__ (self, filePath, absUrl, treeWrapper, elementWrapperClass):
+ """Constructor for this class
+
+ Input parameter:
+ filePath: contains the file path of the corresponding XML file
+ absUrl: contains the absolute URL of the corresponding XML file
+ """
+ self.filePath = filePath
+ self.absUrl = absUrl
+ self.baseUrlStack = [absUrl, ]
+ self.treeWrapper = treeWrapper
+ self.elementWrapperClass = elementWrapperClass
+
+
+ def startElementHandler (self, curNode, startLineNumber, curNs, attributes=[]):
+ """Called by the XML parser at creation of an element node.
+
+ Input parameter:
+ curNode: current element node
+ startLineNumber: first line number of the element tag in XML file
+ curNs: namespaces visible for this element node
+ attributes: list of attributes and their values for this element node
+ (same sequence as int he XML file)
+ """
+
+ elementWrapper = self.elementWrapperClass(curNode, self.treeWrapper, curNs, initAttrSeq=0)
+
+ elementWrapper.baseUrl = self.__getBaseUrl(elementWrapper)
+ elementWrapper.absUrl = self.absUrl
+ elementWrapper.filePath = self.filePath
+ elementWrapper.startLineNumber = startLineNumber
+ elementWrapper.curNs.extend ([("xml", XML_NAMESPACE), ("xmlns", XMLNS_NAMESPACE)])
+
+ if attributes != []:
+ for i in range (0, len(attributes), 2):
+ elementWrapper.attributeSequence.append(attributes[i])
+ else:
+ attrList = elementWrapper.getAttributeDict().keys()
+ attrList.sort()
+ elementWrapper.attributeSequence.extend (attrList)
+
+ self.baseUrlStack.insert (0, elementWrapper.baseUrl)
+
+
+ def endElementHandler (self, curNode, endLineNumber):
+ """Called by the XML parser after creation of an element node.
+
+ Input parameter:
+ curNode: current element node
+ endLineNumber: last line number of the element tag in XML file
+ """
+ curNode.xmlIfExtElementWrapper.endLineNumber = endLineNumber
+ self.baseUrlStack.pop (0)
+
+
+ def __getBaseUrl (self, elementWrapper):
+ """Retrieve base URL for the given element node.
+
+ Input parameter:
+ elementWrapper: wrapper of current element node
+ """
+ nsNameBaseAttr = NsNameTupleFactory ((XML_NAMESPACE, "base"))
+ if elementWrapper.hasAttribute(nsNameBaseAttr):
+ return convertToAbsUrl (elementWrapper.getAttribute(nsNameBaseAttr), self.baseUrlStack[0])
+ else:
+ return self.baseUrlStack[0]
+
diff --git a/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifDom.py b/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifDom.py
new file mode 100644
index 0000000..83e357d
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifDom.py
@@ -0,0 +1,352 @@
+#
+# genxmlif, Release 0.9.0
+# file: xmlifDom.py
+#
+# XML interface base class for Python DOM implementations
+#
+# history:
+# 2005-04-25 rl created
+# 2007-07-02 rl complete re-design, internal wrapper
+# for DOM trees and elements introduced
+# 2008-07-01 rl Limited support of XInclude added
+#
+# Copyright (c) 2005-2008 by Roland Leuthe. All rights reserved.
+#
+# --------------------------------------------------------------------
+# The generic XML interface is
+#
+# Copyright (c) 2005-2008 by Roland Leuthe
+#
+# By obtaining, using, and/or copying this software and/or its
+# associated documentation, you agree that you have read, understood,
+# and will comply with the following terms and conditions:
+#
+# Permission to use, copy, modify, and distribute this software and
+# its associated documentation for any purpose and without fee is
+# hereby granted, provided that the above copyright notice appears in
+# all copies, and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of
+# the author not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
+# ABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+# --------------------------------------------------------------------
+
+import string
+import copy
+import urllib
+from types import TupleType
+from xml.dom import Node, getDOMImplementation, XMLNS_NAMESPACE
+from ..genxmlif import XINC_NAMESPACE, GenXmlIfError
+from xmlifUtils import nsNameToQName, processWhitespaceAction, collapseString, NsNameTupleFactory, convertToAbsUrl
+from xmlifBase import XmlIfBuilderExtensionBase
+from xmlifApi import XmlInterfaceBase
+
+
+class XmlInterfaceDom (XmlInterfaceBase):
+ """Derived interface class for handling of DOM parsers.
+
+ For description of the interface methods see xmlifbase.py.
+ """
+
+ def xInclude (self, elementWrapper, baseUrl, ownerDoc):
+ filePath = elementWrapper.getFilePath()
+ for childElementWrapper in elementWrapper.getChildren():
+ line = childElementWrapper.getStartLineNumber()
+ if childElementWrapper.getNsName() == (XINC_NAMESPACE, "include"):
+ href = childElementWrapper["href"]
+ parse = childElementWrapper.getAttributeOrDefault ("parse", "xml")
+ encoding = childElementWrapper.getAttribute ("encoding")
+ if self.verbose:
+ print "Xinclude: %s" %href
+ try:
+ if parse == "xml":
+ subTreeWrapper = self.parse (href, baseUrl, ownerDoc)
+ elementWrapper.replaceChildBySubtree (childElementWrapper, subTreeWrapper)
+ elif parse == "text":
+ absUrl = convertToAbsUrl (href, baseUrl)
+ fp = urllib.urlopen (absUrl)
+ data = fp.read()
+ if encoding:
+ data = data.decode(encoding)
+ newTextNode = ownerDoc.xmlIfExtCreateTextNode(data)
+ elementWrapper.element.element.insertBefore (newTextNode, childElementWrapper.element.element)
+ elementWrapper.removeChild (childElementWrapper)
+ fp.close()
+ else:
+ raise GenXmlIfError, "%s: line %s: XIncludeError: Invalid 'parse' Attribut: '%s'" %(filePath, line, parse)
+ except IOError, errInst:
+ raise GenXmlIfError, "%s: line %s: IOError: %s" %(filePath, line, str(errInst))
+ elif childElementWrapper.getNsName() == (XINC_NAMESPACE, "fallback"):
+ raise GenXmlIfError, "%s: line %s: XIncludeError: xi:fallback tag must be child of xi:include" %(filePath, line)
+ else:
+ self.xInclude(childElementWrapper, baseUrl, ownerDoc)
+
+
+
+class InternalDomTreeWrapper:
+ """Internal wrapper for a DOM Document class.
+ """
+ def __init__ (self, document):
+ self.document = document
+
+ def xmlIfExtGetRootNode (self):
+ domNode = self.document
+ if domNode.nodeType == Node.DOCUMENT_NODE:
+ return domNode.documentElement.xmlIfExtInternalWrapper
+ elif domNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE:
+ for node in domNode.childNodes:
+ if node.nodeType == Node.ELEMENT_NODE:
+ return node.xmlIfExtInternalWrapper
+ else:
+ return None
+ else:
+ return None
+
+
+ def xmlIfExtCreateElement (self, nsName, attributeDict, curNs):
+ elementNode = self.document.createElementNS (nsName[0], nsName[1])
+ intElementWrapper = self.internalElementWrapperClass(elementNode, self)
+ for attrName, attrValue in attributeDict.items():
+ intElementWrapper.xmlIfExtSetAttribute (NsNameTupleFactory(attrName), attrValue, curNs)
+ return intElementWrapper
+
+
+ def xmlIfExtCreateTextNode (self, data):
+ return self.document.createTextNode(data)
+
+
+ def xmlIfExtImportNode (self, node):
+ return self.document.importNode (node, 0)
+
+
+ def xmlIfExtCloneTree (self, rootElementCopy):
+ domImpl = getDOMImplementation()
+# documentCopy = domImpl.createDocument(rootElementCopy.xmlIfExtGetNamespaceURI(), rootElementCopy.xmlIfExtGetTagName(), None)
+ documentCopy = domImpl.createDocument(None, None, None)
+# documentCopy = copy.copy(self.document)
+ documentCopy.documentElement = rootElementCopy.element
+ return self.__class__(documentCopy)
+
+
+
+#########################################################
+# Internal Wrapper class for a Dom Element class
+
+class InternalDomElementWrapper:
+ """Internal Wrapper for a Dom Element class.
+ """
+
+ def __init__ (self, element, internalDomTreeWrapper):
+ self.element = element
+ element.xmlIfExtInternalWrapper = self
+ self.internalDomTreeWrapper = internalDomTreeWrapper
+
+
+ def xmlIfExtUnlink (self):
+ self.xmlIfExtElementWrapper = None
+
+
+ def xmlIfExtCloneNode (self):
+ nodeCopy = self.__class__(self.element.cloneNode(deep=0), self.internalDomTreeWrapper)
+ for childTextNode in self.__xmlIfExtGetChildTextNodes():
+ childTextNodeCopy = childTextNode.cloneNode(0)
+ nodeCopy.element.appendChild (childTextNodeCopy)
+# for nsAttrName, attrValue in self.xmlIfExtGetAttributeDict().items():
+# nodeCopy.xmlIfExtSetAttribute(nsAttrName, attrValue, self.xmlIfExtElementWrapper.getCurrentNamespaces())
+ return nodeCopy
+
+
+ def xmlIfExtGetTagName (self):
+ return self.element.tagName
+
+
+ def xmlIfExtGetNamespaceURI (self):
+ return self.element.namespaceURI
+
+
+ def xmlIfExtGetParentNode (self):
+ parentNode = self.element.parentNode
+ if parentNode.nodeType == Node.ELEMENT_NODE:
+ return self.element.parentNode.xmlIfExtInternalWrapper
+ else:
+ return None
+
+
+ def xmlIfExtSetParentNode (self, parentElement):
+ pass # nothing to do since parent is provided by DOM interface
+
+
+ def xmlIfExtGetChildren (self, tagFilter=None):
+ # TODO: Handle also wildcard tagFilter = (namespace, None)
+ children = filter (lambda e: (e.nodeType == Node.ELEMENT_NODE) and # - only ELEMENTs
+ (tagFilter == None or
+ (e.namespaceURI == tagFilter[0] and e.localName == tagFilter[1])), # - if tagFilter given --> check
+ self.element.childNodes ) # from element's nodes
+
+ return map(lambda element: element.xmlIfExtInternalWrapper, children)
+
+
+ def xmlIfExtGetFirstChild (self, tagFilter=None):
+ children = self.xmlIfExtGetChildren (tagFilter)
+ if children != []:
+ return children[0]
+ else:
+ None
+
+
+ def xmlIfExtGetElementsByTagName (self, tagFilter=('*','*')):
+ elementList = self.element.getElementsByTagNameNS( tagFilter[0], tagFilter[1] )
+ return map( lambda element: element.xmlIfExtInternalWrapper, elementList )
+
+
+ def xmlIfExtGetIterator (self, tagFilter=('*','*')):
+ elementList = []
+ if tagFilter in (('*','*'), (self.element.namespaceURI, self.element.localName)):
+ elementList.append(self.element)
+ elementList.extend(self.element.getElementsByTagNameNS( tagFilter[0], tagFilter[1] ))
+ return map( lambda element: element.xmlIfExtInternalWrapper, elementList )
+
+
+ def xmlIfExtAppendChild (self, childElement):
+ self.element.appendChild (childElement.element)
+
+
+ def xmlIfExtInsertBefore (self, childElement, refChildElement):
+ self.element.insertBefore (childElement.element, refChildElement.element)
+
+
+ def xmlIfExtRemoveChild (self, childElement):
+ self.element.removeChild (childElement.element)
+
+
+ def xmlIfExtInsertSubtree (self, refChildElement, subTree, insertSubTreeRootNode):
+ if insertSubTreeRootNode:
+ childElementList = [subTree.xmlIfExtGetRootNode(),]
+ else:
+ childElementList = subTree.xmlIfExtGetRootNode().xmlIfExtGetChildren()
+
+ for childElement in childElementList:
+ if refChildElement != None:
+ self.element.insertBefore(childElement.element, refChildElement.element)
+ else:
+ self.element.appendChild(childElement.element)
+
+
+ def xmlIfExtGetAttributeDict (self):
+ attribDict = {}
+ for nsAttrName, attrNodeOrValue in self.element.attributes.items():
+ attribDict[NsNameTupleFactory(nsAttrName)] = attrNodeOrValue.nodeValue
+ return attribDict
+
+
+ def xmlIfExtGetAttribute (self, nsAttrName):
+ if self.element.attributes.has_key (nsAttrName):
+ return self.element.getAttributeNS (nsAttrName[0], nsAttrName[1])
+ elif nsAttrName[1] == "xmlns" and self.element.attributes.has_key(nsAttrName[1]):
+ # workaround for minidom for correct access of xmlns attribute
+ return self.element.getAttribute (nsAttrName[1])
+ else:
+ return None
+
+
+ def xmlIfExtSetAttribute (self, nsAttrName, attributeValue, curNs):
+ if nsAttrName[0] != None:
+ qName = nsNameToQName (nsAttrName, curNs)
+ else:
+ qName = nsAttrName[1]
+
+ self.element.setAttributeNS (nsAttrName[0], qName, attributeValue)
+
+
+ def xmlIfExtRemoveAttribute (self, nsAttrName):
+ self.element.removeAttributeNS (nsAttrName[0], nsAttrName[1])
+
+
+ def xmlIfExtGetElementValueFragments (self, ignoreEmtpyStringFragments):
+ elementValueList = []
+ for childTextNode in self.__xmlIfExtGetChildTextNodes():
+ elementValueList.append(childTextNode.data)
+ if ignoreEmtpyStringFragments:
+ elementValueList = filter (lambda s: collapseString(s) != "", elementValueList)
+ if elementValueList == []:
+ elementValueList = ["",]
+ return elementValueList
+
+
+ def xmlIfExtGetElementText (self):
+ elementTextList = ["",]
+ if self.element.childNodes != []:
+ for childNode in self.element.childNodes:
+ if childNode.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE):
+ elementTextList.append (childNode.data)
+ else:
+ break
+ return "".join(elementTextList)
+
+
+ def xmlIfExtGetElementTailText (self):
+ tailTextList = ["",]
+ nextSib = self.element.nextSibling
+ while nextSib:
+ if nextSib.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE):
+ tailTextList.append (nextSib.data)
+ nextSib = nextSib.nextSibling
+ else:
+ break
+ return "".join(tailTextList)
+
+
+ def xmlIfExtSetElementValue (self, elementValue):
+ if self.__xmlIfExtGetChildTextNodes() == []:
+ textNode = self.internalDomTreeWrapper.xmlIfExtCreateTextNode (elementValue)
+ self.element.appendChild (textNode)
+ else:
+ self.__xmlIfExtGetChildTextNodes()[0].data = elementValue
+ if len (self.__xmlIfExtGetChildTextNodes()) > 1:
+ for textNode in self.__xmlIfExtGetChildTextNodes()[1:]:
+ textNode.data = ""
+
+
+ def xmlIfExtProcessWsElementValue (self, wsAction):
+ textNodes = self.__xmlIfExtGetChildTextNodes()
+
+ if len(textNodes) == 1:
+ textNodes[0].data = processWhitespaceAction (textNodes[0].data, wsAction)
+ elif len(textNodes) > 1:
+ textNodes[0].data = processWhitespaceAction (textNodes[0].data, wsAction, rstrip=0)
+ lstrip = 0
+ if len(textNodes[0].data) > 0 and textNodes[0].data[-1] == " ":
+ lstrip = 1
+ for textNode in textNodes[1:-1]:
+ textNode.data = processWhitespaceAction (textNode.data, wsAction, lstrip, rstrip=0)
+ if len(textNode.data) > 0 and textNode.data[-1] == " ":
+ lstrip = 1
+ else:
+ lstrip = 0
+ textNodes[-1].data = processWhitespaceAction (textNodes[-1].data, wsAction, lstrip)
+
+
+ ###############################################################
+ # PRIVATE methods
+ ###############################################################
+
+ def __xmlIfExtGetChildTextNodes ( self ):
+ """Return list of TEXT nodes."""
+ return filter (lambda e: ( e.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE) ), # - only TEXT-NODES
+ self.element.childNodes) # from element's child nodes
+
+
+
+class XmlIfBuilderExtensionDom (XmlIfBuilderExtensionBase):
+ """XmlIf builder extension class for DOM parsers."""
+
+ pass
diff --git a/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifElementTree.py b/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifElementTree.py
new file mode 100644
index 0000000..4e49da8
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifElementTree.py
@@ -0,0 +1,407 @@
+#
+# genxmlif, Release 0.9.0
+# file: xmlifElementTree.py
+#
+# XML interface class to elementtree toolkit by Fredrik Lundh
+#
+# history:
+# 2005-04-25 rl created
+# 2007-05-25 rl performance optimization (caching) added, some bugfixes
+# 2007-06-29 rl complete re-design, ElementExtension class introduced
+# 2008-07-01 rl Limited support of XInclude added
+#
+# Copyright (c) 2005-2008 by Roland Leuthe. All rights reserved.
+#
+# --------------------------------------------------------------------
+# The generic XML interface is
+#
+# Copyright (c) 2005-2008 by Roland Leuthe
+#
+# By obtaining, using, and/or copying this software and/or its
+# associated documentation, you agree that you have read, understood,
+# and will comply with the following terms and conditions:
+#
+# Permission to use, copy, modify, and distribute this software and
+# its associated documentation for any purpose and without fee is
+# hereby granted, provided that the above copyright notice appears in
+# all copies, and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of
+# the author not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
+# ABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+# --------------------------------------------------------------------
+
+import sys
+import string
+import urllib
+from xml.dom import EMPTY_NAMESPACE, XMLNS_NAMESPACE
+from xml.parsers.expat import ExpatError
+# from version 2.5 on the elementtree module is part of the standard python distribution
+if sys.version_info[:2] >= (2,5):
+ from xml.etree.ElementTree import ElementTree, _ElementInterface, XMLTreeBuilder, TreeBuilder
+ from xml.etree import ElementInclude
+else:
+ from elementtree.ElementTree import ElementTree, _ElementInterface, XMLTreeBuilder, TreeBuilder
+ from elementtree import ElementInclude
+from ..genxmlif import XMLIF_ELEMENTTREE, GenXmlIfError
+from xmlifUtils import convertToAbsUrl, processWhitespaceAction, collapseString, toClarkQName, splitQName
+from xmlifBase import XmlIfBuilderExtensionBase
+from xmlifApi import XmlInterfaceBase
+
+#########################################################
+# Derived interface class for elementtree toolkit
+
+class XmlInterfaceElementTree (XmlInterfaceBase):
+ #####################################################
+ # for description of the interface methods see xmlifbase.py
+ #####################################################
+
+ def __init__ (self, verbose, useCaching, processXInclude):
+ XmlInterfaceBase.__init__ (self, verbose, useCaching, processXInclude)
+ self.xmlIfType = XMLIF_ELEMENTTREE
+ if self.verbose:
+ print "Using elementtree interface module..."
+
+
+ def createXmlTree (self, namespace, xmlRootTagName, attributeDict={}, publicId=None, systemId=None):
+ rootNode = ElementExtension(toClarkQName(xmlRootTagName), attributeDict)
+ rootNode.xmlIfExtSetParentNode(None)
+ treeWrapper = self.treeWrapperClass(self, ElementTreeExtension(rootNode), self.useCaching)
+ rootNodeWrapper = self.elementWrapperClass (rootNode, treeWrapper, []) # TODO: namespace handling
+ return treeWrapper
+
+
+ def parse (self, file, baseUrl="", ownerDoc=None):
+ absUrl = convertToAbsUrl (file, baseUrl)
+ fp = urllib.urlopen (absUrl)
+ try:
+ tree = ElementTreeExtension()
+ treeWrapper = self.treeWrapperClass(self, tree, self.useCaching)
+ parser = ExtXMLTreeBuilder(file, absUrl, self, treeWrapper)
+ treeWrapper.getTree().parse(fp, parser)
+ fp.close()
+
+ # XInclude support
+ if self.processXInclude:
+ loaderInst = ExtXIncludeLoader (self.parse, absUrl, ownerDoc)
+ try:
+ ElementInclude.include(treeWrapper.getTree().getroot(), loaderInst.loader)
+ except IOError, errInst:
+ raise GenXmlIfError, "%s: IOError: %s" %(file, str(errInst))
+
+ except ExpatError, errstr:
+ fp.close()
+ raise GenXmlIfError, "%s: ExpatError: %s" %(file, str(errstr))
+ except ElementInclude.FatalIncludeError, errInst:
+ fp.close()
+ raise GenXmlIfError, "%s: XIncludeError: %s" %(file, str(errInst))
+
+ return treeWrapper
+
+
+ def parseString (self, text, baseUrl="", ownerDoc=None):
+ absUrl = convertToAbsUrl ("", baseUrl)
+ tree = ElementTreeExtension()
+ treeWrapper = self.treeWrapperClass(self, tree, self.useCaching)
+ parser = ExtXMLTreeBuilder("", absUrl, self, treeWrapper)
+ parser.feed(text)
+ treeWrapper.getTree()._setroot(parser.close())
+
+ # XInclude support
+ if self.processXInclude:
+ loaderInst = ExtXIncludeLoader (self.parse, absUrl, ownerDoc)
+ ElementInclude.include(treeWrapper.getTree().getroot(), loaderInst.loader)
+
+ return treeWrapper
+
+
+#########################################################
+# Extension (derived) class for ElementTree class
+
+class ElementTreeExtension (ElementTree):
+
+ def xmlIfExtGetRootNode (self):
+ return self.getroot()
+
+
+ def xmlIfExtCreateElement (self, nsName, attributeDict, curNs):
+ clarkQName = toClarkQName(nsName)
+ return ElementExtension (clarkQName, attributeDict)
+
+
+ def xmlIfExtCloneTree (self, rootElementCopy):
+ return self.__class__(element=rootElementCopy)
+
+
+#########################################################
+# Wrapper class for Element class
+
+class ElementExtension (_ElementInterface):
+
+ def __init__ (self, xmlRootTagName, attributeDict):
+ _ElementInterface.__init__(self, xmlRootTagName, attributeDict)
+
+
+ def xmlIfExtUnlink (self):
+ self.xmlIfExtElementWrapper = None
+ self.__xmlIfExtParentElement = None
+
+
+ def xmlIfExtCloneNode (self):
+ nodeCopy = self.__class__(self.tag, self.attrib.copy())
+ nodeCopy.text = self.text
+ nodeCopy.tail = self.tail
+ return nodeCopy
+
+
+ def xmlIfExtGetTagName (self):
+ return self.tag
+
+
+ def xmlIfExtGetNamespaceURI (self):
+ prefix, localName = splitQName(self.tag)
+ return prefix
+
+
+ def xmlIfExtGetParentNode (self):
+ return self.__xmlIfExtParentElement
+
+
+ def xmlIfExtSetParentNode (self, parentElement):
+ self.__xmlIfExtParentElement = parentElement
+
+
+ def xmlIfExtGetChildren (self, filterTag=None):
+ if filterTag == None:
+ return self.getchildren()
+ else:
+ clarkFilterTag = toClarkQName(filterTag)
+ return self.findall(clarkFilterTag)
+
+
+ def xmlIfExtGetFirstChild (self, filterTag=None):
+ # replace base method (performance optimized)
+ if filterTag == None:
+ children = self.getchildren()
+ if children != []:
+ element = children[0]
+ else:
+ element = None
+ else:
+ clarkFilterTag = toClarkQName(filterTag)
+ element = self.find(clarkFilterTag)
+
+ return element
+
+
+ def xmlIfExtGetElementsByTagName (self, filterTag=(None,None)):
+ clarkFilterTag = toClarkQName(filterTag)
+ descendants = []
+ for node in self.xmlIfExtGetChildren():
+ descendants.extend(node.getiterator(clarkFilterTag))
+ return descendants
+
+
+ def xmlIfExtGetIterator (self, filterTag=(None,None)):
+ clarkFilterTag = toClarkQName(filterTag)
+ return self.getiterator (clarkFilterTag)
+
+
+ def xmlIfExtAppendChild (self, childElement):
+ self.append (childElement)
+ childElement.xmlIfExtSetParentNode(self)
+
+
+ def xmlIfExtInsertBefore (self, childElement, refChildElement):
+ self.insert (self.getchildren().index(refChildElement), childElement)
+ childElement.xmlIfExtSetParentNode(self)
+
+
+ def xmlIfExtRemoveChild (self, childElement):
+ self.remove (childElement)
+
+
+ def xmlIfExtInsertSubtree (self, refChildElement, subTree, insertSubTreeRootNode):
+ if refChildElement != None:
+ insertIndex = self.getchildren().index (refChildElement)
+ else:
+ insertIndex = 0
+ if insertSubTreeRootNode:
+ elementList = [subTree.xmlIfExtGetRootNode(),]
+ else:
+ elementList = subTree.xmlIfExtGetRootNode().xmlIfExtGetChildren()
+ elementList.reverse()
+ for element in elementList:
+ self.insert (insertIndex, element)
+ element.xmlIfExtSetParentNode(self)
+
+
+ def xmlIfExtGetAttributeDict (self):
+ attrDict = {}
+ for attrName, attrValue in self.attrib.items():
+ namespaceEndIndex = string.find (attrName, '}')
+ if namespaceEndIndex != -1:
+ attrName = (attrName[1:namespaceEndIndex], attrName[namespaceEndIndex+1:])
+ else:
+ attrName = (EMPTY_NAMESPACE, attrName)
+ attrDict[attrName] = attrValue
+ return attrDict
+
+
+ def xmlIfExtGetAttribute (self, tupleOrAttrName):
+ clarkQName = toClarkQName(tupleOrAttrName)
+ if self.attrib.has_key(clarkQName):
+ return self.attrib[clarkQName]
+ else:
+ return None
+
+
+ def xmlIfExtSetAttribute (self, tupleOrAttrName, attributeValue, curNs):
+ self.attrib[toClarkQName(tupleOrAttrName)] = attributeValue
+
+
+ def xmlIfExtRemoveAttribute (self, tupleOrAttrName):
+ clarkQName = toClarkQName(tupleOrAttrName)
+ if self.attrib.has_key(clarkQName):
+ del self.attrib[clarkQName]
+
+
+ def xmlIfExtGetElementValueFragments (self, ignoreEmtpyStringFragments):
+ elementValueList = []
+ if self.text != None:
+ elementValueList.append(self.text)
+ for child in self.getchildren():
+ if child.tail != None:
+ elementValueList.append(child.tail)
+ if ignoreEmtpyStringFragments:
+ elementValueList = filter (lambda s: collapseString(s) != "", elementValueList)
+ if elementValueList == []:
+ elementValueList = ["",]
+ return elementValueList
+
+
+ def xmlIfExtGetElementText (self):
+ if self.text != None:
+ return self.text
+ else:
+ return ""
+
+
+ def xmlIfExtGetElementTailText (self):
+ if self.tail != None:
+ return self.tail
+ else:
+ return ""
+
+
+ def xmlIfExtSetElementValue (self, elementValue):
+ self.text = elementValue
+ for child in self.getchildren():
+ child.tail = None
+
+
+ def xmlIfExtProcessWsElementValue (self, wsAction):
+ noOfTextFragments = reduce(lambda sum, child: sum + (child.tail != None), self.getchildren(), 0)
+ noOfTextFragments += (self.text != None)
+
+ rstrip = 0
+ lstrip = 1
+ if self.text != None:
+ if noOfTextFragments == 1:
+ rstrip = 1
+ self.text = processWhitespaceAction (self.text, wsAction, lstrip, rstrip)
+ noOfTextFragments -= 1
+ lstrip = 0
+ for child in self.getchildren():
+ if child.tail != None:
+ if noOfTextFragments == 1:
+ rstrip = 1
+ child.tail = processWhitespaceAction (child.tail, wsAction, lstrip, rstrip)
+ noOfTextFragments -= 1
+ lstrip = 0
+
+
+###################################################
+# Element tree builder class derived from XMLTreeBuilder
+# extended to store related line numbers in the Element object
+
+class ExtXMLTreeBuilder (XMLTreeBuilder, XmlIfBuilderExtensionBase):
+ def __init__(self, filePath, absUrl, xmlIf, treeWrapper):
+ XMLTreeBuilder.__init__(self, target=TreeBuilder(element_factory=ElementExtension))
+ self._parser.StartNamespaceDeclHandler = self._start_ns
+ self._parser.EndNamespaceDeclHandler = self._end_ns
+ self.namespaces = []
+ XmlIfBuilderExtensionBase.__init__(self, filePath, absUrl, treeWrapper, xmlIf.elementWrapperClass)
+
+ def _start(self, tag, attrib_in):
+ elem = XMLTreeBuilder._start(self, tag, attrib_in)
+ self.start(elem)
+
+ def _start_list(self, tag, attrib_in):
+ elem = XMLTreeBuilder._start_list(self, tag, attrib_in)
+ self.start(elem, attrib_in)
+
+ def _end(self, tag):
+ elem = XMLTreeBuilder._end(self, tag)
+ self.end(elem)
+
+ def _start_ns(self, prefix, value):
+ self.namespaces.insert(0, (prefix, value))
+
+ def _end_ns(self, prefix):
+ assert self.namespaces.pop(0)[0] == prefix, "implementation confused"
+
+
+ def start(self, element, attributes):
+ # bugfix for missing start '{'
+ for i in range (0, len(attributes), 2):
+ attrName = attributes[i]
+ namespaceEndIndex = string.find (attrName, '}')
+ if namespaceEndIndex != -1 and attrName[0] != "{":
+ attributes[i] = '{' + attributes[i]
+ # bugfix end
+
+ XmlIfBuilderExtensionBase.startElementHandler (self, element, self._parser.ErrorLineNumber, self.namespaces[:], attributes)
+ if len(self._target._elem) > 1:
+ element.xmlIfExtSetParentNode (self._target._elem[-2])
+ else:
+ for namespace in self.namespaces:
+ if namespace[1] != None:
+ element.xmlIfExtElementWrapper.setAttribute((XMLNS_NAMESPACE, namespace[0]), namespace[1])
+
+
+ def end(self, element):
+ XmlIfBuilderExtensionBase.endElementHandler (self, element, self._parser.ErrorLineNumber)
+
+
+###################################################
+# XInclude loader
+#
+
+class ExtXIncludeLoader:
+
+ def __init__(self, parser, baseUrl, ownerDoc):
+ self.parser = parser
+ self.baseUrl = baseUrl
+ self.ownerDoc = ownerDoc
+
+ def loader(self, href, parse, encoding=None):
+ if parse == "xml":
+ data = self.parser(href, self.baseUrl, self.ownerDoc).getTree().getroot()
+ else:
+ absUrl = convertToAbsUrl (href, self.baseUrl)
+ fp = urllib.urlopen (absUrl)
+ data = fp.read()
+ if encoding:
+ data = data.decode(encoding)
+ fp.close()
+ return data
diff --git a/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifMinidom.py b/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifMinidom.py
new file mode 100644
index 0000000..036ac6c
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifMinidom.py
@@ -0,0 +1,198 @@
+#
+# genxmlif, Release 0.9.0
+# file: xmlifMinidom.py
+#
+# XML interface class to Python standard minidom
+#
+# history:
+# 2005-04-25 rl created
+# 2007-07-02 rl complete re-design, internal wrapper
+# for DOM trees and elements introduced
+# 2008-07-01 rl Limited support of XInclude added
+#
+# Copyright (c) 2005-2008 by Roland Leuthe. All rights reserved.
+#
+# --------------------------------------------------------------------
+# The generix XML interface is
+#
+# Copyright (c) 2005-2008 by Roland Leuthe
+#
+# By obtaining, using, and/or copying this software and/or its
+# associated documentation, you agree that you have read, understood,
+# and will comply with the following terms and conditions:
+#
+# Permission to use, copy, modify, and distribute this software and
+# its associated documentation for any purpose and without fee is
+# hereby granted, provided that the above copyright notice appears in
+# all copies, and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of
+# the author not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
+# ABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+# --------------------------------------------------------------------
+
+import string
+import urllib
+from xml.dom import Node, XMLNS_NAMESPACE
+from xml.dom.expatbuilder import ExpatBuilderNS
+from xml.parsers.expat import ExpatError
+from ..genxmlif import XMLIF_MINIDOM, GenXmlIfError
+from xmlifUtils import convertToAbsUrl, NsNameTupleFactory
+from xmlifDom import XmlInterfaceDom, InternalDomTreeWrapper, InternalDomElementWrapper, XmlIfBuilderExtensionDom
+
+
+class XmlInterfaceMinidom (XmlInterfaceDom):
+ """Derived interface class for handling of minidom parser.
+
+ For description of the interface methods see xmlifbase.py.
+ """
+
+ def __init__ (self, verbose, useCaching, processXInclude):
+ XmlInterfaceDom.__init__ (self, verbose, useCaching, processXInclude)
+ self.xmlIfType = XMLIF_MINIDOM
+ if self.verbose:
+ print "Using minidom interface module..."
+
+
+ def createXmlTree (self, namespace, xmlRootTagName, attributeDict={}, publicId=None, systemId=None):
+ from xml.dom.minidom import getDOMImplementation
+ domImpl = getDOMImplementation()
+ doctype = domImpl.createDocumentType(xmlRootTagName, publicId, systemId)
+ domTree = domImpl.createDocument(namespace, xmlRootTagName, doctype)
+ treeWrapper = self.treeWrapperClass(self, InternalMinidomTreeWrapper(domTree), self.useCaching)
+
+ intRootNodeWrapper = InternalMinidomElementWrapper(domTree.documentElement, treeWrapper.getTree())
+ rootNodeWrapper = self.elementWrapperClass (intRootNodeWrapper, treeWrapper, []) # TODO: namespace handling
+ for attrName, attrValue in attributeDict.items():
+ rootNodeWrapper.setAttribute (attrName, attrValue)
+
+ return treeWrapper
+
+
+ def parse (self, file, baseUrl="", internalOwnerDoc=None):
+ absUrl = convertToAbsUrl(file, baseUrl)
+ fp = urllib.urlopen (absUrl)
+ try:
+ builder = ExtExpatBuilderNS(file, absUrl, self)
+ tree = builder.parseFile(fp)
+
+ # XInclude support
+ if self.processXInclude:
+ if internalOwnerDoc == None:
+ internalOwnerDoc = builder.treeWrapper.getTree()
+ self.xInclude (builder.treeWrapper.getRootNode(), absUrl, internalOwnerDoc)
+
+ fp.close()
+ except ExpatError, errInst:
+ fp.close()
+ raise GenXmlIfError, "%s: ExpatError: %s" %(file, str(errInst))
+
+ return builder.treeWrapper
+
+
+ def parseString (self, text, baseUrl="", internalOwnerDoc=None):
+ absUrl = convertToAbsUrl ("", baseUrl)
+ try:
+ builder = ExtExpatBuilderNS("", absUrl, self)
+ builder.parseString (text)
+
+ # XInclude support
+ if self.processXInclude:
+ if internalOwnerDoc == None:
+ internalOwnerDoc = builder.treeWrapper.getTree()
+ self.xInclude (builder.treeWrapper.getRootNode(), absUrl, internalOwnerDoc)
+ except ExpatError, errInst:
+ raise GenXmlIfError, "%s: ExpatError: %s" %(baseUrl, str(errInst))
+
+ return builder.treeWrapper
+
+
+
+class InternalMinidomTreeWrapper (InternalDomTreeWrapper):
+ """Internal wrapper for a minidom Document class.
+ """
+
+ def __init__ (self, document):
+ InternalDomTreeWrapper.__init__(self, document)
+ self.internalElementWrapperClass = InternalMinidomElementWrapper
+
+
+
+class InternalMinidomElementWrapper (InternalDomElementWrapper):
+ """Internal Wrapper for a Dom Element class.
+ """
+
+ def xmlIfExtGetAttributeDict (self):
+ """Return a dictionary with all attributes of this element."""
+ attribDict = {}
+ for attrNameNS, attrNodeOrValue in self.element.attributes.itemsNS():
+ attribDict[NsNameTupleFactory(attrNameNS)] = attrNodeOrValue
+
+ return attribDict
+
+
+
+class ExtExpatBuilderNS (ExpatBuilderNS, XmlIfBuilderExtensionDom):
+ """Extended Expat Builder class derived from ExpatBuilderNS.
+
+ Extended to store related line numbers, file/URL names and
+ defined namespaces in the node object.
+ """
+
+ def __init__ (self, filePath, absUrl, xmlIf):
+ ExpatBuilderNS.__init__(self)
+ internalMinidomTreeWrapper = InternalMinidomTreeWrapper(self.document)
+ self.treeWrapper = xmlIf.treeWrapperClass(self, internalMinidomTreeWrapper, xmlIf.useCaching)
+ XmlIfBuilderExtensionDom.__init__(self, filePath, absUrl, self.treeWrapper, xmlIf.elementWrapperClass)
+
+ # set EndNamespaceDeclHandler, currently not used by minidom
+ self.getParser().EndNamespaceDeclHandler = self.end_namespace_decl_handler
+ self.curNamespaces = []
+
+
+ def start_element_handler(self, name, attributes):
+ ExpatBuilderNS.start_element_handler(self, name, attributes)
+
+ # use attribute format {namespace}localName
+ attrList = []
+ for i in range (0, len(attributes), 2):
+ attrName = attributes[i]
+ attrNameSplit = string.split(attrName, " ")
+ if len(attrNameSplit) > 1:
+ attrName = (attrNameSplit[0], attrNameSplit[1])
+ attrList.extend([attrName, attributes[i+1]])
+
+ internalMinidomElementWrapper = InternalMinidomElementWrapper(self.curNode, self.treeWrapper.getTree())
+ XmlIfBuilderExtensionDom.startElementHandler (self, internalMinidomElementWrapper, self.getParser().ErrorLineNumber, self.curNamespaces[:], attrList)
+
+ if self.curNode.parentNode.nodeType == Node.DOCUMENT_NODE:
+ for namespace in self.curNamespaces:
+ if namespace[0] != None:
+ internalMinidomElementWrapper.xmlIfExtElementWrapper.attributeSequence.append((XMLNS_NAMESPACE, namespace[0]))
+ else:
+ internalMinidomElementWrapper.xmlIfExtElementWrapper.attributeSequence.append("xmlns")
+# internalMinidomElementWrapper.xmlIfExtElementWrapper.setAttribute((XMLNS_NAMESPACE, namespace[0]), namespace[1])
+
+
+ def end_element_handler(self, name):
+ XmlIfBuilderExtensionDom.endElementHandler (self, self.curNode.xmlIfExtInternalWrapper, self.getParser().ErrorLineNumber)
+ ExpatBuilderNS.end_element_handler(self, name)
+
+
+ def start_namespace_decl_handler(self, prefix, uri):
+ ExpatBuilderNS.start_namespace_decl_handler(self, prefix, uri)
+ self.curNamespaces.insert(0, (prefix, uri))
+
+
+ def end_namespace_decl_handler(self, prefix):
+ assert self.curNamespaces.pop(0)[0] == prefix, "implementation confused"
+
diff --git a/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifODict.py b/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifODict.py
new file mode 100644
index 0000000..ca10b04
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifODict.py
@@ -0,0 +1,57 @@
+from types import DictType
+from UserDict import UserDict
+
+class odict(UserDict):
+ def __init__(self, dictOrTuple = None):
+ self._keys = []
+ UserDict.__init__(self, dictOrTuple)
+
+ def __delitem__(self, key):
+ UserDict.__delitem__(self, key)
+ self._keys.remove(key)
+
+ def __setitem__(self, key, item):
+ UserDict.__setitem__(self, key, item)
+ if key not in self._keys: self._keys.append(key)
+
+ def clear(self):
+ UserDict.clear(self)
+ self._keys = []
+
+ def copy(self):
+ newInstance = odict()
+ newInstance.update(self)
+ return newInstance
+
+ def items(self):
+ return zip(self._keys, self.values())
+
+ def keys(self):
+ return self._keys[:]
+
+ def popitem(self):
+ try:
+ key = self._keys[-1]
+ except IndexError:
+ raise KeyError('dictionary is empty')
+
+ val = self[key]
+ del self[key]
+
+ return (key, val)
+
+ def setdefault(self, key, failobj = None):
+ if key not in self._keys:
+ self._keys.append(key)
+ return UserDict.setdefault(self, key, failobj)
+
+ def update(self, dictOrTuple):
+ if isinstance(dictOrTuple, DictType):
+ itemList = dictOrTuple.items()
+ else:
+ itemList = dictOrTuple
+ for key, val in itemList:
+ self.__setitem__(key,val)
+
+ def values(self):
+ return map(self.get, self._keys)
\ No newline at end of file
diff --git a/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifUtils.py b/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifUtils.py
new file mode 100644
index 0000000..f452dd1
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/lib/genxmlif/xmlifUtils.py
@@ -0,0 +1,374 @@
+#
+# genxmlif, Release 0.9.0
+# file: xmlifUtils.py
+#
+# utility module for genxmlif
+#
+# history:
+# 2005-04-25 rl created
+# 2008-08-01 rl encoding support added
+#
+# Copyright (c) 2005-2008 by Roland Leuthe. All rights reserved.
+#
+# --------------------------------------------------------------------
+# The generic XML interface is
+#
+# Copyright (c) 2005-2008 by Roland Leuthe
+#
+# By obtaining, using, and/or copying this software and/or its
+# associated documentation, you agree that you have read, understood,
+# and will comply with the following terms and conditions:
+#
+# Permission to use, copy, modify, and distribute this software and
+# its associated documentation for any purpose and without fee is
+# hereby granted, provided that the above copyright notice appears in
+# all copies, and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of
+# the author not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
+# ABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
+# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+# --------------------------------------------------------------------
+
+import string
+import re
+import os
+import urllib
+import urlparse
+from types import StringTypes, TupleType
+from xml.dom import EMPTY_PREFIX, EMPTY_NAMESPACE
+
+######################################################################
+# DEFINITIONS
+######################################################################
+
+######################################################################
+# REGULAR EXPRESSION OBJECTS
+######################################################################
+
+_reWhitespace = re.compile('\s')
+_reWhitespaces = re.compile('\s+')
+
+_reSplitUrlApplication = re.compile (r"(file|http|ftp|gopher):(.+)") # "file:///d:\test.xml" => "file" + "///d:\test.xml"
+
+
+######################################################################
+# FUNCTIONS
+######################################################################
+
+
+########################################
+# remove all whitespaces from a string
+#
+def removeWhitespaces (strValue):
+ return _reWhitespaces.sub('', strValue)
+
+
+########################################
+# substitute multiple whitespace characters by a single ' '
+#
+def collapseString (strValue, lstrip=1, rstrip=1):
+ collStr = _reWhitespaces.sub(' ', strValue)
+ if lstrip and rstrip:
+ return collStr.strip()
+ elif lstrip:
+ return collStr.lstrip()
+ elif rstrip:
+ return collStr.rstrip()
+ else:
+ return collStr
+
+
+
+########################################
+# substitute each whitespace characters by a single ' '
+#
+def normalizeString (strValue):
+ return _reWhitespace.sub(' ', strValue)
+
+
+########################################
+# process whitespace action
+#
+def processWhitespaceAction (strValue, wsAction, lstrip=1, rstrip=1):
+ if wsAction == "collapse":
+ return collapseString(strValue, lstrip, rstrip)
+ elif wsAction == "replace":
+ return normalizeString(strValue)
+ else:
+ return strValue
+
+
+##########################################################
+# convert input parameter 'fileOrUrl' into a valid URL
+
+def convertToUrl (fileOrUrl):
+ matchObject = _reSplitUrlApplication.match(fileOrUrl)
+ if matchObject:
+ # given fileOrUrl is an absolute URL
+ if matchObject.group(1) == 'file':
+ path = re.sub(':', '|', matchObject.group(2)) # replace ':' by '|' in the path string
+ url = "file:" + path
+ else:
+ url = fileOrUrl
+ elif not os.path.isfile(fileOrUrl):
+ # given fileOrUrl is treated as a relative URL
+ url = fileOrUrl
+ else:
+ # local filename
+# url = "file:" + urllib.pathname2url (fileOrUrl)
+ url = urllib.pathname2url (fileOrUrl)
+
+ return url
+
+
+##########################################################
+# convert input parameter 'fileOrUrl' into a valid absolute URL
+
+def convertToAbsUrl (fileOrUrl, baseUrl):
+ if fileOrUrl == "" and baseUrl != "":
+ absUrl = "file:" + urllib.pathname2url (os.path.join(os.getcwd(), baseUrl, "__NO_FILE__"))
+ elif os.path.isfile(fileOrUrl):
+ absUrl = "file:" + urllib.pathname2url (os.path.join(os.getcwd(), fileOrUrl))
+ else:
+ matchObject = _reSplitUrlApplication.match(fileOrUrl)
+ if matchObject:
+ # given fileOrUrl is an absolute URL
+ if matchObject.group(1) == 'file':
+ path = re.sub(':', '|', matchObject.group(2)) # replace ':' by '|' in the path string
+ absUrl = "file:" + path
+ else:
+ absUrl = fileOrUrl
+ else:
+ # given fileOrUrl is treated as a relative URL
+ if baseUrl != "":
+ absUrl = urlparse.urljoin (baseUrl, fileOrUrl)
+ else:
+ absUrl = fileOrUrl
+# raise IOError, "File %s not found!" %(fileOrUrl)
+ return absUrl
+
+
+##########################################################
+# normalize filter
+def normalizeFilter (filterVar):
+ if filterVar == None or filterVar == '*':
+ filterVar = ("*",)
+ elif not isinstance(filterVar, TupleType):
+ filterVar = (filterVar,)
+ return filterVar
+
+
+######################################################################
+# Namespace handling
+######################################################################
+
+def nsNameToQName (nsLocalName, curNs):
+ """Convert a tuple '(namespace, localName)' to a string 'prefix:localName'
+
+ Input parameter:
+ nsLocalName: tuple '(namespace, localName)' to be converted
+ curNs: list of current namespaces
+ Returns the corresponding string 'prefix:localName' for 'nsLocalName'.
+ """
+ ns = nsLocalName[0]
+ for prefix, namespace in curNs:
+ if ns == namespace:
+ if prefix != None:
+ return "%s:%s" %(prefix, nsLocalName[1])
+ else:
+ return "%s" %nsLocalName[1]
+ else:
+ if ns == None:
+ return nsLocalName[1]
+ else:
+ raise LookupError, "Prefix for namespaceURI '%s' not found!" % (ns)
+
+
+def splitQName (qName):
+ """Split the given 'qName' into prefix/namespace and local name.
+
+ Input parameter:
+ 'qName': contains a string 'prefix:localName' or '{namespace}localName'
+ Returns a tuple (prefixOrNamespace, localName)
+ """
+ namespaceEndIndex = string.find (qName, '}')
+ if namespaceEndIndex != -1:
+ prefix = qName[1:namespaceEndIndex]
+ localName = qName[namespaceEndIndex+1:]
+ else:
+ namespaceEndIndex = string.find (qName, ':')
+ if namespaceEndIndex != -1:
+ prefix = qName[:namespaceEndIndex]
+ localName = qName[namespaceEndIndex+1:]
+ else:
+ prefix = None
+ localName = qName
+ return prefix, localName
+
+
+def toClarkQName (tupleOrLocalName):
+ """converts a tuple (namespace, localName) into clark notation {namespace}localName
+ qNames without namespace remain unchanged
+
+ Input parameter:
+ 'tupleOrLocalName': tuple '(namespace, localName)' to be converted
+ Returns a string {namespace}localName
+ """
+ if isinstance(tupleOrLocalName, TupleType):
+ if tupleOrLocalName[0] != EMPTY_NAMESPACE:
+ return "{%s}%s" %(tupleOrLocalName[0], tupleOrLocalName[1])
+ else:
+ return tupleOrLocalName[1]
+ else:
+ return tupleOrLocalName
+
+
+def splitClarkQName (qName):
+ """converts clark notation {namespace}localName into a tuple (namespace, localName)
+
+ Input parameter:
+ 'qName': {namespace}localName to be converted
+ Returns prefix and localName as separate strings
+ """
+ namespaceEndIndex = string.find (qName, '}')
+ if namespaceEndIndex != -1:
+ prefix = qName[1:namespaceEndIndex]
+ localName = qName[namespaceEndIndex+1:]
+ else:
+ prefix = None
+ localName = qName
+ return prefix, localName
+
+
+##################################################################
+# XML serialization of text
+# the following functions assume an ascii-compatible encoding
+# (or "utf-16")
+
+_escape = re.compile(eval(r'u"[&<>\"\u0080-\uffff]+"'))
+
+_escapeDict = {
+ "&": "&",
+ "<": "<",
+ ">": ">",
+ '"': """,
+}
+
+
+def _raiseSerializationError(text):
+ raise TypeError("cannot serialize %r (type %s)" % (text, type(text).__name__))
+
+
+def _encode(text, encoding):
+ try:
+ return text.encode(encoding)
+ except AttributeError:
+ return text # assume the string uses the right encoding
+
+
+def _encodeEntity(text, pattern=_escape):
+ # map reserved and non-ascii characters to numerical entities
+ def escapeEntities(m, map=_escapeDict):
+ out = []
+ append = out.append
+ for char in m.group():
+ text = map.get(char)
+ if text is None:
+ text = "%d;" % ord(char)
+ append(text)
+ return string.join(out, "")
+ try:
+ return _encode(pattern.sub(escapeEntities, text), "ascii")
+ except TypeError:
+ _raise_serialization_error(text)
+
+
+def escapeCdata(text, encoding=None, replace=string.replace):
+ # escape character data
+ try:
+ if encoding:
+ try:
+ text = _encode(text, encoding)
+ except UnicodeError:
+ return _encodeEntity(text)
+ text = replace(text, "&", "&")
+ text = replace(text, "<", "<")
+ text = replace(text, ">", ">")
+ return text
+ except (TypeError, AttributeError):
+ _raiseSerializationError(text)
+
+
+def escapeAttribute(text, encoding=None, replace=string.replace):
+ # escape attribute value
+ try:
+ if encoding:
+ try:
+ text = _encode(text, encoding)
+ except UnicodeError:
+ return _encodeEntity(text)
+ text = replace(text, "&", "&")
+ text = replace(text, "'", "'") # FIXME: overkill
+ text = replace(text, "\"", """)
+ text = replace(text, "<", "<")
+ text = replace(text, ">", ">")
+ return text
+ except (TypeError, AttributeError):
+ _raiseSerializationError(text)
+
+
+######################################################################
+# CLASSES
+######################################################################
+
+######################################################################
+# class containing a tuple of namespace prefix and localName
+#
+class QNameTuple(tuple):
+ def __str__(self):
+ if self[0] != EMPTY_PREFIX:
+ return "%s:%s" %(self[0],self[1])
+ else:
+ return self[1]
+
+
+def QNameTupleFactory(initValue):
+ if isinstance(initValue, StringTypes):
+ separatorIndex = string.find (initValue, ':')
+ if separatorIndex != -1:
+ initValue = (initValue[:separatorIndex], initValue[separatorIndex+1:])
+ else:
+ initValue = (EMPTY_PREFIX, initValue)
+ return QNameTuple(initValue)
+
+
+######################################################################
+# class containing a tuple of namespace and localName
+#
+class NsNameTuple(tuple):
+ def __str__(self):
+ if self[0] != EMPTY_NAMESPACE:
+ return "{%s}%s" %(self[0],self[1])
+ elif self[1] != None:
+ return self[1]
+ else:
+ return "None"
+
+
+def NsNameTupleFactory(initValue):
+ if isinstance(initValue, StringTypes):
+ initValue = splitClarkQName(initValue)
+ elif initValue == None:
+ initValue = (EMPTY_NAMESPACE, initValue)
+ return NsNameTuple(initValue)
+
+
diff --git a/mavlink-solo/pymavlink/generator/lib/genxmlif/xmliftest.py b/mavlink-solo/pymavlink/generator/lib/genxmlif/xmliftest.py
new file mode 100644
index 0000000..7c26f78
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/lib/genxmlif/xmliftest.py
@@ -0,0 +1,14 @@
+from .. import genxmlif
+from ..genxmlif.xmlifODict import odict
+
+xmlIf = genxmlif.chooseXmlIf(genxmlif.XMLIF_ELEMENTTREE)
+xmlTree = xmlIf.createXmlTree(None, "testTree", {"rootAttr1":"RootAttr1"})
+xmlRootNode = xmlTree.getRootNode()
+myDict = odict( (("childTag1","123"), ("childTag2","123")) )
+xmlRootNode.appendChild("childTag", myDict)
+xmlRootNode.appendChild("childTag", {"childTag1":"123456", "childTag2":"123456"})
+xmlRootNode.appendChild("childTag", {"childTag1":"123456789", "childTag3":"1234", "childTag2":"123456789"})
+xmlRootNode.appendChild("childTag", {"childTag1":"1", "childTag2":"1"})
+print xmlTree.printTree(prettyPrint=1)
+print xmlTree
+print xmlTree.getRootNode()
diff --git a/mavlink-solo/pymavlink/generator/lib/minixsv/README.txt b/mavlink-solo/pymavlink/generator/lib/minixsv/README.txt
new file mode 100644
index 0000000..c887e7d
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/lib/minixsv/README.txt
@@ -0,0 +1,178 @@
+Release Notes for minixsv, Release 0.9.0
+
+minixsv is a XML schema validator written in "pure" Python
+(minixsv requires at least Python 2.4)
+
+Currently a subset of the XML schema standard is supported
+(list of limitations/restrictions see below).
+
+minixsv is based on genxmlif, a generic XML interface class,
+which currently supports minidom, elementtree or 4DOM/pyXML as XML parser
+Other parsers can be adapted by implementing an appropriate derived interface class
+
+Using the 4DOM interface is rather slow.
+For best performance the elementtree parser should be used!
+
+After successful validation minixsv provides the input XML tree with the following changes:
+- Whitespaces inside strings are automatically normalized/collapsed as specified
+ in the XML schema file
+- Default/Fixed attributes are automatically inserted if not specified in the input file
+- The "post validation" XML tree can be accessed using genxmlif or the contained
+ original interface (minidom, elementtree or 4DOM/pyXML).
+
+--------------------------------------------------------------------
+ The minixsv XML schema validator is
+
+ Copyright (c) 2004-2008 by Roland Leuthe
+
+ By obtaining, using, and/or copying this software and/or its
+ associated documentation, you agree that you have read, understood,
+ and will comply with the following terms and conditions:
+
+ Permission to use, copy, modify, and distribute this software and
+ its associated documentation for any purpose and without fee is
+ hereby granted, provided that the above copyright notice appears in
+ all copies, and that both that copyright notice and this permission
+ notice appear in supporting documentation, and that the name of
+ the author not be used in advertising or publicity
+ pertaining to distribution of the software without specific, written
+ prior permission.
+
+ THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
+ TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
+ ABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
+ BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
+ DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ OF THIS SOFTWARE.
+---------------------------------------------------------------------
+
+
+Limitations/restrictions of the current release:
+
+- no checks if derived type and base type match
+- no check of attributes "final", "finalDefault"
+- no support of substitution groups
+- no support of abstract elements and types
+- restrictions regarding for pattern matching:
+ * subtraction of character sets not supported, e.g. regex = "[\w-[ab]]"
+ * characters sets with \I, \C, \P{...} not supported, e.g. regex = "[\S\I\?a-c\?]"
+ (character sets with \i, \c, \p{...} are supported!)
+
+Note: This constraint list may not be complete!!
+
+
+---------------------------------------------------------------------
+
+Contents
+========
+
+README.txt
+__init__.py
+minixsv
+minixsvWrapper.py
+pyxsval.py
+xsvalBase.py
+xsvalErrorHandler.py
+xsvalSchema.py
+xsvalSimpleTypes.py
+xsvalUtils.py
+xsvalXmlIf.py
+datatypes.xsd
+XInclude.xsd
+xml.xsd
+XMLSchema.xsd
+XMLSchema-instance.xsd
+
+---------------------------------------------------------------------
+
+HISTORY:
+=======
+
+Changes for Release 0.9.0
+=========================
+
+- Caution, Interface changed!
+ * In case of parser and XInclude errors now a GenXmlIfError exception is raised!
+ * New optional parameter 'useCaching=1' and 'processXInclude=1' to XsValidator class added
+
+- check of facets of derived primitive types added
+- unicode support added (except wide unicode characters)
+- major improvements for pattern matching (but there are still some restrictions, refer above)
+- limited support of XInclude added (no support of fallback tag)
+- performance optimizations (caching introduced)
+- several bugs fixed (new W3C test suite (2006-11-06) passed for supported features)
+ 3943 of 3953 nisttest testgroups passed
+ 8645 of 9745 mstest testgroups passed
+ 559 of 679 suntest testgroups passed
+ (most not passed test groups correspond to the limitations listed above)
+
+
+Changes for Release 0.8
+=======================
+
+- Caution, Interface changed!
+ When calling the validator (e.g. using parseAndValidate or parseAndValidateString)
+ the input parameter xsdFile/xsdText is only used if no schema file is specified in the XML input file/string,
+ i.e. the schema specification in the XML input file/string has now priority!!
+
+- uniqueness of attribute/attributeGroup/type IDs now checked
+- problems with different target namespaces fixed
+- "redefine" element now supported
+- performance optimization due to optimized genxmlif (when elementtree parser is used)
+- several bugs fixed (W3C test suite passed for supported features)
+ 3953 of 3953 nisttest testgroups passed
+ 4260 of 4529 msxsdtest testgroups passed
+ 31 of 40 suntest testgroups passed
+ (most not passed test groups correspond to the limitations listed above)
+
+
+Changes for Release 0.7
+=======================
+
+- now all primitive data types are supported
+- check if no element content exists when xsi:nil = "true" is specified
+- support of "processContents" attribute
+- correct uniqueness checking of identity constraints (unique/key/keyref)
+- many bugs fixed (W3C test suite passed for supported features)
+ 3953 of 3953 nisttest testgroups passed
+ 3996 of 4529 msxsdtest testgroups passed
+ 27 of 40 suntest testgroups passed
+ (most not passed test groups correspond to the limitations listed above)
+
+
+Changes for Release 0.5
+=======================
+
+- generic XML interface extracted into a separate python package
+- namespace support added
+- 4DOM support added
+- support of attributes "elementFormDefault", "attributeFormDefault", "form" added
+- support of "import" element added
+- handling of "schemaLocation" and "noNamespaceSchemaLocation" corrected
+- support of derivation of complex types from simple types (extension) added
+- support of mixed content (child nodes and text nodes) added
+- new access function to add user defined XML interface class
+- new access function to add user defined validation function for unsupported predefined types
+- several bugs fixed
+
+
+Changes for Release 0.3
+=======================
+
+- API re-structured
+- XML text processing added
+- several bugs fixed
+- internal re-structuring
+
+
+Changes for Release 0.2
+=======================
+
+- Error/warning outputs contain now also filename and linenumber
+- Basic URI support for include directive added
+- XML interface classes completely re-designed
+- several bugs fixed
+
+
diff --git a/mavlink-solo/pymavlink/generator/lib/minixsv/XInclude.xsd b/mavlink-solo/pymavlink/generator/lib/minixsv/XInclude.xsd
new file mode 100644
index 0000000..f0a4c98
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/lib/minixsv/XInclude.xsd
@@ -0,0 +1,46 @@
+
+
+
+
+ Not normative, but may be useful.
+ See the REC http://www.w3.org/TR/XInclude for definitive
+ information about this namespace.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/mavlink-solo/pymavlink/generator/lib/minixsv/XMLSchema-instance.xsd b/mavlink-solo/pymavlink/generator/lib/minixsv/XMLSchema-instance.xsd
new file mode 100644
index 0000000..517af42
--- /dev/null
+++ b/mavlink-solo/pymavlink/generator/lib/minixsv/XMLSchema-instance.xsd
@@ -0,0 +1,28 @@
+
+
+
+
+
+