鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    ROS2高级教程使用pluginlib自定义插件

    已定时 已固定 已锁定 已移动
    ROS 2相关问题
    ros2 pluginlib
    1
    1
    1.7k
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • 小鱼小
      小鱼 技术大佬
      最后由 小鱼 编辑

      ROS2高级教程使用pluginlib自定义插件

      引言

      很多小伙伴学完导航后可能想用自己的路径规划算法或者控制算法在机器人试一试身手,Nav2文档中提供了详细的操作教程:

      97c9a098-bdce-4160-bbbb-f501d9fa355e-图片.png

      但是这些教程无一例外都使用了pluginlib即插件机制进行组织,包括Nav2的源码在内,都大量使用了它,那什么是pluginlib呢?

      大家知道在C++中使用一个动态库,需要包含动态库的头文件,并链接动态库文件。但这样会降低代码的灵活性,后来的新库文件能不能直接加载和使用,不包含头文件和进行链接呢?

      pluginlib就提供了这样一个解决方案,实现了对库的动态加载和调用,只说不做不是小鱼的风格,上代码,带你从头学习如何使用它。

      当你在ROS 2中开发功能包并使用pluginlib创建动态加载的插件时,下面的步骤将帮助你更好地理解整个过程。我们将以一个简单的运动控制系统为例,展示如何创建一个ROS 2功能包,包含了插件的定义、配置、编译和使用。

      使用pluginlib动态加载库

      灵魂就是main.cpp没有对libsimple_motion_controller.so进行link就直接使用了。

      步骤 1:创建功能包

      首先,在你的ROS 2工作空间中创建一个功能包。我们将使用motion_control_system作为功能包的名称:

      cd ~/ros2_ws/src
      ros2 pkg create motion_control_system
      

      步骤 2:定义插件接口

      在ROS 2功能包中,我们首先定义一个插件接口,即一个纯虚基类,用于规定插件的基本方法。在motion_control_system/include/motion_control_system文件夹中创建一个名为motion_control_interface.hpp的文件,并添加以下内容:

      #ifndef MOTION_CONTROL_INTERFACE_HPP
      #define MOTION_CONTROL_INTERFACE_HPP
      
      namespace motion_control_system {
      
      class MotionController {
      public:
          virtual void start() = 0;
          virtual void stop() = 0;
          virtual ~MotionController() {}
      };
      
      } // namespace motion_control_system
      
      #endif // MOTION_CONTROL_INTERFACE_HPP
      

      步骤 3:创建插件类

      接下来,我们创建一个实现了插件接口的具体插件类。在motion_control_system/include/motion_control_system文件夹中创建一个名为simple_motion_controller.hpp的文件,并添加以下内容:

      #ifndef SIMPLE_MOTION_CONTROLLER_HPP
      #define SIMPLE_MOTION_CONTROLLER_HPP
      
      #include "motion_control_system/motion_control_interface.hpp"
      
      namespace motion_control_system {
      
      class SimpleMotionController : public MotionController {
      public:
          void start() override;
          void stop() override;
      };
      
      } // namespace motion_control_system
      
      #endif // SIMPLE_MOTION_CONTROLLER_HPP
      

      然后,在motion_control_system/src文件夹中创建一个名为simple_motion_controller.cpp的文件,并添加以下内容:

      #include <iostream>
      #include "motion_control_system/simple_motion_controller.hpp"
      
      namespace motion_control_system {
      
      void SimpleMotionController::start() {
          // 实现简单的运动控制逻辑
          std::cout << "SimpleMotionController::start" << std::endl;
      }
      
      void SimpleMotionController::stop() {
          // 停止运动控制
          std::cout << "SimpleMotionController::stop" << std::endl;
      }
      
      } // namespace motion_control_system
      
      #include "pluginlib/class_list_macros.hpp"
      PLUGINLIB_EXPORT_CLASS(motion_control_system::SimpleMotionController, motion_control_system::MotionController)
      

      步骤 4:配置插件描述文件

      在motion_control_system文件夹中创建一个名为simple_motion_plugins.xml的文件,并添加以下内容:

      <library path="simple_motion_controller">
              <class name="motion_control_system/SimpleMotionController" type="motion_control_system::SimpleMotionController" base_class_type="motion_control_system::MotionController">
               <description>简单运动控制器</description>
              </class>
      </library>
      

      步骤 5:配置CMakeLists.txt

      打开motion_control_system/CMakeLists.txt文件,并确保以下内容已添加:

      # ...
      ament_target_dependencies(${library_name}
        pluginlib 
      )
      
      # ...
      
      pluginlib_export_plugin_description_file(motion_control_system simple_motion_plugins.xml)
      
      ament_package()
      

      步骤 6:创建主程序

      在motion_control_system/src文件夹中创建一个名为main.cpp的文件,并添加以下内容:

      #include <rclcpp/rclcpp.hpp>
      #include <pluginlib/class_loader.hpp>
      #include "motion_control_system/motion_control_interface.hpp"
      
      int main(int argc, char **argv) {
          rclcpp::init(argc, argv);
      
          // 创建插件加载器
          pluginlib::ClassLoader<motion_control_system::MotionController> controller_loader("motion_control_system", "motion_control_system::MotionController");
          
          // 选择要加载的插件
          std::string controller_name = "motion_control_system/SimpleMotionController";
      
          // 加载插件
          auto controller = controller_loader.createClassInstance(controller_name);
          
          // 启动运动控制
          controller->start();
      
          // 做一些其他操作
      
          // 停止运动控制
          controller->stop();
      
          rclcpp::shutdown();
          return 0;
      }
      

      步骤 7:编译和运行

      在你的ROS 2工作空间中,执行以下命令编译功能包:

      cd ~/ros2_ws
      colcon build --packages-select motion_control_system
      

      运行编译后的可执行文件:

      source install/setup.bash
      ros2 run motion_control_system test_plugin
      

      通过上述步骤,你已经成功创建了一个ROS 2功能包,其中包含一个简单的运动控制插件。这个插件可以在运行时被动态加载和运行,从而使你的ROS 2应用程序更加灵活和可扩展。

      新书配套视频:https://www.bilibili.com/video/BV1GW42197Ck/

      1 条回复 最后回复 回复 引用 0
      • 第一个帖子
        最后一个帖子
      皖ICP备16016415号-7
      Powered by NodeBB | 鱼香ROS