目标:使用 C++创建并运行一个发布者和订阅者节点。
教程级别:初学者
时间:20 分钟
目录
背景
先决条件
任务
1. 创建一个包
2. 编写发布者节点
3. 编写订阅者节点
4. 构建并运行
摘要
下一步
相关内容
背景
节点是在 ROS 图上进行通信的可执行过程。在本教程中,节点将通过主题相互传递字符串消息形式的信息。这里使用的例子是一个简单的“说话者”和“监听者”系统;一个节点发布数据,另一个节点订阅主题以接收该数据。
这些示例中使用的代码可以在这里找到。
先决条件
在之前的教程中,您学习了如何创建工作区和创建包。
任务
1. 创建一个包
打开一个新的终端并且初始化您的 ROS 2 安装,这样 ros2
命令就会生效。
导航到在之前教程中创建的 ros2_ws
目录。
请记住,包应该在 src
目录中创建,而不是在工作区的根目录中。因此,请导航到 ros2_ws/src
,然后运行包创建命令:
ros2 pkg create --build-type ament_cmake --license Apache-2.0 cpp_pubsub
cxy@ubuntu2404-cxy:~/ros2_ws/src$ ros2 pkg create --build-type ament_cmake --license Apache-2.0 cpp_pubsub
going to create a new package
package name: cpp_pubsub
destination directory: /home/cxy/ros2_ws/src
package format: 3
version: 0.0.0
description: TODO: Package description
maintainer: ['cxy <cxy@todo.todo>']
licenses: ['Apache-2.0']
build type: ament_cmake
dependencies: []
creating folder ./cpp_pubsub
creating ./cpp_pubsub/package.xml
creating source and include folder
creating folder ./cpp_pubsub/src
creating folder ./cpp_pubsub/include/cpp_pubsub
creating ./cpp_pubsub/CMakeLists.txt
您的终端将返回一条消息,确认您的包 cpp_pubsub
及其所有必要的文件和文件夹已创建。
导航到 ros2_ws/src/cpp_pubsub/src
。请记住,这是任何 CMake 包中包含可执行文件的源文件所在的目录。
2. 编写发布者节点
下载示例发布者代码,请输入以下命令:
cxy@ubuntu2404-cxy:~/ros2_ws/src$ cd cpp_pubsub/src
cxy@ubuntu2404-cxy:~/ros2_ws/src/cpp_pubsub/src$ wget -O publisher_lambda_function.cpp https://raw.githubusercontent.com/ros2/examples/jazzy/rclcpp/topics/minimal_publisher/lambda.cpp
--2024-07-05 21:02:40-- https://raw.githubusercontent.com/ros2/examples/jazzy/rclcpp/topics/minimal_publisher/lambda.cpp
正在连接 127.0.0.1:2334... 已连接。
已发出 Proxy 请求,正在等待回应... 200 OK
长度:1849 (1.8K) [text/plain]
正在保存至: ‘publisher_lambda_function.cpp’
publisher_lambda_fu 100%[===================>] 1.81K --.-KB/s 用时 0s
2024-07-05 21:02:42 (6.81 MB/s) - 已保存 ‘publisher_lambda_function.cpp’ [1849/1849])
现在将有一个名为 publisher_lambda_function.cpp
的新文件。使用您喜欢的文本编辑器打开该文件。
// 版权 2016 开源机器人基金会,公司。
//
// 根据 Apache 许可证,版本 2.0(“许可证”)许可;
// 除非符合许可证,否则不得使用此文件。
// 您可以在以下位置获取许可证副本:
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// 除非适用法律要求或书面同意,否则在许可证下分发的软件
// 将按“原样”基础分发,无任何形式的明示或暗示保证或条件。
// 有关在许可证下管理权限和限制的特定语言,请参阅许可证。
#include <chrono> // 包含 C++ 标准库中的时间函数
#include <memory> // 包含 C++ 标准库中的内存管理函数
#include <string> // 包含 C++ 标准库中的字符串函数
#include "rclcpp/rclcpp.hpp" // 包含 ROS 2 的 rclcpp 库
#include "std_msgs/msg/string.hpp" // 包含 ROS 2 的标准消息类型
using namespace std::chrono_literals; // 使用 C++ 标准库中的时间字面量
/* 这个例子创建了一个 Node 的子类,并使用了一个精巧的 C++11 lambda
* 函数来简化回调语法,但这使得代码在初次查看时更难理解。*/
class MinimalPublisher : public rclcpp::Node // 定义一个 MinimalPublisher 类,它是 rclcpp::Node 的子类
{
public:
MinimalPublisher() // MinimalPublisher 类的构造函数
: Node("minimal_publisher"), count_(0) // 初始化节点名为 "minimal_publisher",计数器 count_ 为 0
{
publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10); // 创建一个发布者,发布到 "topic" 主题,队列大