Use ros1 under ros2_ Bridge and ros1 custom message bridge
-
Sample environment
Operating system: ubuntu 20.04 amd64
ros version: noetic
ros2 version: foxy
-
ros1 sample code
-
Create workspace catkin for ros1_ WS, function pack custom_msgs and create an MSG file testnoetic msg
TestNoetic. The contents of the MSG file are as follows:
string test_str1 int32 test_int1
Compile the function package. Since you are familiar with ros1, we will not introduce the details of ros1 compilation here;
-
Create ros2 workspace colcon_ws, function pack custom_msgs and create an MSG file testfoxy msg
ros2 create package instruction:
ros2 pkg create --build-type ament_cmake custom_msgs
TestFoxy. The contents of the MSG file are as follows:
string test_str2 int32 test_int2
Note: the naming of the msg file of ros2 has the rule of regular expression. It should start with a capital letter. Each variable in the file content cannot have a capital letter. For more detailed rules, please refer to the official document
-
Since the file name of the message to be bridged in the example is different from the internal variable name, you need to define the mapping file mapping_rules.yaml
- ros1_package_name: 'custom_msgs' ros1_message_name: 'TestNoetic' ros2_package_name: 'custom_msgs' ros2_message_name: 'TestFoxy' fields_1_to_2: test_str1: 'test_str2' test_int1: 'test_int2'
This mapping file is placed in package XML directory at the same level. This file only needs to be given when the two package names or msg names or variable names are different. If the names are the same, they can be omitted. If this file exists, cmakelists Txt as follows:
cmake_minimum_required(VERSION 3.5) project(custom_msgs) # Default to C++14 if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 14) endif() if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wall -Wextra -Wpedantic) endif() find_package(ament_cmake REQUIRED) find_package(builtin_interfaces REQUIRED) find_package(rosidl_default_generators REQUIRED) rosidl_generate_interfaces(custom_msgs msg/TestFoxy.msg DEPENDENCIES builtin_interfaces ) install(FILES mapping_rules.yaml DESTINATION share/${PROJECT_NAME} ) ament_export_dependencies(rosidl_default_runtime) ament_package()
package. The XML is as follows:
<?xml version="1.0"?> <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> <package format="3"> <name>custom_msgs</name> <version>0.0.0</version> <description>The custom_msgs package</description> <maintainer email="weibw@todo.todo">weibw</maintainer> <license>TODO</license> <depend>rclpy</depend> <depend>builtin_interfaces</depend> <depend>rosidl_default_generators</depend> <member_of_group>rosidl_interface_packages</member_of_group> <export> <build_type>ament_cmake</build_type> <ros1_bridge mapping_rules="mapping_rules.yaml"/> </export> </package>
-
Compile custom under ros2_ Msgs Feature Pack
source /opt/ros/foxy/setup.bash cd colcon_ws colcon build --packages-select custom_msgs
-
Download ros1_bridge source code, because we want to bridge custom messages, so ros1_bridge must be recompiled
Download the source code to github and put it in colcon_ In WS workspace
source /opt/ros/noetic/setup.bash source /opt/ros/foxy/setup.bash source catkin_ws/devel/setup.bash source colcon/install/setup.bash cd colcon_ws colcon build --packages-select ros1_bridge --cmake-force-configure
After compilation, enter the following command line:
source colcon/install/setup.bash ros2 run ros1_bridge dynamic_bridge --print-pairs | grep custom_msgs
If displayed:
- 'custom_msgs/msg/TestFoxy' (ROS 2) <=> 'custom_msgs/TestNoetic' (ROS 1)
It means that the bridge data conversion is successful
-
After compiling, create a ros2 software package bridge for testing_ Test, write a simple subscriber to listen to the topic and verify whether the bridge is successful
ros2 pkg create --build-type ament_cmake bridge_test --dependencies custom_msgs
-
Create test CPP, as follows
#include <memory> #include "rclcpp/rclcpp.hpp" #include "custom_msgs/msg/test_foxy.hpp" using std::placeholders::_1; class MinimalSubscriber : public rclcpp::Node { public: MinimalSubscriber() : Node("minimal_subscriber") { subscription_ = this->create_subscription<custom_msgs::msg::TestFoxy>( "topic", 10, std::bind(&MinimalSubscriber::topic_callback, this, _1)); } private: void topic_callback(const custom_msgs::msg::TestFoxy::SharedPtr msg) const { RCLCPP_INFO(this->get_logger(), "I heard custom_msgs::msg::TestFoxy : '%d'", msg->test_int); } rclcpp::Subscription<custom_msgs::msg::TestFoxy>::SharedPtr subscription_; }; int main(int argc, char * argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared<MinimalSubscriber>()); rclcpp::shutdown(); return 0; }
-
CMakelists.txt as follows
cmake_minimum_required(VERSION 3.5) project(bridge_test) # Default to C99 if(NOT CMAKE_C_STANDARD) set(CMAKE_C_STANDARD 99) endif() # Default to C++14 if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 14) endif() if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wall -Wextra -Wpedantic) endif() # find dependencies find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) find_package(custom_msgs REQUIRED) add_executable(subscriber src/test.cpp) ament_target_dependencies(subscriber rclcpp custom_msgs) install(TARGETS subscriber DESTINATION lib/${PROJECT_NAME}) ament_package()
-
package. The XML is as follows
<?xml version="1.0"?> <?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?> <package format="3"> <name>bridge_test</name> <version>0.0.0</version> <description>TODO: Package description</description> <maintainer email="weibw@todo.todo">weibw</maintainer> <license>TODO: License declaration</license> <buildtool_depend>ament_cmake</buildtool_depend> <depend>rclcpp</depend> <depend>custom_msgs</depend> <test_depend>ament_lint_auto</test_depend> <test_depend>ament_lint_common</test_depend> <export> <build_type>ament_cmake</build_type> </export> </package>
-
Compile function pack
cd colcon_ws colcon build --packages-select bridge_test
-
-
Verify the success of bridging custom messages
-
In the ros1 environment, use the command line tool to broadcast topic data at a fixed frequency
source /opt/ros/noetic/setup.bash source catkin_ws/devel/setup.bash roscore& rostopic pub topic custom_msgs/TestNoetic "test_str1: 'hello' test_int: 234" -r 2
-
Running subscription node in ros2 environment
source /opt/ros/foxy/setup.bash source colcon_ws/install/setup.bash ros2 run bridge_test subscriber
-
Run ros1_bridge
source /opt/ros/noetic/setup.bash source /opt/ros/foxy/setup.bash source catkin_ws/devel/setup.bash source colcon/install/setup.bash ros2 run ros1_bridge dynamic_bridge
At this time, you should see the following print in the subscription node terminal of ros2:
[INFO] [1645162912.958789169] [minimal_subscriber]: I heard custom_msgs::msg::TestFoxy : '234'
So far, this article ends
-
-