├── rosidl_adapter_proto ├── pytest.ini ├── test │ ├── msg │ │ ├── test_rosidl_adapter__empty_args.json │ │ └── BoolTest.idl │ └── test_adapter_proto_message.py ├── package.xml ├── resource │ ├── rosidl_adapter_proto__visibility_control.h.in │ ├── srv.proto.em │ ├── action.proto.em │ ├── msg.proto.em │ └── idl.proto.em ├── CMakeLists.txt ├── cmake │ ├── rosidl_adapter_proto-extras.cmake.in │ └── rosidl_adapt_proto_interfaces.cmake ├── bin │ └── rosidl_adapter_proto └── rosidl_adapter_proto │ └── __init__.py ├── images ├── flow chart type support generation.pptx └── flow_chart_type_support_generation.png ├── rosidl_typesupport_protobuf ├── CHANGELOG.rst ├── package.xml ├── CMakeLists.txt ├── include │ └── rosidl_typesupport_protobuf │ │ ├── service_type_support.hpp │ │ ├── message_type_support.hpp │ │ ├── message_type_support_decl.hpp │ │ ├── service_type_support_decl.hpp │ │ ├── rosidl_generator_c_pkg_adapter.hpp │ │ ├── visibility_control.h │ │ └── proto_descriptor_helper.hpp └── rosidl_typesupport_protobuf │ └── __init__.py ├── .gitignore ├── rosidl_typesupport_protobuf_c ├── rosidl_typesupport_protobuf_c │ └── __init__.py ├── src │ ├── identifier.cpp │ ├── to_ros_c_string.cpp │ └── wstring_conversion.cpp ├── include │ └── rosidl_typesupport_protobuf_c │ │ ├── identifier.hpp │ │ ├── to_ros_c_string.hpp │ │ └── wstring_conversion.hpp ├── cmake │ ├── rosidl_typesupport_protobuf_c-extras.cmake.in │ └── rosidl_typesupport_protobuf_c_generate_interfaces.cmake ├── resource │ ├── srv__rosidl_typesupport_protobuf_c.hpp.em │ ├── tmpl_include_directories.em │ ├── rosidl_typesupport_protobuf_c__visibility_control.h.in │ ├── msg__rosidl_typesupport_protobuf_c.hpp.em │ ├── tmpl_forward_declarations.em │ ├── idl__rosidl_typesupport_protobuf_c.hpp.em │ ├── srv__type_support.cpp.em │ └── idl__type_support.cpp.em ├── package.xml ├── bin │ └── rosidl_typesupport_protobuf_c ├── test │ └── test_wstring_conversion.cpp └── CMakeLists.txt ├── rosidl_typesupport_protobuf_cpp ├── src │ ├── identifier.cpp │ └── wstring_conversion.cpp ├── include │ └── rosidl_typesupport_protobuf_cpp │ │ ├── identifier.hpp │ │ └── wstring_conversion.hpp ├── rosidl_typesupport_protobuf_cpp │ └── __init__.py ├── cmake │ └── rosidl_typesupport_protobuf_cpp-extras.cmake.in ├── resource │ ├── srv__rosidl_typesupport_protobuf_cpp.hpp.em │ ├── tmpl_include_directories.em │ ├── rosidl_typesupport_protobuf_cpp__visibility_control.h.in │ ├── msg__rosidl_typesupport_protobuf_cpp.hpp.em │ ├── tmpl_forward_declarations.em │ ├── idl__typeadapter_protobuf_cpp.hpp.em │ ├── idl__rosidl_typesupport_protobuf_cpp.hpp.em │ ├── srv__type_support.cpp.em │ ├── idl__type_support.cpp.em │ └── msg__type_support.cpp.em ├── package.xml ├── bin │ └── rosidl_typesupport_protobuf_cpp ├── test │ └── test_wstring_conversion.cpp └── CMakeLists.txt ├── rosidl_typeadapter_protobuf_test ├── package.xml ├── test │ ├── subscribe_string_types.hpp │ ├── subscribe_string_types.cpp │ ├── subscribe_basic_types.hpp │ ├── subscribe_array_types.hpp │ ├── subscribe_helper.hpp │ ├── subscribe_basic_types.cpp │ ├── subscribe_array_types.cpp │ └── test_proto_typeadapt.cpp └── CMakeLists.txt ├── .github └── workflows │ └── basic_ci.yaml └── README.md /rosidl_adapter_proto/pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | junit_family=xunit2 3 | -------------------------------------------------------------------------------- /rosidl_adapter_proto/test/msg/test_rosidl_adapter__empty_args.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } -------------------------------------------------------------------------------- /images/flow chart type support generation.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclipse-ecal/rosidl_typesupport_protobuf/HEAD/images/flow chart type support generation.pptx -------------------------------------------------------------------------------- /images/flow_chart_type_support_generation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclipse-ecal/rosidl_typesupport_protobuf/HEAD/images/flow_chart_type_support_generation.png -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2 | Changelog for package rosidl_typesupport_protobuf_cpp 3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -------------------------------------------------------------------------------- /rosidl_adapter_proto/test/msg/BoolTest.idl: -------------------------------------------------------------------------------- 1 | module rosidl_adapter_proto { 2 | @verbatim (language="comment", text= 3 | "This is for test purposes.") 4 | struct Bool { 5 | boolean data; 6 | }; 7 | }; 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | devel/ 2 | logs/ 3 | build/ 4 | lib/ 5 | msg_gen/ 6 | srv_gen/ 7 | msg/*Action.msg 8 | msg/*ActionFeedback.msg 9 | msg/*ActionGoal.msg 10 | msg/*ActionResult.msg 11 | msg/*Feedback.msg 12 | msg/*Goal.msg 13 | msg/*Result.msg 14 | msg/_*.py 15 | build_isolated/ 16 | devel_isolated/ 17 | 18 | # Generated by dynamic reconfigure 19 | *.cfgc 20 | /cfg/cpp/ 21 | /cfg/*.py 22 | 23 | # Ignore generated docs 24 | *.dox 25 | *.wikidoc 26 | 27 | # eclipse stuff 28 | .project 29 | .cproject 30 | 31 | # qcreator stuff 32 | CMakeLists.txt.user 33 | 34 | srv/_*.py 35 | *.pcd 36 | *.pyc 37 | qtcreator-* 38 | *.user 39 | 40 | /planning/cfg 41 | /planning/docs 42 | /planning/src 43 | 44 | *~ 45 | 46 | # vs-code stuff 47 | .vscode 48 | 49 | # Emacs 50 | .#* 51 | 52 | # Catkin custom files 53 | CATKIN_IGNORE -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rosidl_typesupport_protobuf 5 | 0.0.1 6 | Shared code for rosidl_typesupport_protobuf_cpp and rosidl_typesupport_protobuf_c. 7 | Aleksandar Brakmić 8 | Apache License 2.0 9 | 10 | ament_cmake 11 | rosidl_generator_c 12 | rosidl_generator_c 13 | 14 | 15 | 16 | ament_cmake 17 | 18 | -------------------------------------------------------------------------------- /rosidl_adapter_proto/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rosidl_adapter_proto 5 | 0.0.1 6 | Generate the Protobuf interfaces for Protobuf serialization. 7 | Aleksandar Brakmić 8 | Apache License 2.0 9 | 10 | ament_cmake 11 | 12 | python3-empy 13 | rosidl_cli 14 | rosidl_parser 15 | 16 | ament_cmake_pytest 17 | rosidl_cmake 18 | 19 | rosidl_interface_packages 20 | 21 | 22 | 23 | ament_cmake 24 | proto 25 | 26 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/rosidl_typesupport_protobuf_c/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016-2018 Open Source Robotics Foundation, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from rosidl_cmake import generate_files 16 | 17 | 18 | def generate_typesupport_protobuf_c(generator_arguments_file): 19 | mapping = { 20 | 'idl__rosidl_typesupport_protobuf_c.hpp.em': '%s__rosidl_typesupport_protobuf_c.hpp', 21 | 'idl__type_support.cpp.em': 'detail/%s__type_support.cpp', 22 | } 23 | generate_files(generator_arguments_file, mapping) 24 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/src/identifier.cpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | 20 | #include 21 | 22 | namespace rosidl_typesupport_protobuf_c 23 | { 24 | 25 | ROSIDL_TYPESUPPORT_PROTOBUF_EXPORT 26 | const char * identifier = "rosidl_typesupport_protobuf_c"; 27 | 28 | } // namespace rosidl_typesupport_protobuf_c 29 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/src/identifier.cpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | 20 | #include 21 | 22 | namespace rosidl_typesupport_protobuf_cpp 23 | { 24 | 25 | ROSIDL_TYPESUPPORT_PROTOBUF_EXPORT 26 | const char * identifier = "rosidl_typesupport_protobuf_cpp"; 27 | 28 | } // namespace rosidl_typesupport_protobuf_cpp 29 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/src/to_ros_c_string.cpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | 20 | #include "rosidl_typesupport_protobuf_c/to_ros_c_string.hpp" 21 | 22 | namespace typesupport_protobuf_c 23 | { 24 | 25 | void to_ros_c_string(const std::string & str, rosidl_runtime_c__String & ros_str) 26 | { 27 | rosidl_runtime_c__String__assignn(&ros_str, &str[0], str.size()); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/include/rosidl_typesupport_protobuf_c/identifier.hpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | namespace rosidl_typesupport_protobuf_c 25 | { 26 | 27 | ROSIDL_TYPESUPPORT_PROTOBUF_IMPORT 28 | extern const char * identifier; 29 | 30 | } // namespace rosidl_typesupport_protobuf_c 31 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/include/rosidl_typesupport_protobuf_cpp/identifier.hpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | namespace rosidl_typesupport_protobuf_cpp 25 | { 26 | 27 | ROSIDL_TYPESUPPORT_PROTOBUF_IMPORT 28 | extern const char * identifier; 29 | 30 | } // namespace rosidl_typesupport_protobuf_cpp 31 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/include/rosidl_typesupport_protobuf_c/to_ros_c_string.hpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #include "rosidl_typesupport_protobuf/visibility_control.h" 25 | #include "rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp" 26 | 27 | namespace typesupport_protobuf_c 28 | { 29 | 30 | ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC 31 | void to_ros_c_string(const std::string & str, rosidl_runtime_c__String & ros_str); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ================================= Apache 2.0 ================================= 2 | # 3 | # Copyright (C) 2021 Continental 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # ================================= Apache 2.0 ================================= 18 | 19 | cmake_minimum_required(VERSION 3.5) 20 | 21 | project(rosidl_typesupport_protobuf) 22 | 23 | find_package(ament_cmake REQUIRED) 24 | find_package(ament_cmake_python REQUIRED) 25 | find_package(rosidl_generator_c REQUIRED) 26 | 27 | ament_export_include_directories("include/${PROJECT_NAME}") 28 | 29 | ament_python_install_package(${PROJECT_NAME}) 30 | 31 | install( 32 | DIRECTORY include/ 33 | DESTINATION include/${PROJECT_NAME} 34 | ) 35 | 36 | ament_package() -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp/__init__.py: -------------------------------------------------------------------------------- 1 | # ================================= Apache 2.0 ================================= 2 | # 3 | # Copyright (C) 2021 Continental 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # ================================= Apache 2.0 ================================= 18 | 19 | from rosidl_cmake import generate_files 20 | 21 | 22 | def generate_cpp(generator_arguments_file): 23 | mapping = { 24 | "idl__rosidl_typesupport_protobuf_cpp.hpp.em": "%s__rosidl_typesupport_protobuf_cpp.hpp", 25 | "idl__typeadapter_protobuf_cpp.hpp.em": "%s__typeadapter_protobuf_cpp.hpp", 26 | "idl__type_support.cpp.em": "detail/%s__type_support.cpp", 27 | } 28 | generate_files(generator_arguments_file, mapping) 29 | return 0 30 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/include/rosidl_typesupport_protobuf_cpp/wstring_conversion.hpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #include 25 | 26 | 27 | namespace rosidl_typesupport_protobuf_cpp 28 | { 29 | 30 | ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC 31 | void write_to_string(const std::u16string & u16str, std::string & str); 32 | 33 | ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC 34 | void write_to_u16string(const std::string & str, std::u16string & u16str); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/cmake/rosidl_typesupport_protobuf_c-extras.cmake.in: -------------------------------------------------------------------------------- 1 | # generated from 2 | # rosidl_typesupport_protobuf_c/rosidl_typesupport_protobuf_c-extras.cmake.in 3 | 4 | find_package(Protobuf REQUIRED) 5 | 6 | if(NOT Protobuf_FOUND) 7 | message(STATUS "Could not find Protobuf: skipping rosidl_typesupport_protobuf_c") 8 | else() 9 | find_package(ament_cmake_core QUIET REQUIRED) 10 | ament_register_extension( 11 | "rosidl_generate_idl_interfaces" 12 | "rosidl_typesupport_protobuf_c" 13 | "rosidl_typesupport_protobuf_c_generate_interfaces.cmake") 14 | 15 | set(rosidl_typesupport_protobuf_c_BIN 16 | "${rosidl_typesupport_protobuf_c_DIR}/../../../lib/rosidl_typesupport_protobuf_c/rosidl_typesupport_protobuf_c") 17 | normalize_path(rosidl_typesupport_protobuf_c_BIN 18 | "${rosidl_typesupport_protobuf_c_BIN}") 19 | 20 | set(rosidl_typesupport_protobuf_c_GENERATOR_FILES 21 | "${rosidl_typesupport_protobuf_c_DIR}/../../../@PYTHON_INSTALL_DIR@/rosidl_typesupport_protobuf_c/__init__.py") 22 | normalize_path(rosidl_typesupport_protobuf_c_GENERATOR_FILES 23 | "${rosidl_typesupport_protobuf_c_GENERATOR_FILES}") 24 | 25 | set(rosidl_typesupport_protobuf_c_TEMPLATE_DIR 26 | "${rosidl_typesupport_protobuf_c_DIR}/../resource") 27 | normalize_path(rosidl_typesupport_protobuf_c_TEMPLATE_DIR 28 | "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}") 29 | endif() 30 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/service_type_support.hpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #include "rosidl_typesupport_protobuf/message_type_support.hpp" 25 | 26 | namespace rosidl_typesupport_protobuf 27 | { 28 | 29 | typedef struct service_type_support_t 30 | { 31 | const char * service_namespace; 32 | const char * service_name; 33 | 34 | const rosidl_message_type_support_t * request; 35 | const rosidl_message_type_support_t * response; 36 | } service_type_support_t; 37 | 38 | } // namespace rosidl_typesupport_protobuf 39 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/message_type_support.hpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | namespace rosidl_typesupport_protobuf 25 | { 26 | 27 | typedef struct message_type_support_t 28 | { 29 | const char * message_namespace; 30 | const char * message_name; 31 | 32 | bool (* serialize)(const void * ros_message, std::string & serialized_message); 33 | bool (* deserialize)(void * ros_message, const void * serialized_data, size_t size); 34 | std::string (* get_descriptor)(); 35 | } message_type_support_t; 36 | 37 | } // namespace rosidl_typesupport_protobuf 38 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/include/rosidl_typesupport_protobuf_c/wstring_conversion.hpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | #include "rosidl_typesupport_protobuf/visibility_control.h" 25 | #include "rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp" 26 | 27 | namespace rosidl_typesupport_protobuf_c 28 | { 29 | 30 | ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC 31 | void write_to_string(const rosidl_runtime_c__U16String & u16str, std::string & str); 32 | 33 | ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC 34 | void write_to_u16string(const std::string & str, rosidl_runtime_c__U16String & u16str); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/message_type_support_decl.hpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | // rosidl_message_type_support_t 25 | #include "rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp" 26 | 27 | namespace rosidl_typesupport_protobuf 28 | { 29 | 30 | // This is implemented in the shared library provided by this package. 31 | template 32 | ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC 33 | const rosidl_message_type_support_t * get_message_type_support_handle(); 34 | 35 | } // namespace rosidl_typesupport_protobuf 36 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/cmake/rosidl_typesupport_protobuf_cpp-extras.cmake.in: -------------------------------------------------------------------------------- 1 | # generated from 2 | # rosidl_typesupport_protobuf_cpp/ 3 | # rosidl_typesupport_protobuf_cpp-extras.cmake.in 4 | 5 | find_package(Protobuf REQUIRED) 6 | 7 | if(NOT Protobuf_FOUND) 8 | message(STATUS 9 | "Could not find Protobuf - skip rosidl_typesupport_protobuf_cpp" 10 | ) 11 | else() 12 | find_package(ament_cmake_core QUIET REQUIRED) 13 | ament_register_extension( 14 | "rosidl_generate_idl_interfaces" 15 | "rosidl_typesupport_protobuf_cpp" 16 | "rosidl_typesupport_protobuf_cpp_generate_interfaces.cmake") 17 | 18 | set(rosidl_typesupport_protobuf_cpp_BIN 19 | "${rosidl_typesupport_protobuf_cpp_DIR}/../../../lib/rosidl_typesupport_protobuf_cpp/rosidl_typesupport_protobuf_cpp") 20 | normalize_path(rosidl_typesupport_protobuf_cpp_BIN 21 | "${rosidl_typesupport_protobuf_cpp_BIN}") 22 | 23 | set(rosidl_typesupport_protobuf_cpp_GENERATOR_FILES 24 | "${rosidl_typesupport_protobuf_cpp_DIR}/../../../@PYTHON_INSTALL_DIR@/rosidl_typesupport_protobuf_cpp/__init__.py") 25 | normalize_path(rosidl_typesupport_protobuf_cpp_GENERATOR_FILES 26 | "${rosidl_typesupport_protobuf_cpp_GENERATOR_FILES}") 27 | 28 | set(rosidl_typesupport_protobuf_cpp_TEMPLATE_DIR 29 | "${rosidl_typesupport_protobuf_cpp_DIR}/../resource") 30 | normalize_path(rosidl_typesupport_protobuf_cpp_TEMPLATE_DIR 31 | "${rosidl_typesupport_protobuf_cpp_TEMPLATE_DIR}") 32 | endif() 33 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/resource/srv__rosidl_typesupport_protobuf_cpp.hpp.em: -------------------------------------------------------------------------------- 1 | @# Included from rosidl_typesupport_protobuf_cpp/resource/idl__rosidl_typesupport_protobuf_cpp.hpp.em 2 | @{ 3 | system_header_files = [] 4 | header_files = [ 5 | 'rosidl_typesupport_cpp/service_type_support.hpp', 6 | 'rosidl_typesupport_interface/macros.h' 7 | ] 8 | }@ 9 | @{ 10 | TEMPLATE( 11 | 'tmpl_include_directories.em', 12 | header_files=header_files, 13 | system_header_files=system_header_files, 14 | include_directives=include_directives 15 | ) 16 | }@ 17 | 18 | @{ 19 | TEMPLATE( 20 | 'msg__rosidl_typesupport_protobuf_cpp.hpp.em', 21 | package_name=package_name, 22 | interface_path=interface_path, 23 | message=service.request_message, 24 | include_directives=include_directives) 25 | }@ 26 | 27 | @{ 28 | TEMPLATE( 29 | 'msg__rosidl_typesupport_protobuf_cpp.hpp.em', 30 | package_name=package_name, 31 | interface_path=interface_path, 32 | message=service.response_message, 33 | include_directives=include_directives) 34 | }@ 35 | 36 | #ifdef __cplusplus 37 | extern "C" 38 | { 39 | #endif 40 | 41 | ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@(package_name) 42 | const rosidl_service_type_support_t * 43 | ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_protobuf_cpp, @(', '.join([package_name] + list(interface_path.parents[0].parts) + [service.namespaced_type.name])))(); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif 48 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/resource/srv__rosidl_typesupport_protobuf_c.hpp.em: -------------------------------------------------------------------------------- 1 | @# Included from rosidl_typesupport_protobuf_c/resource/idl__rosidl_typesupport_protobuf_c.hpp.em 2 | @{ 3 | system_header_files = [] 4 | header_files = [ 5 | 'rmw/types.h', 6 | 'rosidl_typesupport_cpp/service_type_support.hpp', 7 | 'rosidl_typesupport_interface/macros.h', 8 | 'rosidl_typesupport_protobuf/visibility_control.h', 9 | ] 10 | }@ 11 | @{ 12 | TEMPLATE( 13 | 'tmpl_include_directories.em', 14 | header_files=header_files, 15 | system_header_files=system_header_files, 16 | include_directives=include_directives 17 | ) 18 | }@ 19 | 20 | @{ 21 | TEMPLATE( 22 | 'msg__rosidl_typesupport_protobuf_c.hpp.em', 23 | package_name=package_name, 24 | interface_path=interface_path, 25 | message=service.request_message, 26 | include_directives=include_directives) 27 | }@ 28 | 29 | @{ 30 | TEMPLATE( 31 | 'msg__rosidl_typesupport_protobuf_c.hpp.em', 32 | package_name=package_name, 33 | interface_path=interface_path, 34 | message=service.response_message, 35 | include_directives=include_directives) 36 | }@ 37 | 38 | #ifdef __cplusplus 39 | extern "C" 40 | { 41 | #endif 42 | 43 | ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC 44 | const rosidl_service_type_support_t * 45 | ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_protobuf_c, @(', '.join([package_name] + list(interface_path.parents[0].parts) + [service.namespaced_type.name])))(); 46 | 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/service_type_support_decl.hpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | 20 | #pragma once 21 | 22 | #include 23 | 24 | // rosidl_service_type_support_t 25 | #include "rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp" 26 | 27 | namespace rosidl_typesupport_protobuf 28 | { 29 | 30 | /// Get the rosidl service typesupport handler of the type. 31 | /** 32 | * This is implemented in the shared library provided by this package.a 33 | * \return The rosidl_service_type_support_t of type T. 34 | */ 35 | template 36 | ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC 37 | const rosidl_service_type_support_t * get_service_type_support_handle(); 38 | 39 | } // namespace rosidl_typesupport_protobuf 40 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/src/wstring_conversion.cpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | 20 | #include "rosidl_typesupport_protobuf_cpp/wstring_conversion.hpp" 21 | 22 | #include 23 | 24 | namespace rosidl_typesupport_protobuf_cpp 25 | { 26 | 27 | void write_to_string(const std::u16string & u16str, std::string & str) 28 | { 29 | auto data_size = u16str.size() * sizeof(std::u16string::value_type); 30 | str.resize(data_size); 31 | auto str_start = &str[0]; 32 | std::memcpy(str_start, u16str.data(), data_size); 33 | } 34 | 35 | void write_to_u16string(const std::string & str, std::u16string & u16str) 36 | { 37 | u16str.resize(str.size() / sizeof(std::u16string::value_type)); 38 | auto wstr_start = &u16str[0]; 39 | std::memcpy(wstr_start, str.data(), str.size()); 40 | } 41 | 42 | } // namespace rosidl_typesupport_protobuf_cpp 43 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/resource/tmpl_include_directories.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | @{ 21 | def is_protobuf_header(header_file): 22 | header_file.endswith(".pb.h") 23 | } 24 | @[for header_file in system_header_files]@ 25 | @[ if header_file not in include_directives]@ 26 | @{include_directives.add(header_file)}@ 27 | #include <@(header_file)> 28 | @[ end if]@ 29 | @[end for]@ 30 | 31 | @[for header_file in header_files]@ 32 | @[ if header_file not in include_directives]@ 33 | @{include_directives.add(header_file)}@ 34 | @[ if is_protobuf_header(header_file)]@ 35 | #ifdef _MSC_VER 36 | #pragma warning(push) 37 | #pragma warning(disable : 4127 4146 4800) 38 | #endif 39 | #include "@(header_file)" 40 | #ifdef _MSC_VER 41 | #pragma warning(pop) 42 | #endif 43 | @[ else]@ 44 | #include "@(header_file)" 45 | @[ end if]@ 46 | @[ end if]@ 47 | @[end for]@ -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/resource/tmpl_include_directories.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | @{ 21 | def is_protobuf_header(header_file): 22 | header_file.endswith(".pb.h") 23 | } 24 | @[for header_file in system_header_files]@ 25 | @[ if header_file not in include_directives]@ 26 | @{include_directives.add(header_file)}@ 27 | #include <@(header_file)> 28 | @[ end if]@ 29 | @[end for]@ 30 | 31 | @[for header_file in header_files]@ 32 | @[ if header_file not in include_directives]@ 33 | @{include_directives.add(header_file)}@ 34 | @[ if is_protobuf_header(header_file)]@ 35 | #ifdef _MSC_VER 36 | #pragma warning(push) 37 | #pragma warning(disable : 4127 4146 4800) 38 | #endif 39 | #include "@(header_file)" 40 | #ifdef _MSC_VER 41 | #pragma warning(pop) 42 | #endif 43 | @[ else]@ 44 | #include "@(header_file)" 45 | @[ end if]@ 46 | @[ end if]@ 47 | @[end for]@ 48 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp: -------------------------------------------------------------------------------- 1 | /* ========================= RMW eCAL LICENSE ================================= 2 | * 3 | * Copyright (C) 2019 - 2020 Continental Corporation 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ========================= RMW eCAL LICENSE ================================= 18 | */ 19 | 20 | // From Foxy distro rosidl_generator_c has been renamed to rosidl_generator_c, 21 | // purpose of this header file is to alias old C type names to new ones, that way the 22 | // rest of the code doesn't have to care about old package name regardless of distro. 23 | // any rosidl_generator_c to rosidl_runtime_c adaptions should be added here 24 | 25 | #pragma once 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | -------------------------------------------------------------------------------- /rosidl_typeadapter_protobuf_test/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rosidl_typeadapter_protobuf_test 5 | 0.19.1 6 | Protobuff type adapter test 7 | 8 | Gonzalo de Pedro 9 | 10 | Apache License 2.0 11 | 12 | Gonzalo de Pedro 13 | 14 | rosidl_default_generators 15 | 16 | ament_cmake_auto 17 | 18 | rosidl_default_runtime 19 | 20 | 21 | ament_cmake 22 | ament_cmake_gtest 23 | ament_lint_auto 24 | ament_lint_common 25 | launch 26 | launch_testing 27 | launch_testing_ament_cmake 28 | osrf_testing_tools_cpp 29 | rcl 30 | rclcpp 31 | rclcpp_action 32 | rclpy 33 | rcpputils 34 | rmw_implementation 35 | rmw_implementation_cmake 36 | ros2cli 37 | test_msgs 38 | rosidl_typesupport_protobuf_cpp 39 | 40 | 41 | 42 | ament_cmake 43 | 44 | -------------------------------------------------------------------------------- /rosidl_typeadapter_protobuf_test/test/subscribe_string_types.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef SUBSCRIBE_STRING_TYPES_HPP_ 16 | #define SUBSCRIBE_STRING_TYPES_HPP_ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "rclcpp/rclcpp.hpp" 23 | #include "test_msgs/rosidl_adapter_proto__visibility_control.h" 24 | #include "builtin_interfaces/rosidl_adapter_proto__visibility_control.h" 25 | #include "test_msgs/msg/Strings.pb.h" 26 | #include "test_msgs/msg/WStrings.pb.h" 27 | 28 | 29 | rclcpp::SubscriptionBase::SharedPtr subscribe_strings( 30 | rclcpp::Node::SharedPtr node, 31 | const std::string & message_type, 32 | const std::vector> & expected_messages, 33 | std::vector & received_messages); 34 | 35 | rclcpp::SubscriptionBase::SharedPtr subscribe_wstrings( 36 | rclcpp::Node::SharedPtr node, 37 | const std::string & message_type, 38 | const std::vector> & expected_messages, 39 | std::vector & received_messages); 40 | 41 | #endif // SUBSCRIBE_STRING_TYPES_HPP_ 42 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/src/wstring_conversion.cpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | 20 | #include "rosidl_typesupport_protobuf_c/wstring_conversion.hpp" 21 | 22 | #include 23 | 24 | namespace rosidl_typesupport_protobuf_c 25 | { 26 | 27 | void write_to_string(const rosidl_runtime_c__U16String & u16str, std::string & str) 28 | { 29 | auto data_size = u16str.size * sizeof(decltype(*u16str.data)); 30 | str.resize(data_size); 31 | auto str_start = &str[0]; 32 | std::memcpy(str_start, u16str.data, data_size); 33 | } 34 | 35 | void write_to_u16string(const std::string & str, rosidl_runtime_c__U16String & u16str) 36 | { 37 | auto data_size = str.size(); 38 | auto u16str_size = str.size() / sizeof(decltype(*u16str.data)); 39 | rosidl_runtime_c__U16String__resize(&u16str, u16str_size); 40 | auto wstr_start = u16str.data; 41 | std::memcpy(wstr_start, str.data(), data_size); 42 | } 43 | 44 | } // namespace rosidl_typesupport_protobuf_c 45 | -------------------------------------------------------------------------------- /rosidl_adapter_proto/resource/rosidl_adapter_proto__visibility_control.h.in: -------------------------------------------------------------------------------- 1 | // generated from 2 | // rosidl_typesupport_protobuf/rosidl_adapter_proto/resource/rosidl_adapter_proto__visibility_control.h.in 3 | // generated code does not contain a copyright notice 4 | #pragma once 5 | 6 | #ifdef __cplusplus 7 | extern "C" 8 | { 9 | #endif 10 | 11 | // This logic was borrowed (then namespaced) from the examples on the gcc wiki: 12 | // https://gcc.gnu.org/wiki/Visibility 13 | 14 | #if defined _WIN32 || defined __CYGWIN__ 15 | #ifdef __GNUC__ 16 | #define ROSIDL_ADAPTER_PROTO_EXPORT__@PROJECT_NAME@ __attribute__ ((dllexport)) 17 | #define ROSIDL_ADAPTER_PROTO_IMPORT__@PROJECT_NAME@ __attribute__ ((dllimport)) 18 | #else 19 | #define ROSIDL_ADAPTER_PROTO_EXPORT__@PROJECT_NAME@ __declspec(dllexport) 20 | #define ROSIDL_ADAPTER_PROTO_IMPORT__@PROJECT_NAME@ __declspec(dllimport) 21 | #endif 22 | #ifdef ROSIDL_ADAPTER_PROTO_BUILDING_DLL__@PROJECT_NAME@ 23 | #define ROSIDL_ADAPTER_PROTO_PUBLIC__@PROJECT_NAME@ ROSIDL_ADAPTER_PROTO_EXPORT__@PROJECT_NAME@ 24 | #else 25 | #define ROSIDL_ADAPTER_PROTO_PUBLIC__@PROJECT_NAME@ ROSIDL_ADAPTER_PROTO_IMPORT__@PROJECT_NAME@ 26 | #endif 27 | #define ROSIDL_ADAPTER_PROTO_LOCAL__@PROJECT_NAME@ 28 | #else 29 | #define ROSIDL_ADAPTER_PROTO_EXPORT__@PROJECT_NAME@ __attribute__ ((visibility("default"))) 30 | #define ROSIDL_ADAPTER_PROTO_IMPORT__@PROJECT_NAME@ 31 | #if __GNUC__ >= 4 32 | #define ROSIDL_ADAPTER_PROTO_PUBLIC__@PROJECT_NAME@ __attribute__ ((visibility("default"))) 33 | #define ROSIDL_ADAPTER_PROTO_LOCAL__@PROJECT_NAME@ __attribute__ ((visibility("hidden"))) 34 | #else 35 | #define ROSIDL_ADAPTER_PROTO_PUBLIC__@PROJECT_NAME@ 36 | #define ROSIDL_ADAPTER_PROTO_LOCAL__@PROJECT_NAME@ 37 | #endif 38 | #endif 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rosidl_typesupport_protobuf_cpp 5 | 0.0.1 6 | Generate the C++ interfaces for Protobuf serialization. 7 | Aleksandar Brakmić 8 | Apache License 2.0 9 | 10 | ament_cmake 11 | rosidl_cmake 12 | rosidl_generator_cpp 13 | rosidl_adapter_proto 14 | rosidl_typesupport_protobuf 15 | rosidl_runtime_cpp 16 | 17 | ament_cmake 18 | rosidl_cmake 19 | rosidl_generator_cpp 20 | rosidl_adapter_proto 21 | rosidl_typesupport_protobuf 22 | rosidl_runtime_cpp 23 | 24 | rmw 25 | 26 | rosidl_parser 27 | rosidl_adapter_proto 28 | rosidl_typesupport_interface 29 | rosidl_typesupport_protobuf 30 | 31 | ament_cmake_gtest 32 | 33 | rosidl_typesupport_cpp_packages 34 | 35 | 36 | ament_cmake 37 | 38 | 39 | -------------------------------------------------------------------------------- /.github/workflows/basic_ci.yaml: -------------------------------------------------------------------------------- 1 | name: Basic CI 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | basic_ci: 6 | name: Basic CI 7 | runs-on: ubuntu-latest 8 | strategy: 9 | matrix: 10 | ros_distribution: 11 | - humble 12 | - iron 13 | - rolling 14 | 15 | # Define the Docker image(s) associated with each ROS distribution. 16 | # The include syntax allows additional variables to be defined, like 17 | # docker_image in this case. See documentation: 18 | # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#example-including-configurations-in-a-matrix-build 19 | # 20 | # Platforms are defined in REP 3 and REP 2000: 21 | # https://ros.org/reps/rep-0003.html 22 | # https://ros.org/reps/rep-2000.html 23 | include: 24 | 25 | # Humble Hawksbill (May 2022 - May 2027) 26 | - docker_image: ubuntu:jammy 27 | ros_distribution: humble 28 | 29 | # Iron Irwini (May 2023 - November 2024) 30 | - docker_image: ubuntu:jammy 31 | ros_distribution: iron 32 | 33 | # Rolling Ridley (No End-Of-Life) 34 | - docker_image: ubuntu:jammy 35 | ros_distribution: rolling 36 | 37 | container: 38 | image: ${{ matrix.docker_image }} 39 | steps: 40 | - uses: ros-tooling/setup-ros@v0.7 41 | - name: checkout 42 | uses: actions/checkout@v4 43 | with: 44 | path: ros_ws/src 45 | - uses: ros-tooling/action-ros-ci@v0.3 46 | with: 47 | package-name: rosidl_adapter_proto rosidl_typesupport_protobuf rosidl_typesupport_protobuf_cpp rosidl_typesupport_protobuf_c rosidl_typeadapter_protobuf_test 48 | target-ros2-distro: ${{ matrix.ros_distribution }} 49 | vcs-repo-file-url: https://raw.githubusercontent.com/ros2/ros2/${{ matrix.ros_distribution }}/ros2.repos 50 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/bin/rosidl_typesupport_protobuf_cpp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # ================================= Apache 2.0 ================================= 4 | # 5 | # Copyright (C) 2021 Continental 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | # ================================= Apache 2.0 ================================= 20 | 21 | import argparse 22 | import sys 23 | import pathlib 24 | import os 25 | import rosidl_typesupport_protobuf 26 | 27 | from rosidl_cmake import read_generator_arguments 28 | from rosidl_typesupport_protobuf_cpp import generate_cpp 29 | 30 | def main(argv=sys.argv[1:]): 31 | parser = argparse.ArgumentParser( 32 | description='Generate the Protobuf & C++ interfaces for Protobuf type support.', 33 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 34 | parser.add_argument( 35 | '--generator-arguments-file', 36 | required=True, 37 | help='The location of the file containing the generator arguments') 38 | 39 | args = parser.parse_args(argv) 40 | rosidl_typesupport_protobuf.set_namespace_delimeter("::") 41 | rosidl_typesupport_protobuf.set_type_support_name("rosidl_typesupport_protobuf_cpp") 42 | # Generate typesupport cpp files 43 | rc = generate_cpp(args.generator_arguments_file) 44 | 45 | return rc 46 | 47 | 48 | if __name__ == '__main__': 49 | sys.exit(main()) 50 | -------------------------------------------------------------------------------- /rosidl_adapter_proto/resource/srv.proto.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | @{ 21 | from rosidl_cmake import convert_camel_case_to_lower_case_underscore 22 | import rosidl_parser.definition as rosidl 23 | 24 | from rosidl_adapter_proto import PROTO_PACKAGE_POSTFIX 25 | from rosidl_adapter_proto import MSG_TYPE_TO_PROTO 26 | from rosidl_adapter_proto import PROTO_SERVICE_CALL_NAME 27 | 28 | }@ 29 | option cc_generic_services = true; 30 | 31 | @# 32 | @# ================ Message definitions ================ 33 | @# 34 | @{ 35 | TEMPLATE( 36 | 'msg.proto.em', 37 | package_name=package_name, 38 | interface_path=interface_path, 39 | message=service.request_message, 40 | ) 41 | }@ 42 | 43 | 44 | @{ 45 | TEMPLATE( 46 | 'msg.proto.em', 47 | package_name=package_name, 48 | interface_path=interface_path, 49 | message=service.response_message, 50 | ) 51 | }@ 52 | 53 | 54 | @# 55 | @# ================ Service definitions ================ 56 | @# 57 | service @(service.namespaced_type.name) 58 | { 59 | rpc @(PROTO_SERVICE_CALL_NAME) (@(service.request_message.structure.namespaced_type.name)) returns (@(service.response_message.structure.namespaced_type.name)); 60 | } -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rosidl_typesupport_protobuf_c 5 | 0.0.1 6 | Generate the C interfaces for Protobuf. 7 | Aleksandar Brakmić 8 | Apache License 2.0 9 | 10 | ament_cmake 11 | protobuf-dev 12 | rosidl_cmake 13 | rosidl_generator_c 14 | rosidl_generator_cpp 15 | rosidl_adapter_proto 16 | rosidl_typesupport_protobuf 17 | rosidl_typesupport_introspection_cpp 18 | 19 | ament_cmake 20 | rosidl_cmake 21 | rosidl_adapter_proto 22 | rosidl_generator_c 23 | rosidl_generator_cpp 24 | rosidl_typesupport_protobuf 25 | rosidl_typesupport_introspection_cpp 26 | 27 | rmw 28 | 29 | rosidl_parser 30 | rosidl_typesupport_interface 31 | 32 | ament_cmake_gtest 33 | 34 | rosidl_typesupport_c_packages 35 | 36 | 37 | ament_cmake 38 | 39 | 40 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/resource/rosidl_typesupport_protobuf_c__visibility_control.h.in: -------------------------------------------------------------------------------- 1 | // generated from 2 | // rosidl_typesupport_protobuf/rosidl_typesupport_protobuf_cpp/resource/visibility_control.h.in 3 | // generated code does not contain a copyright notice 4 | #pragma once 5 | 6 | #ifdef __cplusplus 7 | extern "C" 8 | { 9 | #endif 10 | 11 | // This logic was borrowed (then namespaced) from the examples on the gcc wiki: 12 | // https://gcc.gnu.org/wiki/Visibility 13 | 14 | #if defined _WIN32 || defined __CYGWIN__ 15 | #ifdef __GNUC__ 16 | #define ROSIDL_TYPESUPPORT_PROTOBUF_C_EXPORT__@PROJECT_NAME@ __attribute__ ((dllexport)) 17 | #define ROSIDL_TYPESUPPORT_PROTOBUF_C_IMPORT__@PROJECT_NAME@ __attribute__ ((dllimport)) 18 | #else 19 | #define ROSIDL_TYPESUPPORT_PROTOBUF_C_EXPORT__@PROJECT_NAME@ __declspec(dllexport) 20 | #define ROSIDL_TYPESUPPORT_PROTOBUF_C_IMPORT__@PROJECT_NAME@ __declspec(dllimport) 21 | #endif 22 | #ifdef ROSIDL_TYPESUPPORT_PROTOBUF_C_BUILDING_DLL__@PROJECT_NAME@ 23 | #define ROSIDL_TYPESUPPORT_PROTOBUF_C_PUBLIC__@PROJECT_NAME@ ROSIDL_TYPESUPPORT_PROTOBUF_C_EXPORT__@PROJECT_NAME@ 24 | #else 25 | #define ROSIDL_TYPESUPPORT_PROTOBUF_C_PUBLIC__@PROJECT_NAME@ ROSIDL_TYPESUPPORT_PROTOBUF_C_IMPORT__@PROJECT_NAME@ 26 | #endif 27 | #define ROSIDL_TYPESUPPORT_PROTOBUF_C_LOCAL__@PROJECT_NAME@ 28 | #else 29 | #define ROSIDL_TYPESUPPORT_PROTOBUF_C_EXPORT__@PROJECT_NAME@ __attribute__ ((visibility("default"))) 30 | #define ROSIDL_TYPESUPPORT_PROTOBUF_C_IMPORT__@PROJECT_NAME@ 31 | #if __GNUC__ >= 4 32 | #define ROSIDL_TYPESUPPORT_PROTOBUF_C_PUBLIC__@PROJECT_NAME@ __attribute__ ((visibility("default"))) 33 | #define ROSIDL_TYPESUPPORT_PROTOBUF_C_LOCAL__@PROJECT_NAME@ __attribute__ ((visibility("hidden"))) 34 | #else 35 | #define ROSIDL_TYPESUPPORT_PROTOBUF_C_PUBLIC__@PROJECT_NAME@ 36 | #define ROSIDL_TYPESUPPORT_PROTOBUF_C_LOCAL__@PROJECT_NAME@ 37 | #endif 38 | #endif 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif -------------------------------------------------------------------------------- /rosidl_typeadapter_protobuf_test/test/subscribe_string_types.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include "rclcpp/rclcpp.hpp" 20 | 21 | #include "test_msgs/rosidl_adapter_proto__visibility_control.h" 22 | #include "builtin_interfaces/rosidl_adapter_proto__visibility_control.h" 23 | #include "test_msgs/msg/strings__typeadapter_protobuf_cpp.hpp" 24 | #include "test_msgs/msg/w_strings__typeadapter_protobuf_cpp.hpp" 25 | 26 | 27 | #include "subscribe_helper.hpp" 28 | #include "subscribe_string_types.hpp" 29 | 30 | rclcpp::SubscriptionBase::SharedPtr subscribe_strings( 31 | rclcpp::Node::SharedPtr node, 32 | const std::string & message_type, 33 | const std::vector> & expected_messages, 34 | std::vector & received_messages) 35 | { 36 | return subscribe( 37 | node, message_type, expected_messages, received_messages); 38 | } 39 | 40 | rclcpp::SubscriptionBase::SharedPtr subscribe_wstrings( 41 | rclcpp::Node::SharedPtr node, 42 | const std::string & message_type, 43 | const std::vector> & expected_messages, 44 | std::vector & received_messages) 45 | { 46 | return subscribe( 47 | node, message_type, expected_messages, received_messages); 48 | } 49 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/resource/rosidl_typesupport_protobuf_cpp__visibility_control.h.in: -------------------------------------------------------------------------------- 1 | // generated from 2 | // rosidl_typesupport_protobuf/rosidl_typesupport_protobuf_cpp/resource/visibility_control.h.in 3 | // generated code does not contain a copyright notice 4 | #pragma once 5 | 6 | #ifdef __cplusplus 7 | extern "C" 8 | { 9 | #endif 10 | 11 | // This logic was borrowed (then namespaced) from the examples on the gcc wiki: 12 | // https://gcc.gnu.org/wiki/Visibility 13 | 14 | #if defined _WIN32 || defined __CYGWIN__ 15 | #ifdef __GNUC__ 16 | #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_EXPORT__@PROJECT_NAME@ __attribute__ ((dllexport)) 17 | #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_IMPORT__@PROJECT_NAME@ __attribute__ ((dllimport)) 18 | #else 19 | #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_EXPORT__@PROJECT_NAME@ __declspec(dllexport) 20 | #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_IMPORT__@PROJECT_NAME@ __declspec(dllimport) 21 | #endif 22 | #ifdef ROSIDL_TYPESUPPORT_PROTOBUF_CPP_BUILDING_DLL__@PROJECT_NAME@ 23 | #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@PROJECT_NAME@ ROSIDL_TYPESUPPORT_PROTOBUF_CPP_EXPORT__@PROJECT_NAME@ 24 | #else 25 | #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@PROJECT_NAME@ ROSIDL_TYPESUPPORT_PROTOBUF_CPP_IMPORT__@PROJECT_NAME@ 26 | #endif 27 | #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_LOCAL__@PROJECT_NAME@ 28 | #else 29 | #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_EXPORT__@PROJECT_NAME@ __attribute__ ((visibility("default"))) 30 | #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_IMPORT__@PROJECT_NAME@ 31 | #if __GNUC__ >= 4 32 | #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@PROJECT_NAME@ __attribute__ ((visibility("default"))) 33 | #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_LOCAL__@PROJECT_NAME@ __attribute__ ((visibility("hidden"))) 34 | #else 35 | #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@PROJECT_NAME@ 36 | #define ROSIDL_TYPESUPPORT_PROTOBUF_CPP_LOCAL__@PROJECT_NAME@ 37 | #endif 38 | #endif 39 | 40 | #ifdef __cplusplus 41 | } 42 | #endif -------------------------------------------------------------------------------- /rosidl_adapter_proto/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ================================= Apache 2.0 ================================= 2 | # 3 | # Copyright (C) 2021 Continental 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # ================================= Apache 2.0 ================================= 18 | cmake_minimum_required(VERSION 3.12) 19 | 20 | project(rosidl_adapter_proto) 21 | 22 | find_package(ament_cmake REQUIRED) 23 | find_package(ament_cmake_python REQUIRED) 24 | 25 | if(BUILD_TESTING) 26 | find_package(ament_cmake_pytest REQUIRED) 27 | find_package(rosidl_cmake REQUIRED) 28 | ament_add_pytest_test(pytest test) 29 | set(generator_arguments_file "${CMAKE_CURRENT_SOURCE_DIR}/test/msg/test_rosid_adapter_proto__arguments.json") 30 | rosidl_write_generator_arguments( 31 | "${generator_arguments_file}" 32 | PACKAGE_NAME "${PROJECT_NAME}" 33 | IDL_TUPLES "${CMAKE_CURRENT_SOURCE_DIR}/test:msg/BoolTest.idl" 34 | OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/test" 35 | TEMPLATE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/resource" 36 | TARGET_DEPENDENCIES "${CMAKE_CURRENT_SOURCE_DIR}/test/msg/BoolTest.idl" 37 | ADDITIONAL_FILES "") 38 | endif() 39 | 40 | ament_python_install_package(${PROJECT_NAME}) 41 | 42 | ament_package(CONFIG_EXTRAS "cmake/rosidl_adapter_proto-extras.cmake.in") 43 | 44 | install( 45 | PROGRAMS bin/rosidl_adapter_proto 46 | DESTINATION lib/rosidl_adapter_proto 47 | ) 48 | 49 | install( 50 | DIRECTORY cmake resource 51 | DESTINATION share/${PROJECT_NAME} 52 | ) -------------------------------------------------------------------------------- /rosidl_adapter_proto/cmake/rosidl_adapter_proto-extras.cmake.in: -------------------------------------------------------------------------------- 1 | # generated from 2 | # rosidl_adapter_proto/ 3 | # rosidl_adapter_proto-extras.cmake.in 4 | 5 | find_package(Protobuf REQUIRED) 6 | 7 | if(NOT Protobuf_FOUND) 8 | message(STATUS "Could not find Protobuf - skip rosidl_adapter_proto") 9 | else() 10 | find_package(ament_cmake_core QUIET REQUIRED) 11 | ament_register_extension( 12 | "rosidl_generate_idl_interfaces" 13 | "rosidl_adapter_proto" 14 | "${rosidl_adapter_proto_DIR}/rosidl_adapt_proto_interfaces.cmake") 15 | 16 | set(rosidl_adapter_proto_BIN 17 | "${rosidl_adapter_proto_DIR}/../../../lib/rosidl_adapter_proto/rosidl_adapter_proto") 18 | normalize_path(rosidl_adapter_proto_BIN 19 | "${rosidl_adapter_proto_BIN}") 20 | 21 | set(rosidl_adapter_proto_GENERATOR_FILES 22 | "${rosidl_adapter_proto_DIR}/../../../@PYTHON_INSTALL_DIR@/rosidl_adapter_proto/__init__.py") 23 | normalize_path(rosidl_adapter_proto_GENERATOR_FILES 24 | "${rosidl_adapter_proto_GENERATOR_FILES}") 25 | 26 | set(rosidl_adapter_proto_TEMPLATE_DIR 27 | "${rosidl_adapter_proto_DIR}/../resource") 28 | normalize_path(rosidl_adapter_proto_TEMPLATE_DIR 29 | "${rosidl_adapter_proto_TEMPLATE_DIR}") 30 | 31 | include("${rosidl_adapter_proto_DIR}/rosidl_adapt_proto_interfaces.cmake") 32 | 33 | add_compile_definitions("ROSIDL_ADAPTER_PROTO_BUILDING_DLL__${PROJECT_NAME}") 34 | 35 | # There is no clean way to include additional files into protobuf headers 36 | if(NOT WIN32) 37 | add_compile_options("-include${rosidl_adapter_proto_VISIBILITY_CONTROL_HEADER}") 38 | else() 39 | add_compile_options("/FI\"${rosidl_adapter_proto_VISIBILITY_CONTROL_HEADER}\"") 40 | endif() 41 | 42 | foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES}) 43 | set(_proto_dir "${${_pkg_name}_DIR}/../../../include/${_pkg_name}/${_pkg_name}/rosidl_adapter_proto__visibility_control.h") 44 | normalize_path(_proto_dir "${_proto_dir}") 45 | if(NOT WIN32) 46 | add_compile_options("-include${_proto_dir}") 47 | else() 48 | add_compile_options("/FI\"${_proto_dir}\"") 49 | endif() 50 | endforeach() 51 | 52 | endif() 53 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/bin/rosidl_typesupport_protobuf_c: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # ================================= Apache 2.0 ================================= 4 | # 5 | # Copyright (C) 2021 Continental 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | # ================================= Apache 2.0 ================================= 20 | 21 | import argparse 22 | import os 23 | import sys 24 | import rosidl_typesupport_protobuf 25 | 26 | from rosidl_typesupport_protobuf_c import generate_typesupport_protobuf_c 27 | 28 | def is_valid_file(parser, file_name): 29 | if not os.path.exists(file_name): 30 | parser.error("File does not exist: '{0}'".format(file_name)) 31 | file_name_abs = os.path.abspath(file_name) 32 | if not os.path.isfile(file_name_abs): 33 | parser.error("Path exists but is not a file: '{0}'".format(file_name_abs)) 34 | return file_name 35 | 36 | 37 | def main(argv=sys.argv[1:]): 38 | parser = argparse.ArgumentParser( 39 | description='Generate the C interfaces for Protobuf.', 40 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 41 | parser.add_argument( 42 | '--generator-arguments-file', 43 | required=True, 44 | help='The location of the file containing the generator arguments') 45 | args = parser.parse_args(argv) 46 | 47 | rosidl_typesupport_protobuf.set_namespace_delimeter("__") 48 | rosidl_typesupport_protobuf.set_type_support_name("rosidl_typesupport_protobuf_c") 49 | 50 | return generate_typesupport_protobuf_c(args.generator_arguments_file) 51 | 52 | 53 | if __name__ == '__main__': 54 | sys.exit(main()) 55 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/visibility_control.h: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | #pragma once 20 | 21 | #ifdef __cplusplus 22 | extern "C" 23 | { 24 | #endif 25 | 26 | // This logic was borrowed (then namespaced) from the examples on the gcc wiki: 27 | // https://gcc.gnu.org/wiki/Visibility 28 | 29 | #if defined _WIN32 || defined __CYGWIN__ 30 | #ifdef __GNUC__ 31 | #define ROSIDL_TYPESUPPORT_PROTOBUF_EXPORT __attribute__ ((dllexport)) 32 | #define ROSIDL_TYPESUPPORT_PROTOBUF_IMPORT __attribute__ ((dllimport)) 33 | #else 34 | #define ROSIDL_TYPESUPPORT_PROTOBUF_EXPORT __declspec(dllexport) 35 | #define ROSIDL_TYPESUPPORT_PROTOBUF_IMPORT __declspec(dllimport) 36 | #endif 37 | #ifdef ROSIDL_TYPESUPPORT_PROTOBUF_BUILDING_DLL 38 | #define ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC ROSIDL_TYPESUPPORT_PROTOBUF_EXPORT 39 | #else 40 | #define ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC ROSIDL_TYPESUPPORT_PROTOBUF_IMPORT 41 | #endif 42 | #define ROSIDL_TYPESUPPORT_PROTOBUF_LOCAL 43 | #else 44 | #define ROSIDL_TYPESUPPORT_PROTOBUF_EXPORT __attribute__ ((visibility("default"))) 45 | #define ROSIDL_TYPESUPPORT_PROTOBUF_IMPORT 46 | #if __GNUC__ >= 4 47 | #define ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC __attribute__ ((visibility("default"))) 48 | #define ROSIDL_TYPESUPPORT_PROTOBUF_LOCAL __attribute__ ((visibility("hidden"))) 49 | #else 50 | #define ROSIDL_TYPESUPPORT_PROTOBUF_PUBLIC 51 | #define ROSIDL_TYPESUPPORT_PROTOBUF_LOCAL 52 | #endif 53 | #endif 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | -------------------------------------------------------------------------------- /rosidl_adapter_proto/resource/action.proto.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | @{ 21 | from rosidl_cmake import convert_camel_case_to_lower_case_underscore 22 | import rosidl_parser.definition as rosidl 23 | 24 | from rosidl_adapter_proto import PROTO_PACKAGE_POSTFIX 25 | from rosidl_adapter_proto import MSG_TYPE_TO_PROTO 26 | from rosidl_adapter_proto import PROTO_ACTION_SEND_GOAL_CALL_NAME 27 | from rosidl_adapter_proto import PROTO_ACTION_GET_RESULT_CALL_NAME 28 | 29 | }@ 30 | option cc_generic_services = true; 31 | 32 | @# 33 | @# ================ Message definitions ================ 34 | @# 35 | @[for message in [action.goal, 36 | action.send_goal_service.request_message, 37 | action.send_goal_service.response_message, 38 | action.result, 39 | action.get_result_service.request_message, 40 | action.get_result_service.response_message, 41 | action.feedback, 42 | action.feedback_message, 43 | ] 44 | ]@ 45 | @{ 46 | TEMPLATE( 47 | 'msg.proto.em', 48 | package_name=package_name, 49 | interface_path=interface_path, 50 | message=message, 51 | ) 52 | }@ 53 | 54 | 55 | @[end for]@ 56 | @# 57 | @# ================ Service definitions ================ 58 | @# 59 | service @(action.namespaced_type.name) 60 | { 61 | rpc @(PROTO_ACTION_SEND_GOAL_CALL_NAME) (@(action.send_goal_service.request_message.structure.namespaced_type.name)) returns (@(action.send_goal_service.response_message.structure.namespaced_type.name)); 62 | rpc @(PROTO_ACTION_GET_RESULT_CALL_NAME) (@(action.get_result_service.request_message.structure.namespaced_type.name)) returns (@(action.get_result_service.response_message.structure.namespaced_type.name)); 63 | } -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/test/test_wstring_conversion.cpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | 20 | #include 21 | 22 | #include "gtest/gtest.h" 23 | #include 24 | 25 | #include "rosidl_typesupport_protobuf_cpp/wstring_conversion.hpp" 26 | 27 | using rosidl_typesupport_protobuf_cpp::write_to_string; 28 | using rosidl_typesupport_protobuf_cpp::write_to_u16string; 29 | 30 | TEST(test_wstring_conversion, u16string_to_string) { 31 | std::string actual; 32 | 33 | // Default string 34 | write_to_string(std::u16string(), actual); 35 | EXPECT_EQ(std::string(), actual); 36 | 37 | // Empty string 38 | write_to_string(std::u16string(u""), actual); 39 | EXPECT_EQ(std::string(""), actual); 40 | 41 | // Non-empty string 42 | write_to_string(std::u16string(u"Hello World"), actual); 43 | const char byteArray[] = {'H', 0x00, 'e', 0x00, 'l', 0x00, 'l', 0x00, 44 | 'o', 0x00, ' ', 0x00, 'W', 0x00, 'o', 0x00, 45 | 'r', 0x00, 'l', 0x00, 'd', 0x00}; 46 | std::string expected(byteArray, sizeof(byteArray)); 47 | EXPECT_EQ(expected, actual); 48 | } 49 | 50 | TEST(test_wstring_conversion, string_to_u16string) { 51 | std::u16string actual; 52 | 53 | // Default string 54 | write_to_u16string(std::string(), actual); 55 | EXPECT_EQ(std::u16string(), actual); 56 | 57 | // Empty string 58 | write_to_u16string(std::string(""), actual); 59 | EXPECT_EQ(std::u16string(u""), actual); 60 | 61 | // Non-empty string 62 | const char byteArray_input[] = {'H', 0x00, 'e', 0x00, 'l', 0x00, 'l', 0x00, 63 | 'o', 0x00, ' ', 0x00, 'W', 0x00, 'o', 0x00, 64 | 'r', 0x00, 'l', 0x00, 'd', 0x00}; 65 | std::string input_string(byteArray_input, sizeof(byteArray_input)); 66 | write_to_u16string(input_string, actual); 67 | std::u16string expected(u"Hello World"); 68 | EXPECT_EQ(expected, actual); 69 | } -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/resource/msg__rosidl_typesupport_protobuf_cpp.hpp.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | @# Included from rosidl_typesupport_protobuf_cpp/resource/idl__rosidl_typesupport_protobuf_cpp.hpp.em 21 | @{ 22 | from rosidl_cmake import convert_camel_case_to_lower_case_underscore 23 | from rosidl_typesupport_protobuf import * 24 | 25 | system_header_files = [ 26 | "string" 27 | ] 28 | 29 | header_files = [ 30 | ros_message_header(package_name, interface_path), 31 | visibility_control_header(package_name), 32 | 'rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp', 33 | 'rosidl_typesupport_interface/macros.h', 34 | protobuf_message_header(package_name, interface_path) 35 | ] 36 | 37 | ros_type_ns = ros_type_namespace(package_name, interface_path) 38 | ros_type_name = ros_type_name(message) 39 | ros_type = ros_type(package_name, interface_path, message) 40 | proto_type = protobuf_type(package_name, interface_path, message) 41 | 42 | }@ 43 | @{ 44 | TEMPLATE( 45 | 'tmpl_include_directories.em', 46 | header_files=header_files, 47 | system_header_files=system_header_files, 48 | include_directives=include_directives 49 | ) 50 | }@ 51 | 52 | @[for ns in message.structure.namespaced_type.namespaces]@ 53 | namespace @(ns) 54 | { 55 | @[end for]@ 56 | namespace typesupport_protobuf_cpp 57 | { 58 | 59 | bool 60 | ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@(package_name) 61 | convert_to_proto(const @(ros_type) &ros_msg, @(proto_type) &pb_msg); 62 | 63 | bool 64 | ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@(package_name) 65 | convert_to_ros(const @(proto_type) &pb_msg, @(ros_type) &ros_msg); 66 | 67 | } // namespace typesupport_protobuf_cpp 68 | @[ for ns in reversed(message.structure.namespaced_type.namespaces)]@ 69 | } // namespace @(ns) 70 | @[ end for]@ 71 | 72 | #ifdef __cplusplus 73 | extern "C" 74 | { 75 | #endif 76 | 77 | ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@(package_name) 78 | const rosidl_message_type_support_t * 79 | ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_protobuf_cpp, @(ros_type_ns.replace("::", ", ")), @(ros_type_name))(); 80 | 81 | #ifdef __cplusplus 82 | } 83 | #endif 84 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/resource/msg__rosidl_typesupport_protobuf_c.hpp.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | @# Included from rosidl_typesupport_protobuf_c/resource/idl__rosidl_typesupport_protobuf_c.hpp.em 21 | @{ 22 | from rosidl_cmake import convert_camel_case_to_lower_case_underscore 23 | from rosidl_typesupport_protobuf import * 24 | 25 | system_header_files = [ 26 | "string" 27 | ] 28 | 29 | header_files = [ 30 | "rosidl_typesupport_cpp/message_type_support.hpp", 31 | ros_message_header_c(package_name, interface_path), 32 | ros_message_header(package_name, interface_path), 33 | visibility_control_header(package_name), 34 | "rosidl_typesupport_interface/macros.h", 35 | protobuf_message_header(package_name, interface_path) 36 | ] 37 | 38 | ros_type_ns = ros_type_namespace(package_name, interface_path) 39 | ros_type_name = ros_type_name(message) 40 | ros_type = ros_type(package_name, interface_path, message) 41 | proto_type = protobuf_type(package_name, interface_path, message) 42 | 43 | }@ 44 | 45 | @{ 46 | TEMPLATE( 47 | 'tmpl_include_directories.em', 48 | header_files=header_files, 49 | system_header_files=system_header_files, 50 | include_directives=include_directives 51 | ) 52 | }@ 53 | 54 | @[for ns in message.structure.namespaced_type.namespaces]@ 55 | namespace @(ns) 56 | { 57 | @[end for]@ 58 | namespace typesupport_protobuf_c 59 | { 60 | 61 | bool 62 | ROSIDL_TYPESUPPORT_PROTOBUF_C_PUBLIC__@(package_name) 63 | convert_to_proto(const @(ros_type) &ros_msg, @(proto_type) &pb_msg); 64 | 65 | bool 66 | ROSIDL_TYPESUPPORT_PROTOBUF_C_PUBLIC__@(package_name) 67 | convert_to_ros(const @(proto_type) &pb_msg, @(ros_type) &ros_msg); 68 | 69 | } // namespace typesupport_protobuf_c 70 | @[ for ns in reversed(message.structure.namespaced_type.namespaces)]@ 71 | } // namespace @(ns) 72 | @[ end for]@ 73 | 74 | #ifdef __cplusplus 75 | extern "C" 76 | { 77 | #endif 78 | 79 | ROSIDL_TYPESUPPORT_PROTOBUF_C_PUBLIC__@(package_name) 80 | const rosidl_message_type_support_t * 81 | ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_protobuf_c, @(ros_type_ns.replace("__", ", ")), @(ros_type_name))(); 82 | 83 | #ifdef __cplusplus 84 | } 85 | #endif 86 | -------------------------------------------------------------------------------- /rosidl_typeadapter_protobuf_test/test/subscribe_basic_types.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef SUBSCRIBE_BASIC_TYPES_HPP_ 16 | #define SUBSCRIBE_BASIC_TYPES_HPP_ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "rclcpp/rclcpp.hpp" 23 | #include "test_msgs/rosidl_adapter_proto__visibility_control.h" 24 | #include "builtin_interfaces/rosidl_adapter_proto__visibility_control.h" 25 | #include "test_msgs/msg/Arrays.pb.h" 26 | #include "test_msgs/msg/BasicTypes.pb.h" 27 | #include "test_msgs/msg/BoundedPlainSequences.pb.h" 28 | #include "test_msgs/msg/BoundedSequences.pb.h" 29 | #include "test_msgs/msg/Builtins.pb.h" 30 | #include "test_msgs/msg/Constants.pb.h" 31 | #include "test_msgs/msg/Defaults.pb.h" 32 | #include "test_msgs/msg/Empty.pb.h" 33 | #include "test_msgs/msg/MultiNested.pb.h" 34 | #include "test_msgs/msg/Nested.pb.h" 35 | #include "test_msgs/msg/Strings.pb.h" 36 | #include "test_msgs/msg/UnboundedSequences.pb.h" 37 | #include "test_msgs/msg/WStrings.pb.h" 38 | 39 | 40 | rclcpp::SubscriptionBase::SharedPtr subscribe_empty( 41 | rclcpp::Node::SharedPtr node, 42 | const std::string & message_type, 43 | const std::vector> & messages_expected, 44 | std::vector & received_messages); 45 | 46 | rclcpp::SubscriptionBase::SharedPtr subscribe_basic_types( 47 | rclcpp::Node::SharedPtr node, 48 | const std::string & message_type, 49 | const std::vector> & messages_expected, 50 | std::vector & received_messages); 51 | 52 | rclcpp::SubscriptionBase::SharedPtr subscribe_builtins( 53 | rclcpp::Node::SharedPtr node, 54 | const std::string & message_type, 55 | const std::vector> & messages_expected, 56 | std::vector & received_messages); 57 | 58 | rclcpp::SubscriptionBase::SharedPtr subscribe_constants( 59 | rclcpp::Node::SharedPtr node, 60 | const std::string & message_type, 61 | const std::vector> & messages_expected, 62 | std::vector & received_messages); 63 | 64 | rclcpp::SubscriptionBase::SharedPtr subscribe_defaults( 65 | rclcpp::Node::SharedPtr node, 66 | const std::string & message_type, 67 | const std::vector> & messages_expected, 68 | std::vector & received_messages); 69 | 70 | #endif // SUBSCRIBE_BASIC_TYPES_HPP_ 71 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/test/test_wstring_conversion.cpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | 20 | #include 21 | 22 | #include "gtest/gtest.h" 23 | 24 | #include "rosidl_runtime_c/u16string_functions.h" 25 | 26 | #include "rosidl_typesupport_protobuf_c/wstring_conversion.hpp" 27 | 28 | using rosidl_typesupport_protobuf_c::write_to_string; 29 | using rosidl_typesupport_protobuf_c::write_to_u16string; 30 | 31 | TEST(test_wstring_conversion, u16string_to_string) { 32 | std::string actual; 33 | rosidl_runtime_c__U16String input; 34 | ASSERT_TRUE(rosidl_runtime_c__U16String__init(&input)); 35 | 36 | // Default string 37 | write_to_string(input, actual); 38 | EXPECT_EQ(std::string(), actual); 39 | 40 | // Empty String 41 | ASSERT_TRUE( 42 | rosidl_runtime_c__U16String__assign(&input, (const uint16_t *)u"")); 43 | write_to_string(input, actual); 44 | EXPECT_EQ(std::string(""), actual); 45 | 46 | // Non-empty string 47 | ASSERT_TRUE(rosidl_runtime_c__U16String__assign( 48 | &input, (const uint16_t *)u"Hello World")); 49 | write_to_string(input, actual); 50 | const char byteArray[] = {'H', 0x00, 'e', 0x00, 'l', 0x00, 'l', 0x00, 51 | 'o', 0x00, ' ', 0x00, 'W', 0x00, 'o', 0x00, 52 | 'r', 0x00, 'l', 0x00, 'd', 0x00}; 53 | std::string expected(byteArray, sizeof(byteArray)); 54 | EXPECT_EQ(expected, actual); 55 | } 56 | 57 | TEST(test_wstring_conversion, string_to_u16string) { 58 | rosidl_runtime_c__U16String actual; 59 | ASSERT_TRUE(rosidl_runtime_c__U16String__init(&actual)); 60 | 61 | // Default string 62 | write_to_u16string(std::string(), actual); 63 | EXPECT_EQ(0, memcmp(u"", actual.data, actual.size)); 64 | 65 | // Empty String 66 | write_to_u16string(std::string(""), actual); 67 | EXPECT_EQ(0, memcmp(u"", actual.data, actual.size)); 68 | 69 | // Non-empty string 70 | const char byteArray_input[] = {'H', 0x00, 'e', 0x00, 'l', 0x00, 'l', 0x00, 71 | 'o', 0x00, ' ', 0x00, 'W', 0x00, 'o', 0x00, 72 | 'r', 0x00, 'l', 0x00, 'd', 0x00}; 73 | std::string input_string(byteArray_input, sizeof(byteArray_input)); 74 | write_to_u16string(input_string, actual); 75 | EXPECT_EQ(0, memcmp(u"Hello World", actual.data, actual.size)); 76 | } -------------------------------------------------------------------------------- /rosidl_typeadapter_protobuf_test/test/subscribe_array_types.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef SUBSCRIBE_ARRAY_TYPES_HPP_ 16 | #define SUBSCRIBE_ARRAY_TYPES_HPP_ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "rclcpp/rclcpp.hpp" 23 | #include "test_msgs/rosidl_adapter_proto__visibility_control.h" 24 | #include "builtin_interfaces/rosidl_adapter_proto__visibility_control.h" 25 | #include "test_msgs/msg/Arrays.pb.h" 26 | #include "test_msgs/msg/UnboundedSequences.pb.h" 27 | #include "test_msgs/msg/BoundedPlainSequences.pb.h" 28 | #include "test_msgs/msg/BoundedSequences.pb.h" 29 | #include "test_msgs/msg/MultiNested.pb.h" 30 | #include "test_msgs/msg/Nested.pb.h" 31 | 32 | rclcpp::SubscriptionBase::SharedPtr subscribe_arrays( 33 | rclcpp::Node::SharedPtr node, 34 | const std::string & message_type, 35 | const std::vector> & expected_messages, 36 | std::vector & received_messages); 37 | 38 | rclcpp::SubscriptionBase::SharedPtr subscribe_unbounded_sequences( 39 | rclcpp::Node::SharedPtr node, 40 | const std::string & message_type, 41 | const std::vector> & expected_messages, 42 | std::vector & received_messages); 43 | 44 | rclcpp::SubscriptionBase::SharedPtr subscribe_bounded_plain_sequences( 45 | rclcpp::Node::SharedPtr node, 46 | const std::string & message_type, 47 | const std::vector> & expected_messages, 48 | std::vector & received_messages); 49 | 50 | rclcpp::SubscriptionBase::SharedPtr subscribe_bounded_sequences( 51 | rclcpp::Node::SharedPtr node, 52 | const std::string & message_type, 53 | const std::vector> & expected_messages, 54 | std::vector & received_messages); 55 | 56 | rclcpp::SubscriptionBase::SharedPtr subscribe_multi_nested( 57 | rclcpp::Node::SharedPtr node, 58 | const std::string & message_type, 59 | const std::vector> & expected_messages, 60 | std::vector & received_messages); 61 | 62 | rclcpp::SubscriptionBase::SharedPtr subscribe_nested( 63 | rclcpp::Node::SharedPtr node, 64 | const std::string & message_type, 65 | const std::vector> & expected_messages, 66 | std::vector & received_messages); 67 | 68 | #endif // SUBSCRIBE_ARRAY_TYPES_HPP_ 69 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/resource/tmpl_forward_declarations.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | @{ 21 | from rosidl_parser.definition import * 22 | from rosidl_typesupport_protobuf import PROTO_PACKAGE_POSTFIX, ros_type_from_namespaced_type, protobuf_type_from_namespaced_type 23 | 24 | def isNamespacedType(type_): 25 | from rosidl_parser.definition import NamespacedType 26 | return isinstance(type_, NamespacedType) 27 | 28 | def isNamespacedArrayType(type_): 29 | from rosidl_parser.definition import AbstractNestedType 30 | from rosidl_parser.definition import NamespacedType 31 | return isinstance(type_, AbstractNestedType) and isinstance(type_.value_type, NamespacedType) 32 | 33 | def isTypeAlreadyDeclared(type_, fw_declared_types): 34 | from rosidl_typesupport_protobuf import ros_type_from_namespaced_type 35 | return ros_type_from_namespaced_type(type_) in fw_declared_types 36 | 37 | def registerDeclaredType(type_, fw_declared_types): 38 | from rosidl_typesupport_protobuf import ros_type_from_namespaced_type 39 | fw_declared_types.add(ros_type_from_namespaced_type(type_)) 40 | 41 | types_to_declare = list() 42 | for member in message.structure.members: 43 | if isNamespacedType(member.type) and not isTypeAlreadyDeclared(member.type, forward_declared_types): 44 | types_to_declare.append(member.type) 45 | registerDeclaredType(member.type, forward_declared_types) 46 | elif isNamespacedArrayType(member.type) and not isTypeAlreadyDeclared(member.type.value_type, forward_declared_types): 47 | types_to_declare.append(member.type.value_type) 48 | registerDeclaredType(member.type.value_type, forward_declared_types) 49 | }@ 50 | @[if len(types_to_declare) > 0]@ 51 | // forward declaration of message dependencies and their conversion functions 52 | @[end if]@ 53 | @[for type_ in types_to_declare]@ 54 | @{ 55 | ros_type = ros_type_from_namespaced_type(type_) 56 | proto_type = protobuf_type_from_namespaced_type(type_) 57 | }@ 58 | @[ for ns in type_.namespaces]@ 59 | namespace @(ns) 60 | { 61 | @[ end for]@ 62 | namespace typesupport_protobuf_cpp 63 | { 64 | 65 | bool convert_to_proto(const @(ros_type)&, @(proto_type)&); 66 | bool convert_to_ros(const @(proto_type)&, @(ros_type)&); 67 | 68 | } // namespace typesupport_protobuf_cpp 69 | @[ for ns in reversed(type_.namespaces)]@ 70 | } // namespace @(ns) 71 | @[ end for]@ 72 | 73 | @[end for]@ 74 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/resource/idl__typeadapter_protobuf_cpp.hpp.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | @# Included from rosidl_typesupport_protobuf_cpp/resource/idl__rosidl_typesupport_protobuf_cpp.hpp.em 21 | @{ 22 | 23 | from rosidl_parser.definition import Message 24 | 25 | from rosidl_cmake import convert_camel_case_to_lower_case_underscore 26 | from rosidl_typesupport_protobuf import * 27 | 28 | system_header_files = [ 29 | "string" 30 | ] 31 | 32 | header_files = [ 33 | "rclcpp/type_adapter.hpp", 34 | ros_message_header(package_name, interface_path), 35 | adapter_visibility_control_header(package_name), 36 | typesupport_message_header(package_name, interface_path), 37 | visibility_control_header(package_name), 38 | 'rosidl_typesupport_protobuf/rosidl_generator_c_pkg_adapter.hpp', 39 | 'rosidl_typesupport_interface/macros.h', 40 | protobuf_message_header(package_name, interface_path) 41 | ] 42 | 43 | include_directives = set() 44 | 45 | }@ 46 | @{ 47 | TEMPLATE( 48 | 'tmpl_include_directories.em', 49 | header_files=header_files, 50 | system_header_files=system_header_files, 51 | include_directives=include_directives 52 | ) 53 | }@ 54 | 55 | @[for message in content.get_elements_of_type(Message)]@ 56 | 57 | @{ 58 | ros_type_ns = ros_type_namespace(package_name, interface_path) 59 | ros_type_name = ros_type_name(message) 60 | ros_type = ros_type(package_name, interface_path, message) 61 | proto_type = protobuf_type(package_name, interface_path, message) 62 | }@ 63 | 64 | template<> 65 | struct rclcpp::TypeAdapter<@(proto_type), @(ros_type)> 66 | { 67 | using is_specialized = std::true_type; 68 | using custom_type = @(proto_type); 69 | using ros_message_type = @(ros_type); 70 | 71 | static 72 | void 73 | convert_to_ros_message( 74 | const custom_type & source, 75 | ros_message_type & destination) 76 | { 77 | @("::".join(message.structure.namespaced_type.namespaces))::typesupport_protobuf_cpp::convert_to_ros(source, destination); 78 | } 79 | 80 | static 81 | void 82 | convert_to_custom( 83 | const ros_message_type & source, 84 | custom_type & destination) 85 | { 86 | @("::".join(message.structure.namespaced_type.namespaces))::typesupport_protobuf_cpp::convert_to_proto(source, destination); 87 | } 88 | }; 89 | 90 | RCLCPP_USING_CUSTOM_TYPE_AS_ROS_MESSAGE_TYPE(@(proto_type), @(ros_type)); 91 | 92 | @[end for]@ 93 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/resource/tmpl_forward_declarations.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | @{ 21 | from rosidl_parser.definition import * 22 | from rosidl_typesupport_protobuf import PROTO_PACKAGE_POSTFIX, ros_type_from_namespaced_type, ros_type_from_namespaced_type_c, protobuf_type_from_namespaced_type, protobuf_type_from_namespaced_type_c 23 | 24 | def isNamespacedType(type_): 25 | from rosidl_parser.definition import NamespacedType 26 | return isinstance(type_, NamespacedType) 27 | 28 | def isNamespacedArrayType(type_): 29 | from rosidl_parser.definition import AbstractNestedType 30 | from rosidl_parser.definition import NamespacedType 31 | return isinstance(type_, AbstractNestedType) and isinstance(type_.value_type, NamespacedType) 32 | 33 | def isTypeAlreadyDeclared(type_, fw_declared_types): 34 | from rosidl_typesupport_protobuf import ros_type_from_namespaced_type 35 | return ros_type_from_namespaced_type(type_) in fw_declared_types 36 | 37 | def registerDeclaredType(type_, fw_declared_types): 38 | from rosidl_typesupport_protobuf import ros_type_from_namespaced_type 39 | fw_declared_types.add(ros_type_from_namespaced_type(type_)) 40 | 41 | types_to_declare = list() 42 | for member in message.structure.members: 43 | if isNamespacedType(member.type) and not isTypeAlreadyDeclared(member.type, forward_declared_types): 44 | types_to_declare.append(member.type) 45 | registerDeclaredType(member.type, forward_declared_types) 46 | elif isNamespacedArrayType(member.type) and not isTypeAlreadyDeclared(member.type.value_type, forward_declared_types): 47 | types_to_declare.append(member.type.value_type) 48 | registerDeclaredType(member.type.value_type, forward_declared_types) 49 | }@ 50 | @[if len(types_to_declare) > 0]@ 51 | // forward declaration of message dependencies and their conversion functions 52 | @[end if]@ 53 | @[for type_ in types_to_declare]@ 54 | @{ 55 | ros_type = ros_type_from_namespaced_type_c(type_) 56 | proto_type = protobuf_type_from_namespaced_type_c(type_) 57 | }@ 58 | 59 | @[ for ns in type_.namespaces]@ 60 | namespace @(ns) 61 | { 62 | @[ end for]@ 63 | namespace typesupport_protobuf_c 64 | { 65 | 66 | bool convert_to_proto(const @(ros_type)&, @(proto_type)&); 67 | bool convert_to_ros(const @(proto_type)&, @(ros_type)&); 68 | 69 | } // namespace typesupport_protobuf_cpp 70 | @[ for ns in reversed(type_.namespaces)]@ 71 | } // namespace @(ns) 72 | @[ end for]@ 73 | 74 | @[end for]@ 75 | -------------------------------------------------------------------------------- /rosidl_typeadapter_protobuf_test/test/subscribe_helper.hpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #ifndef SUBSCRIBE_HELPER_HPP_ 16 | #define SUBSCRIBE_HELPER_HPP_ 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "rclcpp/rclcpp.hpp" 27 | 28 | template 29 | rclcpp::SubscriptionBase::SharedPtr subscribe( 30 | rclcpp::Node::SharedPtr node, 31 | const std::string & message_type, 32 | const std::vector::custom_type>> 33 | & expected_messages, 34 | std::vector & received_messages) 35 | { 36 | received_messages.assign(expected_messages.size(), false); 37 | 38 | auto callback = 39 | [&expected_messages, &received_messages]( 40 | const std::shared_ptr::custom_type> received_message 41 | ) -> void 42 | { 43 | google::protobuf::util::MessageDifferencer mdiff; 44 | mdiff.set_message_field_comparison( 45 | google::protobuf::util::MessageDifferencer::MessageFieldComparison::EQUAL); 46 | mdiff.set_scope(google::protobuf::util::MessageDifferencer::Scope::PARTIAL); 47 | 48 | // find received message in vector of expected messages 49 | auto received = received_messages.begin(); 50 | bool known_message = false; 51 | size_t index = 0; 52 | for (auto expected_message : expected_messages) { 53 | if (!expected_message->ByteSize()) { 54 | if (!received_message->ByteSize() ) { 55 | *received = true; 56 | printf("received message #%zu of %zu\n", index + 1, expected_messages.size()); 57 | known_message = true; 58 | break; 59 | } 60 | } else if (mdiff.Compare(*expected_message, *received_message)) { 61 | *received = true; 62 | printf("received message #%zu of %zu\n", index + 1, expected_messages.size()); 63 | known_message = true; 64 | break; 65 | } 66 | ++received; 67 | ++index; 68 | } 69 | if (!known_message) { 70 | throw std::runtime_error("received message does not match any expected message"); 71 | } 72 | 73 | // shutdown node when all expected messages have been received 74 | for (auto received_msg : received_messages) { 75 | if (!received_msg) { 76 | return; 77 | } 78 | } 79 | rclcpp::shutdown(); 80 | }; 81 | 82 | auto qos = rclcpp::QoS(rclcpp::KeepLast(expected_messages.size())); 83 | 84 | return 85 | node->create_subscription(std::string("test/message/") + message_type, qos, callback); 86 | } 87 | 88 | #endif // SUBSCRIBE_HELPER_HPP_ 89 | -------------------------------------------------------------------------------- /rosidl_adapter_proto/bin/rosidl_adapter_proto: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # ================================= Apache 2.0 ================================= 4 | # 5 | # Copyright (C) 2021 Continental 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | # ================================= Apache 2.0 ================================= 20 | 21 | import argparse 22 | import sys 23 | import pathlib 24 | import os 25 | 26 | from rosidl_cmake import read_generator_arguments 27 | from rosidl_adapter_proto import generate_proto 28 | from rosidl_adapter_proto import compile_proto 29 | 30 | def main(argv=sys.argv[1:]): 31 | parser = argparse.ArgumentParser( 32 | description='Generate the Protobuf interfaces for Protobuf type support.', 33 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) 34 | parser.add_argument( 35 | '--generator-arguments-file', 36 | required=True, 37 | help='The location of the file containing the generator arguments') 38 | parser.add_argument( 39 | '--protoc-path', 40 | required=True, 41 | help='Path to the protoc executable') 42 | 43 | args = parser.parse_args(argv) 44 | 45 | generator_args = read_generator_arguments(args.generator_arguments_file) 46 | 47 | # Generate .proto files 48 | rc = generate_proto(args.generator_arguments_file) 49 | if rc: 50 | return rc 51 | 52 | # Compile .proto files using protoc 53 | cpp_out_dir = str(pathlib.Path(generator_args["output_dir"] + "/..").resolve()) 54 | proto_path_list = [str(pathlib.Path(generator_args["output_dir"] + "/..").resolve())] 55 | proto_files = [] 56 | package_name = generator_args["package_name"] 57 | 58 | if "additional_files" in generator_args: 59 | proto_path_list += generator_args["additional_files"] 60 | 61 | pathlib.Path(cpp_out_dir).mkdir(parents=True, exist_ok=True) 62 | 63 | for idl_tuple in generator_args.get('idl_tuples', []): 64 | idl_parts = idl_tuple.rsplit(':', 1) 65 | assert len(idl_parts) == 2 66 | idl_rel_path = pathlib.Path(idl_parts[1]) 67 | idl_stem = idl_rel_path.stem 68 | generated_file = os.path.join( 69 | generator_args['output_dir'], 70 | str(idl_rel_path.parent), 71 | idl_stem + ".proto" 72 | ) 73 | proto_files.append(str(pathlib.Path(generated_file).resolve())) 74 | 75 | # compile proto files with protoc 76 | rc = compile_proto(protoc_path = args.protoc_path, 77 | proto_path_list = proto_path_list, 78 | cpp_out_dir = cpp_out_dir, 79 | proto_files = proto_files, 80 | package_name = package_name 81 | ) 82 | 83 | return rc 84 | 85 | 86 | if __name__ == '__main__': 87 | sys.exit(main()) 88 | -------------------------------------------------------------------------------- /rosidl_typeadapter_protobuf_test/test/subscribe_basic_types.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include "rclcpp/rclcpp.hpp" 20 | 21 | #include "test_msgs/rosidl_adapter_proto__visibility_control.h" 22 | #include "builtin_interfaces/rosidl_adapter_proto__visibility_control.h" 23 | #include "test_msgs/msg/basic_types__typeadapter_protobuf_cpp.hpp" 24 | #include "test_msgs/msg/builtins__typeadapter_protobuf_cpp.hpp" 25 | #include "test_msgs/msg/constants__typeadapter_protobuf_cpp.hpp" 26 | #include "test_msgs/msg/defaults__typeadapter_protobuf_cpp.hpp" 27 | #include "test_msgs/msg/empty__typeadapter_protobuf_cpp.hpp" 28 | 29 | #include "subscribe_basic_types.hpp" 30 | #include "subscribe_helper.hpp" 31 | 32 | rclcpp::SubscriptionBase::SharedPtr subscribe_empty( 33 | rclcpp::Node::SharedPtr node, 34 | const std::string & message_type, 35 | const std::vector> & messages_expected, 36 | std::vector & received_messages) 37 | { 38 | return subscribe( 39 | node, message_type, messages_expected, received_messages); 40 | } 41 | 42 | rclcpp::SubscriptionBase::SharedPtr subscribe_basic_types( 43 | rclcpp::Node::SharedPtr node, 44 | const std::string & message_type, 45 | const std::vector> & messages_expected, 46 | std::vector & received_messages) 47 | { 48 | return subscribe( 49 | node, message_type, messages_expected, received_messages); 50 | } 51 | 52 | rclcpp::SubscriptionBase::SharedPtr subscribe_builtins( 53 | rclcpp::Node::SharedPtr node, 54 | const std::string & message_type, 55 | const std::vector> & messages_expected, 56 | std::vector & received_messages) 57 | { 58 | return subscribe( 59 | node, message_type, messages_expected, received_messages); 60 | } 61 | 62 | rclcpp::SubscriptionBase::SharedPtr subscribe_constants( 63 | rclcpp::Node::SharedPtr node, 64 | const std::string & message_type, 65 | const std::vector> & messages_expected, 66 | std::vector & received_messages) 67 | { 68 | return subscribe( 69 | node, message_type, messages_expected, received_messages); 70 | } 71 | 72 | rclcpp::SubscriptionBase::SharedPtr subscribe_defaults( 73 | rclcpp::Node::SharedPtr node, 74 | const std::string & message_type, 75 | const std::vector> & messages_expected, 76 | std::vector & received_messages) 77 | { 78 | return subscribe( 79 | node, message_type, messages_expected, received_messages); 80 | } 81 | -------------------------------------------------------------------------------- /rosidl_typeadapter_protobuf_test/test/subscribe_array_types.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include "rclcpp/rclcpp.hpp" 20 | 21 | #include "test_msgs/rosidl_adapter_proto__visibility_control.h" 22 | #include "builtin_interfaces/rosidl_adapter_proto__visibility_control.h" 23 | #include "test_msgs/msg/arrays__typeadapter_protobuf_cpp.hpp" 24 | #include "test_msgs/msg/bounded_plain_sequences__typeadapter_protobuf_cpp.hpp" 25 | #include "test_msgs/msg/bounded_sequences__typeadapter_protobuf_cpp.hpp" 26 | #include "test_msgs/msg/multi_nested__typeadapter_protobuf_cpp.hpp" 27 | #include "test_msgs/msg/nested__typeadapter_protobuf_cpp.hpp" 28 | #include "test_msgs/msg/unbounded_sequences__typeadapter_protobuf_cpp.hpp" 29 | 30 | 31 | #include "subscribe_array_types.hpp" 32 | #include "subscribe_helper.hpp" 33 | 34 | rclcpp::SubscriptionBase::SharedPtr subscribe_arrays( 35 | rclcpp::Node::SharedPtr node, 36 | const std::string & message_type, 37 | const std::vector> & expected_messages, 38 | std::vector & received_messages) 39 | { 40 | return subscribe( 41 | node, message_type, expected_messages, received_messages); 42 | } 43 | 44 | rclcpp::SubscriptionBase::SharedPtr subscribe_unbounded_sequences( 45 | rclcpp::Node::SharedPtr node, 46 | const std::string & message_type, 47 | const std::vector> & expected_messages, 48 | std::vector & received_messages) 49 | { 50 | return subscribe( 51 | node, message_type, expected_messages, received_messages); 52 | } 53 | 54 | rclcpp::SubscriptionBase::SharedPtr subscribe_bounded_plain_sequences( 55 | rclcpp::Node::SharedPtr node, 56 | const std::string & message_type, 57 | const std::vector> & expected_messages, 58 | std::vector & received_messages) 59 | { 60 | return subscribe( 61 | node, message_type, expected_messages, received_messages); 62 | } 63 | 64 | rclcpp::SubscriptionBase::SharedPtr subscribe_bounded_sequences( 65 | rclcpp::Node::SharedPtr node, 66 | const std::string & message_type, 67 | const std::vector> & expected_messages, 68 | std::vector & received_messages) 69 | { 70 | return subscribe( 71 | node, message_type, expected_messages, received_messages); 72 | } 73 | 74 | rclcpp::SubscriptionBase::SharedPtr subscribe_multi_nested( 75 | rclcpp::Node::SharedPtr node, 76 | const std::string & message_type, 77 | const std::vector> & expected_messages, 78 | std::vector & received_messages) 79 | { 80 | return subscribe( 81 | node, message_type, expected_messages, received_messages); 82 | } 83 | 84 | rclcpp::SubscriptionBase::SharedPtr subscribe_nested( 85 | rclcpp::Node::SharedPtr node, 86 | const std::string & message_type, 87 | const std::vector> & expected_messages, 88 | std::vector & received_messages) 89 | { 90 | return subscribe( 91 | node, message_type, expected_messages, received_messages); 92 | } 93 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf/include/rosidl_typesupport_protobuf/proto_descriptor_helper.hpp: -------------------------------------------------------------------------------- 1 | /* ================================ Apache 2.0 ================================= 2 | * 3 | * Copyright (C) 2021 Continental 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | * 17 | * ================================ Apache 2.0 ================================= 18 | */ 19 | #pragma once 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | // protobuf includes 26 | #ifdef _MSC_VER 27 | #pragma warning(push) 28 | #pragma warning(disable: 4100 4127 4146 4800) // disable proto warnings 29 | #endif 30 | #include 31 | #ifdef _MSC_VER 32 | #pragma warning(pop) 33 | #endif 34 | 35 | 36 | inline bool HasFile(const google::protobuf::FileDescriptorSet & fset_, const std::string & fname_) 37 | { 38 | for (auto findex = 0; findex < fset_.file_size(); ++findex) { 39 | if (fset_.file(findex).name() == fname_) { 40 | return true; 41 | } 42 | } 43 | return false; 44 | } 45 | 46 | inline bool GetFileDescriptor( 47 | const google::protobuf::Descriptor * desc_, 48 | google::protobuf::FileDescriptorSet & fset_) 49 | { 50 | if (desc_ == nullptr) {return false;} 51 | const google::protobuf::FileDescriptor * fdesc = desc_->file(); 52 | 53 | for (auto dep = 0; dep < fdesc->dependency_count(); ++dep) { 54 | // iterate containing messages 55 | const google::protobuf::FileDescriptor * sfdesc = fdesc->dependency(dep); 56 | 57 | for (auto mtype = 0; mtype < sfdesc->message_type_count(); ++mtype) { 58 | const google::protobuf::Descriptor * desc = sfdesc->message_type(mtype); 59 | GetFileDescriptor(desc, fset_); 60 | } 61 | 62 | // containing enums ? 63 | if (sfdesc->enum_type_count() > 0) { 64 | const google::protobuf::EnumDescriptor * edesc = sfdesc->enum_type(0); 65 | const google::protobuf::FileDescriptor * efdesc = edesc->file(); 66 | 67 | if (!HasFile(fset_, efdesc->name())) { 68 | google::protobuf::FileDescriptorProto * epdesc = fset_.add_file(); 69 | efdesc->CopyTo(epdesc); 70 | } 71 | } 72 | 73 | // containing services ? 74 | if (sfdesc->service_count() > 0) { 75 | const google::protobuf::ServiceDescriptor * svdesc = sfdesc->service(0); 76 | const google::protobuf::FileDescriptor * svfdesc = svdesc->file(); 77 | 78 | if (!HasFile(fset_, svfdesc->name())) { 79 | google::protobuf::FileDescriptorProto * svpdesc = fset_.add_file(); 80 | svfdesc->CopyTo(svpdesc); 81 | } 82 | } 83 | } 84 | 85 | if (HasFile(fset_, fdesc->name())) {return true;} 86 | 87 | google::protobuf::FileDescriptorProto * pdesc = fset_.add_file(); 88 | fdesc->CopyTo(pdesc); 89 | for (auto field = 0; field < desc_->field_count(); ++field) { 90 | const google::protobuf::FieldDescriptor * fddesc = desc_->field(field); 91 | const google::protobuf::Descriptor * desc = fddesc->message_type(); 92 | GetFileDescriptor(desc, fset_); 93 | } 94 | 95 | return true; 96 | } 97 | 98 | template 99 | inline std::string GetProtoMessageDescription() 100 | { 101 | const google::protobuf::Descriptor * desc = T::descriptor(); 102 | google::protobuf::FileDescriptorSet pset; 103 | if (GetFileDescriptor(desc, pset)) { 104 | std::string desc_s = pset.SerializeAsString(); 105 | return desc_s; 106 | } 107 | return ""; 108 | } 109 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/resource/idl__rosidl_typesupport_protobuf_c.hpp.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | // generated from rosidl_typesupport_protobuf_c/resource/idl__rosidl_typesupport_protobuf_c.hpp.em 21 | // with input from @(package_name):@(interface_path) 22 | // generated code does not contain a copyright notice 23 | @ 24 | @####################################################################### 25 | @# EmPy template for generating __rosidl_typesupport_protobuf_c.hpp files 26 | @# 27 | @# Context: 28 | @# - package_name (string) 29 | @# - interface_path (Path relative to the directory named after the package) 30 | @# - content (IdlContent, list of elements, e.g. Messages or Services) 31 | @####################################################################### 32 | @ 33 | #pragma once 34 | 35 | @{ 36 | 37 | include_directives = set() 38 | 39 | ####################################################################### 40 | # Handle message 41 | ####################################################################### 42 | from rosidl_parser.definition import Message 43 | for message in content.get_elements_of_type(Message): 44 | TEMPLATE( 45 | 'msg__rosidl_typesupport_protobuf_c.hpp.em', 46 | package_name=package_name, 47 | interface_path=interface_path, 48 | message=message, 49 | include_directives=include_directives) 50 | 51 | ####################################################################### 52 | # Handle service 53 | ####################################################################### 54 | from rosidl_parser.definition import Service 55 | for service in content.get_elements_of_type(Service): 56 | TEMPLATE( 57 | 'srv__rosidl_typesupport_protobuf_c.hpp.em', 58 | package_name=package_name, 59 | interface_path=interface_path, 60 | service=service, 61 | include_directives=include_directives) 62 | 63 | ####################################################################### 64 | # Handle action 65 | ####################################################################### 66 | from rosidl_parser.definition import Action 67 | for action in content.get_elements_of_type(Action): 68 | TEMPLATE( 69 | 'msg__rosidl_typesupport_protobuf_c.hpp.em', 70 | package_name=package_name, interface_path=interface_path, message=action.goal, 71 | include_directives=include_directives) 72 | TEMPLATE( 73 | 'msg__rosidl_typesupport_protobuf_c.hpp.em', 74 | package_name=package_name, interface_path=interface_path, message=action.result, 75 | include_directives=include_directives) 76 | TEMPLATE( 77 | 'msg__rosidl_typesupport_protobuf_c.hpp.em', 78 | package_name=package_name, interface_path=interface_path, message=action.feedback, 79 | include_directives=include_directives) 80 | TEMPLATE( 81 | 'srv__rosidl_typesupport_protobuf_c.hpp.em', 82 | package_name=package_name, interface_path=interface_path, service=action.send_goal_service, 83 | include_directives=include_directives) 84 | TEMPLATE( 85 | 'srv__rosidl_typesupport_protobuf_c.hpp.em', 86 | package_name=package_name, interface_path=interface_path, service=action.get_result_service, 87 | include_directives=include_directives) 88 | TEMPLATE( 89 | 'msg__rosidl_typesupport_protobuf_c.hpp.em', 90 | package_name=package_name, interface_path=interface_path, message=action.feedback_message, 91 | include_directives=include_directives) 92 | }@ -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/resource/idl__rosidl_typesupport_protobuf_cpp.hpp.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | // generated from rosidl_typesupport_protobuf_cpp/resource/idl__rosidl_typesupport_protobuf_cpp.hpp.em 21 | // with input from @(package_name):@(interface_path) 22 | // generated code does not contain a copyright notice 23 | @ 24 | @####################################################################### 25 | @# EmPy template for generating __rosidl_typesupport_protobuf_cpp.hpp files 26 | @# 27 | @# Context: 28 | @# - package_name (string) 29 | @# - interface_path (Path relative to the directory named after the package) 30 | @# - content (IdlContent, list of elements, e.g. Messages or Services) 31 | @####################################################################### 32 | @ 33 | #pragma once 34 | 35 | @{ 36 | 37 | include_directives = set() 38 | 39 | ####################################################################### 40 | # Handle message 41 | ####################################################################### 42 | from rosidl_parser.definition import Message 43 | for message in content.get_elements_of_type(Message): 44 | TEMPLATE( 45 | 'msg__rosidl_typesupport_protobuf_cpp.hpp.em', 46 | package_name=package_name, 47 | interface_path=interface_path, 48 | message=message, 49 | include_directives=include_directives) 50 | 51 | ####################################################################### 52 | # Handle service 53 | ####################################################################### 54 | from rosidl_parser.definition import Service 55 | for service in content.get_elements_of_type(Service): 56 | TEMPLATE( 57 | 'srv__rosidl_typesupport_protobuf_cpp.hpp.em', 58 | package_name=package_name, 59 | interface_path=interface_path, 60 | service=service, 61 | include_directives=include_directives) 62 | 63 | ####################################################################### 64 | # Handle action 65 | ####################################################################### 66 | from rosidl_parser.definition import Action 67 | for action in content.get_elements_of_type(Action): 68 | TEMPLATE( 69 | 'msg__rosidl_typesupport_protobuf_cpp.hpp.em', 70 | package_name=package_name, interface_path=interface_path, message=action.goal, 71 | include_directives=include_directives) 72 | TEMPLATE( 73 | 'msg__rosidl_typesupport_protobuf_cpp.hpp.em', 74 | package_name=package_name, interface_path=interface_path, message=action.result, 75 | include_directives=include_directives) 76 | TEMPLATE( 77 | 'msg__rosidl_typesupport_protobuf_cpp.hpp.em', 78 | package_name=package_name, interface_path=interface_path, message=action.feedback, 79 | include_directives=include_directives) 80 | TEMPLATE( 81 | 'srv__rosidl_typesupport_protobuf_cpp.hpp.em', 82 | package_name=package_name, interface_path=interface_path, service=action.send_goal_service, 83 | include_directives=include_directives) 84 | TEMPLATE( 85 | 'srv__rosidl_typesupport_protobuf_cpp.hpp.em', 86 | package_name=package_name, interface_path=interface_path, service=action.get_result_service, 87 | include_directives=include_directives) 88 | TEMPLATE( 89 | 'msg__rosidl_typesupport_protobuf_cpp.hpp.em', 90 | package_name=package_name, interface_path=interface_path, message=action.feedback_message, 91 | include_directives=include_directives) 92 | }@ -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ================================= Apache 2.0 ================================= 2 | # 3 | # Copyright (C) 2021 Continental 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # ================================= Apache 2.0 ================================= 18 | cmake_minimum_required(VERSION 3.12) 19 | 20 | project(rosidl_typesupport_protobuf_cpp) 21 | 22 | if(DEFINED ENV{PROTOBUF_STATIC_DISABLE}) 23 | set(PROTOBUF_STATIC_DISABLE $ENV{PROTOBUF_STATIC_DISABLE} 24 | CACHE BOOL "If Protobuf Static should be disabled.") 25 | else() 26 | set(PROTOBUF_STATIC_DISABLE FALSE 27 | CACHE BOOL "If Protobuf Static should be disabled.") 28 | endif() 29 | 30 | if(NOT CMAKE_CXX_STANDARD) 31 | set(CMAKE_CXX_STANDARD 14) 32 | endif() 33 | 34 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 35 | add_compile_options(-Wall -Wextra -Wpedantic) 36 | endif() 37 | 38 | if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") 39 | add_compile_options(/W4) 40 | add_compile_definitions(_CRT_SECURE_NO_WARNINGS) 41 | endif() 42 | 43 | find_package(ament_cmake REQUIRED) 44 | if(PROTOBUF_STATIC_DISABLE) 45 | ament_package() 46 | message(STATUS "Protobuf static typesupport implementation explicitly disabled - skipping '${PROJECT_NAME}'") 47 | return() 48 | endif() 49 | 50 | find_package(ament_cmake_python REQUIRED) 51 | find_package(rosidl_typesupport_protobuf REQUIRED) 52 | find_package(rosidl_generator_c REQUIRED) 53 | find_package(rosidl_runtime_cpp REQUIRED) 54 | 55 | ament_export_dependencies(rmw) 56 | ament_export_dependencies(rcutils) 57 | ament_export_dependencies(rosidl_cmake) 58 | ament_export_dependencies(rosidl_generator_c) 59 | ament_export_dependencies(rosidl_generator_cpp) 60 | ament_export_dependencies(rosidl_typesupport_interface) 61 | ament_export_dependencies(rosidl_typesupport_protobuf) 62 | ament_export_dependencies(rosidl_runtime_cpp) 63 | 64 | ament_python_install_package(${PROJECT_NAME}) 65 | 66 | add_library(${PROJECT_NAME} SHARED 67 | src/identifier.cpp 68 | src/wstring_conversion.cpp) 69 | 70 | if(WIN32) 71 | target_compile_definitions(${PROJECT_NAME} 72 | PRIVATE "ROSIDL_TYPESUPPORT_PROTOBUF_CPP_BUILDING_DLL") 73 | endif() 74 | 75 | target_include_directories(${PROJECT_NAME} PUBLIC 76 | "$" 77 | "$") 78 | 79 | ament_target_dependencies(${PROJECT_NAME} rosidl_typesupport_protobuf rosidl_runtime_cpp) 80 | 81 | ament_export_dependencies(rosidl_runtime_cpp) 82 | 83 | # Export old-style CMake variables 84 | ament_export_include_directories("include/${PROJECT_NAME}") 85 | ament_export_libraries(${PROJECT_NAME}) 86 | 87 | # Export modern CMake targets 88 | ament_export_targets(${PROJECT_NAME}) 89 | 90 | ament_index_register_resource("rosidl_typesupport_cpp") 91 | 92 | if(BUILD_TESTING) 93 | find_package(ament_cmake_gtest REQUIRED) 94 | ament_add_gtest(test_wstring_conversion test/test_wstring_conversion.cpp) 95 | if(TARGET test_wstring_conversion) 96 | target_link_libraries(test_wstring_conversion 97 | ${PROJECT_NAME}) 98 | endif() 99 | endif() 100 | 101 | ament_package(CONFIG_EXTRAS "cmake/rosidl_typesupport_protobuf_cpp-extras.cmake.in") 102 | 103 | install( 104 | PROGRAMS bin/rosidl_typesupport_protobuf_cpp 105 | DESTINATION lib/rosidl_typesupport_protobuf_cpp 106 | ) 107 | 108 | install( 109 | DIRECTORY cmake resource 110 | DESTINATION share/${PROJECT_NAME} 111 | ) 112 | 113 | install( 114 | DIRECTORY include/ 115 | DESTINATION include/${PROJECT_NAME} 116 | ) 117 | 118 | install( 119 | TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME} 120 | ARCHIVE DESTINATION lib 121 | LIBRARY DESTINATION lib 122 | RUNTIME DESTINATION bin 123 | ) 124 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/resource/srv__type_support.cpp.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | @# Included from rosidl_typesupport_protobuf_cpp/resource/idl__type_support.cpp.em 21 | @{ 22 | from rosidl_cmake import convert_camel_case_to_lower_case_underscore 23 | from rosidl_typesupport_protobuf import ros_service_name, ros_service_namespace, ros_service_type 24 | 25 | system_header_files = [] 26 | header_files = [ 27 | 'rosidl_typesupport_protobuf_cpp/identifier.hpp', 28 | 'rosidl_typesupport_protobuf/service_type_support.hpp', 29 | 'rosidl_typesupport_protobuf/service_type_support_decl.hpp' 30 | ] 31 | 32 | service_name = ros_service_name(service) 33 | service_namespace = ros_service_namespace(package_name, interface_path) 34 | service_type = ros_service_type(package_name, interface_path, service) 35 | 36 | }@ 37 | @{ 38 | TEMPLATE( 39 | 'tmpl_include_directories.em', 40 | header_files=header_files, 41 | system_header_files = system_header_files, 42 | include_directives=include_directives 43 | ) 44 | }@ 45 | 46 | @{ 47 | TEMPLATE( 48 | 'msg__type_support.cpp.em', 49 | package_name=package_name, 50 | interface_path=interface_path, 51 | message=service.request_message, 52 | include_directives=include_directives, 53 | forward_declared_types = forward_declared_types) 54 | }@ 55 | @{ 56 | TEMPLATE( 57 | 'msg__type_support.cpp.em', 58 | package_name=package_name, 59 | interface_path=interface_path, 60 | message=service.response_message, 61 | include_directives=include_directives, 62 | forward_declared_types = forward_declared_types) 63 | }@ 64 | 65 | @[for ns in service.namespaced_type.namespaces]@ 66 | namespace @(ns) 67 | { 68 | @[end for]@ 69 | namespace typesupport_protobuf_cpp 70 | { 71 | 72 | static rosidl_typesupport_protobuf::service_type_support_t _@(service_name)__callbacks = { 73 | "@(service_namespace)", 74 | "@(service_name)", 75 | ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_protobuf_cpp, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name)_Request)(), 76 | ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_protobuf_cpp, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name)_Response)(), 77 | }; 78 | 79 | static rosidl_service_type_support_t _@(service.namespaced_type.name)__handle = { 80 | rosidl_typesupport_protobuf_cpp::identifier, 81 | &_@(service_name)__callbacks, 82 | get_service_typesupport_handle_function, 83 | }; 84 | 85 | } // namespace typesupport_protobuf_cpp 86 | @[for ns in reversed(service.namespaced_type.namespaces)]@ 87 | } // namespace @(ns) 88 | @[end for]@ 89 | 90 | namespace rosidl_typesupport_protobuf 91 | { 92 | 93 | template<> 94 | ROSIDL_TYPESUPPORT_PROTOBUF_CPP_EXPORT__@(package_name) 95 | const rosidl_service_type_support_t * 96 | get_service_type_support_handle<@(service_type)>() 97 | { 98 | return &@(service_namespace)::typesupport_protobuf_cpp::_@(service_name)__handle; 99 | } 100 | 101 | } // namespace rosidl_typesupport_protobuf 102 | 103 | #ifdef __cplusplus 104 | extern "C" 105 | { 106 | #endif 107 | 108 | const rosidl_service_type_support_t * 109 | ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_protobuf_cpp, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name))() { 110 | return &@(service_namespace)::typesupport_protobuf_cpp::_@(service_name)__handle; 111 | } 112 | 113 | #ifdef __cplusplus 114 | } 115 | #endif 116 | -------------------------------------------------------------------------------- /rosidl_adapter_proto/cmake/rosidl_adapt_proto_interfaces.cmake: -------------------------------------------------------------------------------- 1 | # ================================= Apache 2.0 ================================= 2 | # 3 | # Copyright (C) 2021 Continental 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # ================================= Apache 2.0 ================================= 18 | 19 | if(POLICY CMP0148) 20 | cmake_policy(SET CMP0148 OLD) 21 | endif() 22 | 23 | find_package(PythonInterp REQUIRED) 24 | if(NOT PYTHON_EXECUTABLE) 25 | message(FATAL_ERROR "Variable 'PYTHON_EXECUTABLE' must not be empty") 26 | endif() 27 | 28 | set(rosidl_adapter_proto_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/rosidl_adapter_proto/${PROJECT_NAME}") 29 | 30 | # Create a list of proto directories 31 | set(_proto_include_dirs "") 32 | foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES}) 33 | set(_proto_dir "${${_pkg_name}_DIR}/../../../share/${_pkg_name}") 34 | normalize_path(_proto_dir "${_proto_dir}") 35 | list(APPEND _proto_include_dirs "${_proto_dir}") 36 | endforeach() 37 | 38 | set(_target_dependencies 39 | "${rosidl_adapter_proto_BIN}" 40 | ${rosidl_adapter_proto_GENERATOR_FILES} 41 | ${rosidl_generate_interfaces_ABS_IDL_FILES} 42 | ${_proto_include_dirs}) 43 | foreach(dep ${_target_dependencies}) 44 | if(NOT EXISTS "${dep}") 45 | message(FATAL_ERROR "Target dependency '${dep}' does not exist") 46 | endif() 47 | endforeach() 48 | 49 | # Write all this to a file to work around command line length limitations on some platforms 50 | set(generator_arguments_file "${CMAKE_CURRENT_BINARY_DIR}/rosidl_adapter_proto__arguments.json") 51 | rosidl_write_generator_arguments( 52 | "${generator_arguments_file}" 53 | PACKAGE_NAME "${PROJECT_NAME}" 54 | IDL_TUPLES "${rosidl_generate_interfaces_IDL_TUPLES}" 55 | OUTPUT_DIR "${rosidl_adapter_proto_OUTPUT_DIR}" 56 | TEMPLATE_DIR "${rosidl_adapter_proto_TEMPLATE_DIR}" 57 | TARGET_DEPENDENCIES ${_target_dependencies} 58 | ADDITIONAL_FILES "${_proto_include_dirs}") 59 | 60 | set(rosidl_adapter_proto_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/rosidl_adapter_proto") 61 | foreach(_abs_idl_file ${rosidl_generate_interfaces_ABS_IDL_FILES}) 62 | get_filename_component(_parent_folder "${_abs_idl_file}" DIRECTORY) 63 | get_filename_component(_parent_folder "${_parent_folder}" NAME) 64 | get_filename_component(_idl_name "${_abs_idl_file}" NAME_WE) 65 | list(APPEND rosidl_adapter_proto_GENERATED_CPP "${rosidl_adapter_proto_OUTPUT_DIR}/${_parent_folder}/${_idl_name}.pb.cc") 66 | list(APPEND rosidl_adapter_proto_GENERATED_H "${rosidl_adapter_proto_OUTPUT_DIR}/${_parent_folder}/${_idl_name}.pb.h") 67 | list(APPEND rosidl_adapter_proto_GENERATED_PROTO "${rosidl_adapter_proto_OUTPUT_DIR}/${_parent_folder}/${_idl_name}.proto") 68 | endforeach() 69 | 70 | add_custom_command( 71 | OUTPUT ${rosidl_adapter_proto_GENERATED_CPP} 72 | ${rosidl_adapter_proto_GENERATED_H} 73 | ${rosidl_adapter_proto_GENERATED_PROTO} 74 | COMMAND "${PYTHON_EXECUTABLE}" 75 | ARGS "${rosidl_adapter_proto_BIN}" 76 | --generator-arguments-file "${generator_arguments_file}" 77 | --protoc-path "${Protobuf_PROTOC_EXECUTABLE}" 78 | DEPENDS ${_target_dependencies} "${PYTHON_EXECUTABLE}" 79 | COMMENT "Generating type support for Protobuf" 80 | VERBATIM 81 | ) 82 | 83 | # generate header to switch between export and import for a specific package 84 | set(rosidl_adapter_proto_VISIBILITY_CONTROL_HEADER 85 | "${rosidl_adapter_proto_OUTPUT_DIR}/rosidl_adapter_proto__visibility_control.h") 86 | string(TOUPPER "${PROJECT_NAME}" PROJECT_NAME_UPPER) 87 | configure_file( 88 | "${rosidl_adapter_proto_TEMPLATE_DIR}/rosidl_adapter_proto__visibility_control.h.in" 89 | "${rosidl_adapter_proto_VISIBILITY_CONTROL_HEADER}" 90 | @ONLY 91 | ) 92 | 93 | install( 94 | DIRECTORY ${rosidl_adapter_proto_OUTPUT_DIR} 95 | DESTINATION "include/${PROJECT_NAME}" 96 | PATTERN "*.h" 97 | ) 98 | 99 | install( 100 | DIRECTORY ${rosidl_adapter_proto_OUTPUT_DIR} 101 | DESTINATION "share/${PROJECT_NAME}" 102 | PATTERN "*.proto" 103 | ) 104 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Protobuf ROS Interface Design 2 | ## Abstract 3 | This project provides the ability to publish and subscribe with Protobuf Datatypes to ROS native publishers and subscribers. So the user could work with the ROS native messages or use the Protobuf Datatypes. 4 | 5 | ## Example Usage 6 | 7 | #### Dependencies 8 | 9 | * Include the type adapter for the Protobuf data type message. 10 | ```cpp 11 | #include "std_msgs/msg/string__typeadapter_protobuf_cpp.hpp" 12 | ``` 13 | #### Publisher Example 14 | ```cpp 15 | publisher_ = this->create_publisher("topic", 10); 16 | ``` 17 | To publish a message, it is only required to specify the protobuf message type to send the topic. 18 | 19 | #### Subscriber Example 20 | ```cpp 21 | subscription2_ = this->create_subscription( 22 | "topic", 10, std::bind(&MinimalSubscriber::topic_callback2, this, _1)); 23 | void topic_callback2(const std_msgs::msg::pb::String & msg) const 24 | { 25 | RCLCPP_INFO(this->get_logger(), "I heard Proto: '%s'", msg.data().c_str()); 26 | } 27 | ``` 28 | To subscribe to the topic the user needs to specify the protobuf message type, and for the callback specify the protobuf message to hear the message received. 29 | 30 | Another path to hear the message is using the ROS types messages: 31 | 32 | ```cpp 33 | subscription_ = this->create_subscription( 34 | "topic", 10, std::bind(&MinimalSubscriber::topic_callback, this, _1)); 35 | void topic_callback(const std_msgs::msg::String & msg) const 36 | { 37 | RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg.data.c_str()); 38 | } 39 | 40 | ``` 41 | 42 | ## Concepts 43 | ## Type Specific Interface 44 | The following diagram shows the system to perform type-specific functions to support .msg and .proto files. 45 | 46 |

