2019-11-23 14:21:58 -04:00
|
|
|
#!/usr/bin/env python3
|
2019-01-28 11:28:40 -04:00
|
|
|
"""
|
2021-07-17 12:47:59 -03:00
|
|
|
Script to read an yaml file containing the microRTPS topics and update the naming convention to PascalCase
|
2019-01-28 11:28:40 -04:00
|
|
|
"""
|
|
|
|
|
2021-07-24 14:42:42 -03:00
|
|
|
import argparse
|
2019-12-19 06:05:55 -04:00
|
|
|
import errno
|
2021-07-24 14:42:42 -03:00
|
|
|
from pathlib import Path
|
2019-01-28 11:28:40 -04:00
|
|
|
import os
|
2019-12-19 06:05:55 -04:00
|
|
|
import six
|
2021-07-24 14:42:42 -03:00
|
|
|
import yaml
|
2019-01-28 11:28:40 -04:00
|
|
|
|
|
|
|
__author__ = 'PX4 Development Team'
|
|
|
|
__copyright__ = \
|
|
|
|
'''
|
|
|
|
'
|
2021-07-17 12:30:13 -03:00
|
|
|
' Copyright (c) 2018-2021 PX4 Development Team. All rights reserved.
|
2019-01-28 11:28:40 -04:00
|
|
|
'
|
|
|
|
' Redistribution and use in source and binary forms, or without
|
|
|
|
' modification, permitted provided that the following conditions
|
|
|
|
' are met:
|
|
|
|
'
|
|
|
|
' 1. Redistributions of source code must retain the above copyright
|
|
|
|
' notice, list of conditions and the following disclaimer.
|
|
|
|
' 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
' notice, list of conditions and the following disclaimer in
|
|
|
|
' the documentation and/or other materials provided with the
|
|
|
|
' distribution.
|
|
|
|
' 3. Neither the name PX4 nor the names of its contributors may be
|
|
|
|
' used to endorse or promote products derived from self software
|
|
|
|
' without specific prior written permission.
|
|
|
|
'
|
|
|
|
' THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
' "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, NOT
|
|
|
|
' LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
|
|
' FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
|
|
' COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
' INCIDENTAL, SPECIAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
|
|
' BUT NOT LIMITED TO, OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
|
|
' OF USE, DATA, PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
|
|
' AND ON ANY THEORY OF LIABILITY, IN CONTRACT, STRICT
|
|
|
|
' LIABILITY, TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
|
|
' ANY WAY OUT OF THE USE OF THIS SOFTWARE, IF ADVISED OF THE
|
|
|
|
' POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
'
|
|
|
|
'''
|
|
|
|
__credits__ = ['Nuno Marques <nuno.marques@dronesolution.io>']
|
|
|
|
__license__ = 'BSD-3-Clause'
|
|
|
|
__version__ = '0.1.0'
|
|
|
|
__maintainer__ = 'Nuno Marques'
|
|
|
|
__email__ = 'nuno.marques@dronesolution.io'
|
|
|
|
__status__ = 'Development'
|
|
|
|
|
2021-07-24 14:42:42 -03:00
|
|
|
verbose = False
|
2019-01-28 11:28:40 -04:00
|
|
|
|
|
|
|
|
|
|
|
class IndenterDumper(yaml.Dumper):
|
|
|
|
""" Custom dumper for yaml files that apply the correct indentation """
|
|
|
|
|
|
|
|
def increase_indent(self, flow=False, indentless=False):
|
|
|
|
return super(IndenterDumper, self).increase_indent(flow, False)
|
|
|
|
|
|
|
|
|
|
|
|
def load_yaml_file(file):
|
|
|
|
"""
|
|
|
|
Open yaml file and parse the data into a list of dict
|
|
|
|
|
|
|
|
:param file: the yaml file to load
|
2021-07-17 12:47:59 -03:00
|
|
|
:returns: the list of dictionaries that represent the topics to send and receive
|
2019-01-28 11:28:40 -04:00
|
|
|
:raises IOError: raises and error when the file is not found
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
with open(file, 'r') as f:
|
|
|
|
if verbose:
|
2021-07-24 14:42:42 -03:00
|
|
|
print(("--\t\t- '%s' file loaded" % file))
|
2019-07-11 03:18:12 -03:00
|
|
|
return yaml.safe_load(f)
|
2019-01-28 11:28:40 -04:00
|
|
|
except OSError as e:
|
|
|
|
if e.errno == errno.ENOENT:
|
|
|
|
raise IOError(errno.ENOENT, os.strerror(errno.ENOENT), file)
|
|
|
|
else:
|
|
|
|
raise
|
|
|
|
|
|
|
|
|
|
|
|
def update_dict(list):
|
|
|
|
"""
|
|
|
|
Update the message naming on the dictionary to fit the PascalCase convention
|
|
|
|
|
|
|
|
:param file: the list of dicts to be updated
|
|
|
|
"""
|
|
|
|
if verbose:
|
|
|
|
num_of_msgs = 0
|
|
|
|
for i, dictionary in enumerate(list["rtps"]):
|
2019-12-19 06:05:55 -04:00
|
|
|
list["rtps"][i] = {k: v.title().replace('_', '') if isinstance(
|
|
|
|
v, six.string_types) else v for k, v in six.iteritems(dictionary)}
|
2019-01-28 11:28:40 -04:00
|
|
|
if verbose:
|
|
|
|
num_of_msgs += 1
|
|
|
|
if verbose:
|
2021-07-24 14:42:42 -03:00
|
|
|
print(("--\t\t- %d ROS message file names updated" % num_of_msgs))
|
2019-01-28 11:28:40 -04:00
|
|
|
|
|
|
|
|
2021-07-24 14:42:42 -03:00
|
|
|
def update_yaml_file(list, in_file, out_file):
|
2019-01-28 11:28:40 -04:00
|
|
|
"""
|
|
|
|
Open the yaml file to dump the new list of dict toself.
|
|
|
|
|
|
|
|
:param list: the list of updated dicts
|
|
|
|
:param file: the yaml file to load and write the new data
|
|
|
|
:raises IOError: raises and error when the file is not found
|
|
|
|
"""
|
|
|
|
try:
|
2021-07-24 14:42:42 -03:00
|
|
|
with open(out_file, 'w') as f:
|
2021-07-17 12:30:13 -03:00
|
|
|
f.write("# AUTOGENERATED-FILE! DO NOT MODIFY IT DIRECTLY.\n#"
|
2021-07-17 12:47:59 -03:00
|
|
|
" Edit instead the same file under PX4-Autopilot/msg/tools and"
|
|
|
|
" use the \n# PX4-Autopilot/msg/tools/uorb_to_ros_urtps_topics.py"
|
|
|
|
" to regenerate this file.\n")
|
2019-01-28 11:28:40 -04:00
|
|
|
yaml.dump(list, f, Dumper=IndenterDumper, default_flow_style=False)
|
|
|
|
if verbose:
|
|
|
|
if in_file == out_file:
|
2021-07-24 14:42:42 -03:00
|
|
|
print(("--\t\t- '%s' updated" % in_file))
|
2019-01-28 11:28:40 -04:00
|
|
|
else:
|
2021-07-24 14:42:42 -03:00
|
|
|
print(("--\t\t- '%s' created" % out_file))
|
2019-01-28 11:28:40 -04:00
|
|
|
|
2021-07-24 14:42:42 -03:00
|
|
|
except OSError as err:
|
|
|
|
if err.errno == errno.ENOENT:
|
|
|
|
raise IOError(errno.ENOENT, os.strerror(errno.ENOENT), out_file)
|
|
|
|
raise
|
2019-01-28 11:28:40 -04:00
|
|
|
|
|
|
|
|
2021-07-24 14:42:42 -03:00
|
|
|
def main():
|
2019-01-28 11:28:40 -04:00
|
|
|
parser = argparse.ArgumentParser(
|
2021-07-17 12:47:59 -03:00
|
|
|
description='Read an yaml file containing the microRTPS topics and update the naming convention to PascalCase')
|
2019-01-28 11:28:40 -04:00
|
|
|
optional = parser._action_groups.pop()
|
|
|
|
required = parser.add_argument_group('Required')
|
|
|
|
required.add_argument("-i", "--input-file", dest="input_file",
|
|
|
|
help="Yaml file to read", metavar="INFILE")
|
|
|
|
optional.add_argument("-o", "--output-file", dest="output_file",
|
|
|
|
help="Yaml file to dump. If not set, it is the same as the input",
|
|
|
|
metavar="OUTFILE", default="")
|
|
|
|
optional.add_argument("-q", "--quiet", action="store_false", dest="verbose",
|
|
|
|
default=True, help="Don't print status messages to stdout")
|
|
|
|
|
|
|
|
args = parser.parse_args()
|
2021-07-24 14:42:42 -03:00
|
|
|
global verbose
|
2019-01-28 11:28:40 -04:00
|
|
|
verbose = args.verbose
|
2021-07-24 14:42:42 -03:00
|
|
|
in_file = Path(args.input_file)
|
|
|
|
out_file = Path(args.output_file) if (
|
|
|
|
Path(args.output_file) != in_file and Path(args.output_file) != "") else in_file
|
2019-01-28 11:28:40 -04:00
|
|
|
|
|
|
|
if verbose:
|
2021-07-24 14:42:42 -03:00
|
|
|
print("---------------------- \033[1mmicroRTPS bridge yaml PX4 to ROS topics\033[0m ----------------------")
|
|
|
|
print("-------------------------------------------------------------------------------------------------------")
|
2019-01-28 11:28:40 -04:00
|
|
|
|
|
|
|
list = load_yaml_file(in_file)
|
|
|
|
update_dict(list)
|
2021-07-24 14:42:42 -03:00
|
|
|
update_yaml_file(list, in_file, out_file)
|
|
|
|
if verbose:
|
|
|
|
print("-------------------------------------------------------------------------------------------------------")
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|