mavgen.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 '''
00004 parse a MAVLink protocol XML file and generate a python implementation
00005 
00006 Copyright Andrew Tridgell 2011
00007 Released under GNU GPL version 3 or later
00008 
00009 '''
00010 import sys, textwrap, os, copy
00011 from . import mavparse
00012 
00013 # XSD schema file
00014 schemaFile = os.path.join(os.path.dirname(os.path.realpath(__file__)), "mavschema.xsd")
00015 
00016 # Set defaults for generating MAVLink code
00017 DEFAULT_WIRE_PROTOCOL = mavparse.PROTOCOL_1_0
00018 DEFAULT_LANGUAGE = 'Python'
00019 DEFAULT_ERROR_LIMIT = 200
00020 DEFAULT_VALIDATE = True
00021 
00022 # List the supported languages. This is done globally because it's used by the GUI wrapper too
00023 supportedLanguages = ["C", "CS", "JavaScript", "Python", "WLua", "ObjC", "Swift", "Java"]
00024 
00025 
00026 def mavgen(opts, args) :
00027     """Generate mavlink message formatters and parsers (C and Python ) using options
00028     and args where args are a list of xml files. This function allows python
00029     scripts under Windows to control mavgen using the same interface as
00030     shell scripts under Unix"""
00031 
00032     xml = []
00033 
00034     # Enable validation by default, disabling it if explicitly requested
00035     if opts.validate:
00036         try:
00037             from lib.genxmlif import GenXmlIfError
00038             from lib.minixsv import pyxsval
00039         except:
00040             print("WARNING: Unable to load XML validator libraries. XML validation will not be performed")
00041             opts.validate = False
00042 
00043     def mavgen_validate(fname, schema, errorLimitNumber) :
00044         """Uses minixsv to validate an XML file with a given XSD schema file. We define mavgen_validate
00045            here because it relies on the XML libs that were loaded in mavgen(), so it can't be called standalone"""
00046         # use default values of minixsv, location of the schema file must be specified in the XML file
00047         domTreeWrapper = pyxsval.parseAndValidate(fname, xsdFile=schema, errorLimit=errorLimitNumber)
00048 
00049     # Process all XML files, validating them as necessary.
00050     for fname in args:
00051         if opts.validate:
00052             print("Validating %s" % fname)
00053             mavgen_validate(fname, schemaFile, opts.error_limit);
00054         else:
00055             print("Validation skipped for %s." % fname)
00056 
00057         print("Parsing %s" % fname)
00058         xml.append(mavparse.MAVXML(fname, opts.wire_protocol))
00059 
00060     # expand includes
00061     for x in xml[:]:
00062         for i in x.include:
00063             fname = os.path.join(os.path.dirname(x.filename), i)
00064 
00065             ## Validate XML file with XSD file if possible.
00066             if opts.validate:
00067                 print("Validating %s" % fname)
00068                 mavgen_validate(fname, schemaFile, opts.error_limit);
00069             else:
00070                 print("Validation skipped for %s." % fname)
00071 
00072             ## Parsing
00073             print("Parsing %s" % fname)
00074             xml.append(mavparse.MAVXML(fname, opts.wire_protocol))
00075 
00076             # include message lengths and CRCs too
00077             x.message_crcs.update(xml[-1].message_crcs)
00078             x.message_lengths.update(xml[-1].message_lengths)
00079             x.message_min_lengths.update(xml[-1].message_min_lengths)
00080             x.message_flags.update(xml[-1].message_flags)
00081             x.message_target_system_ofs.update(xml[-1].message_target_system_ofs)
00082             x.message_target_component_ofs.update(xml[-1].message_target_component_ofs)
00083             x.message_names.update(xml[-1].message_names)
00084             x.largest_payload = max(x.largest_payload, xml[-1].largest_payload)
00085 
00086     # work out max payload size across all includes
00087     largest_payload = 0
00088     for x in xml:
00089         if x.largest_payload > largest_payload:
00090             largest_payload = x.largest_payload
00091     for x in xml:
00092         x.largest_payload = largest_payload
00093 
00094     if mavparse.check_duplicates(xml):
00095         sys.exit(1)
00096 
00097     print("Found %u MAVLink message types in %u XML files" % (
00098         mavparse.total_msgs(xml), len(xml)))
00099 
00100     # Convert language option to lowercase and validate
00101     opts.language = opts.language.lower()
00102     if opts.language == 'python':
00103         from . import mavgen_python
00104         mavgen_python.generate(opts.output, xml)
00105     elif opts.language == 'c':
00106         from . import mavgen_c
00107         mavgen_c.generate(opts.output, xml)
00108     elif opts.language == 'wlua':
00109         from . import mavgen_wlua
00110         mavgen_wlua.generate(opts.output, xml)
00111     elif opts.language == 'cs':
00112         from . import mavgen_cs
00113         mavgen_cs.generate(opts.output, xml)
00114     elif opts.language == 'javascript':
00115         from . import mavgen_javascript
00116         mavgen_javascript.generate(opts.output, xml)
00117     elif opts.language == 'objc':
00118         from . import mavgen_objc
00119         mavgen_objc.generate(opts.output, xml)
00120     elif opts.language == 'swift':
00121         from . import mavgen_swift
00122         mavgen_swift.generate(opts.output, xml)
00123     elif opts.language == 'java':
00124         from . import mavgen_java
00125         mavgen_java.generate(opts.output, xml)
00126     else:
00127         print("Unsupported language %s" % opts.language)
00128 
00129 
00130 # build all the dialects in the dialects subpackage
00131 class Opts:
00132     def __init__(self, output, wire_protocol=DEFAULT_WIRE_PROTOCOL, language=DEFAULT_LANGUAGE, validate=DEFAULT_VALIDATE, error_limit=DEFAULT_ERROR_LIMIT):
00133         self.wire_protocol = wire_protocol
00134         self.error_limit = error_limit
00135         self.language = language
00136         self.output = output
00137         self.validate = validate
00138 
00139 def mavgen_python_dialect(dialect, wire_protocol):
00140     '''generate the python code on the fly for a MAVLink dialect'''
00141     dialects = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'dialects')
00142     mdef = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', 'message_definitions')
00143     if wire_protocol == mavparse.PROTOCOL_0_9:
00144         py = os.path.join(dialects, 'v09', dialect + '.py')
00145         xml = os.path.join(dialects, 'v09', dialect + '.xml')
00146         if not os.path.exists(xml):
00147             xml = os.path.join(mdef, 'v0.9', dialect + '.xml')
00148     elif wire_protocol == mavparse.PROTOCOL_1_0:
00149         py = os.path.join(dialects, 'v10', dialect + '.py')
00150         xml = os.path.join(dialects, 'v10', dialect + '.xml')
00151         if not os.path.exists(xml):
00152             xml = os.path.join(mdef, 'v1.0', dialect + '.xml')
00153     else:
00154         py = os.path.join(dialects, 'v20', dialect + '.py')
00155         xml = os.path.join(dialects, 'v20', dialect + '.xml')
00156         if not os.path.exists(xml):
00157             xml = os.path.join(mdef, 'v1.0', dialect + '.xml')
00158     opts = Opts(py, wire_protocol)
00159 
00160      # Python 2 to 3 compatibility
00161     try:
00162         import StringIO as io
00163     except ImportError:
00164         import io
00165 
00166     # throw away stdout while generating
00167     stdout_saved = sys.stdout
00168     sys.stdout = io.StringIO()
00169     try:
00170         xml = os.path.relpath(xml)
00171         mavgen( opts, [xml] )
00172     except Exception:
00173         sys.stdout = stdout_saved
00174         raise
00175     sys.stdout = stdout_saved
00176 
00177 if __name__ == "__main__":
00178     raise DeprecationWarning("Executable was moved to pymavlink.tools.mavgen")


mavlink
Author(s): Lorenz Meier
autogenerated on Thu Jun 6 2019 19:01:57