From 4790bdbdea043f042430f3194bf6b0b611fb97a0 Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Tue, 11 Sep 2018 16:24:38 +0200 Subject: [PATCH 01/17] refs #3365 --- CMakeLists.txt | 43 +++++++++++++++++++++++++++++++++++++++++++ package.xml | 23 +++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 package.xml diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b5a44f4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,43 @@ +# Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# Set CMake version +cmake_minimum_required(VERSION 3.5) + + +# Set proyect name +project(micro-ros-agent) + + +# Find packages depencences +find_package(ament_cmake REQUIRED) + +find_package(fastcdr REQUIRED CONFIG) +find_package(fastrtps REQUIRED CONFIG) +find_package(micrortps_agent REQUIRED CONFIG) + +#find_package(ament_cmake_python REQUIRED) + + +# Export dependencies to downstream packages +ament_export_dependencies(fastcdr) +ament_export_dependencies(fastrtps) +ament_export_dependencies(micrortps_agent) + +#ament_export_dependencies(rosidl_cmake) +#ament_export_dependencies(rosidl_generator_c) +#ament_export_dependencies(rosidl_generator_dds_idl) + +ament_package() \ No newline at end of file diff --git a/package.xml b/package.xml new file mode 100644 index 0000000..c5fc1f3 --- /dev/null +++ b/package.xml @@ -0,0 +1,23 @@ + + + + micro-ros-agent + 0.0.1 + DDS-XCRE agent implementation + Javier Moreno + Apache License 2.0 + + ament_cmake_ros + rosidl_cmake + + ament_cmake + rosidl_cmake + + fastcdr + fastrtps + micrortps_agent + + + ament_cmake + + From c54a384b4cb2b976a64d4de6c3535ddaaa2053d7 Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Fri, 14 Sep 2018 08:58:44 +0200 Subject: [PATCH 02/17] Refs #3366. XML generator works fine. The path of the generated xml may need to be changed. --- CMakeLists.txt | 42 +++++- bin/AAA | 51 +++++++ bin/micro_ros_agent | 45 ++++++ cmake/micrortps_agent_xml_generator.cmake | 62 +++++++++ micro_ros_agent-extras.cmake.in | 11 ++ micro_ros_agent/__init__.py | 162 ++++++++++++++++++++++ package.xml | 31 ++++- 7 files changed, 395 insertions(+), 9 deletions(-) create mode 100644 bin/AAA create mode 100644 bin/micro_ros_agent create mode 100644 cmake/micrortps_agent_xml_generator.cmake create mode 100644 micro_ros_agent-extras.cmake.in create mode 100644 micro_ros_agent/__init__.py diff --git a/CMakeLists.txt b/CMakeLists.txt index b5a44f4..0ff4bbc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ cmake_minimum_required(VERSION 3.5) # Set proyect name -project(micro-ros-agent) +project(micro_ros_agent) # Find packages depencences @@ -28,7 +28,7 @@ find_package(fastcdr REQUIRED CONFIG) find_package(fastrtps REQUIRED CONFIG) find_package(micrortps_agent REQUIRED CONFIG) -#find_package(ament_cmake_python REQUIRED) +find_package(ament_cmake_python REQUIRED) # Export dependencies to downstream packages @@ -36,8 +36,38 @@ ament_export_dependencies(fastcdr) ament_export_dependencies(fastrtps) ament_export_dependencies(micrortps_agent) -#ament_export_dependencies(rosidl_cmake) -#ament_export_dependencies(rosidl_generator_c) -#ament_export_dependencies(rosidl_generator_dds_idl) +ament_export_dependencies(rosidl_cmake) +ament_export_dependencies(rosidl_generator_c) +ament_export_dependencies(rosidl_generator_dds_idl) -ament_package() \ No newline at end of file + +#ament_export_include_directories(include) + +# Install python files +ament_python_install_package(${PROJECT_NAME}) + + +ament_index_register_resource("rosidl_typesupport_c") + + +# Install the package.xml file, and generate code for +# ``find_package`` so that other packages can get information about +# this package. +# +# :param CONFIG_EXTRAS: a list of CMake files containing extra stuff +# that should be accessible to users of this package after +# ``find_package``\ -ing it. +ament_package( + CONFIG_EXTRAS "micro_ros_agent-extras.cmake.in" +) + + +install( + PROGRAMS bin/micro_ros_agent + DESTINATION lib/micro_ros_agent +) + +install( + DIRECTORY cmake resource + DESTINATION share/${PROJECT_NAME} +) \ No newline at end of file diff --git a/bin/AAA b/bin/AAA new file mode 100644 index 0000000..054fb18 --- /dev/null +++ b/bin/AAA @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 + +import argparse +import os +import sys + +from rosidl_cmake import read_generator_arguments +from rosidl_parser import UnknownMessageType +from micro_ros_agent import generate_typesupport_micrortps_c + +def is_valid_file(parser, file_name): + if not os.path.exists(file_name): + parser.error("File does not exist: '{0}'".format(file_name)) + file_name_abs = os.path.abspath(file_name) + if not os.path.isfile(file_name_abs): + parser.error("Path exists but is not a file: '{0}'".format(file_name_abs)) + return file_name + + +def main(argv=sys.argv[1:]): + + print "-------------------------B-------------" + return 0 + + parser = argparse.ArgumentParser( + description='Generate the C interfaces for Micro RTPS.', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument( + '--generator-arguments-file', + required=True, + help='The location of the file containing the generator arguments') + args = parser.parse_args(argv) + + generator_args = read_generator_arguments(args.generator_arguments_file) + + try: + rc = generate_typesupport_micrortps_c(generator_args) + + return 0 + except UnknownMessageType as e: + print(str(e), file=sys.stderr) + return 1 + if rc: + return rc + return 0 + + +if __name__ == '__main__': + print "-------------------------C-------------" + + sys.exit(main()) diff --git a/bin/micro_ros_agent b/bin/micro_ros_agent new file mode 100644 index 0000000..a717221 --- /dev/null +++ b/bin/micro_ros_agent @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 + +import argparse +import os +import sys + +from rosidl_cmake import read_generator_arguments +from rosidl_parser import UnknownMessageType +from micro_ros_agent import generate_micro_ros_agent_xml_support + +def is_valid_file(parser, file_name): + if not os.path.exists(file_name): + parser.error("File does not exist: '{0}'".format(file_name)) + file_name_abs = os.path.abspath(file_name) + if not os.path.isfile(file_name_abs): + parser.error("Path exists but is not a file: '{0}'".format(file_name_abs)) + return file_name + + +def main(argv=sys.argv[1:]): + parser = argparse.ArgumentParser( + description='Generate xml files for micrortps agent.', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument( + '--generator-arguments-file', + required=True, + help='The location of the file containing the generator arguments') + args = parser.parse_args(argv) + + generator_args = read_generator_arguments(args.generator_arguments_file) + + try: + rc = generate_micro_ros_agent_xml_support(generator_args) + + return 0 + except UnknownMessageType as e: + print(str(e), file=sys.stderr) + return 1 + if rc: + return rc + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/cmake/micrortps_agent_xml_generator.cmake b/cmake/micrortps_agent_xml_generator.cmake new file mode 100644 index 0000000..b92fa42 --- /dev/null +++ b/cmake/micrortps_agent_xml_generator.cmake @@ -0,0 +1,62 @@ +# Copyright 2014-2015 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +# list msg files +set(_ros_idl_files "") +foreach(_idl_file ${rosidl_generate_interfaces_IDL_FILES}) + get_filename_component(_extension "${_idl_file}" EXT) + # Skip .srv files + if(_extension STREQUAL ".msg") + list(APPEND _ros_idl_files "${_idl_file}") + endif() +endforeach() + + +# Set output dir +set(_output_path "${CMAKE_CURRENT_BINARY_DIR}/micro_ros_agent/${PROJECT_NAME}") + + +# check if all templates exits +set(target_dependencies + "${micro_ros_agent_BIN}" + "${micro_ros_agent_GENERATOR_FILES}" + ${rosidl_generate_interfaces_IDL_FILES} + ${_dependency_files}) +foreach(dep ${target_dependencies}) + if(NOT EXISTS "${dep}") + message(FATAL_ERROR "Target dependency '${dep}' does not exist") + endif() +endforeach() + + +# generate script argument file +set(generator_arguments_file "${CMAKE_CURRENT_BINARY_DIR}/micro_ros_agent__arguments.json") +rosidl_write_generator_arguments( + "${generator_arguments_file}" + PACKAGE_NAME "${PROJECT_NAME}" + ROS_INTERFACE_FILES "${rosidl_generate_interfaces_IDL_FILES}" + ROS_INTERFACE_DEPENDENCIES "${_dependencies}" + OUTPUT_DIR "${_output_path}" + TEMPLATE_DIR "${micro_ros_agent_TEMPLATE_DIR}" + TARGET_DEPENDENCIES ${target_dependencies} + ADDITIONAL_FILES ${_dds_idl_files} +) + + +# Execute python script +execute_process( + COMMAND ${PYTHON_EXECUTABLE} ${micro_ros_agent_BIN} + --generator-arguments-file "${generator_arguments_file}" + ) diff --git a/micro_ros_agent-extras.cmake.in b/micro_ros_agent-extras.cmake.in new file mode 100644 index 0000000..7cce9bb --- /dev/null +++ b/micro_ros_agent-extras.cmake.in @@ -0,0 +1,11 @@ +find_package(ament_cmake_core QUIET REQUIRED) +ament_register_extension( + "rosidl_generate_interfaces" + "micro_ros_agent" + "micrortps_agent_xml_generator.cmake") + +set(micro_ros_agent_BIN "${micro_ros_agent_DIR}/../../../lib/micro_ros_agent/micro_ros_agent") +normalize_path(micro_ros_agent_BIN "${micro_ros_agent_BIN}") + +set(micro_ros_agent_GENERATOR_FILES "${micro_ros_agent_DIR}/../../../@PYTHON_INSTALL_DIR@/micro_ros_agent/__init__.py") +normalize_path(micro_ros_agent_GENERATOR_FILES "${micro_ros_agent_GENERATOR_FILES}") \ No newline at end of file diff --git a/micro_ros_agent/__init__.py b/micro_ros_agent/__init__.py new file mode 100644 index 0000000..926fa8c --- /dev/null +++ b/micro_ros_agent/__init__.py @@ -0,0 +1,162 @@ +# Copyright 2016 Open Source Robotics Foundation, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import os + +from rosidl_cmake import convert_camel_case_to_lower_case_underscore +from rosidl_cmake import expand_template +from rosidl_cmake import extract_message_types +from rosidl_cmake import get_newest_modification_time +from rosidl_parser import parse_message_file +from rosidl_parser import parse_service_file +from rosidl_parser import validate_field_types +from pathlib import Path + + +def generate_micro_ros_agent_xml_support(args): + pkg_name = args['package_name'] + known_msg_types = extract_message_types( + pkg_name, args['ros_interface_files'], args.get('ros_interface_dependencies', [])) + + functions = { + 'get_header_filename_from_msg_name': convert_camel_case_to_lower_case_underscore, + } + + for idl_file in args['ros_interface_files']: + extension = os.path.splitext(idl_file)[1] + if extension == '.msg': + spec = parse_message_file(pkg_name, idl_file) + validate_field_types(spec, known_msg_types) + subfolder = os.path.basename(os.path.dirname(idl_file)) + + data = { + 'spec': spec, + 'pkg': spec.base_type.pkg_name, + 'msg': spec.msg_name, + 'type': spec.base_type.type, + 'subfolder': subfolder, + } + data.update(functions) + + + # Make destinatino dir + if not os.path.exists(args['output_dir']): + os.makedirs(args['output_dir']) + + # Check if publixher exists + pub_file_path = "/root/install/publisher.xml" + pub_file = Path(pub_file_path) + if not pub_file.is_file(): + publ = open(pub_file_path, 'a') + publ.write("\n") + else: + publ = open(pub_file_path) + lines = publ.readlines() + publ.close() + publ = open(pub_file_path,'w') + publ.writelines([item for item in lines[:-1]]) + + + #publ = open(os.path.join(args['output_dir'], 'publisher.xml'), 'w+') + #publ = open('/root/install/publisher.xml', 'a') + publ.write(" \n") + publ.write(" \n") + publ.write(" NO_KEY\n") + publ.write(" %sPubSubTopic\n" % (spec.msg_name)) + publ.write(" %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name)) + publ.write(" \n") + publ.write(" KEEP_LAST\n") + publ.write(" 5\n") + publ.write(" \n") + publ.write(" \n") + publ.write(" TRANSIENT_LOCAL\n") + publ.write(" \n") + publ.write(" \n") + publ.write(" \n") + publ.write("\n") + publ.close() + + + + # Check if subcriber exists + subs_file_path = "/root/install/subscriber.xml" + subs_file = Path(subs_file_path) + if not subs_file.is_file(): + subs = open(subs_file_path, 'a') + subs.write("\n") + else: + subs = open(subs_file_path) + lines = subs.readlines() + subs.close() + subs = open(subs_file_path,'w') + subs.writelines([item for item in lines[:-1]]) + + + #subs = open(os.path.join(args['output_dir'], 'subscriber.xml'), 'w+') + #subs = open('/root/install/subscriber.xml', 'a') + #subs.write("\n") + subs.write(" \n") + subs.write(" \n") + subs.write(" NO_KEY\n") + subs.write(" %sPubSubTopic\n" % (spec.msg_name)) + subs.write(" %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name)) + subs.write(" \n") + subs.write(" KEEP_LAST\n") + subs.write(" 5\n") + subs.write(" \n") + subs.write(" \n") + subs.write(" TRANSIENT_LOCAL\n") + subs.write(" \n") + subs.write(" \n") + subs.write(" \n") + subs.write("\n") + subs.close() + + + # Check if topic exists + topi_file_path = "/root/install/topic.xml" + topi_file = Path(topi_file_path) + if not topi_file.is_file(): + topi = open(topi_file_path, 'a') + topi.write("\n") + else: + topi = open(topi_file_path) + lines = topi.readlines() + topi.close() + topi = open(topi_file_path,'w') + topi.writelines([item for item in lines[:-1]]) + + + #topi = open(os.path.join(args['output_dir'], 'topic.xml'), 'w+') + #topi = open('/root/install/topic.xml', 'a') + #topi.write("\n") + topi.write(" \n") + topi.write(" %sPubSubTopic\n" % (spec.msg_name)) + topi.write(" %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name)) + topi.write(" \n") + topi.write("\n") + topi.close() + + #elif extension == '.srv': + + #data = {'spec': spec} + #data.update(functions) + + #if not os.path.exists(args['output_dir']): + # os.makedirs(args['output_dir']) + + #f = open(os.path.join(args['output_dir'], 'demofile.txt'), 'w+') + #f.write("%s\n" % spec) + #f.close() + return 0 diff --git a/package.xml b/package.xml index c5fc1f3..87d8f9b 100644 --- a/package.xml +++ b/package.xml @@ -1,23 +1,48 @@ - micro-ros-agent + micro_ros_agent 0.0.1 DDS-XCRE agent implementation Javier Moreno Apache License 2.0 - ament_cmake_ros + ament_cmake rosidl_cmake + rosidl_generator_c + rosidl_generator_dds_idl ament_cmake rosidl_cmake - + rosidl_generator_c + rosidl_generator_dds_idl + + rmw + + rosidl_parser + rosidl_typesupport_interface + fastcdr fastrtps micrortps_agent + + + rosidl_parser + rosidl_typesupport_interface + + ament_lint_auto + ament_lint_common + + rosidl_typesupport_c_packages + + + ament_cmake + + + + From becb074a2fb68177f159ef723d15b19fe5007098 Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Fri, 14 Sep 2018 11:34:55 +0200 Subject: [PATCH 03/17] Refs #3366. Errors fix --- CMakeLists.txt | 2 +- bin/AAA | 51 ----------------------- cmake/micrortps_agent_xml_generator.cmake | 11 ++++- micro_ros_agent/__init__.py | 20 ++++----- 4 files changed, 17 insertions(+), 67 deletions(-) delete mode 100644 bin/AAA diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ff4bbc..5066069 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,6 @@ install( ) install( - DIRECTORY cmake resource + DIRECTORY cmake DESTINATION share/${PROJECT_NAME} ) \ No newline at end of file diff --git a/bin/AAA b/bin/AAA deleted file mode 100644 index 054fb18..0000000 --- a/bin/AAA +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import os -import sys - -from rosidl_cmake import read_generator_arguments -from rosidl_parser import UnknownMessageType -from micro_ros_agent import generate_typesupport_micrortps_c - -def is_valid_file(parser, file_name): - if not os.path.exists(file_name): - parser.error("File does not exist: '{0}'".format(file_name)) - file_name_abs = os.path.abspath(file_name) - if not os.path.isfile(file_name_abs): - parser.error("Path exists but is not a file: '{0}'".format(file_name_abs)) - return file_name - - -def main(argv=sys.argv[1:]): - - print "-------------------------B-------------" - return 0 - - parser = argparse.ArgumentParser( - description='Generate the C interfaces for Micro RTPS.', - formatter_class=argparse.ArgumentDefaultsHelpFormatter) - parser.add_argument( - '--generator-arguments-file', - required=True, - help='The location of the file containing the generator arguments') - args = parser.parse_args(argv) - - generator_args = read_generator_arguments(args.generator_arguments_file) - - try: - rc = generate_typesupport_micrortps_c(generator_args) - - return 0 - except UnknownMessageType as e: - print(str(e), file=sys.stderr) - return 1 - if rc: - return rc - return 0 - - -if __name__ == '__main__': - print "-------------------------C-------------" - - sys.exit(main()) diff --git a/cmake/micrortps_agent_xml_generator.cmake b/cmake/micrortps_agent_xml_generator.cmake index b92fa42..1cf3f6c 100644 --- a/cmake/micrortps_agent_xml_generator.cmake +++ b/cmake/micrortps_agent_xml_generator.cmake @@ -25,7 +25,7 @@ endforeach() # Set output dir -set(_output_path "${CMAKE_CURRENT_BINARY_DIR}/micro_ros_agent/${PROJECT_NAME}") +set(_output_path "${CMAKE_CURRENT_BINARY_DIR}/../micro_ros_agent/xml_gen") # check if all templates exits @@ -49,7 +49,7 @@ rosidl_write_generator_arguments( ROS_INTERFACE_FILES "${rosidl_generate_interfaces_IDL_FILES}" ROS_INTERFACE_DEPENDENCIES "${_dependencies}" OUTPUT_DIR "${_output_path}" - TEMPLATE_DIR "${micro_ros_agent_TEMPLATE_DIR}" + TEMPLATE_DIR "NONE" TARGET_DEPENDENCIES ${target_dependencies} ADDITIONAL_FILES ${_dds_idl_files} ) @@ -60,3 +60,10 @@ execute_process( COMMAND ${PYTHON_EXECUTABLE} ${micro_ros_agent_BIN} --generator-arguments-file "${generator_arguments_file}" ) + + +#Install +install( + DIRECTORY "${_output_path}/" + DESTINATION "../micrortps_agent/bin" +) \ No newline at end of file diff --git a/micro_ros_agent/__init__.py b/micro_ros_agent/__init__.py index 926fa8c..67535e7 100644 --- a/micro_ros_agent/__init__.py +++ b/micro_ros_agent/__init__.py @@ -55,7 +55,7 @@ def generate_micro_ros_agent_xml_support(args): os.makedirs(args['output_dir']) # Check if publixher exists - pub_file_path = "/root/install/publisher.xml" + pub_file_path = os.path.join(args['output_dir'], 'publisher.xml') pub_file = Path(pub_file_path) if not pub_file.is_file(): publ = open(pub_file_path, 'a') @@ -66,10 +66,11 @@ def generate_micro_ros_agent_xml_support(args): publ.close() publ = open(pub_file_path,'w') publ.writelines([item for item in lines[:-1]]) + #publ = open(pub_file_path, "w") + #publ.seek(publ.seek(-1,2) - len("\n")) + - #publ = open(os.path.join(args['output_dir'], 'publisher.xml'), 'w+') - #publ = open('/root/install/publisher.xml', 'a') publ.write(" \n") publ.write(" \n") publ.write(" NO_KEY\n") @@ -89,8 +90,8 @@ def generate_micro_ros_agent_xml_support(args): - # Check if subcriber exists - subs_file_path = "/root/install/subscriber.xml" + # Check if subcriber exists + subs_file_path = os.path.join(args['output_dir'], 'subscriber.xml') subs_file = Path(subs_file_path) if not subs_file.is_file(): subs = open(subs_file_path, 'a') @@ -103,9 +104,6 @@ def generate_micro_ros_agent_xml_support(args): subs.writelines([item for item in lines[:-1]]) - #subs = open(os.path.join(args['output_dir'], 'subscriber.xml'), 'w+') - #subs = open('/root/install/subscriber.xml', 'a') - #subs.write("\n") subs.write(" \n") subs.write(" \n") subs.write(" NO_KEY\n") @@ -125,7 +123,7 @@ def generate_micro_ros_agent_xml_support(args): # Check if topic exists - topi_file_path = "/root/install/topic.xml" + topi_file_path = os.path.join(args['output_dir'], 'topic.xml') topi_file = Path(topi_file_path) if not topi_file.is_file(): topi = open(topi_file_path, 'a') @@ -137,10 +135,6 @@ def generate_micro_ros_agent_xml_support(args): topi = open(topi_file_path,'w') topi.writelines([item for item in lines[:-1]]) - - #topi = open(os.path.join(args['output_dir'], 'topic.xml'), 'w+') - #topi = open('/root/install/topic.xml', 'a') - #topi.write("\n") topi.write(" \n") topi.write(" %sPubSubTopic\n" % (spec.msg_name)) topi.write(" %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name)) From 331a44bc9c23de521766d457045aa11e2ed0aa2f Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Thu, 20 Sep 2018 17:10:29 +0200 Subject: [PATCH 04/17] Refs #3365. Integration with rmw_microros --- CMakeLists.txt | 2 +- cmake/micrortps_agent_xml_generator.cmake | 2 +- micro_ros_agent-extras.cmake.in | 5 +- micro_ros_agent/__init__.py | 185 ++++++++++++---------- resource/StaticValues.xml | 39 +++++ 5 files changed, 147 insertions(+), 86 deletions(-) create mode 100644 resource/StaticValues.xml diff --git a/CMakeLists.txt b/CMakeLists.txt index 5066069..0ff4bbc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,6 @@ install( ) install( - DIRECTORY cmake + DIRECTORY cmake resource DESTINATION share/${PROJECT_NAME} ) \ No newline at end of file diff --git a/cmake/micrortps_agent_xml_generator.cmake b/cmake/micrortps_agent_xml_generator.cmake index 1cf3f6c..acf6d1b 100644 --- a/cmake/micrortps_agent_xml_generator.cmake +++ b/cmake/micrortps_agent_xml_generator.cmake @@ -49,7 +49,7 @@ rosidl_write_generator_arguments( ROS_INTERFACE_FILES "${rosidl_generate_interfaces_IDL_FILES}" ROS_INTERFACE_DEPENDENCIES "${_dependencies}" OUTPUT_DIR "${_output_path}" - TEMPLATE_DIR "NONE" + TEMPLATE_DIR "${micro_ros_agent_DEFAULT_PROFILES_DIR}" TARGET_DEPENDENCIES ${target_dependencies} ADDITIONAL_FILES ${_dds_idl_files} ) diff --git a/micro_ros_agent-extras.cmake.in b/micro_ros_agent-extras.cmake.in index 7cce9bb..aa4e047 100644 --- a/micro_ros_agent-extras.cmake.in +++ b/micro_ros_agent-extras.cmake.in @@ -8,4 +8,7 @@ set(micro_ros_agent_BIN "${micro_ros_agent_DIR}/../../../lib/micro_ros_agent/mic normalize_path(micro_ros_agent_BIN "${micro_ros_agent_BIN}") set(micro_ros_agent_GENERATOR_FILES "${micro_ros_agent_DIR}/../../../@PYTHON_INSTALL_DIR@/micro_ros_agent/__init__.py") -normalize_path(micro_ros_agent_GENERATOR_FILES "${micro_ros_agent_GENERATOR_FILES}") \ No newline at end of file +normalize_path(micro_ros_agent_GENERATOR_FILES "${micro_ros_agent_GENERATOR_FILES}") + +set(micro_ros_agent_DEFAULT_PROFILES_DIR "${micro_ros_agent_DIR}/../resource") +normalize_path(micro_ros_agent_DEFAULT_PROFILES_DIR "${micro_ros_agent_DEFAULT_PROFILES_DIR}") \ No newline at end of file diff --git a/micro_ros_agent/__init__.py b/micro_ros_agent/__init__.py index 67535e7..f07a321 100644 --- a/micro_ros_agent/__init__.py +++ b/micro_ros_agent/__init__.py @@ -12,7 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. +import struct +import fcntl import os +import sys from rosidl_cmake import convert_camel_case_to_lower_case_underscore from rosidl_cmake import expand_template @@ -21,6 +24,7 @@ from rosidl_cmake import get_newest_modification_time from rosidl_parser import parse_message_file from rosidl_parser import parse_service_file from rosidl_parser import validate_field_types +from shutil import copyfile from pathlib import Path @@ -33,6 +37,34 @@ def generate_micro_ros_agent_xml_support(args): 'get_header_filename_from_msg_name': convert_camel_case_to_lower_case_underscore, } + + # Set file format + file_format = ".xml" + ros2_prefix = "rt/" + + + # Check destination dir + dest_dir = args['output_dir'] + if not os.path.exists(dest_dir): + os.makedirs(dest_dir) + + + # Check source dir + srcs_dir = os.path.join(dest_dir, "srcs") + if not os.path.exists(srcs_dir): + os.makedirs(srcs_dir) + + + # Copy all included xml files + for filename in os.listdir(args['template_dir']): + if filename.endswith(file_format): + template_src_path = os.path.join(args['template_dir'], filename) + template_dest_path = os.path.join(srcs_dir, filename) + if not os.path.isfile(template_dest_path): + copyfile(template_src_path, template_dest_path) + + + # Iterate throw all msgs/srvs for idl_file in args['ros_interface_files']: extension = os.path.splitext(idl_file)[1] if extension == '.msg': @@ -50,97 +82,84 @@ def generate_micro_ros_agent_xml_support(args): data.update(functions) - # Make destinatino dir - if not os.path.exists(args['output_dir']): - os.makedirs(args['output_dir']) - - # Check if publixher exists - pub_file_path = os.path.join(args['output_dir'], 'publisher.xml') - pub_file = Path(pub_file_path) - if not pub_file.is_file(): - publ = open(pub_file_path, 'a') - publ.write("\n") - else: - publ = open(pub_file_path) - lines = publ.readlines() - publ.close() - publ = open(pub_file_path,'w') - publ.writelines([item for item in lines[:-1]]) - #publ = open(pub_file_path, "w") - #publ.seek(publ.seek(-1,2) - len("\n")) + # Generate source file path + src_file = os.path.join(srcs_dir, "%s_%s_%s.xml" % (spec.base_type.pkg_name, subfolder, spec.msg_name)) - - publ.write(" \n") - publ.write(" \n") - publ.write(" NO_KEY\n") - publ.write(" %sPubSubTopic\n" % (spec.msg_name)) - publ.write(" %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name)) - publ.write(" \n") - publ.write(" KEEP_LAST\n") - publ.write(" 5\n") - publ.write(" \n") - publ.write(" \n") - publ.write(" TRANSIENT_LOCAL\n") - publ.write(" \n") - publ.write(" \n") - publ.write(" \n") - publ.write("\n") - publ.close() + # Publisher + file_content = " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " NO_KEY\n" + file_content += " %s%s_%s_%s\n" % (ros2_prefix, spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " \n" + file_content += " KEEP_LAST\n" + file_content += " 5\n" + file_content += " \n" + file_content += " \n" + file_content += " TRANSIENT_LOCAL\n" + file_content += " \n" + file_content += " \n" + file_content += " \n" - - # Check if subcriber exists - subs_file_path = os.path.join(args['output_dir'], 'subscriber.xml') - subs_file = Path(subs_file_path) - if not subs_file.is_file(): - subs = open(subs_file_path, 'a') - subs.write("\n") - else: - subs = open(subs_file_path) - lines = subs.readlines() - subs.close() - subs = open(subs_file_path,'w') - subs.writelines([item for item in lines[:-1]]) + # Subscriber + file_content += " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " NO_KEY\n" + file_content += " %s%s_%s_%s\n" % (ros2_prefix, spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " \n" + file_content += " KEEP_LAST\n" + file_content += " 5\n" + file_content += " \n" + file_content += " \n" + file_content += " TRANSIENT_LOCAL\n" + file_content += " \n" + file_content += " \n" + file_content += " \n" - subs.write(" \n") - subs.write(" \n") - subs.write(" NO_KEY\n") - subs.write(" %sPubSubTopic\n" % (spec.msg_name)) - subs.write(" %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name)) - subs.write(" \n") - subs.write(" KEEP_LAST\n") - subs.write(" 5\n") - subs.write(" \n") - subs.write(" \n") - subs.write(" TRANSIENT_LOCAL\n") - subs.write(" \n") - subs.write(" \n") - subs.write(" \n") - subs.write("\n") - subs.close() + # Topic + file_content += " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " %s%s_%s_%s\n" % (ros2_prefix, spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " \n" - # Check if topic exists - topi_file_path = os.path.join(args['output_dir'], 'topic.xml') - topi_file = Path(topi_file_path) - if not topi_file.is_file(): - topi = open(topi_file_path, 'a') - topi.write("\n") - else: - topi = open(topi_file_path) - lines = topi.readlines() - topi.close() - topi = open(topi_file_path,'w') - topi.writelines([item for item in lines[:-1]]) + # Write file content + fd1 = open(src_file, "w") + fcntl.lockf(fd1, fcntl.LOCK_EX) + fd1.write(file_content) + fd1.close() + + + # Open collect file + collec_file = os.path.join(args['output_dir'], "DEFAULT_FASTRTPS_PROFILES.xml") + fd2 = open(collec_file, "w") + fcntl.lockf(fd2, fcntl.LOCK_EX) + + + # Generate head + fd2.write("\n") + + + # Append all files contents + for filename in os.listdir(srcs_dir): + if filename.endswith(".xml"): + fd3 = open(os.path.join(srcs_dir, filename), "r+") + fcntl.lockf(fd3, fcntl.LOCK_EX) + fd2.write(fd3.read()) + fd3.close() + + + # Generate tail + fd2.write("\n") + + + # Close file + fd2.close() - topi.write(" \n") - topi.write(" %sPubSubTopic\n" % (spec.msg_name)) - topi.write(" %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name)) - topi.write(" \n") - topi.write("\n") - topi.close() #elif extension == '.srv': @@ -153,4 +172,4 @@ def generate_micro_ros_agent_xml_support(args): #f = open(os.path.join(args['output_dir'], 'demofile.txt'), 'w+') #f.write("%s\n" % spec) #f.close() - return 0 + return 0 \ No newline at end of file diff --git a/resource/StaticValues.xml b/resource/StaticValues.xml new file mode 100644 index 0000000..7444a10 --- /dev/null +++ b/resource/StaticValues.xml @@ -0,0 +1,39 @@ + + + + + INFINITE + + 0 + + DataReader_participant_subscriber + + + + + WITH_KEY + Square + ShapeType + + KEEP_LAST + 5 + + + TRANSIENT_LOCAL + + + + + + WITH_KEY + Square + ShapeType + + KEEP_LAST + 5 + + + TRANSIENT_LOCAL + + + From 9d0289f0b59cee64c80931ab5cb70fb67a3f17c6 Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Thu, 27 Sep 2018 08:14:33 +0200 Subject: [PATCH 05/17] Copyright changed. --- cmake/micrortps_agent_xml_generator.cmake | 2 +- micro_ros_agent/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/micrortps_agent_xml_generator.cmake b/cmake/micrortps_agent_xml_generator.cmake index acf6d1b..6f269f0 100644 --- a/cmake/micrortps_agent_xml_generator.cmake +++ b/cmake/micrortps_agent_xml_generator.cmake @@ -1,4 +1,4 @@ -# Copyright 2014-2015 Open Source Robotics Foundation, Inc. +# Copyright 2016-2018 Proyectos y Sistemas de Mantenimiento SL (eProsima). # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/micro_ros_agent/__init__.py b/micro_ros_agent/__init__.py index f07a321..a59b27c 100644 --- a/micro_ros_agent/__init__.py +++ b/micro_ros_agent/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2016 Open Source Robotics Foundation, Inc. +# Copyright 2016-2018 Proyectos y Sistemas de Mantenimiento SL (eProsima). # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. From 950eb25bfba91c21254c21a4ec4f0991ca8ee8ed Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Thu, 27 Sep 2018 11:44:40 +0200 Subject: [PATCH 06/17] Remove unnecessary dependencies. --- CMakeLists.txt | 17 ++--------------- package.xml | 17 ----------------- 2 files changed, 2 insertions(+), 32 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ff4bbc..a3f9f81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,11 +23,9 @@ project(micro_ros_agent) # Find packages depencences find_package(ament_cmake REQUIRED) - find_package(fastcdr REQUIRED CONFIG) find_package(fastrtps REQUIRED CONFIG) find_package(micrortps_agent REQUIRED CONFIG) - find_package(ament_cmake_python REQUIRED) @@ -36,27 +34,16 @@ ament_export_dependencies(fastcdr) ament_export_dependencies(fastrtps) ament_export_dependencies(micrortps_agent) -ament_export_dependencies(rosidl_cmake) -ament_export_dependencies(rosidl_generator_c) -ament_export_dependencies(rosidl_generator_dds_idl) - - -#ament_export_include_directories(include) # Install python files ament_python_install_package(${PROJECT_NAME}) +# Register package resource in order to be called when a new msg package is generated ament_index_register_resource("rosidl_typesupport_c") -# Install the package.xml file, and generate code for -# ``find_package`` so that other packages can get information about -# this package. -# -# :param CONFIG_EXTRAS: a list of CMake files containing extra stuff -# that should be accessible to users of this package after -# ``find_package``\ -ing it. +# Install the package.xml file, and generate code for ``find_package`` so that other packages can get information about this package. ament_package( CONFIG_EXTRAS "micro_ros_agent-extras.cmake.in" ) diff --git a/package.xml b/package.xml index 87d8f9b..461ed8a 100644 --- a/package.xml +++ b/package.xml @@ -8,36 +8,19 @@ Apache License 2.0 ament_cmake - rosidl_cmake - rosidl_generator_c - rosidl_generator_dds_idl - ament_cmake - rosidl_cmake - rosidl_generator_c - rosidl_generator_dds_idl - - rmw rosidl_parser - rosidl_typesupport_interface fastcdr fastrtps micrortps_agent - - - rosidl_parser - rosidl_typesupport_interface - ament_lint_auto ament_lint_common rosidl_typesupport_c_packages - - ament_cmake From 463dcb8991f3b7e420316ecba831824449ad2b0f Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Thu, 27 Sep 2018 12:02:00 +0200 Subject: [PATCH 07/17] Solved not portable code. --- micro_ros_agent/__init__.py | 110 ++++++++++++++++++++++++++++-------- 1 file changed, 88 insertions(+), 22 deletions(-) diff --git a/micro_ros_agent/__init__.py b/micro_ros_agent/__init__.py index a59b27c..34ad0b0 100644 --- a/micro_ros_agent/__init__.py +++ b/micro_ros_agent/__init__.py @@ -13,10 +13,19 @@ # limitations under the License. import struct -import fcntl import os import sys +if os.name == 'nt': + import win32con + import win32file + import pywintypes + __overlapped = pywintypes.OVERLAPPED() +elif os.name == 'posix': + import fcntl +else: + raise RuntimeError('PortaLocker only defined for nt and posix platforms') + from rosidl_cmake import convert_camel_case_to_lower_case_underscore from rosidl_cmake import expand_template from rosidl_cmake import extract_message_types @@ -129,34 +138,91 @@ def generate_micro_ros_agent_xml_support(args): # Write file content fd1 = open(src_file, "w") - fcntl.lockf(fd1, fcntl.LOCK_EX) - fd1.write(file_content) + if os.name == 'nt': + # Lock + hfile1 = win32file._get_osfhandle(fd1.fileno()) + win32file.LockFileEx(hfile1, win32con.LOCKFILE_EXCLUSIVE_LOCK, 0, -0x10000, __overlapped) + + # Write + fd1.write(file_content) + + # Unlock + win32file.UnlockFileEx(hfile1, 0, -0x10000, __overlapped) + elif os.name == 'posix': + # Lock + fcntl.flock(fd1.fileno(), fcntl.LOCK_EX) + + # Write + fd1.write(file_content) + + # Unlock + fcntl.flock(fd1.fileno(), fcntl.LOCK_UN) fd1.close() # Open collect file collec_file = os.path.join(args['output_dir'], "DEFAULT_FASTRTPS_PROFILES.xml") fd2 = open(collec_file, "w") - fcntl.lockf(fd2, fcntl.LOCK_EX) - - - # Generate head - fd2.write("\n") - - - # Append all files contents - for filename in os.listdir(srcs_dir): - if filename.endswith(".xml"): - fd3 = open(os.path.join(srcs_dir, filename), "r+") - fcntl.lockf(fd3, fcntl.LOCK_EX) - fd2.write(fd3.read()) - fd3.close() - - - # Generate tail - fd2.write("\n") - + if os.name == 'nt': + # Lock + hfile2 = win32file._get_osfhandle(fd2.fileno()) + win32file.LockFileEx(hfile2, win32con.LOCKFILE_EXCLUSIVE_LOCK, 0, -0x10000, __overlapped) + + # Generate head + fd2.write("\n") + + # Append all files contents + for filename in os.listdir(srcs_dir): + if filename.endswith(".xml"): + # Open + fd3 = open(os.path.join(srcs_dir, filename), "r+") + + # Lock + hfile3 = win32file._get_osfhandle(fd3.fileno()) + win32file.LockFileEx(hfile3, win32con.LOCKFILE_EXCLUSIVE_LOCK, 0, -0x10000, __overlapped) + + # Write + fd2.write(fd3.read()) + + # Unlock + win32file.UnlockFileEx(hfile3, 0, -0x10000, __overlapped) + fd3.close() + + # Generate tail + fd2.write("\n") + + # UnLock + win32file.UnlockFileEx(hfile2, 0, -0x10000, __overlapped) + elif os.name == 'posix': + # Lock + fcntl.flock(fd2.fileno(), fcntl.LOCK_EX) + + # Generate head + fd2.write("\n") + + # Append all files contents + for filename in os.listdir(srcs_dir): + if filename.endswith(".xml"): + # Open + fd3 = open(os.path.join(srcs_dir, filename), "r+") + + # Lock + fcntl.flock(fd3, fcntl.LOCK_EX) + + # Write + fd2.write(fd3.read()) + + # Unlock + fcntl.flock(fd3.fileno(), fcntl.LOCK_UN) + + # Close + fd3.close() + + # Generate tail + fd2.write("\n") + # UnLock + fcntl.flock(fd2.fileno(), fcntl.LOCK_UN) # Close file fd2.close() From ffc3c372be68379c3f7da219253ff2b3a8a66e2a Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Thu, 4 Oct 2018 09:14:22 +0200 Subject: [PATCH 08/17] Refs #3459. --- CMakeLists.txt | 185 +++++++++++++++-- bin/Xml_interface_gen.py | 30 +++ bin/Xml_read_default_profiles.py | 26 +++ bin/micro_ros_agent | 45 ----- cmake/micrortps_agent_xml_generator.cmake | 69 ------- micro_ros_agent-extras.cmake.in | 14 -- package.xml | 7 +- {micro_ros_agent => uros_agent}/__init__.py | 212 +++++++++----------- 8 files changed, 327 insertions(+), 261 deletions(-) create mode 100644 bin/Xml_interface_gen.py create mode 100644 bin/Xml_read_default_profiles.py delete mode 100644 bin/micro_ros_agent delete mode 100644 cmake/micrortps_agent_xml_generator.cmake delete mode 100644 micro_ros_agent-extras.cmake.in rename {micro_ros_agent => uros_agent}/__init__.py (54%) diff --git a/CMakeLists.txt b/CMakeLists.txt index a3f9f81..782435d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,10 +18,11 @@ cmake_minimum_required(VERSION 3.5) # Set proyect name -project(micro_ros_agent) +project(uros_agent) # Find packages depencences +find_package(rosidl_cmake REQUIRED) find_package(ament_cmake REQUIRED) find_package(fastcdr REQUIRED CONFIG) find_package(fastrtps REQUIRED CONFIG) @@ -35,26 +36,178 @@ ament_export_dependencies(fastrtps) ament_export_dependencies(micrortps_agent) -# Install python files -ament_python_install_package(${PROJECT_NAME}) +# Set variables +set(_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}/python") + +set(_XML_INTERFACE_GEN_BIN "${_OUTPUT_PATH}/bin/Xml_interface_gen.py") +normalize_path(_XML_INTERFACE_GEN_BIN "${_XML_INTERFACE_GEN_BIN}") + +set(_XML_DEFAULT_READ_BIN "${_OUTPUT_PATH}/bin/Xml_read_default_profiles.py") +normalize_path(_XML_DEFAULT_READ_BIN "${_XML_DEFAULT_READ_BIN}") + +set(_PYTHON_PKG_TOOL ${PROJECT_NAME}) + +set(_RESOURCE_DIR "${_OUTPUT_PATH}/resource") +normalize_path(_RESOURCE_DIR "${_RESOURCE_DIR}") -# Register package resource in order to be called when a new msg package is generated -ament_index_register_resource("rosidl_typesupport_c") +set(_DEFAULT_FASTRTPS_PROFILES_PATH "${_OUTPUT_PATH}/gen/DEFAULT_FASTRTPS_PROFILES.xml") +normalize_path(_DEFAULT_FASTRTPS_PROFILES_PATH "${_DEFAULT_FASTRTPS_PROFILES_PATH}") + + +# Get colcon call dir +get_filename_component(_COLCON_CALL_DIR "${CMAKE_INSTALL_PREFIX}" DIRECTORY) +get_filename_component(_COLCON_CALL_DIR "${_COLCON_CALL_DIR}" DIRECTORY) + + +# Generate python header +set( +_PYTHON_SCRIPT_HEAD +" +import os\n +import sys\n +sys.path.append('${_OUTPUT_PATH}')\n +from ${_PYTHON_PKG_TOOL} import *\n +" +) + + +# Copy pyton files +file(COPY "bin" "${_PYTHON_PKG_TOOL}" "resource" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/python") + + +# Extract all packages and manifiest paths +execute_process( + COMMAND + "${PYTHON_EXECUTABLE}" + "-c" + "${_PYTHON_SCRIPT_HEAD}for package in GetInterfacePackages(GetPackageList('${_COLCON_CALL_DIR}')): print ('%s,%s' % (package, GetPackageName(package)))" + OUTPUT_VARIABLE _packages + RESULT_VARIABLE _result + OUTPUT_STRIP_TRAILING_WHITESPACE +) +if(NOT _result EQUAL 0) + message(FATAL_ERROR "Error finding xml packages") +endif() + + +# Convert output to list +string(REPLACE "\n" ";" _packages ${_packages}) + + +# Extract all msg from each package (stored in ${package}_MSG_FILES) +set(ALL_MSG_FILES "") +foreach(package ${_packages}) + + # Extract info + string(REPLACE "," ";" package ${package}) + list(GET package 0 package_file) + list(GET package 1 package) + + + # Get all msg files + execute_process( + COMMAND + "${PYTHON_EXECUTABLE}" + "-c" + "${_PYTHON_SCRIPT_HEAD}for msg in GetInterfacePackageMsgs('${package_file}'): print ('%s' % msg)" + OUTPUT_VARIABLE ${package}_MSG_FILES + RESULT_VARIABLE _result + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + if(NOT _result EQUAL 0) + message(FATAL_ERROR "Error finding .msg files") + endif() + + # Skip if there are no msgs to create + if(${package}_MSG_FILES STREQUAL "") + continue() + endif() + + # Generate list + string(REPLACE "\n" ";" ${package}_MSG_FILES ${${package}_MSG_FILES}) + +endforeach() + + +# Append defaul xml profiles +execute_process( + COMMAND "${PYTHON_EXECUTABLE}" "${_XML_DEFAULT_READ_BIN}" "--default-xml-path" "${_RESOURCE_DIR}" + OUTPUT_VARIABLE _XmlDoc + RESULT_VARIABLE _result + ) +if(NOT _result EQUAL 0) + message(FATAL_ERROR "Error in typesuppor generation") +endif() + + +# Create one xml for each message +foreach(package ${_packages}) + string(REPLACE "," ";" package ${package}) + list(GET package 0 package_file) + list(GET package 1 package) + + + # Skip this generation if there are no msgs to process + if(${package}_MSG_FILES STREQUAL "") + continue() + endif() + + + + # generate script argument file + set(generator_arguments_file "${_OUTPUT_PATH}/XML_ArgFiles/${package}_Args.json") + rosidl_write_generator_arguments( + "${generator_arguments_file}" + PACKAGE_NAME "${package}" + ROS_INTERFACE_FILES "${${package}_MSG_FILES}" + ROS_INTERFACE_DEPENDENCIES "NULL" + OUTPUT_DIR "NULL" + TEMPLATE_DIR "NULL" + TARGET_DEPENDENCIES "NULL" + ADDITIONAL_FILES "" + ) + + + # execute python script + execute_process( + COMMAND "${PYTHON_EXECUTABLE}" "${_XML_INTERFACE_GEN_BIN}" --generator-arguments-file "${generator_arguments_file}" + OUTPUT_VARIABLE _XmlGen + RESULT_VARIABLE _result + ) + if(NOT _result EQUAL 0) + message(FATAL_ERROR "Error in typesuppor generation") + endif() + + + # Strore xml + set(_XmlDoc "${_XmlDoc}${_XmlGen}") + +endforeach() + + +# Close profile +set (_XmlDoc "\n${_XmlDoc}\n") + + +# Save +file(WRITE "${_DEFAULT_FASTRTPS_PROFILES_PATH}" "${_XmlDoc}") + # Install the package.xml file, and generate code for ``find_package`` so that other packages can get information about this package. -ament_package( - CONFIG_EXTRAS "micro_ros_agent-extras.cmake.in" +ament_package() + + +#Install +install( + FILES "${_DEFAULT_FASTRTPS_PROFILES_PATH}" + DESTINATION "../micrortps_agent/bin" ) -install( - PROGRAMS bin/micro_ros_agent - DESTINATION lib/micro_ros_agent -) - -install( - DIRECTORY cmake resource - DESTINATION share/${PROJECT_NAME} -) \ No newline at end of file +# Install package +#install( +# DIRECTORY cmake resource +# DESTINATION share/${PROJECT_NAME} +#) \ No newline at end of file diff --git a/bin/Xml_interface_gen.py b/bin/Xml_interface_gen.py new file mode 100644 index 0000000..07fdb7d --- /dev/null +++ b/bin/Xml_interface_gen.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python3 + +import argparse +import os +import sys + +sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)),'..')) + +from rosidl_cmake import read_generator_arguments +from rosidl_parser import UnknownMessageType +from uros_agent import generate_XML + + +def main(argv=sys.argv[1:]): + parser = argparse.ArgumentParser( + description='Generate the C interfaces for Micro RTPS.', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument( + '--generator-arguments-file', + required=True, + help='The location of the file containing the generator arguments') + args = parser.parse_args(argv) + + generator_args = read_generator_arguments(args.generator_arguments_file) + rc = generate_XML(generator_args) + return rc + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/bin/Xml_read_default_profiles.py b/bin/Xml_read_default_profiles.py new file mode 100644 index 0000000..001d256 --- /dev/null +++ b/bin/Xml_read_default_profiles.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 + +import os +import sys +import argparse +import xml.etree.ElementTree + +sys.path.append(os.path.join(os.path.dirname(os.path.realpath(__file__)),'..')) + +from uros_agent import * + +def main(argv=sys.argv[1:]): + parser = argparse.ArgumentParser( + description='Import default xml files', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument( + '--default-xml-path', + required=True, + help='The location of the default profiles') + args = parser.parse_args(argv) + ReadDefaultXMLs(args.default_xml_path) + + return 0 + +if __name__ == '__main__': + sys.exit(main()) \ No newline at end of file diff --git a/bin/micro_ros_agent b/bin/micro_ros_agent deleted file mode 100644 index a717221..0000000 --- a/bin/micro_ros_agent +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import os -import sys - -from rosidl_cmake import read_generator_arguments -from rosidl_parser import UnknownMessageType -from micro_ros_agent import generate_micro_ros_agent_xml_support - -def is_valid_file(parser, file_name): - if not os.path.exists(file_name): - parser.error("File does not exist: '{0}'".format(file_name)) - file_name_abs = os.path.abspath(file_name) - if not os.path.isfile(file_name_abs): - parser.error("Path exists but is not a file: '{0}'".format(file_name_abs)) - return file_name - - -def main(argv=sys.argv[1:]): - parser = argparse.ArgumentParser( - description='Generate xml files for micrortps agent.', - formatter_class=argparse.ArgumentDefaultsHelpFormatter) - parser.add_argument( - '--generator-arguments-file', - required=True, - help='The location of the file containing the generator arguments') - args = parser.parse_args(argv) - - generator_args = read_generator_arguments(args.generator_arguments_file) - - try: - rc = generate_micro_ros_agent_xml_support(generator_args) - - return 0 - except UnknownMessageType as e: - print(str(e), file=sys.stderr) - return 1 - if rc: - return rc - return 0 - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/cmake/micrortps_agent_xml_generator.cmake b/cmake/micrortps_agent_xml_generator.cmake deleted file mode 100644 index 6f269f0..0000000 --- a/cmake/micrortps_agent_xml_generator.cmake +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright 2016-2018 Proyectos y Sistemas de Mantenimiento SL (eProsima). -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -# list msg files -set(_ros_idl_files "") -foreach(_idl_file ${rosidl_generate_interfaces_IDL_FILES}) - get_filename_component(_extension "${_idl_file}" EXT) - # Skip .srv files - if(_extension STREQUAL ".msg") - list(APPEND _ros_idl_files "${_idl_file}") - endif() -endforeach() - - -# Set output dir -set(_output_path "${CMAKE_CURRENT_BINARY_DIR}/../micro_ros_agent/xml_gen") - - -# check if all templates exits -set(target_dependencies - "${micro_ros_agent_BIN}" - "${micro_ros_agent_GENERATOR_FILES}" - ${rosidl_generate_interfaces_IDL_FILES} - ${_dependency_files}) -foreach(dep ${target_dependencies}) - if(NOT EXISTS "${dep}") - message(FATAL_ERROR "Target dependency '${dep}' does not exist") - endif() -endforeach() - - -# generate script argument file -set(generator_arguments_file "${CMAKE_CURRENT_BINARY_DIR}/micro_ros_agent__arguments.json") -rosidl_write_generator_arguments( - "${generator_arguments_file}" - PACKAGE_NAME "${PROJECT_NAME}" - ROS_INTERFACE_FILES "${rosidl_generate_interfaces_IDL_FILES}" - ROS_INTERFACE_DEPENDENCIES "${_dependencies}" - OUTPUT_DIR "${_output_path}" - TEMPLATE_DIR "${micro_ros_agent_DEFAULT_PROFILES_DIR}" - TARGET_DEPENDENCIES ${target_dependencies} - ADDITIONAL_FILES ${_dds_idl_files} -) - - -# Execute python script -execute_process( - COMMAND ${PYTHON_EXECUTABLE} ${micro_ros_agent_BIN} - --generator-arguments-file "${generator_arguments_file}" - ) - - -#Install -install( - DIRECTORY "${_output_path}/" - DESTINATION "../micrortps_agent/bin" -) \ No newline at end of file diff --git a/micro_ros_agent-extras.cmake.in b/micro_ros_agent-extras.cmake.in deleted file mode 100644 index aa4e047..0000000 --- a/micro_ros_agent-extras.cmake.in +++ /dev/null @@ -1,14 +0,0 @@ -find_package(ament_cmake_core QUIET REQUIRED) -ament_register_extension( - "rosidl_generate_interfaces" - "micro_ros_agent" - "micrortps_agent_xml_generator.cmake") - -set(micro_ros_agent_BIN "${micro_ros_agent_DIR}/../../../lib/micro_ros_agent/micro_ros_agent") -normalize_path(micro_ros_agent_BIN "${micro_ros_agent_BIN}") - -set(micro_ros_agent_GENERATOR_FILES "${micro_ros_agent_DIR}/../../../@PYTHON_INSTALL_DIR@/micro_ros_agent/__init__.py") -normalize_path(micro_ros_agent_GENERATOR_FILES "${micro_ros_agent_GENERATOR_FILES}") - -set(micro_ros_agent_DEFAULT_PROFILES_DIR "${micro_ros_agent_DIR}/../resource") -normalize_path(micro_ros_agent_DEFAULT_PROFILES_DIR "${micro_ros_agent_DEFAULT_PROFILES_DIR}") \ No newline at end of file diff --git a/package.xml b/package.xml index 461ed8a..f895d2a 100644 --- a/package.xml +++ b/package.xml @@ -1,8 +1,8 @@ - micro_ros_agent - 0.0.1 + uros_agent + 0.0.2 DDS-XCRE agent implementation Javier Moreno Apache License 2.0 @@ -15,11 +15,12 @@ fastcdr fastrtps micrortps_agent + rosidl_cmake ament_lint_auto ament_lint_common - rosidl_typesupport_c_packages + rosidl_interface_packages ament_cmake diff --git a/micro_ros_agent/__init__.py b/uros_agent/__init__.py similarity index 54% rename from micro_ros_agent/__init__.py rename to uros_agent/__init__.py index 34ad0b0..a785b15 100644 --- a/micro_ros_agent/__init__.py +++ b/uros_agent/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2016-2018 Proyectos y Sistemas de Mantenimiento SL (eProsima). +# Copyright 2016 Proyectos y Sistemas de Mantenimiento SL (eProsima). # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -12,19 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -import struct import os import sys - -if os.name == 'nt': - import win32con - import win32file - import pywintypes - __overlapped = pywintypes.OVERLAPPED() -elif os.name == 'posix': - import fcntl -else: - raise RuntimeError('PortaLocker only defined for nt and posix platforms') +import xml.etree.ElementTree from rosidl_cmake import convert_camel_case_to_lower_case_underscore from rosidl_cmake import expand_template @@ -33,14 +23,103 @@ from rosidl_cmake import get_newest_modification_time from rosidl_parser import parse_message_file from rosidl_parser import parse_service_file from rosidl_parser import validate_field_types -from shutil import copyfile -from pathlib import Path -def generate_micro_ros_agent_xml_support(args): +def GetPackage(Dir): + + # ignore? + for f in os.listdir(Dir): + full_path = os.path.join(Dir, f) + if os.path.isfile(full_path): + if f == "COLCON_IGNORE": + return "COLCON_IGNORE" + + # found package + found_package_path = "" + for f in os.listdir(Dir): + if f == "package.xml": + found_package_path = os.path.join(Dir, f) + found_package_path = os.path.abspath(found_package_path) + break + + + return found_package_path + + +def GetPackageList(Dir): + package_list = [] + package_path = GetPackage(Dir) + + if package_path == "": + for f in os.listdir(Dir): + full_path = os.path.join(Dir, f) + if os.path.isdir(full_path): + for l in GetPackageList(full_path): + package_list.append(l) + elif package_path != "COLCON_IGNORE": + package_list.append(package_path) + + return package_list + + +def GetInterfacePackages(packages_list): + package_interface_list = [] + for package in packages_list: + xml_root = xml.etree.ElementTree.parse(package).getroot() + for element in xml_root.findall('member_of_group'): + if element.text == "rosidl_interface_packages": + package_interface_list.append(package) + return package_interface_list + + +def GetPackageName(package_path): + xml_root = xml.etree.ElementTree.parse(package_path).getroot() + xml_name_elements = xml_root.findall('name') + if len(xml_name_elements) != 1: + return "" + else: + return xml_name_elements[0].text + + +def GetInterfacePackageMsgs(package_path): + msg_list = [] + package_dir = os.path.dirname(package_path) + for root, dirs, files in os.walk(package_dir): + for file in files: + if file.endswith(".msg"): + full_path = os.path.join(root, file) + msg_list.append(full_path) + + return msg_list + +def GetInterfacePackageSrvs(package_path): + msg_list = [] + package_dir = os.path.dirname(package_path) + for root, dirs, files in os.walk(package_dir): + for file in files: + if file.endswith(".srv"): + full_path = os.path.join(root, file) + msg_list.append(full_path) + + return msg_list + + +def ReadDefaultXMLs(Path): + for f in os.listdir(Path): + full_path = os.path.join(Path, f) + if os.path.isfile(full_path) and f.endswith(".xml"): + #xml_root = xml.etree.ElementTree.parse(full_path).getroot() + #if xml_root.iselement(): + fd = open(full_path) + print ("%s" % fd.read()) + fd.close() + + + +def generate_XML(args): pkg_name = args['package_name'] - known_msg_types = extract_message_types( - pkg_name, args['ros_interface_files'], args.get('ros_interface_dependencies', [])) + #known_msg_types = extract_message_types( + # pkg_name, args['ros_interface_files'], args.get('ros_interface_dependencies', [])) functions = { 'get_header_filename_from_msg_name': convert_camel_case_to_lower_case_underscore, @@ -48,7 +127,6 @@ def generate_micro_ros_agent_xml_support(args): # Set file format - file_format = ".xml" ros2_prefix = "rt/" @@ -63,14 +141,6 @@ def generate_micro_ros_agent_xml_support(args): if not os.path.exists(srcs_dir): os.makedirs(srcs_dir) - - # Copy all included xml files - for filename in os.listdir(args['template_dir']): - if filename.endswith(file_format): - template_src_path = os.path.join(args['template_dir'], filename) - template_dest_path = os.path.join(srcs_dir, filename) - if not os.path.isfile(template_dest_path): - copyfile(template_src_path, template_dest_path) # Iterate throw all msgs/srvs @@ -78,7 +148,7 @@ def generate_micro_ros_agent_xml_support(args): extension = os.path.splitext(idl_file)[1] if extension == '.msg': spec = parse_message_file(pkg_name, idl_file) - validate_field_types(spec, known_msg_types) + #validate_field_types(spec, known_msg_types) subfolder = os.path.basename(os.path.dirname(idl_file)) data = { @@ -137,95 +207,9 @@ def generate_micro_ros_agent_xml_support(args): # Write file content - fd1 = open(src_file, "w") - if os.name == 'nt': - # Lock - hfile1 = win32file._get_osfhandle(fd1.fileno()) - win32file.LockFileEx(hfile1, win32con.LOCKFILE_EXCLUSIVE_LOCK, 0, -0x10000, __overlapped) - - # Write - fd1.write(file_content) - - # Unlock - win32file.UnlockFileEx(hfile1, 0, -0x10000, __overlapped) - elif os.name == 'posix': - # Lock - fcntl.flock(fd1.fileno(), fcntl.LOCK_EX) - - # Write - fd1.write(file_content) - - # Unlock - fcntl.flock(fd1.fileno(), fcntl.LOCK_UN) - fd1.close() + print ("%s" % file_content) - # Open collect file - collec_file = os.path.join(args['output_dir'], "DEFAULT_FASTRTPS_PROFILES.xml") - fd2 = open(collec_file, "w") - if os.name == 'nt': - # Lock - hfile2 = win32file._get_osfhandle(fd2.fileno()) - win32file.LockFileEx(hfile2, win32con.LOCKFILE_EXCLUSIVE_LOCK, 0, -0x10000, __overlapped) - - # Generate head - fd2.write("\n") - - # Append all files contents - for filename in os.listdir(srcs_dir): - if filename.endswith(".xml"): - # Open - fd3 = open(os.path.join(srcs_dir, filename), "r+") - - # Lock - hfile3 = win32file._get_osfhandle(fd3.fileno()) - win32file.LockFileEx(hfile3, win32con.LOCKFILE_EXCLUSIVE_LOCK, 0, -0x10000, __overlapped) - - # Write - fd2.write(fd3.read()) - - # Unlock - win32file.UnlockFileEx(hfile3, 0, -0x10000, __overlapped) - fd3.close() - - # Generate tail - fd2.write("\n") - - # UnLock - win32file.UnlockFileEx(hfile2, 0, -0x10000, __overlapped) - elif os.name == 'posix': - # Lock - fcntl.flock(fd2.fileno(), fcntl.LOCK_EX) - - # Generate head - fd2.write("\n") - - # Append all files contents - for filename in os.listdir(srcs_dir): - if filename.endswith(".xml"): - # Open - fd3 = open(os.path.join(srcs_dir, filename), "r+") - - # Lock - fcntl.flock(fd3, fcntl.LOCK_EX) - - # Write - fd2.write(fd3.read()) - - # Unlock - fcntl.flock(fd3.fileno(), fcntl.LOCK_UN) - - # Close - fd3.close() - - # Generate tail - fd2.write("\n") - - # UnLock - fcntl.flock(fd2.fileno(), fcntl.LOCK_UN) - # Close file - fd2.close() - #elif extension == '.srv': From a77c0f754786dfabb4468c69975015c35ab69b54 Mon Sep 17 00:00:00 2001 From: Borja Outerelo Date: Tue, 16 Oct 2018 11:48:51 +0200 Subject: [PATCH 09/17] Refs #3499. Uses new middleware name, Micro XRCE-DDS. --- CMakeLists.txt | 7 +++---- package.xml | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 782435d..2717f90 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,6 @@ # Set CMake version cmake_minimum_required(VERSION 3.5) - # Set proyect name project(uros_agent) @@ -26,14 +25,14 @@ find_package(rosidl_cmake REQUIRED) find_package(ament_cmake REQUIRED) find_package(fastcdr REQUIRED CONFIG) find_package(fastrtps REQUIRED CONFIG) -find_package(micrortps_agent REQUIRED CONFIG) +find_package(microxrcedds_agent REQUIRED CONFIG) find_package(ament_cmake_python REQUIRED) # Export dependencies to downstream packages ament_export_dependencies(fastcdr) ament_export_dependencies(fastrtps) -ament_export_dependencies(micrortps_agent) +ament_export_dependencies(microxrcedds_agent) # Set variables @@ -202,7 +201,7 @@ ament_package() #Install install( FILES "${_DEFAULT_FASTRTPS_PROFILES_PATH}" - DESTINATION "../micrortps_agent/bin" + DESTINATION "../microxrcedds_agent/bin" ) diff --git a/package.xml b/package.xml index f895d2a..38534c8 100644 --- a/package.xml +++ b/package.xml @@ -14,7 +14,7 @@ fastcdr fastrtps - micrortps_agent + microxrcedds_agent rosidl_cmake ament_lint_auto From e8621a76e68e296ecdafa0cae011a36f32453277 Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Thu, 11 Oct 2018 11:22:32 +0200 Subject: [PATCH 10/17] Refs #3486 - Create Readme.md for uROS agent --- README.md | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 764060f..e103067 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,35 @@ -# micro-ros-agent +# Overview +This repo contains the Micro-Ros Agent package. +Micro-Ros Agent is a ROS2 node that wrapps the Micro XRCE-DDS Agent. +For farther information about Micro XRCE-DDA Agent click [here](https://github.com/eProsima/Micro-XRCE-DDS-Agent) + +The node acts as a server between DDS Network and Micro-ROS nodes. +It will receive messages containing operations from Micro-ROS nodes, keep track of the Micro-ROS nodes. +The node will interact with DDS Global Data Space on behalf of the Micro-ROS nodes. + +While the node is running, it attends any received request from the Micro-ROS nodes and will answers back with the result of a request each time a request is attended. + + +# Package features + +## XML generation + +During the build proces, the package will look for all ROS2 / Micro-ROS messages in order to generare XML profiles. +This XML file can be referenced in the Agent-Client comunication in order to avoid sending the full XML content. + + +## Agent-Client comunication mechanims + +Communication between the Micro-ROS Agent and the Micro-ROS nodes supports two kind transports: +- UDP +- SerialPort. + + +# Node configuration + +## Transport type + +### udp + +### Serial port From fa6e94898bc6c551dff94d5c566d2dba00ca0660 Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Tue, 16 Oct 2018 07:38:00 +0200 Subject: [PATCH 11/17] Review needed. Links are missing until migration to external networks. --- README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index e103067..a4b86a5 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,12 @@ + + # Overview This repo contains the Micro-Ros Agent package. Micro-Ros Agent is a ROS2 node that wrapps the Micro XRCE-DDS Agent. For farther information about Micro XRCE-DDA Agent click [here](https://github.com/eProsima/Micro-XRCE-DDS-Agent) +This package is a part of the Micro-ROS poject stack. +For more information about Micro-ROS project click [here](). The node acts as a server between DDS Network and Micro-ROS nodes. It will receive messages containing operations from Micro-ROS nodes, keep track of the Micro-ROS nodes. @@ -24,12 +28,7 @@ This XML file can be referenced in the Agent-Client comunication in order to avo Communication between the Micro-ROS Agent and the Micro-ROS nodes supports two kind transports: - UDP - SerialPort. - -# Node configuration - -## Transport type -### udp - -### Serial port +All available configurations are supported direcly by the Micro XRCE-DDS agent. +For farther information how configure the agent click [here](). \ No newline at end of file From c5cc9808248eecceade11deda5e15ea64be9031b Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Tue, 16 Oct 2018 14:01:08 +0200 Subject: [PATCH 12/17] logo size ajusted. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a4b86a5..f423928 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ - + # Overview From 45c4a698c31f23002b4ca389c2928cfbd8abe2cb Mon Sep 17 00:00:00 2001 From: Borja Outerelo Date: Fri, 19 Oct 2018 10:14:12 +0200 Subject: [PATCH 13/17] Refs #3486. Adds some wording improvements. --- README.md | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index f423928..70e7cfa 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,31 @@ - +# Micro ROS Agent -# Overview +## Overview -This repo contains the Micro-Ros Agent package. -Micro-Ros Agent is a ROS2 node that wrapps the Micro XRCE-DDS Agent. -For farther information about Micro XRCE-DDA Agent click [here](https://github.com/eProsima/Micro-XRCE-DDS-Agent) -This package is a part of the Micro-ROS poject stack. -For more information about Micro-ROS project click [here](). +This repository contains the Micro-ROS Agent package. +Micro-ROS Agent is a ROS 2 node that wraps the Micro XRCE-DDS Agent. +For further information about Micro XRCE-DDS Agent click [here](https://github.com/eProsima/Micro-XRCE-DDS-Agent) +This package is a part of the Micro-ROS project stack. +For more information about Micro-ROS project click [here](https://microros.github.io/micro-ROS/). -The node acts as a server between DDS Network and Micro-ROS nodes. -It will receive messages containing operations from Micro-ROS nodes, keep track of the Micro-ROS nodes. -The node will interact with DDS Global Data Space on behalf of the Micro-ROS nodes. +The node acts as a server between DDS Network and Micro-ROS nodes inside MCU. +It receives and send messages from Micro-ROS nodes, and keep track of the Micro-ROS nodes exposing them to the ROS 2 network. +The node interacts with DDS Global Data Space on behalf of the Micro-ROS nodes. -While the node is running, it attends any received request from the Micro-ROS nodes and will answers back with the result of a request each time a request is attended. +## Package features +### XML generation -# Package features +During the build process, the package looks for all ROS 2 messages to generate an initial list of XML profiles. +These profiles can are referenced in the Agent-Client communication to avoid sending the full XML content. +This reference mechanism can be switched on and off from the Micro XRCE-DDS middleware layer. -## XML generation +### Agent-Client communication mechanism -During the build proces, the package will look for all ROS2 / Micro-ROS messages in order to generare XML profiles. -This XML file can be referenced in the Agent-Client comunication in order to avoid sending the full XML content. +Communication between the Micro-ROS Agent and the Micro-ROS nodes supports two types of transport: +- UDP. +- SerialPort. -## Agent-Client comunication mechanims - -Communication between the Micro-ROS Agent and the Micro-ROS nodes supports two kind transports: -- UDP -- SerialPort. - - -All available configurations are supported direcly by the Micro XRCE-DDS agent. -For farther information how configure the agent click [here](). \ No newline at end of file +All available configurations are supported directly by the Micro XRCE-DDS agent. +For further information on how to configure the agent click [here](TODO). \ No newline at end of file From bb1fe9561ce34015acda56c71db3555cdb6cde6a Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Wed, 17 Oct 2018 10:54:04 +0200 Subject: [PATCH 14/17] Refs #3561 - Generate uROS_Agent module --- .../CMakeLists.txt | 32 +++++ .../Modules/FindMicroXRCEDDS_Agent.cmake | 124 ++++++++++++++++++ ...croxrcedds_agent_cmake_module-extras.cmake | 15 +++ microxrcedds_agent_cmake_module/package.xml | 22 ++++ CMakeLists.txt => uROS_Agent/CMakeLists.txt | 0 README.md => uROS_Agent/README.md | 0 {bin => uROS_Agent/bin}/Xml_interface_gen.py | 0 .../bin}/Xml_read_default_profiles.py | 0 package.xml => uROS_Agent/package.xml | 0 .../resource}/StaticValues.xml | 0 .../uros_agent}/__init__.py | 0 11 files changed, 193 insertions(+) create mode 100644 microxrcedds_agent_cmake_module/CMakeLists.txt create mode 100644 microxrcedds_agent_cmake_module/cmake/Modules/FindMicroXRCEDDS_Agent.cmake create mode 100644 microxrcedds_agent_cmake_module/microxrcedds_agent_cmake_module-extras.cmake create mode 100644 microxrcedds_agent_cmake_module/package.xml rename CMakeLists.txt => uROS_Agent/CMakeLists.txt (100%) rename README.md => uROS_Agent/README.md (100%) rename {bin => uROS_Agent/bin}/Xml_interface_gen.py (100%) rename {bin => uROS_Agent/bin}/Xml_read_default_profiles.py (100%) rename package.xml => uROS_Agent/package.xml (100%) rename {resource => uROS_Agent/resource}/StaticValues.xml (100%) rename {uros_agent => uROS_Agent/uros_agent}/__init__.py (100%) diff --git a/microxrcedds_agent_cmake_module/CMakeLists.txt b/microxrcedds_agent_cmake_module/CMakeLists.txt new file mode 100644 index 0000000..8d17615 --- /dev/null +++ b/microxrcedds_agent_cmake_module/CMakeLists.txt @@ -0,0 +1,32 @@ +# Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cmake_minimum_required(VERSION 3.5) + +project(microxrcedds_agent_cmake_module) + +find_package(ament_cmake REQUIRED) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + ament_lint_auto_find_test_dependencies() +endif() + +ament_package( + CONFIG_EXTRAS "microxrcedds_agent_cmake_module-extras.cmake" + ) + +install(DIRECTORY cmake + DESTINATION share/${PROJECT_NAME} + ) diff --git a/microxrcedds_agent_cmake_module/cmake/Modules/FindMicroXRCEDDS_Agent.cmake b/microxrcedds_agent_cmake_module/cmake/Modules/FindMicroXRCEDDS_Agent.cmake new file mode 100644 index 0000000..8df1b34 --- /dev/null +++ b/microxrcedds_agent_cmake_module/cmake/Modules/FindMicroXRCEDDS_Agent.cmake @@ -0,0 +1,124 @@ +# Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +############################################################################### +# +# CMake module for finding eProsima MICROXRCEDDS_AGENT. +# +# Output variables: +# +# - MicroXRCEDDS_Agent_FOUND: flag indicating if the package was found +# - MicroXRCEDDS_Agent_INCLUDE_DIR: Paths to the header files +# +# Example usage: +# +# find_package(uros_agent_cmake_module REQUIRED) +# find_package(MicroXRCEDDS_Agent MODULE) +# # use MicroXRCEDDS_Agent_* variables +# +############################################################################### + +# lint_cmake: -convention/filename, -package/stdargs + +set(MicroXRCEDDS_Agent_FOUND FALSE) + +find_package(microxrcedds_agent REQUIRED CONFIG) +find_package(fastcdr REQUIRED CONFIG) +find_package(fastrtps REQUIRED CONFIG) + +find_path(MicroXRCEDDS_Agent_INCLUDE_DIR NAMES uxr) + +string(REGEX MATCH "^[0-9]+\\.[0-9]+" microxrcedds_agent_MAJOR_MINOR_VERSION "${microxrcedds_agent_VERSION}") +string(REGEX MATCH "^[0-9]+\\.[0-9]+" fastcdr_MAJOR_MINOR_VERSION "${fastcdr_VERSION}") +string(REGEX MATCH "^[0-9]+\\.[0-9]+" fastrtps_MAJOR_MINOR_VERSION "${fastrtps_VERSION}") + +## +find_library(MicroXRCEDDS_Agent_LIBRARY_RELEASE + NAMES microxrcedds_agent-${microxrcedds_agent_MAJOR_MINOR_VERSION} microxrcedds_agent) + +find_library(MicroXRCEDDS_Agent_LIBRARY_DEBUG + NAMES microxrcedds_agentd-${microxrcedds_agent_MAJOR_MINOR_VERSION} microxrcedds_agentd) + +if(MicroXRCEDDS_Agent_LIBRARY_RELEASE AND MicroXRCEDDS_Agent_LIBRARY_DEBUG) + set(MicroXRCEDDS_Agent_LIBRARIES + optimized ${MicroXRCEDDS_Agent_LIBRARY_RELEASE} + debug ${MicroXRCEDDS_Agent_LIBRARY_DEBUG} + ) +elseif(MicroXRCEDDS_Agent_LIBRARY_RELEASE) + set(MicroXRCEDDS_Agent_LIBRARIES + ${MicroXRCEDDS_Agent_LIBRARY_RELEASE} + ) +elseif(MicroXRCEDDS_Agent_LIBRARY_DEBUG) + set(MicroXRCEDDS_Agent_LIBRARIES + ${MicroXRCEDDS_Agent_LIBRARY_DEBUG} + ) +else() + set(MicroXRCEDDS_Agent_LIBRARIES "") +endif() + +## +find_library(FastRTPS_LIBRARY_RELEASE + NAMES fastrtps-${fastrtps_MAJOR_MINOR_VERSION} fastrtps) + +find_library(FastRTPS_LIBRARY_DEBUG + NAMES fastrtpsd-${fastrtps_MAJOR_MINOR_VERSION} fastrtpsd) + +if(FastRTPS_LIBRARY_RELEASE AND FastRTPS_LIBRARY_DEBUG) + set(FastRTPS_LIBRARIES + optimized ${FastRTPS_LIBRARY_RELEASE} + debug ${FastRTPS_LIBRARY_DEBUG} + ) +elseif(FastRTPS_LIBRARY_RELEASE) + set(FastRTPS_LIBRARIES + ${MicroXRCEDDS_Agent_LIBRARY_RELEASE} + ) +elseif(FastRTPS_LIBRARY_DEBUG) + set(FastRTPS_LIBRARIES + ${MicroXRCEDDS_Agent_LIBRARY_DEBUG} + ) +else() + set(FastRTPS_LIBRARIES "") +endif() + +## +find_library(FastCDR_LIBRARY_RELEASE + NAMES fastcdr-${fastcdr_MAJOR_MINOR_VERSION} fastcdr) + +find_library(FastCDR_LIBRARY_DEBUG + NAMES fastcdrd-${fastcdr_MAJOR_MINOR_VERSION} fastcdrd) + +if(FastCDR_LIBRARY_RELEASE AND FastCDR_LIBRARY_DEBUG) + set(FastCDR_LIBRARIES + optimized ${FastCDR_LIBRARY_RELEASE} + debug ${FastCDR_LIBRARY_DEBUG} + ) +elseif(FastCDR_LIBRARY_RELEASE) + set(FastCDR_LIBRARIES + ${FastCDR_LIBRARY_RELEASE} + ) +elseif(FastCDR_LIBRARY_DEBUG) + set(FastCDR_LIBRARIES + ${FastCDR_LIBRARY_DEBUG} + ) +else() + set(FastCDR_LIBRARIES "") +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(MicroXRCEDDS_Agent + FOUND_VAR MicroXRCEDDS_Agent_FOUND + REQUIRED_VARS + MicroXRCEDDS_Agent_INCLUDE_DIR + MicroXRCEDDS_Agent_LIBRARIES +) \ No newline at end of file diff --git a/microxrcedds_agent_cmake_module/microxrcedds_agent_cmake_module-extras.cmake b/microxrcedds_agent_cmake_module/microxrcedds_agent_cmake_module-extras.cmake new file mode 100644 index 0000000..d8b7862 --- /dev/null +++ b/microxrcedds_agent_cmake_module/microxrcedds_agent_cmake_module-extras.cmake @@ -0,0 +1,15 @@ +# Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +list(INSERT CMAKE_MODULE_PATH 0 "${microxrcedds_agent_cmake_module_DIR}/Modules") diff --git a/microxrcedds_agent_cmake_module/package.xml b/microxrcedds_agent_cmake_module/package.xml new file mode 100644 index 0000000..6750cbe --- /dev/null +++ b/microxrcedds_agent_cmake_module/package.xml @@ -0,0 +1,22 @@ + + + + microxrcedds_agent_cmake_module + 0.1.0 + Provide CMake module to find eProsima Micro XRCE-DDS Agent + Javier Moreno + Apache License 2.0 + Javier Moreno + + ament_cmake + + ament_lint_auto + ament_lint_common + + microxrcedds_agent + microxrcedds_agent + + + ament_cmake + + diff --git a/CMakeLists.txt b/uROS_Agent/CMakeLists.txt similarity index 100% rename from CMakeLists.txt rename to uROS_Agent/CMakeLists.txt diff --git a/README.md b/uROS_Agent/README.md similarity index 100% rename from README.md rename to uROS_Agent/README.md diff --git a/bin/Xml_interface_gen.py b/uROS_Agent/bin/Xml_interface_gen.py similarity index 100% rename from bin/Xml_interface_gen.py rename to uROS_Agent/bin/Xml_interface_gen.py diff --git a/bin/Xml_read_default_profiles.py b/uROS_Agent/bin/Xml_read_default_profiles.py similarity index 100% rename from bin/Xml_read_default_profiles.py rename to uROS_Agent/bin/Xml_read_default_profiles.py diff --git a/package.xml b/uROS_Agent/package.xml similarity index 100% rename from package.xml rename to uROS_Agent/package.xml diff --git a/resource/StaticValues.xml b/uROS_Agent/resource/StaticValues.xml similarity index 100% rename from resource/StaticValues.xml rename to uROS_Agent/resource/StaticValues.xml diff --git a/uros_agent/__init__.py b/uROS_Agent/uros_agent/__init__.py similarity index 100% rename from uros_agent/__init__.py rename to uROS_Agent/uros_agent/__init__.py From d66fa96f30bce5ddd9c9503bb67e506d0568a3a3 Mon Sep 17 00:00:00 2001 From: "Javier JM. Moreno" Date: Wed, 31 Oct 2018 15:09:09 +0100 Subject: [PATCH 15/17] Refs #3552 - Adapt to new XML profiles --- uROS_Agent/resource/StaticValues.xml | 61 +++++++++++----------------- uROS_Agent/uros_agent/__init__.py | 60 ++++++++++++--------------- 2 files changed, 49 insertions(+), 72 deletions(-) diff --git a/uROS_Agent/resource/StaticValues.xml b/uROS_Agent/resource/StaticValues.xml index 7444a10..1c0e831 100644 --- a/uROS_Agent/resource/StaticValues.xml +++ b/uROS_Agent/resource/StaticValues.xml @@ -1,39 +1,24 @@ - - - - - INFINITE - - 0 - - DataReader_participant_subscriber - - - - - WITH_KEY - Square - ShapeType - - KEEP_LAST - 5 - - - TRANSIENT_LOCAL - + + + default_xrce_participant + + + + + WITH_KEY + Square + ShapeType + + + + + WITH_KEY + Square + ShapeType + + + + WITH_KEY + Square + ShapeType - - - - WITH_KEY - Square - ShapeType - - KEEP_LAST - 5 - - - TRANSIENT_LOCAL - - - diff --git a/uROS_Agent/uros_agent/__init__.py b/uROS_Agent/uros_agent/__init__.py index a785b15..612359e 100644 --- a/uROS_Agent/uros_agent/__init__.py +++ b/uROS_Agent/uros_agent/__init__.py @@ -165,45 +165,37 @@ def generate_XML(args): src_file = os.path.join(srcs_dir, "%s_%s_%s.xml" % (spec.base_type.pkg_name, subfolder, spec.msg_name)) - # Publisher - file_content = " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) - file_content += " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) - file_content += " NO_KEY\n" - file_content += " %s%s_%s_%s\n" % (ros2_prefix, spec.base_type.pkg_name, subfolder, spec.msg_name) - file_content += " %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) - file_content += " \n" - file_content += " KEEP_LAST\n" - file_content += " 5\n" - file_content += " \n" - file_content += " \n" - file_content += " TRANSIENT_LOCAL\n" - file_content += " \n" - file_content += " \n" - file_content += " \n" + # Data writer + #file_content = " \n" + file_content = " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " NO_KEY\n" + file_content += " %s%s_%s_%s\n" % (ros2_prefix, spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " \n" + file_content += " \n" + #file_content += " \n" - # Subscriber - file_content += " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) - file_content += " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) - file_content += " NO_KEY\n" - file_content += " %s%s_%s_%s\n" % (ros2_prefix, spec.base_type.pkg_name, subfolder, spec.msg_name) - file_content += " %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) - file_content += " \n" - file_content += " KEEP_LAST\n" - file_content += " 5\n" - file_content += " \n" - file_content += " \n" - file_content += " TRANSIENT_LOCAL\n" - file_content += " \n" - file_content += " \n" - file_content += " \n" + # Data reader + #file_content += " \n" + file_content += " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " NO_KEY\n" + file_content += " %s%s_%s_%s\n" % (ros2_prefix, spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " \n" + file_content += " \n" + #file_content += " \n" # Topic - file_content += " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) - file_content += " %s%s_%s_%s\n" % (ros2_prefix, spec.base_type.pkg_name, subfolder, spec.msg_name) - file_content += " %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) - file_content += " \n" + #file_content += " \n" + file_content += " \n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " %s%s_%s_%s\n" % (ros2_prefix, spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " %s::%s::dds_::%s_\n" % (spec.base_type.pkg_name, subfolder, spec.msg_name) + file_content += " \n" + #file_content += " \n" # Write file content From b483e7e007f19b396603a0e83b5349962c441c1a Mon Sep 17 00:00:00 2001 From: "Javier JM. Moreno" Date: Wed, 31 Oct 2018 15:49:30 +0100 Subject: [PATCH 16/17] Feature/u ros agent node --- uROS_Agent/CMakeLists.txt | 48 ++++++- uROS_Agent/package.xml | 6 +- uROS_Agent/src/main.cpp | 272 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 324 insertions(+), 2 deletions(-) create mode 100644 uROS_Agent/src/main.cpp diff --git a/uROS_Agent/CMakeLists.txt b/uROS_Agent/CMakeLists.txt index 2717f90..ec0182f 100644 --- a/uROS_Agent/CMakeLists.txt +++ b/uROS_Agent/CMakeLists.txt @@ -20,6 +20,18 @@ cmake_minimum_required(VERSION 3.5) project(uros_agent) +set(CMAKE_C_CLANG_TIDY clang-tidy -checks=*) + +# Default to C++14 +if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 14) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + + # Find packages depencences find_package(rosidl_cmake REQUIRED) find_package(ament_cmake REQUIRED) @@ -193,11 +205,45 @@ set (_XmlDoc "\n${_XmlDoc}\n") file(WRITE "${_DEFAULT_FASTRTPS_PROFILES_PATH}" "${_XmlDoc}") +# Only compile uROS agent if rclcpp is found +find_package(rclcpp QUIET) +if (rclcpp_FOUND) + find_package(microxrcedds_agent_cmake_module REQUIRED) + find_package(MicroXRCEDDS_Agent REQUIRED MODULE) + + add_executable(${PROJECT_NAME} src/main.cpp) + ament_target_dependencies( + ${PROJECT_NAME} + rclcpp + microxrcedds_agent + ) + + # TODO(Javier) Temporal until thread error is solver + target_link_libraries( + ${PROJECT_NAME} + microxrcedds_agent + ) + +else() + message("uROS agent node will be not build") +endif() + + + # Install the package.xml file, and generate code for ``find_package`` so that other packages can get information about this package. ament_package() +# Only install if uROS_Agent is comiled +if (rclcpp_FOUND) + install(TARGETS + ${PROJECT_NAME} + DESTINATION lib/${PROJECT_NAME} + ) +endif() + + #Install install( FILES "${_DEFAULT_FASTRTPS_PROFILES_PATH}" @@ -209,4 +255,4 @@ install( #install( # DIRECTORY cmake resource # DESTINATION share/${PROJECT_NAME} -#) \ No newline at end of file +#) diff --git a/uROS_Agent/package.xml b/uROS_Agent/package.xml index 38534c8..afb3e2f 100644 --- a/uROS_Agent/package.xml +++ b/uROS_Agent/package.xml @@ -14,8 +14,12 @@ fastcdr fastrtps - microxrcedds_agent + microxrcedds_agent_cmake_module rosidl_cmake + + rclcpp + + rclcpp ament_lint_auto ament_lint_common diff --git a/uROS_Agent/src/main.cpp b/uROS_Agent/src/main.cpp new file mode 100644 index 0000000..0d412f6 --- /dev/null +++ b/uROS_Agent/src/main.cpp @@ -0,0 +1,272 @@ + +// Copyright 2018 Proyectos y Sistemas de Mantenimiento SL (eProsima). +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifdef _WIN32 +#include +#include +#else +#include +#include +#include +#include +#include +#endif //_WIN32 +#include +#include +#include +#include "rclcpp/rclcpp.hpp" + +void showHelp() +{ + std::cout << "Usage: program " << std::endl; + std::cout << "List of commands:" << std::endl; + std::cout << " serial " << std::endl; + std::cout << " pseudo-serial" << std::endl; + std::cout << " udp []" << std::endl; + std::cout << " tcp []" << std::endl; +} + +void initializationError() +{ + std::cout << "Error: Invalid arguments." << std::endl; + showHelp(); + std::exit(EXIT_FAILURE); +} + +uint16_t parsePort(const char* str_port) +{ + uint16_t valid_port = 0; + try + { + int port = std::stoi(str_port); + if(port > (std::numeric_limits::max)()) + { + std::cout << "Error: port number '" << port << "out of range." << std::endl; + initializationError(); + } + valid_port = uint16_t(port); + } + catch (const std::invalid_argument& ) + { + initializationError(); + } + return valid_port; +} + + +class uros_agent : public rclcpp::Node +{ +public: + uros_agent() : Node("uROS_Agent") + { + } + + ~uros_agent() + { + } + +private: + +}; + + +int main(int argc, char** argv) +{ + bool initialized = false; + +#ifndef _WIN32 + if(argc == 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)) + { + showHelp(); + } + else if(argc >= 3 && strcmp(argv[1], "udp") == 0) + { + std::cout << "UDP agent initialization... "; + uint16_t port = parsePort(argv[2]); + eprosima::uxr::UDPServer* udp_server = (argc == 4) //discovery port + ? new eprosima::uxr::UDPServer(port, parsePort(argv[3])) + : new eprosima::uxr::UDPServer(port); + if (udp_server->run()) + { + initialized = true; + } + std::cout << ((!initialized) ? "ERROR" : "OK") << std::endl; + } + else if(argc >= 3 && strcmp(argv[1], "tcp") == 0) + { + std::cout << "TCP agent initialization... "; + uint16_t port = parsePort(argv[2]); + eprosima::uxr::TCPServer* tcp_server = (argc == 4) //discovery port + ? new eprosima::uxr::TCPServer(port, parsePort(argv[3])) + : new eprosima::uxr::TCPServer(port); + if (tcp_server->run()) + { + initialized = true; + } + std::cout << ((!initialized) ? "ERROR" : "OK") << std::endl; + } + else if(argc == 3 && strcmp(argv[1], "serial") == 0) + { + std::cout << "Serial agent initialization... "; + + /* Open serial device. */ + int fd = open(argv[2], O_RDWR | O_NOCTTY); + if (0 < fd) + { + struct termios tty_config; + memset(&tty_config, 0, sizeof(tty_config)); + if (0 == tcgetattr(fd, &tty_config)) + { + /* Setting CONTROL OPTIONS. */ + tty_config.c_cflag |= CREAD; // Enable read. + tty_config.c_cflag |= CLOCAL; // Set local mode. + tty_config.c_cflag &= ~PARENB; // Disable parity. + tty_config.c_cflag &= ~CSTOPB; // Set one stop bit. + tty_config.c_cflag &= ~CSIZE; // Mask the character size bits. + tty_config.c_cflag |= CS8; // Set 8 data bits. + tty_config.c_cflag &= ~CRTSCTS; // Disable hardware flow control. + + /* Setting LOCAL OPTIONS. */ + tty_config.c_lflag &= ~ICANON; // Set non-canonical input. + tty_config.c_lflag &= ~ECHO; // Disable echoing of input characters. + tty_config.c_lflag &= ~ECHOE; // Disable echoing the erase character. + tty_config.c_lflag &= ~ISIG; // Disable SIGINTR, SIGSUSP, SIGDSUSP and SIGQUIT signals. + + /* Setting INPUT OPTIONS. */ + tty_config.c_iflag &= ~IXON; // Disable output software flow control. + tty_config.c_iflag &= ~IXOFF; // Disable input software flow control. + tty_config.c_iflag &= ~INPCK; // Disable parity check. + tty_config.c_iflag &= ~ISTRIP; // Disable strip parity bits. + tty_config.c_iflag &= ~IGNBRK; // No ignore break condition. + tty_config.c_iflag &= ~IGNCR; // No ignore carrier return. + tty_config.c_iflag &= ~INLCR; // No map NL to CR. + tty_config.c_iflag &= ~ICRNL; // No map CR to NL. + + /* Setting OUTPUT OPTIONS. */ + tty_config.c_oflag &= ~OPOST; // Set raw output. + + /* Setting OUTPUT CHARACTERS. */ + tty_config.c_cc[VMIN] = 10; + tty_config.c_cc[VTIME] = 1; + + /* Setting BAUD RATE. */ + cfsetispeed(&tty_config, B115200); + cfsetospeed(&tty_config, B115200); + + if (0 == tcsetattr(fd, TCSANOW, &tty_config)) + { + eprosima::uxr::SerialServer* serial_server = new eprosima::uxr::SerialServer(fd, 0); + if (serial_server->run()) + { + initialized = true; + } + } + } + } + + std::cout << ((!initialized) ? "ERROR" : "OK") << std::endl; + } + else if (argc == 2 && strcmp(argv[1], "pseudo-serial") == 0) + { + std::cout << "Pseudo-Serial initialization... "; + + /* Open pseudo-terminal. */ + char* dev = NULL; + int fd = posix_openpt(O_RDWR | O_NOCTTY); + if (-1 != fd) + { + if (grantpt(fd) == 0 && unlockpt(fd) == 0 && (dev = ptsname(fd))) + { + struct termios attr; + tcgetattr(fd, &attr); + cfmakeraw(&attr); + tcflush(fd, TCIOFLUSH); + tcsetattr(fd, TCSANOW, &attr); + } + } + + /* Launch server. */ + eprosima::uxr::SerialServer* serial_server = new eprosima::uxr::SerialServer(fd, 0x00); + if (serial_server->run()) + { + initialized = true; + } + + if (initialized) + { + std::cout << "OK" << std::endl; + std::cout << "Device: " << dev << std::endl; + } + else + { + std::cout << "ERROR" << std::endl; + } + } + else + { + initializationError(); + } +#else + (void) argc; + (void) argv; + + std::string server_type = ""; + std::cout << "Select server type [udp|tcp]: "; + std::cin >> server_type; + + if ("udp" == server_type) + { + uint16_t port = 0; + std::cout << "Select port: "; + std::cin >> port; + + std::cout << "UDP agent initialization.... "; + eprosima::uxr::UDPServer* udp_server = new eprosima::uxr::UDPServer(port); + if (udp_server->run()) + { + initialized = true; + } + std::cout << ((!initialized) ? "ERROR" : "OK") << std::endl; + } + else if ("tcp" == server_type) + { + uint16_t port = 0; + std::cout << "Select port: "; + std::cin >> port; + + std::cout << "UDP agent initialization.... "; + eprosima::uxr::TCPServer* tcp_server = new eprosima::uxr::TCPServer(port); + if (tcp_server->run()) + { + initialized = true; + } + std::cout << ((!initialized) ? "ERROR" : "OK") << std::endl; + } + else + { + std::cout << "Error server type" << std::endl; + } + +#endif + + if(initialized) + { + rclcpp::init(argc, argv); + rclcpp::spin(std::make_shared()); + rclcpp::shutdown(); + } + + return 0; +} From 27203c273eb70dfa1b1f7238c96c7bf750882637 Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Fri, 2 Nov 2018 11:57:07 +0100 Subject: [PATCH 17/17] XML fix --- uROS_Agent/CMakeLists.txt | 2 +- uROS_Agent/resource/StaticValues.xml | 6 +++--- uROS_Agent/resource/rclcpp.xml | 29 ++++++++++++++++++++++++++++ uROS_Agent/src/main.cpp | 22 +++++++++++++++++---- 4 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 uROS_Agent/resource/rclcpp.xml diff --git a/uROS_Agent/CMakeLists.txt b/uROS_Agent/CMakeLists.txt index ec0182f..368b5ba 100644 --- a/uROS_Agent/CMakeLists.txt +++ b/uROS_Agent/CMakeLists.txt @@ -247,7 +247,7 @@ endif() #Install install( FILES "${_DEFAULT_FASTRTPS_PROFILES_PATH}" - DESTINATION "../microxrcedds_agent/bin" + DESTINATION lib/${PROJECT_NAME} ) diff --git a/uROS_Agent/resource/StaticValues.xml b/uROS_Agent/resource/StaticValues.xml index 1c0e831..4d9c1ab 100644 --- a/uROS_Agent/resource/StaticValues.xml +++ b/uROS_Agent/resource/StaticValues.xml @@ -1,6 +1,6 @@ - + - default_xrce_participant + participant_profile @@ -21,4 +21,4 @@ WITH_KEY Square ShapeType - + \ No newline at end of file diff --git a/uROS_Agent/resource/rclcpp.xml b/uROS_Agent/resource/rclcpp.xml new file mode 100644 index 0000000..54a4c50 --- /dev/null +++ b/uROS_Agent/resource/rclcpp.xml @@ -0,0 +1,29 @@ + + rt/parameter_events + rcl_interfaces::msg::dds_::ParameterEvent_ + + + rt/clock + rosgraph_msgs::msg::dds_::Clock_ + + + + NO_KEY + rt/parameter_events + rcl_interfaces::msg::dds_::ParameterEvent_ + + + + + NO_KEY + rt/clock + rosgraph_msgs::msg::dds_::Clock_ + + + + + NO_KEY + rt/parameter_events + rcl_interfaces::msg::dds_::ParameterEvent_ + + \ No newline at end of file diff --git a/uROS_Agent/src/main.cpp b/uROS_Agent/src/main.cpp index 0d412f6..e9d986f 100644 --- a/uROS_Agent/src/main.cpp +++ b/uROS_Agent/src/main.cpp @@ -16,13 +16,18 @@ #ifdef _WIN32 #include #include -#else + +#elif __unix__ +#include +#include + #include #include #include #include #include -#endif //_WIN32 +#endif + #include #include #include @@ -84,9 +89,18 @@ private: int main(int argc, char** argv) { + +#ifdef __unix__ + char exe_path[200]; + ssize_t count = readlink("/proc/self/exe", exe_path, sizeof(exe_path)); + if (count != -1) { + chdir(dirname(exe_path)); + } +#endif + bool initialized = false; -#ifndef _WIN32 +#ifdef __unix__ if(argc == 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)) { showHelp(); @@ -218,7 +232,7 @@ int main(int argc, char** argv) { initializationError(); } -#else +#elif _WIN32 (void) argc; (void) argv;