mavgen_python.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 '''
00003 parse a MAVLink protocol XML file and generate a python implementation
00004 
00005 Copyright Andrew Tridgell 2011
00006 Released under GNU GPL version 3 or later
00007 '''
00008 
00009 import sys, textwrap, os
00010 from . import mavparse, mavtemplate
00011 
00012 t = mavtemplate.MAVTemplate()
00013 
00014 def generate_preamble(outf, msgs, basename, args, xml):
00015     print("Generating preamble")
00016     t.write(outf, """
00017 '''
00018 MAVLink protocol implementation (auto-generated by mavgen.py)
00019 
00020 Generated from: ${FILELIST}
00021 
00022 Note: this file has been auto-generated. DO NOT EDIT
00023 '''
00024 
00025 import struct, array, time, json, os, sys, platform
00026 
00027 from ...generator.mavcrc import x25crc
00028 
00029 WIRE_PROTOCOL_VERSION = "${WIRE_PROTOCOL_VERSION}"
00030 DIALECT = "${DIALECT}"
00031 
00032 native_supported = platform.system() != 'Windows' # Not yet supported on other dialects
00033 native_force = 'MAVNATIVE_FORCE' in os.environ # Will force use of native code regardless of what client app wants
00034 native_testing = 'MAVNATIVE_TESTING' in os.environ # Will force both native and legacy code to be used and their results compared
00035 
00036 if native_supported:
00037     try:
00038         import mavnative
00039     except ImportError:
00040         print("ERROR LOADING MAVNATIVE - falling back to python implementation")
00041         native_supported = False
00042 
00043 # some base types from mavlink_types.h
00044 MAVLINK_TYPE_CHAR     = 0
00045 MAVLINK_TYPE_UINT8_T  = 1
00046 MAVLINK_TYPE_INT8_T   = 2
00047 MAVLINK_TYPE_UINT16_T = 3
00048 MAVLINK_TYPE_INT16_T  = 4
00049 MAVLINK_TYPE_UINT32_T = 5
00050 MAVLINK_TYPE_INT32_T  = 6
00051 MAVLINK_TYPE_UINT64_T = 7
00052 MAVLINK_TYPE_INT64_T  = 8
00053 MAVLINK_TYPE_FLOAT    = 9
00054 MAVLINK_TYPE_DOUBLE   = 10
00055 
00056 
00057 class MAVLink_header(object):
00058     '''MAVLink message header'''
00059     def __init__(self, msgId, mlen=0, seq=0, srcSystem=0, srcComponent=0):
00060         self.mlen = mlen
00061         self.seq = seq
00062         self.srcSystem = srcSystem
00063         self.srcComponent = srcComponent
00064         self.msgId = msgId
00065 
00066     def pack(self):
00067         return struct.pack('BBBBBB', ${PROTOCOL_MARKER}, self.mlen, self.seq,
00068                           self.srcSystem, self.srcComponent, self.msgId)
00069 
00070 class MAVLink_message(object):
00071     '''base MAVLink message class'''
00072     def __init__(self, msgId, name):
00073         self._header     = MAVLink_header(msgId)
00074         self._payload    = None
00075         self._msgbuf     = None
00076         self._crc        = None
00077         self._fieldnames = []
00078         self._type       = name
00079 
00080     def get_msgbuf(self):
00081         if isinstance(self._msgbuf, bytearray):
00082             return self._msgbuf
00083         return bytearray(self._msgbuf)
00084 
00085     def get_header(self):
00086         return self._header
00087 
00088     def get_payload(self):
00089         return self._payload
00090 
00091     def get_crc(self):
00092         return self._crc
00093 
00094     def get_fieldnames(self):
00095         return self._fieldnames
00096 
00097     def get_type(self):
00098         return self._type
00099 
00100     def get_msgId(self):
00101         return self._header.msgId
00102 
00103     def get_srcSystem(self):
00104         return self._header.srcSystem
00105 
00106     def get_srcComponent(self):
00107         return self._header.srcComponent
00108 
00109     def get_seq(self):
00110         return self._header.seq
00111 
00112     def __str__(self):
00113         ret = '%s {' % self._type
00114         for a in self._fieldnames:
00115             v = getattr(self, a)
00116             ret += '%s : %s, ' % (a, v)
00117         ret = ret[0:-2] + '}'
00118         return ret
00119 
00120     def __ne__(self, other):
00121         return not self.__eq__(other)
00122 
00123     def __eq__(self, other):
00124         if other == None:
00125             return False
00126 
00127         if self.get_type() != other.get_type():
00128             return False
00129 
00130         # We do not compare CRC because native code doesn't provide it
00131         #if self.get_crc() != other.get_crc():
00132         #    return False
00133 
00134         if self.get_seq() != other.get_seq():
00135             return False
00136 
00137         if self.get_srcSystem() != other.get_srcSystem():
00138             return False            
00139 
00140         if self.get_srcComponent() != other.get_srcComponent():
00141             return False   
00142             
00143         for a in self._fieldnames:
00144             if getattr(self, a) != getattr(other, a):
00145                 return False
00146 
00147         return True
00148 
00149     def to_dict(self):
00150         d = dict({})
00151         d['mavpackettype'] = self._type
00152         for a in self._fieldnames:
00153           d[a] = getattr(self, a)
00154         return d
00155 
00156     def to_json(self):
00157         return json.dumps(self.to_dict())
00158 
00159     def pack(self, mav, crc_extra, payload):
00160         self._payload = payload
00161         self._header  = MAVLink_header(self._header.msgId, len(payload), mav.seq,
00162                                        mav.srcSystem, mav.srcComponent)
00163         self._msgbuf = self._header.pack() + payload
00164         crc = x25crc(self._msgbuf[1:])
00165         if ${crc_extra}: # using CRC extra
00166             crc.accumulate_str(struct.pack('B', crc_extra))
00167         self._crc = crc.crc
00168         self._msgbuf += struct.pack('<H', self._crc)
00169         return self._msgbuf
00170 
00171 """, {'FILELIST' : ",".join(args),
00172       'PROTOCOL_MARKER' : xml.protocol_marker,
00173       'DIALECT' : os.path.splitext(os.path.basename(basename))[0],
00174       'crc_extra' : xml.crc_extra,
00175       'WIRE_PROTOCOL_VERSION' : xml.wire_protocol_version })
00176 
00177 def generate_enums(outf, enums):
00178     print("Generating enums")
00179     outf.write('''
00180 # enums
00181 
00182 class EnumEntry(object):
00183     def __init__(self, name, description):
00184         self.name = name
00185         self.description = description
00186         self.param = {}
00187         
00188 enums = {}
00189 ''')    
00190     wrapper = textwrap.TextWrapper(initial_indent="", subsequent_indent="                        # ")
00191     for e in enums:
00192         outf.write("\n# %s\n" % e.name)
00193         outf.write("enums['%s'] = {}\n" % e.name)
00194         for entry in e.entry:
00195             outf.write("%s = %u # %s\n" % (entry.name, entry.value, wrapper.fill(entry.description)))
00196             outf.write("enums['%s'][%d] = EnumEntry('%s', '''%s''')\n" % (e.name,
00197                                                                           int(entry.value), entry.name,
00198                                                                           entry.description))
00199             for param in entry.param:
00200                 outf.write("enums['%s'][%d].param[%d] = '''%s'''\n" % (e.name,
00201                                                                        int(entry.value),
00202                                                                        int(param.index),
00203                                                                        param.description))
00204 
00205 def generate_message_ids(outf, msgs):
00206     print("Generating message IDs")
00207     outf.write("\n# message IDs\n")
00208     outf.write("MAVLINK_MSG_ID_BAD_DATA = -1\n")
00209     for m in msgs:
00210         outf.write("MAVLINK_MSG_ID_%s = %u\n" % (m.name.upper(), m.id))
00211 
00212 def generate_classes(outf, msgs):
00213     print("Generating class definitions")
00214     wrapper = textwrap.TextWrapper(initial_indent="        ", subsequent_indent="        ")
00215     for m in msgs:
00216         classname = "MAVLink_%s_message" % m.name.lower()
00217         fieldname_str = ", ".join(map(lambda s: "'%s'" % s, m.fieldnames))
00218         ordered_fieldname_str = ", ".join(map(lambda s: "'%s'" % s, m.ordered_fieldnames))
00219 
00220         outf.write("""
00221 class %s(MAVLink_message):
00222         '''
00223 %s
00224         '''
00225         id = MAVLINK_MSG_ID_%s
00226         name = '%s'
00227         fieldnames = [%s]
00228         ordered_fieldnames = [ %s ]
00229         format = '%s'
00230         native_format = bytearray('%s', 'ascii')
00231         orders = %s
00232         lengths = %s
00233         array_lengths = %s
00234         crc_extra = %s
00235 
00236         def __init__(self""" % (classname, wrapper.fill(m.description.strip()), 
00237             m.name.upper(), 
00238             m.name.upper(),
00239             fieldname_str,
00240             ordered_fieldname_str,
00241             m.fmtstr,
00242             m.native_fmtstr,
00243             m.order_map,
00244             m.len_map,
00245             m.array_len_map,
00246             m.crc_extra))
00247         if len(m.fields) != 0:
00248                 outf.write(", " + ", ".join(m.fieldnames))
00249         outf.write("):\n")
00250         outf.write("                MAVLink_message.__init__(self, %s.id, %s.name)\n" % (classname, classname))
00251         outf.write("                self._fieldnames = %s.fieldnames\n" % (classname))
00252         for f in m.fields:
00253                 outf.write("                self.%s = %s\n" % (f.name, f.name))
00254         outf.write("""
00255         def pack(self, mav):
00256                 return MAVLink_message.pack(self, mav, %u, struct.pack('%s'""" % (m.crc_extra, m.fmtstr))
00257         for field in m.ordered_fields:
00258                 if (field.type != "char" and field.array_length > 1):
00259                         for i in range(field.array_length):
00260                                 outf.write(", self.{0:s}[{1:d}]".format(field.name,i))
00261                 else:
00262                         outf.write(", self.{0:s}".format(field.name))
00263         outf.write("))\n")
00264 
00265 
00266 def native_mavfmt(field):
00267     '''work out the struct format for a type (in a form expected by mavnative)'''
00268     map = {
00269         'float'    : 'f',
00270         'double'   : 'd',
00271         'char'     : 'c',
00272         'int8_t'   : 'b',
00273         'uint8_t'  : 'B',
00274         'uint8_t_mavlink_version'  : 'v',
00275         'int16_t'  : 'h',
00276         'uint16_t' : 'H',
00277         'int32_t'  : 'i',
00278         'uint32_t' : 'I',
00279         'int64_t'  : 'q',
00280         'uint64_t' : 'Q',
00281         }
00282     return map[field.type]
00283 
00284 def mavfmt(field):
00285     '''work out the struct format for a type'''
00286     map = {
00287         'float'    : 'f',
00288         'double'   : 'd',
00289         'char'     : 'c',
00290         'int8_t'   : 'b',
00291         'uint8_t'  : 'B',
00292         'uint8_t_mavlink_version'  : 'B',
00293         'int16_t'  : 'h',
00294         'uint16_t' : 'H',
00295         'int32_t'  : 'i',
00296         'uint32_t' : 'I',
00297         'int64_t'  : 'q',
00298         'uint64_t' : 'Q',
00299         }
00300 
00301     if field.array_length:
00302         if field.type == 'char':
00303             return str(field.array_length)+'s'
00304         return str(field.array_length)+map[field.type]
00305     return map[field.type]
00306 
00307 def generate_mavlink_class(outf, msgs, xml):
00308     print("Generating MAVLink class")
00309 
00310     outf.write("\n\nmavlink_map = {\n");
00311     for m in msgs:
00312         outf.write("        MAVLINK_MSG_ID_%s : MAVLink_%s_message,\n" % (m.name.upper(), m.name.lower()))
00313     outf.write("}\n\n")
00314 
00315     t.write(outf, """
00316 class MAVError(Exception):
00317         '''MAVLink error class'''
00318         def __init__(self, msg):
00319             Exception.__init__(self, msg)
00320             self.message = msg
00321 
00322 class MAVString(str):
00323         '''NUL terminated string'''
00324         def __init__(self, s):
00325                 str.__init__(self)
00326         def __str__(self):
00327             i = self.find(chr(0))
00328             if i == -1:
00329                 return self[:]
00330             return self[0:i]
00331 
00332 class MAVLink_bad_data(MAVLink_message):
00333         '''
00334         a piece of bad data in a mavlink stream
00335         '''
00336         def __init__(self, data, reason):
00337                 MAVLink_message.__init__(self, MAVLINK_MSG_ID_BAD_DATA, 'BAD_DATA')
00338                 self._fieldnames = ['data', 'reason']
00339                 self.data = data
00340                 self.reason = reason
00341                 self._msgbuf = data
00342 
00343         def __str__(self):
00344             '''Override the __str__ function from MAVLink_messages because non-printable characters are common in to be the reason for this message to exist.'''
00345             return '%s {%s, data:%s}' % (self._type, self.reason, [('%x' % ord(i) if isinstance(i, str) else '%x' % i) for i in self.data])
00346 
00347 class MAVLink(object):
00348         '''MAVLink protocol handling class'''
00349         def __init__(self, file, srcSystem=0, srcComponent=0, use_native=False):
00350                 self.seq = 0
00351                 self.file = file
00352                 self.srcSystem = srcSystem
00353                 self.srcComponent = srcComponent
00354                 self.callback = None
00355                 self.callback_args = None
00356                 self.callback_kwargs = None
00357                 self.send_callback = None
00358                 self.send_callback_args = None
00359                 self.send_callback_kwargs = None
00360                 self.buf = bytearray()
00361                 self.expected_length = 8
00362                 self.have_prefix_error = False
00363                 self.robust_parsing = False
00364                 self.protocol_marker = ${protocol_marker}
00365                 self.little_endian = ${little_endian}
00366                 self.crc_extra = ${crc_extra}
00367                 self.sort_fields = ${sort_fields}
00368                 self.total_packets_sent = 0
00369                 self.total_bytes_sent = 0
00370                 self.total_packets_received = 0
00371                 self.total_bytes_received = 0
00372                 self.total_receive_errors = 0
00373                 self.startup_time = time.time()
00374                 if native_supported and (use_native or native_testing or native_force):
00375                     print("NOTE: mavnative is currently beta-test code")
00376                     self.native = mavnative.NativeConnection(MAVLink_message, mavlink_map)
00377                 else:
00378                     self.native = None
00379                 if native_testing:
00380                     self.test_buf = bytearray()
00381 
00382         def set_callback(self, callback, *args, **kwargs):
00383             self.callback = callback
00384             self.callback_args = args
00385             self.callback_kwargs = kwargs
00386 
00387         def set_send_callback(self, callback, *args, **kwargs):
00388             self.send_callback = callback
00389             self.send_callback_args = args
00390             self.send_callback_kwargs = kwargs
00391 
00392         def send(self, mavmsg):
00393                 '''send a MAVLink message'''
00394                 buf = mavmsg.pack(self)
00395                 self.file.write(buf)
00396                 self.seq = (self.seq + 1) % 256
00397                 self.total_packets_sent += 1
00398                 self.total_bytes_sent += len(buf)
00399                 if self.send_callback:
00400                     self.send_callback(mavmsg, *self.send_callback_args, **self.send_callback_kwargs)
00401 
00402         def bytes_needed(self):
00403             '''return number of bytes needed for next parsing stage'''
00404             if self.native:
00405                 ret = self.native.expected_length - len(self.buf)
00406             else:
00407                 ret = self.expected_length - len(self.buf)
00408             
00409             if ret <= 0:
00410                 return 1
00411             return ret
00412 
00413         def __parse_char_native(self, c):
00414             '''this method exists only to see in profiling results'''
00415             m = self.native.parse_chars(c)
00416             return m
00417 
00418         def __callbacks(self, msg):
00419             '''this method exists only to make profiling results easier to read'''
00420             if self.callback:
00421                 self.callback(msg, *self.callback_args, **self.callback_kwargs)
00422 
00423         def parse_char(self, c):
00424             '''input some data bytes, possibly returning a new message'''
00425             self.buf.extend(c)
00426 
00427             self.total_bytes_received += len(c)
00428 
00429             if self.native:
00430                 if native_testing:
00431                     self.test_buf.extend(c)
00432                     m = self.__parse_char_native(self.test_buf)
00433                     m2 = self.__parse_char_legacy()
00434                     if m2 != m:
00435                         print("Native: %s\\nLegacy: %s\\n" % (m, m2))
00436                         raise Exception('Native vs. Legacy mismatch')
00437                 else:
00438                     m = self.__parse_char_native(self.buf)
00439             else:
00440                 m = self.__parse_char_legacy()
00441 
00442             if m != None:
00443                 self.total_packets_received += 1
00444                 self.__callbacks(m)
00445 
00446             return m
00447 
00448         def __parse_char_legacy(self):
00449             '''input some data bytes, possibly returning a new message (uses no native code)'''
00450             if len(self.buf) >= 1 and self.buf[0] != ${protocol_marker}:
00451                 magic = self.buf[0]
00452                 self.buf = self.buf[1:]
00453                 if self.robust_parsing:
00454                     m = MAVLink_bad_data(chr(magic), "Bad prefix")
00455                     self.expected_length = 8
00456                     self.total_receive_errors += 1
00457                     return m
00458                 if self.have_prefix_error:
00459                     return None
00460                 self.have_prefix_error = True
00461                 self.total_receive_errors += 1
00462                 raise MAVError("invalid MAVLink prefix '%s'" % magic)
00463             self.have_prefix_error = False
00464             if len(self.buf) >= 2:
00465                 if sys.version_info[0] < 3:
00466                     (magic, self.expected_length) = struct.unpack('BB', str(self.buf[0:2])) # bytearrays are not supported in py 2.7.3
00467                 else:
00468                     (magic, self.expected_length) = struct.unpack('BB', self.buf[0:2])
00469                 self.expected_length += 8
00470             if self.expected_length >= 8 and len(self.buf) >= self.expected_length:
00471                 mbuf = array.array('B', self.buf[0:self.expected_length])
00472                 self.buf = self.buf[self.expected_length:]
00473                 self.expected_length = 8
00474                 if self.robust_parsing:
00475                     try:
00476                         m = self.decode(mbuf)
00477                     except MAVError as reason:
00478                         m = MAVLink_bad_data(mbuf, reason.message)
00479                         self.total_receive_errors += 1
00480                 else:
00481                     m = self.decode(mbuf)
00482                 return m
00483             return None
00484 
00485         def parse_buffer(self, s):
00486             '''input some data bytes, possibly returning a list of new messages'''
00487             m = self.parse_char(s)
00488             if m is None:
00489                 return None
00490             ret = [m]
00491             while True:
00492                 m = self.parse_char("")
00493                 if m is None:
00494                     return ret
00495                 ret.append(m)
00496             return ret
00497 
00498         def decode(self, msgbuf):
00499                 '''decode a buffer as a MAVLink message'''
00500                 # decode the header
00501                 try:
00502                     magic, mlen, seq, srcSystem, srcComponent, msgId = struct.unpack('cBBBBB', msgbuf[:6])
00503                 except struct.error as emsg:
00504                     raise MAVError('Unable to unpack MAVLink header: %s' % emsg)
00505                 if ord(magic) != ${protocol_marker}:
00506                     raise MAVError("invalid MAVLink prefix '%s'" % magic)
00507                 if mlen != len(msgbuf)-8:
00508                     raise MAVError('invalid MAVLink message length. Got %u expected %u, msgId=%u' % (len(msgbuf)-8, mlen, msgId))
00509 
00510                 if not msgId in mavlink_map:
00511                     raise MAVError('unknown MAVLink message ID %u' % msgId)
00512 
00513                 # decode the payload
00514                 type = mavlink_map[msgId]
00515                 fmt = type.format
00516                 order_map = type.orders
00517                 len_map = type.lengths
00518                 crc_extra = type.crc_extra
00519 
00520                 # decode the checksum
00521                 try:
00522                     crc, = struct.unpack('<H', msgbuf[-2:])
00523                 except struct.error as emsg:
00524                     raise MAVError('Unable to unpack MAVLink CRC: %s' % emsg)
00525                 crcbuf = msgbuf[1:-2]
00526                 if ${crc_extra}: # using CRC extra
00527                     crcbuf.append(crc_extra)
00528                 crc2 = x25crc(crcbuf)
00529                 if crc != crc2.crc:
00530                     raise MAVError('invalid MAVLink CRC in msgID %u 0x%04x should be 0x%04x' % (msgId, crc, crc2.crc))
00531 
00532                 try:
00533                     t = struct.unpack(fmt, msgbuf[6:-2])
00534                 except struct.error as emsg:
00535                     raise MAVError('Unable to unpack MAVLink payload type=%s fmt=%s payloadLength=%u: %s' % (
00536                         type, fmt, len(msgbuf[6:-2]), emsg))
00537 
00538                 tlist = list(t)
00539                 # handle sorted fields
00540                 if ${sort_fields}:
00541                     t = tlist[:]
00542                     if sum(len_map) == len(len_map):
00543                         # message has no arrays in it
00544                         for i in range(0, len(tlist)):
00545                             tlist[i] = t[order_map[i]]
00546                     else:
00547                         # message has some arrays
00548                         tlist = []
00549                         for i in range(0, len(order_map)):
00550                             order = order_map[i]
00551                             L = len_map[order]
00552                             tip = sum(len_map[:order])
00553                             field = t[tip]
00554                             if L == 1 or isinstance(field, str):
00555                                 tlist.append(field)
00556                             else:
00557                                 tlist.append(t[tip:(tip + L)])
00558 
00559                 # terminate any strings
00560                 for i in range(0, len(tlist)):
00561                     if isinstance(tlist[i], str):
00562                         tlist[i] = str(MAVString(tlist[i]))
00563                 t = tuple(tlist)
00564                 # construct the message object
00565                 try:
00566                     m = type(*t)
00567                 except Exception as emsg:
00568                     raise MAVError('Unable to instantiate MAVLink message of type %s : %s' % (type, emsg))
00569                 m._msgbuf = msgbuf
00570                 m._payload = msgbuf[6:-2]
00571                 m._crc = crc
00572                 m._header = MAVLink_header(msgId, mlen, seq, srcSystem, srcComponent)
00573                 return m
00574 """, xml)
00575 
00576 def generate_methods(outf, msgs):
00577     print("Generating methods")
00578 
00579     def field_descriptions(fields):
00580         ret = ""
00581         for f in fields:
00582             ret += "                %-18s        : %s (%s)\n" % (f.name, f.description.strip(), f.type)
00583         return ret
00584 
00585     wrapper = textwrap.TextWrapper(initial_indent="", subsequent_indent="                ")
00586 
00587     for m in msgs:
00588         comment = "%s\n\n%s" % (wrapper.fill(m.description.strip()), field_descriptions(m.fields))
00589 
00590         selffieldnames = 'self, '
00591         for f in m.fields:
00592             if f.omit_arg:
00593                 selffieldnames += '%s=%s, ' % (f.name, f.const_value)
00594             else:
00595                 selffieldnames += '%s, ' % f.name
00596         selffieldnames = selffieldnames[:-2]
00597 
00598         sub = {'NAMELOWER'      : m.name.lower(),
00599                'SELFFIELDNAMES' : selffieldnames,
00600                'COMMENT'        : comment,
00601                'FIELDNAMES'     : ", ".join(m.fieldnames)}
00602 
00603         t.write(outf, """
00604         def ${NAMELOWER}_encode(${SELFFIELDNAMES}):
00605                 '''
00606                 ${COMMENT}
00607                 '''
00608                 return MAVLink_${NAMELOWER}_message(${FIELDNAMES})
00609 
00610 """, sub)
00611 
00612         t.write(outf, """
00613         def ${NAMELOWER}_send(${SELFFIELDNAMES}):
00614                 '''
00615                 ${COMMENT}
00616                 '''
00617                 return self.send(self.${NAMELOWER}_encode(${FIELDNAMES}))
00618 
00619 """, sub)
00620 
00621 
00622 def generate(basename, xml):
00623     '''generate complete python implemenation'''
00624     if basename.endswith('.py'):
00625         filename = basename
00626     else:
00627         filename = basename + '.py'
00628 
00629     msgs = []
00630     enums = []
00631     filelist = []
00632     for x in xml:
00633         msgs.extend(x.message)
00634         enums.extend(x.enum)
00635         filelist.append(os.path.basename(x.filename))
00636 
00637     for m in msgs:
00638         if xml[0].little_endian:
00639             m.fmtstr = '<'
00640         else:
00641             m.fmtstr = '>'
00642         m.native_fmtstr = m.fmtstr
00643         for f in m.ordered_fields:
00644             m.fmtstr += mavfmt(f)
00645             m.native_fmtstr += native_mavfmt(f)
00646         m.order_map = [ 0 ] * len(m.fieldnames)
00647         m.len_map = [ 0 ] * len(m.fieldnames)
00648         m.array_len_map = [ 0 ] * len(m.fieldnames)
00649         for i in range(0, len(m.fieldnames)):
00650             m.order_map[i] = m.ordered_fieldnames.index(m.fieldnames[i])
00651             m.array_len_map[i] = m.ordered_fields[i].array_length
00652         for i in range(0, len(m.fieldnames)):
00653             n = m.order_map[i]
00654             m.len_map[n] = m.fieldlengths[i]
00655 
00656     print("Generating %s" % filename)
00657     outf = open(filename, "w")
00658     generate_preamble(outf, msgs, basename, filelist, xml[0])
00659     generate_enums(outf, enums)
00660     generate_message_ids(outf, msgs)
00661     generate_classes(outf, msgs)
00662     generate_mavlink_class(outf, msgs, xml[0])
00663     generate_methods(outf, msgs)
00664     outf.close()
00665     print("Generated %s OK" % filename)


mavlink
Author(s): Lorenz Meier
autogenerated on Wed Sep 9 2015 18:06:17