一,首先是cmakelists.txt
cmake_minimum_required(VERSION 3.8)
project(my_component_pkg)
set(CMAKE_BUILD_TYPE "RELEASE")
#优化生成的可执行文件以提高其性能,包括开启各种优化选项,减少调试信息输出等。
find_package(ament_cmake_auto REQUIRED)
ament_auto_find_build_dependencies()
#这个宏会自动查找所有已在 package.xml 中声明的依赖项,
#并将它们引入到CMake环境中,省去了手动调用 find_package() 的步骤。
file(GLOB_RECURSE my_component_pkg_srcs "src/*.cpp")
#在 src 目录下找到所有扩展名为 .cpp 的源文件,
#并将这些文件的路径存储在 my_component_pkg_srcs变量中
#定义变量时,不需要添加${}
#SRCS后缀是源文件的含义,整个变量可大写小写,但要保持一致
ament_auto_add_library(my_component_gxk SHARED
${my_component_pkg_srcs})
#构建项目时需要将源代码编译成一个共享库,以便动态链接(组件)
#第一个参数是共享库的名字(my_component_gxk)
#引用变量时,需要添加${}
rclcpp_components_register_node(my_component_gxk
PLUGIN "my_component_pkg::SubscriberComponent"
EXECUTABLE subscriber_node)
rclcpp_components_register_node(my_component_gxk
PLUGIN "my_component_pkg::PublisherComponent"
EXECUTABLE publisher_node)
#用于注册组件节点,EXECUTABLE subscriber_node会生成可执行文件
#第一个参数也是共享库的名字
install(DIRECTORY
launch
DESTINATION share/${PROJECT_NAME}/
)
ament_auto_package()
二,接下来是launch文件
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package='my_component_pkg', #包名
executable='subscriber_node', # 可执行文件名
output='screen', # 输出到控制台
),
Node(
package='my_component_pkg', #包名
executable='publisher_node', # 可执行文件名
output='screen', # 输出到控制台
),
])
三,然后是xml文件,
注意把各种依赖用<depend>
添加至xml文件,这样
find_package(ament_cmake_auto REQUIRED)
ament_auto_find_build_dependencies()
这个代码块才会生效
<?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>my_component_pkg</name>
<version>0.0.0</version>
<description>TODO: Package description</description>
<maintainer email="liujiawei@todo.todo">liujiawei</maintainer>
<license>TODO: License declaration</license>
<buildtool_depend>ament_cmake</buildtool_depend>
<depend>rclcpp</depend>
<depend>rclcpp_components</depend>
<depend>std_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>
此外编写组件时,要用面向对象的方法,记得添加
#include "rclcpp_components/register_node_macro.hpp"
RCLCPP_COMPONENTS_REGISTER_NODE(my_component_pkg::PublisherComponent)
//用来将一个类注册为可动态加载的组件,使其能够进行加载和运行
//PublisherComponent是你节点类的名称
四,完整cpp代码一览:
#include "rclcpp/rclcpp.hpp"
#include "rclcpp_components/register_node_macro.hpp"
#include "std_msgs/msg/string.hpp"
namespace my_component_pkg
{
class SubscriberComponent : public rclcpp::Node
{
public:
SubscriberComponent(const rclcpp::NodeOptions & options)
: Node("subscriber_component", options)
{
// 创建订阅者,订阅“topic”话题
subscription_ = this->create_subscription<std_msgs::msg::String>(
"topic", 10,
std::bind(&SubscriberComponent::topic_callback, this, std::placeholders::_1));
}
private:
void topic_callback(const std_msgs::msg::String::SharedPtr msg)
{
RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg->data.c_str());
}
rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
};
} // namespace my_component_pkg
RCLCPP_COMPONENTS_REGISTER_NODE(my_component_pkg::SubscriberComponent)
#include "rclcpp/rclcpp.hpp"
#include "rclcpp_components/register_node_macro.hpp"
#include "std_msgs/msg/string.hpp"
namespace my_component_pkg
{
class PublisherComponent : public rclcpp::Node
{
public:
PublisherComponent(const rclcpp::NodeOptions & options)
: Node("publisher_component", options)
{
// 创建发布者,发布到“topic”话题
publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10);
// 创建一个定时器,定时发布消息
timer_ = this->create_wall_timer(
std::chrono::seconds(1),
std::bind(&PublisherComponent::publish_message, this));
}
private:
void publish_message()
{
auto message = std_msgs::msg::String();
message.data = "Hello from PublisherComponent!";
RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
publisher_->publish(message);
}
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
rclcpp::TimerBase::SharedPtr timer_;
};
} // namespace my_component_pkg
RCLCPP_COMPONENTS_REGISTER_NODE(my_component_pkg::PublisherComponent)