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文件中的声明。

浙公网安备 33010602011771号