在ros2下使用ros1_bridge与ros1自定义消息桥接

2023-11-13

在ros2下使用ros1_bridge与ros1自定义消息桥接

示例环境

操作系统:ubuntu 20.04 amd64

ros版本:noetic

ros2版本:foxy

ros1示例代码

  1. 创建ros1的工作空间catkin_ws,功能包custom_msgs,并创建一个msg文件TestNoetic.msg

    TestNoetic.msg文件内容如下:

    string test_str1
    int32 test_int1
    

    编译功能包,由于大家对ros1很熟悉了,所以此处不在介绍ros1编译的细节;

  2. 创建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文件命名有正则表达式的规定,要以大写字母开头,文件内容中的每个变量不可以存在大写字母,更详细的规则请参考官方文档

  3. 由于示例中要桥接的消息的文件名和内部变量名不一样,所以需要定义映射文件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>
    
  4. 编译ros2下的custom_msgs功能包

    source /opt/ros/foxy/setup.bash
    cd colcon_ws
    colcon build --packages-select custom_msgs
    
  5. 下载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)
    

    则代表桥接数据转换成功

  6. 编译通过后再创建一个测试用的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
    
  7. 验证桥接自定义消息是否成功

    在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'
    

    至此,本文结束

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在ros2下使用ros1_bridge与ros1自定义消息桥接 的相关文章

  • MDI应用程序中父窗体的问题

    我使用按钮作为容器中的控件 父窗体 当子窗体出现时 父窗体中的控件 按钮 图片 标签 出现在子窗体上并将其覆盖 我看不到子窗体 有谁知道如何防止这种情况 我不想将这些控件设置为 Control Visible false 因为当我最小化子表
  • 如何使用 json 谷歌翻译 api?

    我正在尝试使用来自 python 的 google 翻译和 utf 8 文本 如何调用json api 他们有一个将其嵌入 html 的文档 但我在任何地方都找不到合适的 API 或 wsdl 谢谢 拉斐尔 这是最终对我有用的代码 使用没有
  • 接收UDP数据包

    假设我的程序通过网络 UDP 发送 1000 字节 它是否保证接收方将 一批 接收 1000 个字节 或者他可能需要执行多次 读取 直到收到完整的消息 如果后者为真 我如何确保同一消息的数据包顺序不会 混淆 按顺序 或者协议可能保证这一点
  • Windows 消息

    我需要发送带有自定义 ID 的自定义 Windows 消息 其他应用程序将侦听该消息 Windows 是否为内部消息保留任何预定义的消息 ID 范围 如 SQL Server 那样 内部消息最多为 50 000 The 文档 https m
  • pytube 在 Android 中传输视频所需的时间太长

    我在用pytube在 Android 中流式传输视频 借助chaquopy 视频文件 py from pytube import YouTube def video link yt YouTube f https www youtube c
  • 在matplotlib中绘制曲线连接点

    所以我试图绘制曲线来连接点 这是我正在使用的代码 def hanging line point1 point2 a point2 1 point1 1 np cosh point2 0 np cosh point1 0 b point1 1
  • 如何声明和定义具有推导类型的静态成员?

    我需要定义一个具有复杂 许多模板参数 类型的静态成员 不是 constexpr 因此 希望有这样的东西 struct X static auto x makeObjectWithComplexType 但它不是 C 所以我尝试解决它 并认为
  • AIORedis 和 PUB/SUB 不是 asnyc

    I used aioredis http aioredis readthedocs org en latest examples html用于编写异步服务 该服务将侦听某个通道并以异步方式运行一些命令 基本上我从示例页面 http aior
  • IBM Rhapsody 中状态图终止连接器的理解

    在IBM Rhapsody中 如果我使用new创建了一个类的实例 那么我们是否必须通过调用delete来处理内存的释放 或者Termination Connector将在其状态图中通过内存释放来处理其销毁 如果您使用 C 和 OXF 对象执
  • 当无法处理指定的情况时,在 switch 语句中抛出异常

    假设我们有一个函数可以在 MVC 应用程序的系统中更改用户的密码 public JsonResult ChangePassword string username string currentPassword string newPassw
  • 如何从与桌面交互的应用程序与 Windows 服务进行通信?

    使用 Net 与服务交互的最佳方式是什么 即大多数托盘应用程序如何与其服务器通信 如果这个方法也是跨平台的 那就更好了 在 Mono 中工作 所以我猜远程处理已经过时了 Edit 忘了说了 我们仍然需要在现场支持 Windows 2000
  • 连接字符串:两个字符串列表的“乘法”[重复]

    这个问题在这里已经有答案了 对于字符串列表 将乘法运算定义为连接 l1 aa bb cc l2 11 22 l3 l1 op l2 预期输出 l3 aa11 aa22 bb11 bb22 cc11 cc22 我们可以简单地使用 for l
  • 何时使用 const char * 何时使用 const char[]

    我知道它们是不同的 我知道它们有何不同 并且我阅读了我能找到的所有关于char vs char 但所有这些答案都没有告诉我们什么时候应该使用它们 所以我的问题是 你什么时候使用 const char text text 你什么时候使用 co
  • pytest - ModuleNotFoundError - python 3.6.4

    我有一个具有以下布局的项目 MANIFEST in README md init py company init py api init py auth py debug py exceptions py reporting py rest
  • 如何在 if () 语句中声明变量? [复制]

    这个问题在这里已经有答案了 可能的重复 在 C 的条件或控制语句中声明和初始化变量 https stackoverflow com questions 1516919 declaring and initializing a variabl
  • 为什么这个多处理代码会失败? [复制]

    这个问题在这里已经有答案了 def sample pass Process target sample start Process target sample start 上面的代码失败并出现错误 已尝试在当前进程之前启动新进程 进程已完成
  • 缓存行对齐(需要文章澄清)

    我最近在我的应用程序中遇到了我认为是错误共享的问题 我查了一下关于如何将我的数据与缓存行对齐 他建议使用以下 C 代码 C using C 0x alignment syntax template
  • Security.h 中结构的 macOS 文档

    我正在尝试使用Security h通过 Java 和 JNA 的 macOS 框架 这意味着我需要将某些结构重建为 Java 类 问题是 当我查看文档中的结构时 this one https developer apple com refe
  • Phong 着色问题

    我正在根据以下内容编写着色器冯模型 http en wikipedia org wiki Phong reflection model 我正在尝试实现这个方程 其中 n 是法线 l 是光线方向 v 是相机方向 r 是光反射 维基百科文章中更
  • 为什么 typeof 函数在 C 中不起作用

    我使用GCC编译器 版本9 2 0 我想在 C 中使用 typeof 函数 但它会引发错误 错误 typeof 之前的预期表达式 如果您需要更多信息 请询问我 int a 5 double b the expected result is

随机推荐