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 all commits
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
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)
4 changes: 2 additions & 2 deletions tools/generator/gen_messages_v1_0_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ def generate_messages_h(directory, name, xml):
f = open(os.path.join(directory, name), mode='w')
t.write(f,'''
/** @file
* @brief PPRZLink messages header built from ${filename}
* @see http://paparazziuav.org
* @brief PPRZLink messages header built from ${filename}
* @see http://paparazziuav.org
*/
#ifndef _VAR_MESSAGES_${class_name}_H_
#define _VAR_MESSAGES_${class_name}_H_
Expand Down
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