47 | 48 |

49 | 50 | The left-hand side of the diagram shows how the .msg files are passed to the specific code generators (using vendors or rosidl_generator). The other side shows how the .proto files are passed to the code generators. Finally, the Type adapter block converter from one type to another (proto to msg, or .msg to proto), see [About-Internal-Interfaces](https://docs.ros.org/en/humble/Concepts/Advanced/About-Internal-Interfaces.html) for more information. 51 | 52 | 53 | ## Specification 54 | #### Type Adapter 55 | To adapt the prototype message to a ROS type, protobuf type support generates a specialization for the proto message. The specialization has the following: 56 | * is_specialized is always set to std::true_type, 57 | * Specify the proto custom type using custom = 58 | * Specify the ROS type using ros_message 59 | * Provide static convert functions with the signatures: 60 | * static void convert_to_ros_message(const custom_type &, ros_message_type &), 61 | * static void convert_to_custom(const ros_message_type &, custom_type &) 62 | 63 | The adapted type is also registered as the default type adapter for the ros type: 64 | 65 | * RCLCPP_USING_CUSTOM_TYPE_AS_ROS_MESSAGE_TYPE( /* proto_type */, /* ros_type */ )); 66 | 67 | The convert function must convert from one type to the other, see [Type Adaptation Feature](https://ros.org/reps/rep-2007.html) for more information. 68 | 69 | For example, the specialization for adapting std_msgs::msg::pb::String to the std_msgs_msg::String ROS message type: 70 | 71 | ```cpp 72 | template<> 73 | struct TypeAdapter<::std_msgs::msg::pb::String, ::std_msgs::msg::String> 74 | { 75 | using is_specialized = std::true_type; 76 | using custom_type = ::std_msgs::msg::pb::String; 77 | using ros_message_type = ::std_msgs::msg::String; 78 | 79 | 80 | static 81 | void 82 | convert_to_ros_message( 83 | const custom_type & source, 84 | ros_message_type & destination) 85 | { 86 | std_msgs::msg::typesupport_protobuf_cpp::convert_to_ros(source, destination); 87 | } 88 | 89 | 90 | static 91 | void 92 | convert_to_custom( 93 | const ros_message_type & source, 94 | custom_type & destination) 95 | { 96 | std_msgs::msg::typesupport_protobuf_cpp::convert_to_proto(source, destination); 97 | } 98 | }; 99 | 100 | 101 | RCLCPP_USING_CUSTOM_TYPE_AS_ROS_MESSAGE_TYPE(::std_msgs::msg::pb::String, ::std_msgs::msg::String)); 102 | ``` 103 | 104 | #### Mapping from IDL -> Protobuf Type: 105 | This adapter also mapping from IDL types to Protobuf type. 106 | [IDL to Protobuf type.](rosidl_adapter_proto/rosidl_adapter_proto/__init__.py) -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/resource/srv__type_support.cpp.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | @# Included from rosidl_typesupport_protobuf_c/resource/idl__type_support.cpp.em 21 | @{ 22 | from rosidl_cmake import convert_camel_case_to_lower_case_underscore 23 | from rosidl_typesupport_protobuf import ros_service_name, ros_service_namespace, ros_service_type 24 | 25 | system_header_files = [] 26 | header_files = [ 27 | 'rmw/error_handling.h', 28 | 'rosidl_typesupport_protobuf_c/identifier.hpp', 29 | 'rosidl_typesupport_protobuf/service_type_support.hpp', 30 | 'rosidl_typesupport_protobuf/service_type_support_decl.hpp', 31 | ] 32 | 33 | service_name = ros_service_name(service) 34 | service_namespace = ros_service_namespace(package_name, interface_path) 35 | service_type = ros_service_type(package_name, interface_path, service) 36 | 37 | }@ 38 | @{ 39 | TEMPLATE( 40 | 'tmpl_include_directories.em', 41 | header_files=header_files, 42 | system_header_files = system_header_files, 43 | include_directives=include_directives 44 | ) 45 | }@ 46 | 47 | @{ 48 | TEMPLATE( 49 | 'msg__type_support.cpp.em', 50 | package_name=package_name, 51 | interface_path=interface_path, 52 | message=service.request_message, 53 | include_directives=include_directives, 54 | forward_declared_types = forward_declared_types) 55 | }@ 56 | @{ 57 | TEMPLATE( 58 | 'msg__type_support.cpp.em', 59 | package_name=package_name, 60 | interface_path=interface_path, 61 | message=service.response_message, 62 | include_directives=include_directives, 63 | forward_declared_types = forward_declared_types) 64 | }@ 65 | 66 | @[for ns in service.namespaced_type.namespaces]@ 67 | namespace @(ns) 68 | { 69 | @[end for]@ 70 | namespace typesupport_protobuf_c 71 | { 72 | 73 | static rosidl_typesupport_protobuf::service_type_support_t _@(service.namespaced_type.name)__callbacks = { 74 | "@(service_namespace.replace("__", "::"))", 75 | "@(service_name)", 76 | ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_protobuf_c, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name)_Request)(), 77 | ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_protobuf_c, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name)_Response)(), 78 | }; 79 | 80 | static rosidl_service_type_support_t _@(service.namespaced_type.name)__handle = { 81 | rosidl_typesupport_protobuf_c::identifier, 82 | &_@(service_name)__callbacks, 83 | get_service_typesupport_handle_function, 84 | }; 85 | 86 | } // namespace typesupport_protobuf_c 87 | @[for ns in reversed(service.namespaced_type.namespaces)]@ 88 | } // namespace @(ns) 89 | @[end for]@ 90 | 91 | namespace rosidl_typesupport_protobuf 92 | { 93 | 94 | template<> 95 | ROSIDL_TYPESUPPORT_PROTOBUF_EXPORT 96 | const rosidl_service_type_support_t * 97 | get_service_type_support_handle<@('::'.join([package_name] + list(interface_path.parents[0].parts) + [service.namespaced_type.name]))>() 98 | { 99 | return &@('::'.join([package_name] + list(interface_path.parents[0].parts)))::typesupport_protobuf_c::_@(service.namespaced_type.name)__handle; 100 | } 101 | 102 | } // namespace rosidl_typesupport_protobuf_c 103 | 104 | #ifdef __cplusplus 105 | extern "C" 106 | { 107 | #endif 108 | 109 | const rosidl_service_type_support_t * 110 | ROSIDL_TYPESUPPORT_INTERFACE__SERVICE_SYMBOL_NAME(rosidl_typesupport_protobuf_c, @(', '.join([package_name] + list(interface_path.parents[0].parts))), @(service.namespaced_type.name))() { 111 | return &@('::'.join([package_name] + list(interface_path.parents[0].parts)))::typesupport_protobuf_c::_@(service.namespaced_type.name)__handle; 112 | } 113 | 114 | #ifdef __cplusplus 115 | } 116 | #endif 117 | -------------------------------------------------------------------------------- /rosidl_adapter_proto/rosidl_adapter_proto/__init__.py: -------------------------------------------------------------------------------- 1 | # ================================= Apache 2.0 ================================= 2 | # 3 | # Copyright (C) 2021 Continental 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # ================================= Apache 2.0 ================================= 18 | 19 | import subprocess 20 | import zlib 21 | 22 | from rosidl_cmake import generate_files 23 | import rosidl_parser.definition as rosidl 24 | 25 | # A postfix for the protobuf package name / the c++ namespace 26 | PROTO_PACKAGE_POSTFIX = 'pb' 27 | 28 | # The rpc-function name for service calls. As ros services can only offer a 29 | # single function, this function gets a static name in the protobuf service 30 | PROTO_SERVICE_CALL_NAME = 'Call' 31 | 32 | # The rpc function name for sending an action goal 33 | PROTO_ACTION_SEND_GOAL_CALL_NAME = 'SendGoal' 34 | 35 | # The rpc function name for retrieving the action result 36 | PROTO_ACTION_GET_RESULT_CALL_NAME = 'GetResult' 37 | 38 | # A Mapping from IDL -> Protobuf type 39 | MSG_TYPE_TO_PROTO = { 40 | 'boolean': 'bool', 41 | 'octet': 'uint32', 42 | 'char': 'uint32', 43 | 'wchar': 'uint32', 44 | 'float': 'float', 45 | 'double': 'double', 46 | 'long double': 'double', 47 | 'uint8': 'uint32', 48 | 'int8': 'int32', 49 | 'uint16': 'uint32', 50 | 'int16': 'int32', 51 | 'uint32': 'fixed32', 52 | 'int32': 'sfixed32', 53 | 'uint64': 'fixed64', 54 | 'int64': 'sfixed64', 55 | 'string': 'string', 56 | 'wstring': 'bytes', 57 | } 58 | 59 | field_val = 0 60 | 61 | 62 | def compute_proto_field_number(variable_name): 63 | # Field number rules (https://developers.google.com/protocol-buffers/docs/ 64 | # proto#assigning_field_numbers) 65 | # 66 | # Smallest: 1 67 | # Largest: 536870911 (= 2^29 - 1) 68 | # 69 | # Reserved Range: 19000 to 19999 (=> 1000 values) 70 | 71 | # Create a 32 bit hash from the variable name 72 | field_number = zlib.crc32(bytearray(variable_name, 'utf8')) 73 | # Reduce to the correct amount of values 74 | field_number = (field_number % (536870911 - 1000)) 75 | # Account for the fact that we must not use 0 76 | field_number += 1 77 | # Account for the fact that we must not use 19000 to 19999 78 | if field_number >= 19000: 79 | field_number += 1000 80 | 81 | return field_number 82 | 83 | 84 | def to_proto_import(namespaced_type): 85 | assert isinstance(namespaced_type, rosidl.NamespacedType) 86 | return '/'.join(namespaced_type.namespaces + [namespaced_type.name]) + '.proto' 87 | 88 | 89 | def collect_proto_imports(rosidl_message): 90 | assert isinstance(rosidl_message, rosidl.Message) 91 | import_set = set() 92 | 93 | for member in rosidl_message.structure.members: 94 | if isinstance(member.type, rosidl.NamespacedType): 95 | namespaced_type = member.type 96 | elif isinstance(member.type, rosidl.AbstractNestedType) \ 97 | and isinstance(member.type.value_type, rosidl.NamespacedType): 98 | namespaced_type = member.type.value_type 99 | else: 100 | continue 101 | 102 | import_set.add(to_proto_import(namespaced_type)) 103 | 104 | return import_set 105 | 106 | 107 | def generate_proto(generator_arguments_file): 108 | mapping = { 109 | 'idl.proto.em': '%s.proto', 110 | } 111 | generate_files(generator_arguments_file, mapping, keep_case=True) 112 | return 0 113 | 114 | 115 | def compile_proto(protoc_path, proto_path_list, cpp_out_dir, proto_files, package_name): 116 | protoc_cmd = [protoc_path] 117 | 118 | for path in proto_path_list: 119 | protoc_cmd.append('--proto_path=' + path) 120 | 121 | protoc_cmd.append( 122 | f'--cpp_out=dllexport_decl=ROSIDL_ADAPTER_PROTO_PUBLIC__{package_name}:{cpp_out_dir}') 123 | protoc_cmd = protoc_cmd + proto_files 124 | 125 | subprocess.check_call(protoc_cmd) 126 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # ================================= Apache 2.0 ================================= 2 | # 3 | # Copyright (C) 2021 Continental 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # ================================= Apache 2.0 ================================= 18 | cmake_minimum_required(VERSION 3.12) 19 | 20 | project(rosidl_typesupport_protobuf_c) 21 | 22 | if(DEFINED ENV{PROTOBUF_STATIC_DISABLE}) 23 | set(PROTOBUF_STATIC_DISABLE $ENV{PROTOBUF_STATIC_DISABLE} 24 | CACHE BOOL "If Protobuf Static should be disabled.") 25 | else() 26 | set(PROTOBUF_STATIC_DISABLE FALSE 27 | CACHE BOOL "If Protobuf Static should be disabled.") 28 | endif() 29 | 30 | # Default to C99 31 | if(NOT CMAKE_C_STANDARD) 32 | set(CMAKE_C_STANDARD 99) 33 | endif() 34 | 35 | # Default to C++14 36 | if(NOT CMAKE_CXX_STANDARD) 37 | set(CMAKE_CXX_STANDARD 14) 38 | endif() 39 | 40 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 41 | add_compile_options(-Wall -Wextra -Wpedantic) 42 | endif() 43 | 44 | if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") 45 | add_compile_options(/W4) 46 | add_compile_definitions(_CRT_SECURE_NO_WARNINGS) 47 | endif() 48 | 49 | find_package(ament_cmake REQUIRED) 50 | 51 | if(PROTOBUF_STATIC_DISABLE) 52 | ament_package() 53 | message(STATUS "protobuf static rmw implementation explicitly disabled - skipping '${PROJECT_NAME}'") 54 | return() 55 | endif() 56 | 57 | find_package(rmw REQUIRED) 58 | find_package(ament_cmake_python REQUIRED) 59 | find_package(rosidl_typesupport_protobuf REQUIRED) 60 | find_package(rosidl_generator_c REQUIRED) 61 | find_package(rosidl_generator_cpp REQUIRED) 62 | find_package(rosidl_runtime_c REQUIRED) 63 | find_package(rosidl_typesupport_introspection_c REQUIRED) 64 | find_package(rosidl_typesupport_introspection_cpp REQUIRED) 65 | 66 | ament_export_dependencies(rmw) 67 | ament_export_dependencies(rosidl_cmake) 68 | ament_export_dependencies(rosidl_generator_c) 69 | ament_export_dependencies(rosidl_generator_cpp) 70 | ament_export_dependencies(rosidl_runtime_c) 71 | ament_export_dependencies(rosidl_typesupport_introspection_c) 72 | ament_export_dependencies(rosidl_typesupport_introspection_cpp) 73 | ament_export_dependencies(rosidl_typesupport_interface) 74 | ament_export_dependencies(rosidl_typesupport_protobuf) 75 | 76 | ament_python_install_package(${PROJECT_NAME}) 77 | 78 | add_library(${PROJECT_NAME} SHARED 79 | src/identifier.cpp 80 | src/wstring_conversion.cpp 81 | src/to_ros_c_string.cpp 82 | ) 83 | if(WIN32) 84 | target_compile_definitions(${PROJECT_NAME} 85 | PRIVATE "ROSIDL_TYPESUPPORT_PROTOBUF_C_BUILDING_DLL") 86 | endif() 87 | 88 | # TODO(tfoote) This needs cpp to build due to 89 | # https://github.com/tfoote/rosidl_typesupport_protobuf/blob/132668ae385163ee8b45ce45a9022654e5c77666/ 90 | # rosidl_typesupport_protobuf_c/resource/msg__rosidl_typesupport_protobuf_c.hpp.em#L30 91 | # This looks like it might want to be cleaned up. 92 | ament_target_dependencies(${PROJECT_NAME} "rosidl_typesupport_protobuf" rosidl_runtime_c rosidl_runtime_cpp) 93 | 94 | target_include_directories(${PROJECT_NAME} PUBLIC 95 | "$" 96 | "$") 97 | 98 | # Export old-style CMake variables 99 | ament_export_include_directories("include/${PROJECT_NAME}") 100 | ament_export_libraries(${PROJECT_NAME}) 101 | 102 | # Export modern CMake targets 103 | ament_export_targets(${PROJECT_NAME}) 104 | 105 | ament_target_dependencies(${PROJECT_NAME} rosidl_typesupport_protobuf) 106 | 107 | ament_index_register_resource("rosidl_typesupport_c") 108 | 109 | if(BUILD_TESTING) 110 | # find_package(ament_lint_auto REQUIRED) 111 | # ament_lint_auto_find_test_dependencies() 112 | find_package(ament_cmake_gtest REQUIRED) 113 | ament_add_gtest(test_wstring_conversion test/test_wstring_conversion.cpp) 114 | if(TARGET test_wstring_conversion) 115 | target_link_libraries(test_wstring_conversion 116 | ${PROJECT_NAME}) 117 | endif() 118 | endif() 119 | 120 | ament_package( 121 | CONFIG_EXTRAS "cmake/rosidl_typesupport_protobuf_c-extras.cmake.in" 122 | ) 123 | 124 | install( 125 | PROGRAMS bin/rosidl_typesupport_protobuf_c 126 | DESTINATION lib/rosidl_typesupport_protobuf_c 127 | ) 128 | 129 | install( 130 | DIRECTORY cmake resource 131 | DESTINATION share/${PROJECT_NAME} 132 | ) 133 | 134 | install( 135 | DIRECTORY include/ 136 | DESTINATION include/${PROJECT_NAME} 137 | ) 138 | 139 | install( 140 | TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME} 141 | ARCHIVE DESTINATION lib 142 | LIBRARY DESTINATION lib 143 | RUNTIME DESTINATION bin 144 | ) -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/resource/idl__type_support.cpp.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | // generated from rosidl_typesupport_protobuf_cpp/resource/idl__type_support.cpp.em 21 | // with input from @(package_name):@(interface_path) 22 | // generated code does not contain a copyright notice 23 | @ 24 | @####################################################################### 25 | @# EmPy template for generating __type_support.cpp files 26 | @# 27 | @# Context: 28 | @# - package_name (string) 29 | @# - interface_path (Path relative to the directory named after the package) 30 | @# - content (IdlContent, list of elements, e.g. Messages or Services) 31 | @####################################################################### 32 | @ 33 | @{ 34 | from rosidl_typesupport_protobuf import typesupport_header, ros_message_header 35 | from rosidl_cmake import convert_camel_case_to_lower_case_underscore 36 | 37 | include_directives = set() 38 | forward_declared_types = set() 39 | 40 | system_header_files = [] 41 | header_files = [ 42 | typesupport_header(package_name, interface_path), 43 | ros_message_header(package_name, interface_path) 44 | ] 45 | }@ 46 | 47 | @{ 48 | TEMPLATE( 49 | 'tmpl_include_directories.em', 50 | header_files=header_files, 51 | system_header_files=system_header_files, 52 | include_directives=include_directives 53 | ) 54 | }@ 55 | 56 | @{ 57 | ####################################################################### 58 | # Handle message 59 | ####################################################################### 60 | from rosidl_parser.definition import Message 61 | for message in content.get_elements_of_type(Message): 62 | TEMPLATE( 63 | 'msg__type_support.cpp.em', 64 | package_name=package_name, 65 | interface_path=interface_path, 66 | message=message, 67 | include_directives=include_directives, 68 | forward_declared_types = forward_declared_types) 69 | 70 | ####################################################################### 71 | # Handle service 72 | ####################################################################### 73 | from rosidl_parser.definition import Service 74 | for service in content.get_elements_of_type(Service): 75 | TEMPLATE( 76 | 'srv__type_support.cpp.em', 77 | package_name=package_name, 78 | interface_path=interface_path, 79 | service=service, 80 | include_directives=include_directives, 81 | forward_declared_types = forward_declared_types) 82 | 83 | ####################################################################### 84 | # Handle action 85 | ####################################################################### 86 | from rosidl_parser.definition import Action 87 | for action in content.get_elements_of_type(Action): 88 | TEMPLATE( 89 | 'msg__type_support.cpp.em', 90 | package_name=package_name, interface_path=interface_path, message=action.goal, 91 | include_directives=include_directives, 92 | forward_declared_types = forward_declared_types) 93 | TEMPLATE( 94 | 'msg__type_support.cpp.em', 95 | package_name=package_name, interface_path=interface_path, message=action.result, 96 | include_directives=include_directives, 97 | forward_declared_types = forward_declared_types) 98 | TEMPLATE( 99 | 'msg__type_support.cpp.em', 100 | package_name=package_name, interface_path=interface_path, message=action.feedback, 101 | include_directives=include_directives, 102 | forward_declared_types = forward_declared_types) 103 | TEMPLATE( 104 | 'srv__type_support.cpp.em', 105 | package_name=package_name, interface_path=interface_path, service=action.send_goal_service, 106 | include_directives=include_directives, 107 | forward_declared_types = forward_declared_types) 108 | TEMPLATE( 109 | 'srv__type_support.cpp.em', 110 | package_name=package_name, interface_path=interface_path, service=action.get_result_service, 111 | include_directives=include_directives, 112 | forward_declared_types = forward_declared_types) 113 | TEMPLATE( 114 | 'msg__type_support.cpp.em', 115 | package_name=package_name, interface_path=interface_path, message=action.feedback_message, 116 | include_directives=include_directives, 117 | forward_declared_types = forward_declared_types) 118 | }@ -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/resource/idl__type_support.cpp.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | // generated from rosidl_typesupport_protobuf_c/resource/idl__type_support.cpp.em 21 | // with input from @(package_name):@(interface_path) 22 | // generated code does not contain a copyright notice 23 | @ 24 | @####################################################################### 25 | @# EmPy template for generating __type_support.cpp files 26 | @# 27 | @# Context: 28 | @# - package_name (string) 29 | @# - interface_path (Path relative to the directory named after the package) 30 | @# - content (IdlContent, list of elements, e.g. Messages or Services) 31 | @####################################################################### 32 | @ 33 | @{ 34 | from rosidl_cmake import convert_camel_case_to_lower_case_underscore 35 | from rosidl_typesupport_protobuf import * 36 | 37 | include_directives = set() 38 | forward_declared_types = set() 39 | 40 | system_header_files = [] 41 | header_files = [ 42 | typesupport_header(package_name, interface_path), 43 | ros_message_header_c(package_name, interface_path), 44 | ros_message_functions_header_c(package_name, interface_path) 45 | ] 46 | 47 | }@ 48 | 49 | @{ 50 | TEMPLATE( 51 | 'tmpl_include_directories.em', 52 | header_files=header_files, 53 | system_header_files=system_header_files, 54 | include_directives=include_directives 55 | ) 56 | }@ 57 | 58 | @{ 59 | 60 | ####################################################################### 61 | # Handle message 62 | ####################################################################### 63 | from rosidl_parser.definition import Message 64 | for message in content.get_elements_of_type(Message): 65 | TEMPLATE( 66 | 'msg__type_support.cpp.em', 67 | package_name=package_name, 68 | interface_path=interface_path, 69 | message=message, 70 | include_directives=include_directives, 71 | forward_declared_types = forward_declared_types) 72 | 73 | ####################################################################### 74 | # Handle service 75 | ####################################################################### 76 | from rosidl_parser.definition import Service 77 | for service in content.get_elements_of_type(Service): 78 | TEMPLATE( 79 | 'srv__type_support.cpp.em', 80 | package_name=package_name, 81 | interface_path=interface_path, 82 | service=service, 83 | include_directives=include_directives, 84 | forward_declared_types = forward_declared_types) 85 | 86 | ####################################################################### 87 | # Handle action 88 | ####################################################################### 89 | from rosidl_parser.definition import Action 90 | for action in content.get_elements_of_type(Action): 91 | TEMPLATE( 92 | 'msg__type_support.cpp.em', 93 | package_name=package_name, interface_path=interface_path, message=action.goal, 94 | include_directives=include_directives, 95 | forward_declared_types = forward_declared_types) 96 | TEMPLATE( 97 | 'msg__type_support.cpp.em', 98 | package_name=package_name, interface_path=interface_path, message=action.result, 99 | include_directives=include_directives, 100 | forward_declared_types = forward_declared_types) 101 | TEMPLATE( 102 | 'msg__type_support.cpp.em', 103 | package_name=package_name, interface_path=interface_path, message=action.feedback, 104 | include_directives=include_directives, 105 | forward_declared_types = forward_declared_types) 106 | TEMPLATE( 107 | 'srv__type_support.cpp.em', 108 | package_name=package_name, interface_path=interface_path, service=action.send_goal_service, 109 | include_directives=include_directives, 110 | forward_declared_types = forward_declared_types) 111 | TEMPLATE( 112 | 'srv__type_support.cpp.em', 113 | package_name=package_name, interface_path=interface_path, service=action.get_result_service, 114 | include_directives=include_directives, 115 | forward_declared_types = forward_declared_types) 116 | TEMPLATE( 117 | 'msg__type_support.cpp.em', 118 | package_name=package_name, interface_path=interface_path, message=action.feedback_message, 119 | include_directives=include_directives, 120 | forward_declared_types = forward_declared_types) 121 | }@ -------------------------------------------------------------------------------- /rosidl_typeadapter_protobuf_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(rosidl_typeadapter_protobuf_test) 4 | 5 | # Default to C++17 6 | if(NOT CMAKE_CXX_STANDARD) 7 | set(CMAKE_CXX_STANDARD 17) 8 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 9 | endif() 10 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 11 | add_compile_options(-Wall -Wextra -Wpedantic) 12 | endif() 13 | if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND MSVC) 14 | # /bigobj is needed to avoid error C1128: 15 | # https://msdn.microsoft.com/en-us/library/8578y171.aspx 16 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj") 17 | endif() 18 | 19 | option(SKIP_SINGLE_RMW_TESTS 20 | "Skip tests involving only a single RMW implementation" OFF) 21 | option(SKIP_MULTI_RMW_TESTS 22 | "Skip tests involving only multiple RMW implementations" OFF) 23 | 24 | find_package(ament_cmake_auto REQUIRED) 25 | ament_auto_find_build_dependencies() 26 | 27 | if(BUILD_TESTING) 28 | find_package(ament_cmake REQUIRED) 29 | find_package(osrf_testing_tools_cpp REQUIRED) 30 | find_package(rcpputils REQUIRED) 31 | find_package(rcl REQUIRED) 32 | find_package(rclcpp REQUIRED) 33 | find_package(test_msgs REQUIRED) 34 | find_package(rosidl_typesupport_protobuf_cpp REQUIRED) 35 | 36 | 37 | include_directories(include) 38 | 39 | ament_index_get_resource(interface_files "rosidl_interfaces" "test_msgs") 40 | string(REPLACE "\n" ";" interface_files "${interface_files}") 41 | 42 | 43 | set(message_files "") 44 | set(service_files "") 45 | set(action_files "") 46 | foreach(interface_file ${interface_files}) 47 | get_filename_component(interface_ns "${interface_file}" DIRECTORY) 48 | get_filename_component(interface_ns "${interface_ns}" NAME) 49 | string_ends_with("${interface_file}" ".msg" is_message) 50 | if(is_message AND interface_ns STREQUAL "msg") 51 | list(APPEND message_files "${interface_file}") 52 | continue() 53 | endif() 54 | string_ends_with("${interface_file}" ".srv" is_service) 55 | if(is_service AND interface_ns STREQUAL "srv") 56 | list(APPEND service_files "${interface_file}") 57 | continue() 58 | endif() 59 | string_ends_with("${interface_file}" ".idl" is_action) 60 | if(is_action AND interface_ns STREQUAL "action") 61 | list(APPEND action_files "${interface_file}") 62 | continue() 63 | endif() 64 | endforeach() 65 | 66 | find_package(ament_lint_auto REQUIRED) 67 | ament_lint_auto_find_test_dependencies() 68 | 69 | # # Provides PYTHON_EXECUTABLE_DEBUG 70 | # find_package(python_cmake_module REQUIRED) 71 | # find_package(PythonExtra REQUIRED) 72 | 73 | # get the rmw implementations ahead of time 74 | find_package(rmw_implementation_cmake REQUIRED) 75 | get_available_rmw_implementations(rmw_implementations2) 76 | foreach(rmw_implementation ${rmw_implementations2}) 77 | find_package("${rmw_implementation}" REQUIRED) 78 | endforeach() 79 | 80 | function(custom_test target with_message_argument) 81 | if(with_message_argument) 82 | # adding test for each message type 83 | foreach(message_file ${message_files}) 84 | get_filename_component(TEST_MESSAGE_TYPE "${message_file}" NAME_WE) 85 | ament_add_test( 86 | "${target}${target_suffix}__${TEST_MESSAGE_TYPE}" 87 | COMMAND "$" "${TEST_MESSAGE_TYPE}" 88 | TIMEOUT 15 89 | GENERATE_RESULT_FOR_RETURN_CODE_ZERO 90 | APPEND_LIBRARY_DIRS "${append_library_dirs}") 91 | set_tests_properties( 92 | "${target}${target_suffix}__${TEST_MESSAGE_TYPE}" 93 | PROPERTIES REQUIRED_FILES "$" 94 | ) 95 | endforeach() 96 | else() 97 | ament_add_test( 98 | "${target}${target_suffix}" 99 | COMMAND "$" 100 | TIMEOUT 15 101 | GENERATE_RESULT_FOR_RETURN_CODE_ZERO 102 | APPEND_LIBRARY_DIRS "${append_library_dirs}") 103 | set_tests_properties( 104 | "${target}${target_suffix}" 105 | PROPERTIES REQUIRED_FILES "$" 106 | ) 107 | endif() 108 | endfunction() 109 | 110 | function(custom_executable target) 111 | add_executable(${target} ${ARGN}) 112 | ament_target_dependencies(${target} 113 | "rclcpp" 114 | "rclcpp_action" 115 | "test_msgs" 116 | ) 117 | endfunction() 118 | 119 | add_library(subscribe_types STATIC 120 | "test/subscribe_array_types.cpp" 121 | "test/subscribe_basic_types.cpp" 122 | "test/subscribe_string_types.cpp") 123 | ament_target_dependencies(subscribe_types 124 | "rclcpp" 125 | "test_msgs") 126 | 127 | # publisher combined with a subscriber 128 | custom_executable(test_proto_typeadapt_cpp 129 | "test/test_proto_typeadapt.cpp") 130 | target_link_libraries(test_proto_typeadapt_cpp subscribe_types rcpputils::rcpputils) 131 | 132 | 133 | set(append_library_dirs "${CMAKE_CURRENT_BINARY_DIR}") 134 | if(WIN32) 135 | set(append_library_dirs "${append_library_dirs}/$") 136 | endif() 137 | 138 | # finding gtest once in the highest scope 139 | # prevents finding it repeatedly in each local scope 140 | ament_find_gtest() 141 | 142 | custom_test(test_proto_typeadapt_cpp TRUE) 143 | 144 | endif() # BUILD_TESTING 145 | 146 | 147 | 148 | ament_auto_package() -------------------------------------------------------------------------------- /rosidl_adapter_proto/resource/msg.proto.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | @{ 21 | import rosidl_parser.definition as rosidl 22 | 23 | from rosidl_adapter_proto import PROTO_PACKAGE_POSTFIX 24 | from rosidl_adapter_proto import MSG_TYPE_TO_PROTO 25 | from rosidl_adapter_proto import compute_proto_field_number 26 | 27 | import sys 28 | import re 29 | 30 | }@ 31 | @# 32 | @# ================ Message definition ================ 33 | @# 34 | @{ 35 | comment = "" 36 | for annotation in message.structure.annotations: 37 | if (annotation.name == "verbatim") \ 38 | and ("language" in annotation.value) \ 39 | and (annotation.value["language"] == "comment") \ 40 | and ("text" in annotation.value): 41 | comment = "//" + re.sub("\n", "\n// ", annotation.value["text"]) 42 | break 43 | }@ 44 | @[if comment != ""]@ 45 | @(comment) 46 | @[end if]@ 47 | message @(message.structure.namespaced_type.name) 48 | { 49 | 50 | @# Message fields 51 | @{ 52 | used_field_numbers = set() 53 | proto_member_list = [] 54 | 55 | str_max_len_type = 0 56 | str_max_len_name = 0 57 | str_max_len_field_number = 0 58 | 59 | for member in message.structure.members: 60 | 61 | idl_type = member.type 62 | 63 | is_repeated = False 64 | is_byte_type = False 65 | is_char_type = False 66 | 67 | # Check if datatype is repeated 68 | if isinstance(idl_type, rosidl.AbstractNestedType): 69 | is_repeated = True 70 | idl_type = idl_type.value_type 71 | 72 | # Check for actual datatype 73 | if isinstance(idl_type, rosidl.BasicType): 74 | proto_type = MSG_TYPE_TO_PROTO[idl_type.typename] 75 | if idl_type.typename in [rosidl.OCTET_TYPE, 'uint8', 'int8']: 76 | is_byte_type = True 77 | elif idl_type.typename in rosidl.CHARACTER_TYPES: 78 | is_char_type = True 79 | elif isinstance(idl_type, rosidl.AbstractString): 80 | proto_type = "string" 81 | elif isinstance(idl_type, rosidl.AbstractWString): 82 | proto_type = "bytes" 83 | elif isinstance(idl_type, rosidl.NamespacedType): 84 | proto_type = ".".join(idl_type.namespaces + [PROTO_PACKAGE_POSTFIX] + [idl_type.name]) 85 | elif isinstance(idl_type, rosidl.NamedType): 86 | proto_type = idl_type.name 87 | 88 | # Check if we can improve the repeated field with a scalar type 89 | if is_repeated: 90 | if is_byte_type: 91 | proto_type = "bytes" 92 | elif is_char_type: 93 | proto_type = "string" 94 | else: 95 | proto_type = "repeated " + proto_type 96 | 97 | # Compute a field number of the actual variable name. This will almost always be unique. 98 | member_name_for_field_number = member.name 99 | additional_counter = 0 100 | 101 | field_number = compute_proto_field_number(member_name_for_field_number) 102 | 103 | while field_number in used_field_numbers: 104 | sys.stderr.write("WARNING: Field " + member.name + " maps to a protobuf field number that is already in use. This will hurt the downward compatibility of this message..\n") 105 | member_name_for_field_number = member.name + str(additional_counter) 106 | field_number = compute_proto_field_number(member_name_for_field_number) 107 | additional_counter += 1 108 | 109 | used_field_numbers.add(field_number) 110 | 111 | member_dict = { 112 | "type": proto_type, 113 | "name": member.name, 114 | "field_number": field_number, 115 | } 116 | 117 | for annotation in member.annotations: 118 | if (annotation.name == "verbatim") \ 119 | and ("language" in annotation.value) \ 120 | and (annotation.value["language"] == "comment") \ 121 | and ("text" in annotation.value): 122 | member_dict["comment"] = " //" + re.sub("\n", "\n //", annotation.value["text"]) 123 | if (annotation.name == "unit") and ("value" in annotation.value): 124 | member_dict["unit"] = annotation.value["value"] 125 | 126 | 127 | proto_member_list.append(member_dict) 128 | 129 | str_max_len_type = max(str_max_len_type, len(proto_type)) 130 | str_max_len_name = max(str_max_len_name, len(member.name)) 131 | str_max_len_field_number = max(str_max_len_field_number, len(str(field_number))) 132 | }@ 133 | @[for proto_member in proto_member_list]@ 134 | @[ if "comment" in proto_member]@ 135 | 136 | @(proto_member["comment"]) 137 | @[ end if]@ 138 | @(str.ljust(proto_member["type"], str_max_len_type)) @(str.ljust(proto_member["name"], str_max_len_name)) = @(str.rjust(str(proto_member["field_number"]), str_max_len_field_number));@ 139 | @[ if "unit" in proto_member]@ 140 | // [@(proto_member["unit"])@]@ 141 | @[ end if] 142 | @[end for]@ 143 | } -------------------------------------------------------------------------------- /rosidl_adapter_proto/resource/idl.proto.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | @{ 21 | from rosidl_adapter_proto import PROTO_PACKAGE_POSTFIX 22 | }@ 23 | // generated from rosidl_adapter_proto/resource/idl.proto.em 24 | // with input from @(package_name):@(interface_path) 25 | // generated code does not contain a copyright notice 26 | 27 | syntax = "proto3"; 28 | 29 | package @('.'.join([package_name] + list(interface_path.parts)[:-1] + [PROTO_PACKAGE_POSTFIX])); 30 | 31 | @{ 32 | ####################################################################### 33 | # Protobuf imports 34 | ####################################################################### 35 | from rosidl_adapter_proto import collect_proto_imports 36 | from rosidl_adapter_proto import to_proto_import 37 | import rosidl_parser.definition as rosidl 38 | 39 | proto_import_set = set() 40 | already_imported = set() 41 | 42 | # Collect imports from plain messages 43 | for message in content.get_elements_of_type(rosidl.Message): 44 | proto_import_set |= collect_proto_imports(message) 45 | 46 | already_imported.add(to_proto_import(message.structure.namespaced_type)) 47 | 48 | # Collect imports from services 49 | for service in content.get_elements_of_type(rosidl.Service): 50 | proto_import_set |= collect_proto_imports(service.request_message) 51 | proto_import_set |= collect_proto_imports(service.response_message) 52 | 53 | already_imported.add(to_proto_import(service.namespaced_type)) 54 | already_imported.add(to_proto_import(service.request_message.structure.namespaced_type)) 55 | already_imported.add(to_proto_import(service.response_message.structure.namespaced_type)) 56 | 57 | # Collect imports from actions 58 | for action in content.get_elements_of_type(rosidl.Action): 59 | proto_import_set |= collect_proto_imports(action.goal) 60 | proto_import_set |= collect_proto_imports(action.send_goal_service.request_message) 61 | proto_import_set |= collect_proto_imports(action.send_goal_service.response_message) 62 | proto_import_set |= collect_proto_imports(action.result) 63 | proto_import_set |= collect_proto_imports(action.get_result_service.request_message) 64 | proto_import_set |= collect_proto_imports(action.get_result_service.response_message) 65 | proto_import_set |= collect_proto_imports(action.feedback) 66 | proto_import_set |= collect_proto_imports(action.feedback_message) 67 | 68 | already_imported.add(to_proto_import(action.namespaced_type)) 69 | already_imported.add(to_proto_import(action.goal.structure.namespaced_type)) 70 | already_imported.add(to_proto_import(action.send_goal_service.request_message.structure.namespaced_type)) 71 | already_imported.add(to_proto_import(action.send_goal_service.response_message.structure.namespaced_type)) 72 | already_imported.add(to_proto_import(action.result.structure.namespaced_type)) 73 | already_imported.add(to_proto_import(action.get_result_service.request_message.structure.namespaced_type)) 74 | already_imported.add(to_proto_import(action.get_result_service.response_message.structure.namespaced_type)) 75 | already_imported.add(to_proto_import(action.feedback.structure.namespaced_type)) 76 | already_imported.add(to_proto_import(action.feedback_message.structure.namespaced_type)) 77 | 78 | for already_imported_proto_file in already_imported: 79 | if already_imported_proto_file in proto_import_set: 80 | proto_import_set.remove(already_imported_proto_file) 81 | }@ 82 | @[for import_proto_file_path in sorted(proto_import_set)]@ 83 | import "@(import_proto_file_path)"; 84 | @[end for]@ 85 | @# 86 | @# Newline after import statements 87 | @# 88 | @[if len(proto_import_set) != 0]@ 89 | 90 | @[end if]@ 91 | @{ 92 | ####################################################################### 93 | # Handle message 94 | ####################################################################### 95 | from rosidl_parser.definition import Message 96 | for message in content.get_elements_of_type(Message): 97 | TEMPLATE( 98 | 'msg.proto.em', 99 | package_name=package_name, 100 | interface_path=interface_path, 101 | message=message, 102 | ) 103 | 104 | ######################################################################## 105 | ## Handle service 106 | ######################################################################## 107 | from rosidl_parser.definition import Service 108 | for service in content.get_elements_of_type(Service): 109 | TEMPLATE( 110 | 'srv.proto.em', 111 | package_name=package_name, 112 | interface_path=interface_path, 113 | service=service, 114 | ) 115 | 116 | ######################################################################## 117 | ## Handle action 118 | ######################################################################## 119 | from rosidl_parser.definition import Action 120 | for action in content.get_elements_of_type(Action): 121 | TEMPLATE( 122 | 'action.proto.em', 123 | package_name=package_name, 124 | interface_path=interface_path, 125 | action=action, 126 | ) 127 | }@ -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf/rosidl_typesupport_protobuf/__init__.py: -------------------------------------------------------------------------------- 1 | # ================================= Apache 2.0 ================================= 2 | # 3 | # Copyright (C) 2021 Continental 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # ================================= Apache 2.0 ================================= 18 | 19 | from rosidl_cmake import convert_camel_case_to_lower_case_underscore 20 | 21 | # A postfix for the protobuf package name / the c++ namespace 22 | PROTO_PACKAGE_POSTFIX = 'pb' 23 | 24 | _TYPE_SUPPORT_NAME = '' 25 | _NAMESPACE_DELIMETER = '' 26 | 27 | 28 | def set_type_support_name(val): 29 | global _TYPE_SUPPORT_NAME 30 | _TYPE_SUPPORT_NAME = val 31 | 32 | 33 | def set_namespace_delimeter(val): 34 | global _NAMESPACE_DELIMETER 35 | _NAMESPACE_DELIMETER = val 36 | 37 | 38 | def typesupport_message_header(package_name, interface_path): 39 | include_parts = [package_name] + list(interface_path.parents[0].parts) 40 | include_parts += [convert_camel_case_to_lower_case_underscore(interface_path.stem)] 41 | include_base = '/'.join(include_parts) 42 | 43 | return f"{include_base}__rosidl_typesupport_protobuf_cpp.hpp" 44 | 45 | def ros_message_header(package_name, interface_path): 46 | include_parts = [package_name] + list(interface_path.parents[0].parts) 47 | include_parts += ['detail'] 48 | include_parts += [convert_camel_case_to_lower_case_underscore(interface_path.stem)] 49 | include_base = '/'.join(include_parts) 50 | 51 | return f'{include_base}__struct.hpp' 52 | 53 | 54 | def ros_message_header_c(package_name, interface_path): 55 | include_parts = [package_name] + list(interface_path.parents[0].parts) 56 | include_parts += ['detail'] 57 | include_parts += [convert_camel_case_to_lower_case_underscore(interface_path.stem)] 58 | include_base = '/'.join(include_parts) 59 | 60 | return f'{include_base}__struct.h' 61 | 62 | 63 | def ros_message_functions_header_c(package_name, interface_path): 64 | include_parts = [package_name] + list(interface_path.parents[0].parts) 65 | include_parts += ['detail'] 66 | include_parts += [convert_camel_case_to_lower_case_underscore(interface_path.stem)] 67 | include_base = '/'.join(include_parts) 68 | 69 | return f'{include_base}__functions.h' 70 | 71 | 72 | def ros_message_functions_header_c_from_namespace(namespace, name): 73 | include_parts = list(namespace) 74 | include_parts += ['detail'] 75 | include_parts += [convert_camel_case_to_lower_case_underscore(name)] 76 | include_base = '/'.join(include_parts) 77 | 78 | return f'{include_base}__functions.h' 79 | 80 | 81 | def protobuf_message_header(package_name, interface_path): 82 | include_parts = [package_name] + list(interface_path.parents[0].parts) 83 | include_prefix = interface_path.stem 84 | 85 | return '/'.join(include_parts + [include_prefix + '.pb.h']) 86 | 87 | 88 | def typesupport_header(package_name, interface_path): 89 | include_parts = [package_name] + list(interface_path.parents[0].parts) + \ 90 | [convert_camel_case_to_lower_case_underscore(interface_path.stem)] 91 | include_base = '/'.join(include_parts) 92 | 93 | return f'{include_base}__{_TYPE_SUPPORT_NAME}.hpp' 94 | 95 | 96 | def visibility_control_header(package_name): 97 | return f'{package_name}/{_TYPE_SUPPORT_NAME}__visibility_control.h' 98 | 99 | 100 | def adapter_visibility_control_header(package_name): 101 | return f'{package_name}/rosidl_adapter_proto__visibility_control.h' 102 | 103 | 104 | def ros_type_namespace(package_name, interface_path): 105 | return _NAMESPACE_DELIMETER.join([package_name] + list(interface_path.parents[0].parts)) 106 | 107 | 108 | def ros_type_name(message): 109 | return message.structure.namespaced_type.name 110 | 111 | 112 | def ros_type(package_name, interface_path, message): 113 | ros_type_ns = ros_type_namespace(package_name, interface_path) 114 | ros_type_nm = ros_type_name(message) 115 | return '::' + _NAMESPACE_DELIMETER.join([ros_type_ns, ros_type_nm]) 116 | 117 | 118 | def ros_type_from_namespaced_type(namespaced_type): 119 | return '::' + _NAMESPACE_DELIMETER.join(namespaced_type.namespaces + [namespaced_type.name]) 120 | 121 | 122 | def ros_type_from_namespaced_type_c(namespaced_type): 123 | return '::' + _NAMESPACE_DELIMETER.join(namespaced_type.namespaces + [namespaced_type.name]) 124 | 125 | 126 | def ros_service_namespace(package_name, interface_path): 127 | return _NAMESPACE_DELIMETER.join([package_name] + list(interface_path.parents[0].parts)) 128 | 129 | 130 | def ros_service_name(service): 131 | return service.namespaced_type.name 132 | 133 | 134 | def ros_service_type(package_name, interface_path, service): 135 | ros_type_ns = ros_service_namespace(package_name, interface_path) 136 | ros_type_nm = ros_service_name(service) 137 | return '::' + _NAMESPACE_DELIMETER.join([ros_type_ns, ros_type_nm]) 138 | 139 | 140 | def protobuf_type(package_name, interface_path, message): 141 | namespace = '::'.join([package_name] + list(interface_path.parents[0].parts)) 142 | return '::' + '::'.join([namespace, PROTO_PACKAGE_POSTFIX, ros_type_name(message)]) 143 | 144 | 145 | def protobuf_type_from_namespaced_type(namespaced_type): 146 | return '::' + '::'.join(namespaced_type.namespaces + 147 | [PROTO_PACKAGE_POSTFIX, namespaced_type.name]) 148 | 149 | 150 | def protobuf_type_from_namespaced_type_c(namespaced_type): 151 | return '::' + '::'.join(namespaced_type.namespaces + 152 | [PROTO_PACKAGE_POSTFIX, namespaced_type.name]) 153 | -------------------------------------------------------------------------------- /rosidl_adapter_proto/test/test_adapter_proto_message.py: -------------------------------------------------------------------------------- 1 | # ================================= Apache 2.0 ================================= 2 | # 3 | # Copyright (C) 2021 Continental 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # ================================= Apache 2.0 ================================= 18 | 19 | import pathlib 20 | 21 | import pytest 22 | 23 | from rosidl_adapter_proto import collect_proto_imports 24 | from rosidl_adapter_proto import compute_proto_field_number 25 | from rosidl_adapter_proto import generate_proto 26 | from rosidl_adapter_proto import MSG_TYPE_TO_PROTO 27 | from rosidl_adapter_proto import to_proto_import 28 | from rosidl_parser.definition import IdlLocator 29 | from rosidl_parser.definition import Message 30 | from rosidl_parser.parser import parse_idl_file 31 | 32 | 33 | MESSAGE_IDL_LOCATOR = IdlLocator(pathlib.Path(__file__).parent, 34 | pathlib.Path('msg') / 'BoolTest.idl') 35 | 36 | 37 | @pytest.fixture(scope='module') 38 | def message_idl_file(): 39 | return parse_idl_file(MESSAGE_IDL_LOCATOR) 40 | 41 | 42 | def search_word(file_path, word): 43 | with open(file_path, 'r') as file: 44 | content = file.read() 45 | if word in content: 46 | return True 47 | return False 48 | 49 | 50 | def get_member_name(message_idl_file): 51 | messages = message_idl_file.content.get_elements_of_type(Message) 52 | member = messages[0].structure.members[0] 53 | return member.name 54 | 55 | 56 | def test_message_proto_generated_invalid_argument(): 57 | with pytest.raises(Exception): 58 | generate_file_argument = IdlLocator( 59 | pathlib.Path(__file__).parent, 60 | pathlib.Path('msg') / 'empty_document.json') 61 | rc = generate_proto(generate_file_argument.get_absolute_path()) 62 | 63 | assert rc is None 64 | 65 | 66 | def test_message_proto_generated_empty_file(): 67 | with pytest.raises(Exception): 68 | generate_file_argument = IdlLocator( 69 | pathlib.Path(__file__).parent, 70 | pathlib.Path('msg') / 'test_rosidl_adapter__empty_args.json') 71 | rc = generate_proto(generate_file_argument.get_absolute_path()) 72 | 73 | assert rc is None 74 | 75 | 76 | def test_message_proto_generated(message_idl_file): 77 | generate_file_argument = IdlLocator( 78 | pathlib.Path(__file__).parent, 79 | pathlib.Path('msg') / 'test_rosid_adapter_proto__arguments.json') 80 | rc = generate_proto(generate_file_argument.get_absolute_path()) 81 | 82 | assert rc is not None 83 | 84 | messages = message_idl_file.content.get_elements_of_type(Message) 85 | member = messages[0].structure.members[0] 86 | field_number = compute_proto_field_number(member.name) 87 | proto_type = MSG_TYPE_TO_PROTO[member.type.typename] 88 | 89 | proto_file_name = IdlLocator( 90 | pathlib.Path(__file__).parent, 91 | pathlib.Path('msg') / 'BoolTest.proto') 92 | 93 | assert search_word(proto_file_name.get_absolute_path(), member.name) is True 94 | assert search_word(proto_file_name.get_absolute_path(), str(field_number)) is True 95 | assert search_word(proto_file_name.get_absolute_path(), proto_type) is True 96 | 97 | 98 | def test_compute_proto_field_number_is_greter_than_0(message_idl_file): 99 | member_name = get_member_name(message_idl_file) 100 | field_number = compute_proto_field_number(member_name) 101 | 102 | assert field_number > 0 103 | 104 | 105 | def test_compute_proto_field_number_is_not_in_the_reserved_range(message_idl_file): 106 | member_name = get_member_name(message_idl_file) 107 | field_number = compute_proto_field_number(member_name) 108 | 109 | assert field_number not in range(19000, 19999) 110 | 111 | 112 | def test_compute_proto_field_number_repeated_with_same_member_name(message_idl_file): 113 | member_name = get_member_name(message_idl_file) 114 | field_number = compute_proto_field_number(member_name) 115 | second_field_number = compute_proto_field_number('data') 116 | 117 | assert field_number == second_field_number 118 | 119 | 120 | def test_msg_type_to_proto_from_message_file(message_idl_file): 121 | messages = message_idl_file.content.get_elements_of_type(Message) 122 | member = messages[0].structure.members[0] 123 | proto_type = MSG_TYPE_TO_PROTO[member.type.typename] 124 | assert proto_type == 'bool' 125 | 126 | 127 | def test_msg_type_to_proto_mapping(): 128 | idl_messages = ['boolean', 'octet', 'char', 'wchar', 'float', 129 | 'double', 'long double', 'uint8', 'int8', 130 | 'uint16', 'int16', 'uint32', 'int32', 'uint64', 131 | 'int64', 'string', 'wstring'] 132 | expected_proto_type_ = ['bool', 'uint32', 'uint32', 'uint32', 133 | 'float', 'double', 'double', 'uint32', 134 | 'int32', 'uint32', 'int32', 'fixed32', 135 | 'sfixed32', 'fixed64', 'sfixed64', 136 | 'string', 'bytes'] 137 | index = 0 138 | for idl_message in idl_messages: 139 | proto_type = MSG_TYPE_TO_PROTO[idl_message] 140 | assert expected_proto_type_[index] == proto_type 141 | index += 1 142 | 143 | 144 | def test_msg_type_to_proto_invalid(): 145 | with pytest.raises(Exception): 146 | MSG_TYPE_TO_PROTO['integer'] 147 | 148 | 149 | def test_to_proto_import(message_idl_file): 150 | messages = message_idl_file.content.get_elements_of_type(Message) 151 | namespace_type = messages[0].structure.namespaced_type 152 | proto_import = to_proto_import(namespace_type) 153 | assert proto_import == 'rosidl_adapter_proto/Bool.proto' 154 | 155 | 156 | def test_to_proto_import_invalid_argument(): 157 | with pytest.raises(Exception): 158 | to_proto_import('invalid argument') 159 | 160 | 161 | def test_collect_proto_import(message_idl_file): 162 | messages = message_idl_file.content.get_elements_of_type(Message) 163 | proto_import_set = set() 164 | for message in messages: 165 | proto_import_set.update(collect_proto_imports(message)) 166 | for proto_file in proto_import_set: 167 | assert proto_file == 'rosidl_adapter_proto/Bool.proto' 168 | 169 | 170 | def test_collect_proto_import_invalid_argument(): 171 | with pytest.raises(Exception): 172 | collect_proto_imports('string value') 173 | -------------------------------------------------------------------------------- /rosidl_typeadapter_protobuf_test/test/test_proto_typeadapt.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2021 Open Source Robotics Foundation, Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "rclcpp/rclcpp.hpp" 21 | 22 | #include "rcpputils/scope_exit.hpp" 23 | 24 | #include "test_msgs/message_fixtures.hpp" 25 | #include "rosidl_typeadapter_protobuf_test/typeadapt_message_fixtures.hpp" 26 | 27 | #include "subscribe_array_types.hpp" 28 | #include "subscribe_basic_types.hpp" 29 | #include "subscribe_string_types.hpp" 30 | 31 | template 32 | void publish( 33 | rclcpp::Node::SharedPtr node, 34 | const std::string & message_type, 35 | std::vector::custom_type>> messages, 36 | size_t number_of_cycles = 100) 37 | { 38 | auto qos = rclcpp::QoS(rclcpp::KeepLast(messages.size())); 39 | 40 | auto publisher = node->create_publisher>( 41 | std::string("test/message/") + message_type, qos); 42 | 43 | try { 44 | rclcpp::WallRate cycle_rate(10); 45 | rclcpp::WallRate message_rate(100); 46 | size_t cycle_index = 0; 47 | // publish all messages up to number_of_cycles times, longer sleep between each cycle 48 | while (rclcpp::ok() && cycle_index < number_of_cycles) { 49 | size_t message_index = 0; 50 | // publish all messages one by one, shorter sleep between each message 51 | while (rclcpp::ok() && message_index < messages.size()) { 52 | printf("publishing message #%zu\n", message_index + 1); 53 | publisher->publish(*messages[message_index]); 54 | ++message_index; 55 | message_rate.sleep(); 56 | } 57 | ++cycle_index; 58 | cycle_rate.sleep(); 59 | } 60 | } catch (const std::exception & ex) { 61 | // It is expected to get into invalid context during the sleep, since rclcpp::shutdown() 62 | // might be called earlier (e.g. by subscribe() routine or when running *AfterShutdown case) 63 | if (ex.what() != std::string("context cannot be slept with because it's invalid")) { 64 | printf("ERROR: got unexpected exception: %s\n", ex.what()); 65 | throw ex; 66 | } 67 | } 68 | } 69 | 70 | int main(int argc, char ** argv) 71 | { 72 | rclcpp::init(argc, argv); 73 | RCPPUTILS_SCOPE_EXIT( 74 | { 75 | rclcpp::shutdown(); 76 | }); 77 | if (argc != 2) { 78 | fprintf(stderr, "Wrong number of arguments, pass one message type\n"); 79 | return 1; 80 | } 81 | 82 | auto start = std::chrono::steady_clock::now(); 83 | 84 | std::string message = argv[1]; 85 | auto node = rclcpp::Node::make_shared(std::string("test_publisher_subscriber_") + message); 86 | 87 | rclcpp::SubscriptionBase::SharedPtr subscriber; 88 | std::vector received_messages; // collect flags about received messages 89 | 90 | auto messages_empty = get_proto_messages_empty(); 91 | auto messages_basic_types = get_proto_messages_basic_types(); 92 | auto messages_arrays = get_proto_messages_arrays(); 93 | auto messages_bounded_plain_sequences = get_proto_messages_bounded_plain_sequences(); 94 | auto messages_bounded_sequences = get_proto_messages_bounded_sequences(); 95 | auto messages_unbounded_sequences = get_proto_messages_unbounded_sequences(); 96 | auto messages_multi_nested = get_proto_messages_multi_nested(); 97 | auto messages_nested = get_proto_messages_nested(); 98 | auto messages_builtins = get_proto_messages_builtins(); 99 | auto messages_constants = get_proto_messages_constants(); 100 | auto messages_defaults = get_proto_messages_defaults(); 101 | auto messages_strings = get_proto_messages_strings(); 102 | auto messages_wstrings = get_proto_messages_wstrings(); 103 | 104 | std::thread spin_thread([node]() { 105 | rclcpp::spin(node); 106 | }); 107 | 108 | 109 | if (message == "Empty") { 110 | subscriber = subscribe_empty(node, message, messages_empty, received_messages); 111 | publish( 112 | node, message, messages_empty); 113 | } else if (message == "BasicTypes") { 114 | subscriber = subscribe_basic_types(node, message, messages_basic_types, received_messages); 115 | publish( 116 | node, message, messages_basic_types); 117 | } else if (message == "Arrays") { 118 | subscriber = subscribe_arrays(node, message, messages_arrays, received_messages); 119 | publish( 120 | node, message, messages_arrays); 121 | } else if (message == "UnboundedSequences") { 122 | subscriber = subscribe_unbounded_sequences( 123 | node, message, messages_unbounded_sequences, received_messages); 124 | publish( 125 | node, message, messages_unbounded_sequences); 126 | } else if (message == "BoundedPlainSequences") { 127 | subscriber = subscribe_bounded_plain_sequences( 128 | node, message, messages_bounded_plain_sequences, received_messages); 129 | publish( 130 | node, message, messages_bounded_plain_sequences); 131 | } else if (message == "BoundedSequences") { 132 | subscriber = subscribe_bounded_sequences( 133 | node, message, messages_bounded_sequences, received_messages); 134 | publish( 135 | node, message, messages_bounded_sequences); 136 | } else if (message == "MultiNested") { 137 | subscriber = subscribe_multi_nested(node, message, messages_multi_nested, received_messages); 138 | publish( 139 | node, message, messages_multi_nested); 140 | } else if (message == "Nested") { 141 | subscriber = subscribe_nested(node, message, messages_nested, received_messages); 142 | publish( 143 | node, message, messages_nested); 144 | } else if (message == "Builtins") { 145 | subscriber = subscribe_builtins(node, message, messages_builtins, received_messages); 146 | publish( 147 | node, message, messages_builtins); 148 | } else if (message == "Constants") { 149 | subscriber = subscribe_constants(node, message, messages_constants, received_messages); 150 | publish( 151 | node, message, messages_constants); 152 | } else if (message == "Defaults") { 153 | subscriber = subscribe_defaults(node, message, messages_defaults, received_messages); 154 | publish( 155 | node, message, messages_defaults); 156 | } else if (message == "Strings") { 157 | subscriber = subscribe_strings(node, message, messages_strings, received_messages); 158 | publish( 159 | node, message, messages_strings); 160 | } else if (message == "WStrings") { 161 | subscriber = subscribe_wstrings(node, message, messages_wstrings, received_messages); 162 | publish( 163 | node, message, messages_wstrings); 164 | } else { 165 | fprintf(stderr, "Unknown message argument '%s'\n", message.c_str()); 166 | return 1; 167 | } 168 | 169 | spin_thread.join(); 170 | 171 | auto end = std::chrono::steady_clock::now(); 172 | std::chrono::duration diff = (end - start); 173 | printf("published and subscribed for %f seconds\n", diff.count()); 174 | 175 | for (auto received : received_messages) { 176 | if (!received) { 177 | return 1; 178 | } 179 | } 180 | 181 | return 0; 182 | } 183 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_c/cmake/rosidl_typesupport_protobuf_c_generate_interfaces.cmake: -------------------------------------------------------------------------------- 1 | # ================================= Apache 2.0 ================================= 2 | # 3 | # Copyright (C) 2021 Continental 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | # ================================= Apache 2.0 ================================= 18 | 19 | find_package(Protobuf REQUIRED) 20 | 21 | find_package(rosidl_adapter_proto REQUIRED) 22 | find_package(rosidl_typesupport_protobuf REQUIRED) 23 | 24 | set(_output_path "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_protobuf_c/${PROJECT_NAME}") 25 | set(_generated_files "") 26 | foreach(_abs_idl_file ${rosidl_generate_interfaces_ABS_IDL_FILES}) 27 | get_filename_component(_parent_folder "${_abs_idl_file}" DIRECTORY) 28 | get_filename_component(_parent_folder "${_parent_folder}" NAME) 29 | get_filename_component(_idl_name "${_abs_idl_file}" NAME_WE) 30 | string_camel_case_to_lower_case_underscore("${_idl_name}" _header_name) 31 | list(APPEND _generated_files 32 | "${_output_path}/${_parent_folder}/${_header_name}__rosidl_typesupport_protobuf_c.hpp" 33 | "${_output_path}/${_parent_folder}/detail/${_header_name}__type_support.cpp" 34 | ) 35 | endforeach() 36 | 37 | set(_dependency_files "") 38 | set(_dependencies "") 39 | foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES}) 40 | foreach(_idl_file ${${_pkg_name}_IDL_FILES}) 41 | set(_abs_idl_file "${${_pkg_name}_DIR}/../${_idl_file}") 42 | normalize_path(_abs_idl_file "${_abs_idl_file}") 43 | list(APPEND _dependency_files "${_abs_idl_file}") 44 | list(APPEND _dependencies "${_pkg_name}:${_abs_idl_file}") 45 | endforeach() 46 | endforeach() 47 | 48 | set(target_dependencies 49 | "${rosidl_typesupport_protobuf_c_BIN}" 50 | ${rosidl_typesupport_protobuf_c_GENERATOR_FILES} 51 | "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}/idl__rosidl_typesupport_protobuf_c.hpp.em" 52 | "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}/idl__type_support.cpp.em" 53 | "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}/msg__rosidl_typesupport_protobuf_c.hpp.em" 54 | "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}/msg__type_support.cpp.em" 55 | "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}/srv__rosidl_typesupport_protobuf_c.hpp.em" 56 | "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}/srv__type_support.cpp.em" 57 | "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}/rosidl_typesupport_protobuf_c__visibility_control.h.in" 58 | ${rosidl_generate_interfaces_ABS_IDL_FILES} 59 | ${_dependency_files} 60 | ) 61 | 62 | set(generator_arguments_file "${CMAKE_CURRENT_BINARY_DIR}/rosidl_typesupport_protobuf_c__arguments.json") 63 | rosidl_write_generator_arguments( 64 | "${generator_arguments_file}" 65 | PACKAGE_NAME "${PROJECT_NAME}" 66 | IDL_TUPLES "${rosidl_generate_interfaces_IDL_TUPLES}" 67 | ROS_INTERFACE_DEPENDENCIES "${_dependencies}" 68 | OUTPUT_DIR "${_output_path}" 69 | TEMPLATE_DIR "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}" 70 | TARGET_DEPENDENCIES ${target_dependencies} 71 | ) 72 | 73 | add_custom_command( 74 | OUTPUT ${_generated_files} 75 | COMMAND ${PYTHON_EXECUTABLE} ${rosidl_typesupport_protobuf_c_BIN} 76 | --generator-arguments-file "${generator_arguments_file}" 77 | DEPENDS ${target_dependencies} 78 | COMMENT "Generating C type support for Protobuf" 79 | VERBATIM 80 | ) 81 | 82 | set(_target_suffix "__rosidl_typesupport_protobuf_c") 83 | 84 | link_directories(${Protobuf_LIBRARY_DIRS}) 85 | 86 | add_library(${rosidl_generate_interfaces_TARGET}${_target_suffix} SHARED 87 | ${_generated_files} 88 | ${rosidl_adapter_proto_GENERATED_CPP} 89 | ) 90 | 91 | if(rosidl_generate_interfaces_LIBRARY_NAME) 92 | set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix} 93 | PROPERTIES OUTPUT_NAME "${rosidl_generate_interfaces_LIBRARY_NAME}${_target_suffix}") 94 | endif() 95 | 96 | set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix} 97 | PROPERTIES CXX_STANDARD 14 98 | ) 99 | 100 | # Set flag for visibility macro 101 | if(WIN32) 102 | target_compile_definitions(${rosidl_generate_interfaces_TARGET}${_target_suffix} 103 | PRIVATE "ROSIDL_TYPESUPPORT_PROTOBUF_BUILDING_DLL" "ROSIDL_TYPESUPPORT_PROTOBUF_C_BUILDING_DLL__${PROJECT_NAME}") 104 | set(Protobuf_USE_STATIC_LIBS TRUE) 105 | endif() 106 | 107 | if(NOT WIN32) 108 | set(_target_compile_flags "-Wall -Wextra -Wpedantic") 109 | else() 110 | set(_target_compile_flags "/W4") 111 | endif() 112 | 113 | string(REPLACE ";" " " _target_compile_flags "${_target_compile_flags}") 114 | set_target_properties(${rosidl_generate_interfaces_TARGET}${_target_suffix} 115 | PROPERTIES COMPILE_FLAGS "${_target_compile_flags}" 116 | ) 117 | 118 | # Include headers from other generators 119 | target_include_directories(${rosidl_generate_interfaces_TARGET}${_target_suffix} 120 | PUBLIC 121 | "$" 122 | "$" 123 | "$" 124 | "$" 125 | "$" 126 | ) 127 | 128 | 129 | ament_target_dependencies(${rosidl_generate_interfaces_TARGET}${_target_suffix} 130 | rmw 131 | rosidl_typesupport_protobuf 132 | rosidl_typesupport_protobuf_c 133 | rosidl_typesupport_interface 134 | ) 135 | 136 | 137 | # generate header to switch between export and import for a specific package 138 | set(_visibility_control_file 139 | "${_output_path}/rosidl_typesupport_protobuf_c__visibility_control.h") 140 | string(TOUPPER "${PROJECT_NAME}" PROJECT_NAME_UPPER) 141 | configure_file( 142 | "${rosidl_typesupport_protobuf_c_TEMPLATE_DIR}/rosidl_typesupport_protobuf_c__visibility_control.h.in" 143 | "${_visibility_control_file}" 144 | @ONLY 145 | ) 146 | 147 | # Depend on dependencies 148 | foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES}) 149 | ament_target_dependencies(${rosidl_generate_interfaces_TARGET}${_target_suffix} 150 | ${_pkg_name}) 151 | target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix} 152 | ${${_pkg_name}_LIBRARIES${_target_suffix}}) 153 | endforeach() 154 | 155 | target_link_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix} 156 | ${Protobuf_LIBRARY} 157 | ) 158 | 159 | add_dependencies( 160 | ${rosidl_generate_interfaces_TARGET}${_target_suffix} 161 | ${rosidl_generate_interfaces_TARGET}__rosidl_generator_c 162 | ${rosidl_generate_interfaces_TARGET}__rosidl_generator_cpp 163 | ) 164 | 165 | if(NOT rosidl_generate_interfaces_SKIP_INSTALL) 166 | install( 167 | DIRECTORY "${_output_path}/" 168 | DESTINATION "include/${PROJECT_NAME}/${PROJECT_NAME}" 169 | PATTERN "*.cpp" EXCLUDE 170 | ) 171 | 172 | if(NOT _generated_files STREQUAL "") 173 | ament_export_include_directories("include/${PROJECT_NAME}") 174 | endif() 175 | 176 | # Export old-style CMake variables 177 | ament_export_include_directories("include/${PROJECT_NAME}") 178 | rosidl_export_typesupport_libraries(${_target_suffix} 179 | ${rosidl_generate_interfaces_TARGET}${_target_suffix}) 180 | 181 | # Export modern CMake targets 182 | ament_export_targets(export_${rosidl_generate_interfaces_TARGET}${_target_suffix}) 183 | rosidl_export_typesupport_targets(${_target_suffix} 184 | ${rosidl_generate_interfaces_TARGET}${_target_suffix}) 185 | 186 | install( 187 | TARGETS ${rosidl_generate_interfaces_TARGET}${_target_suffix} 188 | EXPORT export_${rosidl_generate_interfaces_TARGET}${_target_suffix} 189 | ARCHIVE DESTINATION lib 190 | LIBRARY DESTINATION lib 191 | RUNTIME DESTINATION bin 192 | ) 193 | 194 | rosidl_export_typesupport_libraries(${_target_suffix} 195 | ${rosidl_generate_interfaces_TARGET}${_target_suffix}) 196 | 197 | ament_export_libraries(${rosidl_generate_interfaces_TARGET}${_target_suffix}) 198 | endif() 199 | -------------------------------------------------------------------------------- /rosidl_typesupport_protobuf_cpp/resource/msg__type_support.cpp.em: -------------------------------------------------------------------------------- 1 | @{ 2 | # ================================= Apache 2.0 ================================= 3 | # 4 | # Copyright (C) 2021 Continental 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | # ================================= Apache 2.0 ================================= 19 | }@ 20 | @# Included from rosidl_typesupport_protobuf_cpp/resource/idl__type_support.cpp.em 21 | @{ 22 | import rosidl_parser.parser as rosidl 23 | from rosidl_parser.definition import * 24 | from rosidl_typesupport_protobuf import * 25 | 26 | ros_type_ns = ros_type_namespace(package_name, interface_path) 27 | ros_type_name = ros_type_name(message) 28 | ros_type = ros_type(package_name, interface_path, message) 29 | proto_type = protobuf_type(package_name, interface_path, message) 30 | 31 | system_header_files = [ 32 | 'string', 33 | 'algorithm' 34 | ] 35 | 36 | header_files = [ 37 | 'rosidl_typesupport_cpp/message_type_support.hpp', 38 | 'rosidl_typesupport_protobuf_cpp/identifier.hpp', 39 | 'rosidl_typesupport_protobuf_cpp/wstring_conversion.hpp', 40 | 'rosidl_typesupport_protobuf/message_type_support.hpp', 41 | 'rosidl_typesupport_protobuf/message_type_support_decl.hpp', 42 | 'rosidl_typesupport_protobuf/proto_descriptor_helper.hpp', 43 | visibility_control_header(package_name), 44 | protobuf_message_header(package_name, interface_path) 45 | ] 46 | }@ 47 | @{ 48 | TEMPLATE( 49 | 'tmpl_include_directories.em', 50 | header_files=header_files, 51 | system_header_files=system_header_files, 52 | include_directives=include_directives 53 | ) 54 | }@ 55 | 56 | @{ 57 | TEMPLATE( 58 | 'tmpl_forward_declarations.em', 59 | message=message, 60 | forward_declared_types=forward_declared_types 61 | ) 62 | }@ 63 | @[ for ns in message.structure.namespaced_type.namespaces]@ 64 | namespace @(ns) 65 | { 66 | @[ end for]@ 67 | namespace typesupport_protobuf_cpp 68 | { 69 | 70 | ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@(package_name) 71 | bool convert_to_proto(const @(ros_type) &ros_msg, @(proto_type) &pb_msg) 72 | { 73 | @[for member in message.structure.members]@ 74 | // Member: @(member.name) 75 | @[ if isinstance(member.type, AbstractNestedType)]@ 76 | @[ if isinstance(member.type.value_type, BasicType) or isinstance(member.type.value_type, AbstractString)]@ 77 | *pb_msg.mutable_@(member.name)() = { ros_msg.@(member.name).begin(), ros_msg.@(member.name).end() }; 78 | @[ elif isinstance(member.type.value_type, AbstractWString)]@ 79 | for(auto &member : ros_msg.@(member.name)) 80 | { 81 | ::rosidl_typesupport_protobuf_cpp::write_to_string(member, *pb_msg.add_@(member.name)()); 82 | } 83 | @[ elif isinstance(member.type.value_type, NamespacedType)]@ 84 | for(auto &member : ros_msg.@(member.name)) 85 | { 86 | auto ptr{pb_msg.add_@(member.name)()}; 87 | @("::" + "::".join(member.type.value_type.namespaces))::typesupport_protobuf_cpp::convert_to_proto(member, *ptr); 88 | } 89 | @[ end if]@ 90 | @[ elif isinstance(member.type, BasicType) or isinstance(member.type, AbstractString)]@ 91 | pb_msg.set_@(member.name)(ros_msg.@(member.name)); 92 | @[ elif isinstance(member.type, BasicType) or isinstance(member.type, AbstractWString)]@ 93 | ::rosidl_typesupport_protobuf_cpp::write_to_string(ros_msg.@(member.name), *pb_msg.mutable_@(member.name)()); 94 | @[ elif isinstance(member.type, NamespacedType)]@ 95 | @("::" + "::".join(member.type.namespaces))::typesupport_protobuf_cpp::convert_to_proto(ros_msg.@(member.name), *pb_msg.mutable_@(member.name)()); 96 | @[ end if]@ 97 | @[end for]@ 98 | 99 | return true; 100 | } 101 | 102 | ROSIDL_TYPESUPPORT_PROTOBUF_CPP_PUBLIC__@(package_name) 103 | bool convert_to_ros(const @(proto_type) &pb_msg, @(ros_type) &ros_msg) 104 | { 105 | @[for member in message.structure.members]@ 106 | // Member: @(member.name) 107 | @[ if isinstance(member.type, AbstractNestedType)]@ 108 | @[ if isinstance(member.type.value_type, BasicType) or isinstance(member.type.value_type, AbstractString)]@ 109 | @[ if isinstance(member.type, Array)]@ 110 | std::copy_n(pb_msg.@(member.name)().begin(), pb_msg.@(member.name)().size(), ros_msg.@(member.name).begin()); 111 | @[ else]@ 112 | @[ if isinstance(member.type.value_type, BasicType) and member.type.value_type.typename == BOOLEAN_TYPE]@ 113 | for(auto val : pb_msg.@(member.name)()) 114 | { 115 | ros_msg.@(member.name).push_back(val); 116 | } 117 | @[ else]@ 118 | ros_msg.@(member.name) = { pb_msg.@(member.name)().begin(), pb_msg.@(member.name)().end() }; 119 | @[ end if]@ 120 | @[ end if]@ 121 | @[ elif isinstance(member.type.value_type, AbstractWString)]@ 122 | { 123 | @[ if not isinstance(member.type, Array)]@ 124 | auto size{pb_msg.@(member.name)_size()}; 125 | ros_msg.@(member.name).resize(size); 126 | 127 | @[ end if]@ 128 | auto& data{pb_msg.@(member.name)()}; 129 | auto& ros_data{ros_msg.@(member.name)}; 130 | int i{0}; 131 | for(auto &str : data) 132 | { 133 | ::rosidl_typesupport_protobuf_cpp::write_to_u16string(str, ros_data[i]); 134 | i++; 135 | } 136 | } 137 | @[ elif isinstance(member.type.value_type, NamespacedType)]@ 138 | { 139 | @[ if not isinstance(member.type, Array)]@ 140 | auto size{pb_msg.@(member.name)_size()}; 141 | ros_msg.@(member.name).resize(size); 142 | 143 | @[ end if]@ 144 | auto& data{pb_msg.@(member.name)()}; 145 | auto& ros_data{ros_msg.@(member.name)}; 146 | int i{0}; 147 | for(auto &member : data) 148 | { 149 | @("::" + "::".join(member.type.value_type.namespaces))::typesupport_protobuf_cpp::convert_to_ros(member, ros_data[i]); 150 | i++; 151 | } 152 | } 153 | @[ end if]@ 154 | @[ elif isinstance(member.type, BasicType) or isinstance(member.type, AbstractString)]@ 155 | ros_msg.@(member.name) = pb_msg.@(member.name)(); 156 | @[ elif isinstance(member.type, BasicType) or isinstance(member.type, AbstractWString)]@ 157 | ::rosidl_typesupport_protobuf_cpp::write_to_u16string(pb_msg.@(member.name)(), ros_msg.@(member.name)); 158 | @[ elif isinstance(member.type, NamespacedType)]@ 159 | @("::" + "::".join(member.type.namespaces))::typesupport_protobuf_cpp::convert_to_ros(pb_msg.@(member.name)(), ros_msg.@(member.name)); 160 | @[ end if]@ 161 | @[end for]@ 162 | 163 | return true; 164 | } 165 | 166 | static bool _@(ros_type_name)__serialize(const void *untyped_ros_msg, std::string &serialized_msg) 167 | { 168 | @(proto_type) pb_msg{}; 169 | auto ros_msg{static_cast(untyped_ros_msg)}; 170 | 171 | convert_to_proto(*ros_msg, pb_msg); 172 | return pb_msg.SerializeToString(&serialized_msg); 173 | } 174 | 175 | static bool _@(ros_type_name)__deserialize(void *untyped_ros_msg, const void *serialized_msg, size_t size) 176 | { 177 | @(proto_type) pb_msg{}; 178 | auto ros_msg{static_cast<@(ros_type) *>(untyped_ros_msg)}; 179 | 180 | pb_msg.ParseFromArray(serialized_msg, size); 181 | return convert_to_ros(pb_msg, *ros_msg); 182 | } 183 | 184 | static std::string _@(ros_type_name)__get_descriptor() 185 | { 186 | return ""; 187 | return GetProtoMessageDescription<@(proto_type)>(); 188 | } 189 | 190 | @{type_support_name = "_" + ros_type_name + "__type_support"}@ 191 | static rosidl_typesupport_protobuf::message_type_support_t @(type_support_name) = { 192 | "@(ros_type_ns)", 193 | "@(ros_type_name)", 194 | _@(ros_type_name)__serialize, 195 | _@(ros_type_name)__deserialize, 196 | _@(ros_type_name)__get_descriptor 197 | }; 198 | 199 | @{ 200 | handle_name = "_" + ros_type_name + "__handle" 201 | namespaced_handle_name = "::".join([ros_type_ns, "typesupport_protobuf_cpp", handle_name]) 202 | }@ 203 | static rosidl_message_type_support_t @(handle_name) = { 204 | rosidl_typesupport_protobuf_cpp::identifier, 205 | &@(type_support_name), 206 | get_message_typesupport_handle_function 207 | }; 208 | 209 | } // namespace typesupport_protobuf_cpp 210 | @[ for ns in reversed(message.structure.namespaced_type.namespaces)]@ 211 | } // namespace @(ns) 212 | @[ end for]@ 213 | 214 | namespace rosidl_typesupport_protobuf 215 | { 216 | 217 | template<> 218 | ROSIDL_TYPESUPPORT_PROTOBUF_CPP_EXPORT__@(package_name) 219 | const rosidl_message_type_support_t *get_message_type_support_handle<@(ros_type)>() 220 | { 221 | return &@(namespaced_handle_name); 222 | } 223 | 224 | } // namespace rosidl_typesupport_protobuf 225 | 226 | #ifdef __cplusplus 227 | extern "C" 228 | { 229 | #endif 230 | 231 | const rosidl_message_type_support_t * 232 | ROSIDL_TYPESUPPORT_INTERFACE__MESSAGE_SYMBOL_NAME(rosidl_typesupport_protobuf_cpp, @(ros_type_ns.replace("::", ", ")), @(ros_type_name))() { 233 | return &@(namespaced_handle_name); 234 | } 235 | 236 | #ifdef __cplusplus 237 | } 238 | #endif 239 | --------------------------------------------------------------------------------