Commit 376aa04e authored by lm's avatar lm

MAVLink generator works as python call now on *nix systems

parent f6397a08
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _CHECKSUM_H_
#define _CHECKSUM_H_
/**
*
* 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(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
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _CHECKSUM_H_
#define _CHECKSUM_H_
/**
*
* 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(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
This diff is collapsed.
#ifndef MAVLINK_TYPES_H_
#define MAVLINK_TYPES_H_
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
};
#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
typedef struct param_union {
union {
float param_float;
int32_t param_int32;
uint32_t param_uint32;
};
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 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 array_length; // if non-zero, field is an array
unsigned wire_offset; // offset of each field in the payload
unsigned 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) ((char *)(&(msg)->payload64[0]))
// checksum is immediately after the payload bytes
#define mavlink_ck_a(msg) *(msg->len + (uint8_t *)_MAV_PAYLOAD(msg))
#define mavlink_ck_b(msg) *((msg->len+(uint16_t)1) + (uint8_t *)_MAV_PAYLOAD(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_ */
This diff is collapsed.
#!/usr/bin/env python
'''
parse a MAVLink protocol XML file and generate a python implementation
Copyright Andrew Tridgell 2011
Released under GNU GPL version 3 or later
'''
import sys, textwrap, os
from optparse import OptionParser
# allow import from the parent directory, where mavutil.py is
sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), '..'))
import mavparse
import mavgen_python
import mavgen_c
parser = OptionParser("mavgen.py [options] <XML files>")
parser.add_option("-o", "--output", dest="output", default="mavlink", help="output base name")
parser.add_option("--lang", dest="language", default="python", help="language to generate")
parser.add_option("--wire-protocol", dest="wire_protocol", default=mavparse.PROTOCOL_0_9, help="wire protocol version")
(opts, args) = parser.parse_args()
if len(args) < 1:
parser.error("You must supply at least one MAVLink XML protocol definition")
xml = []
for fname in args:
print("Parsing %s" % fname)
xml.append(mavparse.MAVXML(fname, opts.wire_protocol))
# expand includes
for x in xml[:]:
for i in x.include:
fname = os.path.join(os.path.dirname(x.filename), i)
print("Parsing %s" % fname)
xml.append(mavparse.MAVXML(fname, opts.wire_protocol))
# include message lengths and CRCs too
for idx in range(0, 256):
if x.message_lengths[idx] == 0:
x.message_lengths[idx] = xml[-1].message_lengths[idx]
x.message_crcs[idx] = xml[-1].message_crcs[idx]
x.message_names[idx] = xml[-1].message_names[idx]
# work out max payload size across all includes
largest_payload = 0
for x in xml:
if x.largest_payload > largest_payload:
largest_payload = x.largest_payload
for x in xml:
x.largest_payload = largest_payload
if mavparse.check_duplicates(xml):
sys.exit(1)
print("Found %u MAVLink message types in %u XML files" % (
mavparse.total_msgs(xml), len(xml)))
if opts.language == 'python':
mavgen_python.generate(opts.output, xml)
elif opts.language == 'C':
mavgen_c.generate(opts.output, xml)
else:
print("Unsupported language %s" % opts.language)
#!/usr/bin/env python
'''
generate a MAVLink test suite
Copyright Andrew Tridgell 2011
Released under GNU GPL version 3 or later
'''
import sys, textwrap
from optparse import OptionParser
import mavparse
def gen_value(f, i, language):
'''generate a test value for the ith field of a message'''
type = f.type
# could be an array
if type.find("[") != -1:
aidx = type.find("[")
basetype = type[0:aidx]
if basetype == "array":
basetype = "int8_t"
if language == 'C':
return '(const %s *)"%s%u"' % (basetype, f.name, i)
return '"%s%u"' % (f.name, i)
if type == 'float':
return 17.0 + i*7
if type == 'char':
return 'A' + i
if type == 'int8_t':
return 5 + i
if type in ['int8_t', 'uint8_t']:
return 5 + i
if type in ['uint8_t_mavlink_version']:
return 2
if type in ['int16_t', 'uint16_t']:
return 17235 + i*52
if type in ['int32_t', 'uint32_t']:
v = 963497464 + i*52
if language == 'C':
return "%sL" % v
return v
if type in ['int64_t', 'uint64_t']:
v = 9223372036854775807 + i*63
if language == 'C':
return "%sLL" % v
return v
def generate_methods_python(outf, msgs):
outf.write("""
'''
MAVLink protocol test implementation (auto-generated by mavtestgen.py)
Generated from: %s
Note: this file has been auto-generated. DO NOT EDIT
'''
import mavlink
def generate_outputs(mav):
'''generate all message types as outputs'''
""")
for m in msgs:
if m.name == "HEARTBEAT": continue
outf.write("\tmav.%s_send(" % m.name.lower())
for i in range(0, len(m.fields)):
f = m.fields[i]
outf.write("%s=%s" % (f.name, gen_value(f, i, 'py')))
if i != len(m.fields)-1:
outf.write(",")
outf.write(")\n")
def generate_methods_C(outf, msgs):
outf.write("""
/*
MAVLink protocol test implementation (auto-generated by mavtestgen.py)
Generated from: %s
Note: this file has been auto-generated. DO NOT EDIT
*/
static void mavtest_generate_outputs(mavlink_channel_t chan)
{
""")
for m in msgs:
if m.name == "HEARTBEAT": continue
outf.write("\tmavlink_msg_%s_send(chan," % m.name.lower())
for i in range(0, len(m.fields)):
f = m.fields[i]
outf.write("%s" % gen_value(f, i, 'C'))
if i != len(m.fields)-1:
outf.write(",")
outf.write(");\n")
outf.write("}\n")
######################################################################
'''main program'''
parser = OptionParser("mavtestgen.py [options] <XML files>")
parser.add_option("-o", "--output", dest="output", default="mavtest", help="output file base name")
(opts, args) = parser.parse_args()
if len(args) < 1:
parser.error("You must supply at least one MAVLink XML protocol definition")
msgs = []
enums = []
for fname in args:
(m, e) = mavparse.parse_mavlink_xml(fname)
msgs.extend(m)
enums.extend(e)
if mavparse.check_duplicates(msgs):
sys.exit(1)
print("Found %u MAVLink message types" % len(msgs))
print("Generating python %s" % (opts.output+'.py'))
outf = open(opts.output + '.py', "w")
generate_methods_python(outf, msgs)
outf.close()
print("Generating C %s" % (opts.output+'.h'))
outf = open(opts.output + '.h', "w")
generate_methods_C(outf, msgs)
outf.close()
print("Generated %s OK" % opts.output)
......@@ -96,24 +96,32 @@ void MAVLinkXMLParserV10::processError(QProcess::ProcessError err)
bool MAVLinkXMLParserV10::generate()
{
#ifdef Q_OS_WIN
QString python("python.exe");
QString generatorCall("%1/files/mavlink_generator/generator/mavgen.exe");
#endif
#if (defined Q_OS_MAC) || (defined Q_OS_LINUX)
QString python("python");
QString generatorCall("python");
#endif
QString lang("C");
QString version("1.0");
QStringList arguments;
#if (defined Q_OS_MAC) || (defined Q_OS_LINUX)
// Script is only needed as argument if Python is used, the Py2Exe implicitely knows the script
arguments << QString("%1/files/mavlink_generator/generator/mavgen.py").arg(QApplication::applicationDirPath());
#endif
arguments << QString("--lang=%1").arg(lang);
arguments << QString("--output=%2").arg(outputDirName);
arguments << QString("%3").arg(fileName);
arguments << QString("--wire-protocol=%4").arg(version);
QString generatorCall(QString("%1 %2/files/pymavlink/generator/mavgen.py %3").arg(python).arg(QApplication::applicationDirPath()));
qDebug() << "Attempted to start" << generatorCall << arguments;
return (process->execute(generatorCall, arguments) == 0);
process = new QProcess(this);
connect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
bool result = (process->execute(generatorCall, arguments) == 0);
// Print process status
emit parseState(QString("<font color=\"red\">%1</font>").arg(QString(process->readAllStandardError())));
emit parseState(QString(process->readAllStandardOutput()));
return result;
}
///**
......
......@@ -71,17 +71,6 @@ void XMLCommProtocolWidget::setXML(const QString& xml)
} else {
m_ui->validXMLLabel->setText(tr("<font color=\"red\">File is NOT valid XML, please fix in editor</font>"));
}
if (model != NULL) {
m_ui->xmlTreeView->reset();
//delete model;
}
model = new DomModel(doc, this);
m_ui->xmlTreeView->setModel(model);
// Expand the tree so that message names are visible
m_ui->xmlTreeView->expandToDepth(1);
m_ui->xmlTreeView->hideColumn(2);
m_ui->xmlTreeView->repaint();
}
void XMLCommProtocolWidget::selectOutputDirectory()
......
......@@ -13,7 +13,7 @@
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout" rowstretch="1,1,100,1,1,1,0" columnstretch="1,1,1,100">
<layout class="QGridLayout" name="gridLayout" rowstretch="1,0,0,0,0,0" columnstretch="1,0,0,0">
<property name="topMargin">
<number>6</number>
</property>
......@@ -56,7 +56,7 @@
</property>
</widget>
</item>
<item row="0" column="3" rowspan="7">
<item row="0" column="3" rowspan="6">
<widget class="QGCMAVLinkTextEdit" name="xmlTextView">
<property name="minimumSize">
<size>
......@@ -102,34 +102,31 @@
</property>
</widget>
</item>
<item row="3" column="0" colspan="3">
<widget class="QTreeView" name="xmlTreeView"/>
</item>
<item row="4" column="0" colspan="2">
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="label">
<property name="text">
<string>Compile Output</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="3">
<item row="4" column="0" colspan="3">
<widget class="QPlainTextEdit" name="compileLog"/>
</item>
<item row="6" column="0">
<item row="5" column="0">
<widget class="QLabel" name="validXMLLabel">
<property name="text">
<string>No file loaded</string>
</property>
</widget>
</item>
<item row="6" column="1">
<item row="5" column="1">
<widget class="QPushButton" name="saveButton">
<property name="text">
<string>Save file</string>
</property>
</widget>
</item>
<item row="6" column="2">
<item row="5" column="2">
<widget class="QPushButton" name="generateButton">
<property name="text">
<string>Save and generate</string>
......@@ -149,11 +146,11 @@
</item>
<item row="2" column="2">
<widget class="QComboBox" name="versionComboBox">
<item>
<property name="text">
<string>MAVLink v1.0 (Sept'10+)</string>
</property>
</item>
<item>
<property name="text">
<string>MAVLink v1.0 (Sept'10+)</string>
</property>
</item>
<item>
<property name="text">
<string>MAVLink v0.9 (-Aug'10)</string>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment