-
创建ros1的工作空间catkin_ws,功能包custom_msgs,并创建一个msg文件TestNoetic.msg
TestNoetic.msg文件内容如下:
string test_str1
int32 test_int1
编译功能包,由于大家对ros1很熟悉了,所以此处不在介绍ros1编译的细节;
-
创建ros2的工作空间colcon_ws,功能包custom_msgs,并创建一个msg文件TestFoxy.msg
ros2创建包指令:
ros2 pkg create --build-type ament_cmake custom_msgs
TestFoxy.msg文件内容如下:
string test_str2
int32 test_int2
注意事项:ros2的msg文件命名有正则表达式的规定,要以大写字母开头,文件内容中的每个变量不可以存在大写字母,更详细的规则请参考官方文档
-
由于示例中要桥接的消息的文件名和内部变量名不一样,所以需要定义映射文件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'
此映射文件放在package.xml同级目录下即可,此文件中只需要在两个包名或msg名或者变量名不相同时给出,如果名称都相同可以省略,如果存在此文件,则CMakeLists.txt如下:
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.xml如下:
<?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>
-
编译ros2下的custom_msgs功能包
source /opt/ros/foxy/setup.bash
cd colcon_ws
colcon build --packages-select custom_msgs
-
下载ros1_bridge源码,由于我们要桥接自定义消息,所以ros1_bridge必须重新编译
源码到github自行下载,放到colcon_ws工作空间中
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
编译完成后命令行输入:
source colcon/install/setup.bash
ros2 run ros1_bridge dynamic_bridge --print-pairs | grep custom_msgs
如果显示:
- 'custom_msgs/msg/TestFoxy' (ROS 2) <=> 'custom_msgs/TestNoetic' (ROS 1)
则代表桥接数据转换成功
-
编译通过后再创建一个测试用的ros2软件包bridge_test,编写一个简单的订阅器来监听话题,验证桥接是否成功
ros2 pkg create --build-type ament_cmake bridge_test --dependencies custom_msgs
创建test.cpp,内容如下
#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如下
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.xml如下
<?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>
编译功能包
cd colcon_ws
colcon build --packages-select bridge_test
-
验证桥接自定义消息是否成功
在ros1环境下使用命令行工具以固定频率向外广播话题数据
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
在ros2环境下运行订阅节点
source /opt/ros/foxy/setup.bash
source colcon_ws/install/setup.bash
ros2 run bridge_test subscriber
运行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
此时应该在ros2的订阅节点终端中看到如下打印:
[INFO] [1645162912.958789169] [minimal_subscriber]: I heard custom_msgs::msg::TestFoxy : '234'
至此,本文结束