Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export pprz messages into OpenDDS format #69

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Option to generate OpenDDS compatible IDL file
  • Loading branch information
podhrmic committed Dec 1, 2017
commit 2831bdc5db3e3d07ccac0e2484f45e4994ff95bd
2 changes: 1 addition & 1 deletion tools/generator/gen_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def pprz_validate(fname, schema, errorLimitNumber) :
parser = ArgumentParser(description="This tool generate implementations from PPRZLink message definitions")
parser.add_argument("-o", "--output", default="stdout", help="output file or stream [default: %(default)s]")
parser.add_argument("--lang", dest="language", choices=supportedLanguages, default=DEFAULT_LANGUAGE, help="language of generated code [default: %(default)s]")
parser.add_argument("--protocol", choices=[pprz_parse.PROTOCOL_1_0,pprz_parse.PROTOCOL_2_0], default=DEFAULT_PROTOCOL, help="PPRZLink protocol version. [default: %(default)s]")
parser.add_argument("--protocol", choices=[pprz_parse.PROTOCOL_1_0,pprz_parse.PROTOCOL_2_0, pprz_parse.PROTOCOL_OPENDDS], default=DEFAULT_PROTOCOL, help="PPRZLink protocol version. [default: %(default)s]")
parser.add_argument("--messages", choices=[pprz_parse.MESSAGES_1_0], default=DEFAULT_MESSAGES, help="PPRZLink message definitino version. [default: %(default)s]")
parser.add_argument("--no-validate", action="store_false", dest="validate", default=DEFAULT_VALIDATE, help="Do not perform XML validation. Can speed up code generation if XML files are known to be correct.")
parser.add_argument("--only-validate", action="store_true", dest="only_validate", help="Only validate messages without generation.")
Expand Down
97 changes: 97 additions & 0 deletions tools/generator/gen_messages_opendds_c.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/usr/bin/env python
'''
parse a PPRZLink protocol XML file and generate a OpenDDS compatible
IDL file. See http://opendds.org/ for details.

Copyright (C) 2017 Michal Podhradsky <mpodhradsky@galois.com>
For the Paparazzi UAV and PPRZLINK projects
'''
import re
import sys, os
import gen_messages, pprz_template, pprz_parse

t = pprz_template.PPRZTemplate()

def generate_messages_h(directory, name, xml):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe find a better name, it is not a .h file

print(xml)
'''generate messages header'''
if name == 'stdout':
f = sys.stdout
else:
f = open(os.path.join(directory, name), mode='w')
t.write(f,'''
/*
*
*
* Distributed under the OpenDDS License.
* See: http://www.opendds.org/license.html
*/

typedef sequence<unsigned short> unsigned_short_array; // uint8 ot uint16[]
typedef sequence<short> short_array; // int8 or int16[]
typedef sequence<unsigned long> unsigned_long_array; // uint32[]
typedef sequence<long> long_array; // int32[]
typedef sequence<float> float_array; // float[]
typedef sequence<double> double_array; // double[]

module ${class_name} {
${{message:
#pragma DCPS_DATA_TYPE "${class_name}::${msg_name}"
#pragma DCPS_DATA_TYPE "${class_name}::${msg_name} msg_id"

struct ${msg_name} {
short msg_id;
${{fields: ${opendds_type} field_${attrib_macro}}}
};
}}

};
''', xml)
if name != 'stdout':
f.close()

def eval_int(expr):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is it used ?

import ast
return int(eval(compile(ast.parse(expr, mode='eval'), '<string>', 'eval')))

def generate(output, xml):
'''generate complete PPRZLink C implemenation from a XML messages file'''

directory, name = os.path.split(output)


print("Generating C implementation in %s" % output)
if directory != '':
pprz_parse.mkdir_p(directory)

# fix the class name to conform with standards
xml.class_name = xml.class_name.title()

# add some extra field attributes for convenience with arrays
for m in xml.message:
m.msg_name = m.msg_name.title()
m.msg_name = re.sub('[_]', '', m.msg_name)
offset = 2 # 2 bytes initial offset (sender id, message id)
for f in m.fields:
if f.type == 'uint8_t' or f.type == 'uint16_t' or f.type == 'char':
f.opendds_type = 'unsigned short'
elif f.type == 'int8_t' or f.type == 'int16_t':
f.opendds_type = 'short'
elif f.type == 'uint32_t':
f.opendds_type = 'unsigned long'
elif f.type == 'int32_t':
f.opendds_type = 'long'
elif f.type == 'float':
f.opendds_type = 'float'
elif f.type == 'double':
f.opendds_type = 'double'
else:
f.opendds_type = 'void'

if not type(f.array_type) == type(None):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usually something like if f.array_type is not None works

# it is an array - wrap as a stream
f.opendds_type = re.sub('[ ]', '_', f.opendds_type) + '_array'

f.attrib_macro = '%s;\n' % f.field_name

generate_messages_h(directory, name, xml)
7 changes: 6 additions & 1 deletion tools/generator/pprz_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

PROTOCOL_1_0 = "1.0"
PROTOCOL_2_0 = "2.0"
PROTOCOL_OPENDDS = "DDS"
MESSAGES_1_0 = "1.0"

class PPRZParseError(Exception):
Expand Down Expand Up @@ -101,9 +102,13 @@ def __init__(self, filename, class_name, protocol_version=PROTOCOL_1_0):
self.protocol_version_major = 2
self.protocol_version_minor = 0
self.generator_module = "gen_messages_v2_0"
elif protocol_version == PROTOCOL_OPENDDS:
self.protocol_version_major = 0
self.protocol_version_minor = 0
self.generator_module = "gen_messages_opendds"
else:
print("Unknown wire protocol version")
print("Available versions are: %s" % (PROTOCOL_1_0))
print("Available versions are: %s, %s and %s" % (PROTOCOL_1_0, PROTOCOL_2_0, PROTOCOL_OPENDDS))
raise PPRZParseError('Unknown PPRZLink protocol version %s' % protocol_version)

in_element_list = []
Expand Down