2019-11-23 14:21:58 -04:00
#!/usr/bin/env python3
2018-09-30 13:25:02 -03:00
################################################################################
#
2021-02-02 06:03:02 -04:00
# Copyright (c) 2018-2021 PX4 Development Team. All rights reserved.
2018-09-30 13:25:02 -03:00
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this 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, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
################################################################################
import argparse
2021-07-17 12:25:01 -03:00
import difflib
2019-12-19 06:05:55 -04:00
import errno
2021-07-17 12:25:01 -03:00
import os
from typing import Dict , List , Tuple
2018-09-30 15:23:56 -03:00
import yaml
2018-09-30 13:25:02 -03:00
class Classifier ( ) :
2021-07-17 12:25:01 -03:00
""" Class to classify RTPS msgs as to send, receive and set their IDs. """
2018-09-30 13:25:02 -03:00
2021-07-17 12:25:01 -03:00
def __init__ ( self , yaml_file , msg_folder ) - > None :
2018-09-30 13:25:02 -03:00
self . msg_folder = msg_folder
2021-07-17 12:25:01 -03:00
self . msg_map = self . parse_yaml_msgs_file ( yaml_file )
2019-06-03 16:54:12 -03:00
2021-07-17 12:25:01 -03:00
# Check if base types are defined correctly
2019-06-03 16:54:12 -03:00
self . check_base_type ( )
2019-06-01 10:27:21 -03:00
2021-07-17 12:25:01 -03:00
# Get messages to send and to receive
self . msgs_to_send : Dict [ str , int ] = dict ( )
self . msgs_to_receive : Dict [ str , int ] = dict ( )
self . alias_msgs_to_send : List [ Tuple [ str , str ] ] = [ ]
self . alias_msgs_to_receive : List [ Tuple [ str , str ] ] = [ ]
2021-07-22 05:22:29 -03:00
self . msg_list : List [ str ] = [ ]
2018-09-30 13:25:02 -03:00
2021-07-17 12:25:01 -03:00
# Create message map
self . setup_msg_map ( )
2021-02-02 06:03:02 -04:00
2021-07-17 12:25:01 -03:00
self . msg_files_send = self . set_msg_files_send ( )
self . msg_files_receive = self . set_msg_files_receive ( )
2018-09-30 13:25:02 -03:00
2021-07-17 12:25:01 -03:00
def setup_msg_map ( self ) - > None :
""" Setup dictionary with an ID map for the messages. """
for topic in self . msg_map [ ' rtps ' ] :
if ' send ' in list ( topic . keys ( ) ) :
if ' base ' in list ( topic . keys ( ) ) :
self . alias_msgs_to_send . append (
( topic [ ' msg ' ] , topic [ ' base ' ] ) )
2019-06-02 12:12:50 -03:00
else :
2021-07-17 12:25:01 -03:00
self . msgs_to_send . update ( { topic [ ' msg ' ] : 0 } )
if ' receive ' in list ( topic . keys ( ) ) :
if ' base ' in list ( topic . keys ( ) ) :
self . alias_msgs_to_receive . append (
( topic [ ' msg ' ] , topic [ ' base ' ] ) )
2019-06-02 12:12:50 -03:00
else :
2021-07-17 12:25:01 -03:00
self . msgs_to_receive . update ( { topic [ ' msg ' ] : 0 } )
2021-07-22 05:22:29 -03:00
self . msg_list . append ( topic [ ' msg ' ] )
2018-09-30 13:25:02 -03:00
2021-07-17 12:25:01 -03:00
def set_msg_files_send ( self ) - > list :
"""
Append the path to the files which messages are marked to
be sent .
"""
2018-10-02 12:04:46 -03:00
return [ os . path . join ( self . msg_folder , msg + " .msg " )
2019-11-23 14:21:58 -04:00
for msg in list ( self . msgs_to_send . keys ( ) ) ]
2018-09-30 13:25:02 -03:00
2021-07-17 12:25:01 -03:00
def set_msg_files_receive ( self ) - > list :
2019-06-01 10:27:21 -03:00
"""
2021-07-17 12:25:01 -03:00
Append the path to the files which messages are marked to
be received .
2019-06-01 10:27:21 -03:00
"""
2021-07-17 12:25:01 -03:00
return [ os . path . join ( self . msg_folder , msg + " .msg " )
for msg in list ( self . msgs_to_receive . keys ( ) ) ]
2019-06-01 10:27:21 -03:00
2021-07-17 12:25:01 -03:00
def check_base_type ( self ) - > None :
""" Check if alias message has correct base type. """
2019-08-25 18:21:44 -03:00
registered_alias_msgs = list (
2021-07-17 12:25:01 -03:00
topic [ ' base ' ] for topic in self . msg_map [ ' rtps ' ] if ' base ' in list ( topic . keys ( ) ) )
2019-06-03 16:54:12 -03:00
2019-08-25 18:21:44 -03:00
base_types = [ ]
2021-07-17 12:25:01 -03:00
for topic in self . msg_map [ ' rtps ' ] :
if ' base ' not in list ( topic . keys ( ) ) :
base_types . append ( topic [ ' msg ' ] )
2019-08-25 18:21:44 -03:00
incorrect_base_types = list (
set ( registered_alias_msgs ) - set ( base_types ) )
base_types_suggestion = { }
2019-06-03 16:54:12 -03:00
for incorrect in incorrect_base_types :
2019-08-25 18:21:44 -03:00
base_types_suggestion . update ( { incorrect : difflib . get_close_matches (
incorrect , base_types , n = 1 , cutoff = 0.6 ) } )
2019-06-03 16:54:12 -03:00
2019-08-25 18:21:44 -03:00
if len ( base_types_suggestion ) > 0 :
2019-06-03 16:54:12 -03:00
raise AssertionError (
2019-11-23 14:21:58 -04:00
( ' \n ' + ' \n ' . join ( ' \t - The multi-topic message base type \' {} \' does not exist. {} ' . format ( k , ( ' Did you mean \' ' + v [ 0 ] + ' \' ? ' if v else ' ' ) ) for k , v in list ( base_types_suggestion . items ( ) ) ) ) )
2019-08-25 18:45:43 -03:00
2018-09-30 15:23:56 -03:00
@staticmethod
2021-07-17 12:25:01 -03:00
def parse_yaml_msgs_file ( yaml_file ) - > dict :
""" Parses a yaml file into a dict. """
2018-09-30 15:23:56 -03:00
try :
2021-07-17 12:25:01 -03:00
with open ( yaml_file , ' r ' ) as file :
return yaml . safe_load ( file )
except OSError as err :
if err . errno == errno . ENOENT :
2018-09-30 15:23:56 -03:00
raise IOError ( errno . ENOENT , os . strerror (
errno . ENOENT ) , yaml_file )
2021-07-17 12:25:01 -03:00
raise
2018-09-30 15:23:56 -03:00
2018-09-30 13:25:02 -03:00
if __name__ == " __main__ " :
parser = argparse . ArgumentParser ( )
parser . add_argument ( " -s " , " --send " , dest = ' send ' ,
2019-06-02 12:12:50 -03:00
action = " store_true " , help = " Get topics to be sent " )
parser . add_argument ( " -a " , " --alias " , dest = ' alias ' ,
action = " store_true " , help = " Get alias topics " )
2018-09-30 13:25:02 -03:00
parser . add_argument ( " -r " , " --receive " , dest = ' receive ' ,
action = " store_true " , help = " Get topics to be received " )
parser . add_argument ( " -i " , " --ignore " , dest = ' ignore ' ,
action = " store_true " , help = " Get topics to be ignored " )
parser . add_argument ( " -p " , " --path " , dest = ' path ' ,
action = " store_true " , help = " Get msgs and its paths " )
parser . add_argument ( " -m " , " --topic-msg-dir " , dest = ' msgdir ' , type = str ,
help = " Topics message dir, by default msg/ " , default = " msg " )
parser . add_argument ( " -y " , " --rtps-ids-file " , dest = ' yaml_file ' , type = str ,
2021-07-17 12:25:01 -03:00
help = " RTPS msg IDs definition file absolute path, by default use relative path to msg, tools/urtps_bridge_topics.yaml " ,
default = ' tools/urtps_bridge_topics.yaml ' )
2018-09-30 13:25:02 -03:00
# Parse arguments
args = parser . parse_args ( )
2019-01-27 09:01:22 -04:00
msg_dir = args . msgdir
2018-10-13 17:30:58 -03:00
if args . msgdir == ' msg ' :
2019-01-27 09:01:22 -04:00
msg_dir = os . path . dirname ( os . path . dirname ( os . path . abspath ( __file__ ) ) )
2019-01-20 18:23:41 -04:00
else :
2019-01-27 09:01:22 -04:00
msg_dir = os . path . abspath ( args . msgdir )
2019-06-01 10:27:21 -03:00
classifier = ( Classifier ( os . path . abspath ( args . yaml_file ) , msg_dir ) if os . path . isabs ( args . yaml_file )
else Classifier ( os . path . join ( msg_dir , args . yaml_file ) , msg_dir ) )
2018-09-30 13:25:02 -03:00
if args . send :
if args . path :
2019-11-23 14:21:58 -04:00
print ( ( ' send files: ' + ' , ' . join ( str ( msg_file )
2021-07-17 12:25:01 -03:00
for msg_file in classifier . msg_files_send ) + ' \n ' ) )
2018-09-30 13:25:02 -03:00
else :
2019-06-02 12:12:50 -03:00
if args . alias :
2019-11-23 14:21:58 -04:00
print ( ( ' , ' . join ( str ( msg )
2021-07-17 12:25:01 -03:00
for msg in sorted ( classifier . msgs_to_send ) ) + ( ' alias ' + ' , ' . join ( msg [ 0 ]
for msg in classifier . alias_msgs_to_send ) if len ( classifier . alias_msgs_to_send ) > 0 else ' ' ) + ' \n ' ) )
2019-06-02 12:12:50 -03:00
else :
2019-11-23 14:21:58 -04:00
print ( ( ' , ' . join ( str ( msg )
2021-07-17 12:25:01 -03:00
for msg in sorted ( classifier . msgs_to_send ) ) ) )
2018-09-30 13:25:02 -03:00
if args . receive :
if args . path :
2019-11-23 14:21:58 -04:00
print ( ( ' receive files: ' + ' , ' . join ( str ( msg_file )
2021-07-17 12:25:01 -03:00
for msg_file in classifier . msg_files_receive ) + ' \n ' ) )
2018-09-30 13:25:02 -03:00
else :
2019-06-02 12:12:50 -03:00
if args . alias :
2019-11-23 14:21:58 -04:00
print ( ( ' , ' . join ( str ( msg )
2021-07-17 12:25:01 -03:00
for msg in sorted ( classifier . msgs_to_receive ) ) + ( ' alias ' + ' , ' . join ( msg [ 0 ]
for msg in classifier . alias_msgs_to_receive ) if len ( classifier . alias_msgs_to_receive ) > 0 else ' ' ) + ' \n ' ) )
2019-06-02 12:12:50 -03:00
else :
2019-11-23 14:21:58 -04:00
print ( ( ' , ' . join ( str ( msg )
2021-07-17 12:25:01 -03:00
for msg in sorted ( classifier . msgs_to_receive ) ) ) )