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 + + + +