From 4790bdbdea043f042430f3194bf6b0b611fb97a0 Mon Sep 17 00:00:00 2001 From: Javier Moreno Date: Tue, 11 Sep 2018 16:24:38 +0200 Subject: [PATCH 1/7] 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 2/7] 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 3/7] 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 4/7] 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 5/7] 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 6/7] 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 7/7] 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()