ros2 humble plugin 的第一个入门例子

记录《ROS2机器人开发:从入门到实践》的第一个plugin 入门例子

安装pluginlib,创建ws目录并在~/ros2_ws/src下建立一个package。命令如下:

$ source /opt/ros/humble/setup.bash
$ sudo apt install ros-$ROS_DISTRO-pluginlib -y $ mkdir -p ~/ros2_ws/src
$ cd ~/ros2_ws/src
~/ros2_ws/src$ ros2 pkg create motion_control_system --build-type ament_cmake --license Apache-2.0 --dependencies pluginlib

在~/ros2_ws/src/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 {
// 命名空间  同pakage的名
class MotionController {
public:
    virtual void start() = 0; // =0 代表无参数
    virtual void stop() = 0;
    virtual ~MotionController() {}
};

} // namespace motion_control_system

#endif // MOTION_CONTROL_INTERFACE_HPP

在~/ros2_ws/src/motion_control_system/include/motion_control_system下建立spin_motion_controller.hpp,声明具体类。代码如下:

#ifndef SPIN_MOTION_CONTROLLER_HPP
#define SPIN_MOTION_CONTROLLER_HPP

#include "motion_control_system/motion_control_interface.hpp"

namespace motion_control_system // 命名空间 同pakage的名
{
    class SpinMotionController : public MotionController // 继承虚类MotionController
    {
    public:
        void start() override; // 重载类方法函数
        void stop() override;
    };

} // namespace motion_control_system

#endif // SPIN_MOTION_CONTROLLER_HPP

在~/ros2_ws/src/motion_control_system/src下建立spin_motion_controller.cpp,实现具体类。代码如下:

#include <iostream>
#include "motion_control_system/spin_motion_controller.hpp"
namespace motion_control_system  // 命名空间,同pakage的名
{
    void SpinMotionController::start()
    {
        // 实现旋转运动控制逻辑
        std::cout << "SpinMotionController::start running" << std::endl;
    }
    void SpinMotionController::stop()
    {
        // 停止运动控制
        std::cout << "SpinMotionController::stop running" << std::endl;
    }
} // namespace motion_control_system
#include "pluginlib/class_list_macros.hpp"
PLUGINLIB_EXPORT_CLASS(motion_control_system::SpinMotionController, motion_control_system::MotionController)

修改~/ros2_ws/src/motion_control_system/CMakeLists.txt,实现编译控制。代码如下:

cmake_minimum_required(VERSION 3.8)
project(motion_control_system)

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(pluginlib REQUIRED) 

include_directories(include) //添加
# ================添加库文件=====================
add_library(spin_motion_controller SHARED src/spin_motion_controller.cpp)
ament_target_dependencies(spin_motion_controller pluginlib)
install(TARGETS spin_motion_controller 
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
)

install(DIRECTORY include/        
        DESTINATION include/
)
if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # comment the line when a copyright and license is added to all source files
  set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # comment the line when this package is in a git repo and when
  # a copyright and license is added to all source files
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()
# ===添加====
pluginlib_export_plugin_description_file(motion_control_system spin_motion_plugins.xml)

ament_package()

创建~/ros2_ws/src/motion_control_system/spin_motion_plugins.xml下建立spin_motion_plugins.xml,描述插件。代码如下:

注意 <library path="spin_motion_controller"> 与CMakeLists.txt的add_library()内一致。

注意:class标签的name属性,就是加载插件时用的名字,格式:包名/类名

注意:类名称与hpp中类声明一致。命名空间::类名

<library path="spin_motion_controller">
    <class name="motion_control_system/SpinMotionController" type="motion_control_system::SpinMotionController" base_class_type="motion_control_system::MotionController">
     <description>Spin Motion Controller</description>
    </class>
</library>

创建~/ros2_ws/src/motion_control_system/src/test_plugin.cpp,测试plugin。代码如下:

#include "motion_control_system/motion_control_interface.hpp"
#include <pluginlib/class_loader.hpp>

int main(int argc, char **argv) {
  // 判断参数数量是否合法
  if (argc != 2)
    return 0;
  // 通过命令行参数,选择要加载的插件,argv[0]是可执行文件名,argv[1]表示参数名
  std::string controller_name = argv[1];
  // 1.通过功能包名称和基类名称创建控制器加载器
  pluginlib::ClassLoader<motion_control_system::MotionController>
      controller_loader("motion_control_system",
                        "motion_control_system::MotionController");
  // 2.使用加载器加载指定名称的插件,返回的是指定插件类的对象的指针
  auto controller = controller_loader.createSharedInstance(controller_name);
  // 3.调用插件的方法
  controller->start();
  controller->stop();
  return 0;
}

使用的包描述文件/home/ubuntu/ros2_ws/src/motion_control_system/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>motion_control_system</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="xxxx@qq.com">ubuntu</maintainer>
  <license>Apache-2.0</license>

  <buildtool_depend>ament_cmake</buildtool_depend>

  <depend>pluginlib</depend>

  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

在~/ros2_ws/src/motion_control_system/src下建立test_plugin.cpp,测试plugin。代码如下:

#include "motion_control_system/motion_control_interface.hpp"
#include <pluginlib/class_loader.hpp>

int main(int argc, char **argv) {
  // 判断参数数量是否合法
  if (argc != 2)
    return 0;
  // 通过命令行参数,选择要加载的插件,argv[0]是可执行文件名,argv[1]表示参数名
  std::string controller_name = argv[1];
  // 1.通过功能包名称和基类名称创建控制器加载器
  pluginlib::ClassLoader<motion_control_system::MotionController>
      controller_loader("motion_control_system",
                        "motion_control_system::MotionController");
  // 2.使用加载器加载指定名称的插件,返回的是指定插件类的对象的指针
  auto controller = controller_loader.createSharedInstance(controller_name);
  // 3.调用插件的方法
  controller->start();
  controller->stop();
  return 0;
}

修改~/ros2_ws/src/motion_control_system/CMakeLists.txt,实现test_plugin.cpp编译控制。代码如下:

cmake_minimum_required(VERSION 3.8)
project(motion_control_system)

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(pluginlib REQUIRED)

include_directories(include)
# ================添加库文件=====================
add_library(motion_controllers SHARED src/spin_motion_controller.cpp)

ament_target_dependencies(motion_controllers pluginlib)


install(TARGETS motion_controllers
  ARCHIVE DESTINATION lib
  LIBRARY DESTINATION lib
  RUNTIME DESTINATION bin
)

install(DIRECTORY include/
        DESTINATION include/
)
# ================执行文件=====================
add_executable(test_plugin
  src/test_plugin.cpp  # 或您的主程序文件
)
ament_target_dependencies(test_plugin pluginlib)

install(TARGETS test_plugin DESTINATION lib/${PROJECT_NAME})


if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # comment the line when a copyright and license is added to all source files
  set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # comment the line when this package is in a git repo and when
  # a copyright and license is added to all source files
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()
# ===  第一个参数必须是包名称 ===
pluginlib_export_plugin_description_file(motion_control_system spin_motion_plugins.xml)

ament_package()

编译和测试命令如下:

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

~/ros2_ws$ source install/setup.bash

~/ros2_ws$ ros2 run motion_control_system test_plugin motion_control_system/SpinMotionController
注意:~/ros2_ws$ ros2 run motion_control_system test_plugin motion_control_system/SpinMotionController
中的motion_control_system/SpinMotionController 见spin_motion_plugins.xml文件中的声明。

 

posted @ 2026-09-10 18:23  辛河  阅读(12)  评论(0)    收藏  举报