1 专栏介绍
本专栏为ROS2的从零基础到应用于落地项目的实用教程,附C++工程级全套代码。
详情:ROS | 实战,教程源码:gorilla_ros_tutorials
2 communication包
此包已经构建,延续使用,可以翻阅ROS2基础 | topic 实战一查看。
3 从零构建订阅者
从零构建一个订阅者的话,只需要简短的三步:
3.1 创建通用模子
基于上篇博客的ROS2的基本的、通用的模子,构建一个HelloWorldSubscriber类
hello_world_subscriber_tutorial.cc文件内容如下
// Copyright (c) 2024 Gorilla
//
// Licensed under the Apache License, Version 2.0 (the "License");
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: Gorilla <gorilla_robot@126.com>
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
namespace {
constexpr char kHelloWorldTopic[] = "/hello_world";
constexpr int kInfiniteSubscriberQueueSize = 0;
} // namespace
class HelloWorldSubscriber : public rclcpp::Node {
public:
HelloWorldSubscriber(const std::string& name);
~HelloWorldSubscriber() = default;
}; // class HelloWorldSubscriber
HelloWorldSubscriber::HelloWorldSubscriber(const std::string& name) : Node(name) {
RCLCPP_INFO(this->get_logger(), "The node is %s.", name.c_str());
}
int main(int argc, char** argv) {
rclcpp::init(argc, argv);
auto node = std::make_shared<HelloWorldSubscriber>("hello_world_subscriber");
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
修改CMakeLists.txt文件,添加对新增文件的编译及install。
# ############################ topic tutorial ############################
add_executable(hello_world_subscriber_tutorial tutorials/topic/hello_world_subscriber_tutorial.cc)
ament_target_dependencies(hello_world_subscriber_tutorial ${dependencies})
install(TARGETS
communication
hello_world_publisher_tutorial
hello_world_subscriber_tutorial
DESTINATION lib/${PROJECT_NAME})
清除build、log、install,再编译并运行,不出意外的话会出现如下显示
[INFO] [1741139507.193254071] [hello_world_subscriber]: The node is hello_world_subscriber.
3.2 创建订阅器
模子已经构建好了,那我们就来创建最重要的订阅器吧。
private:
rclcpp::Subscription<std_msgs::msg::String>::SharedPtr hello_world_subscriber_ptr_;
先申明一个私有的订阅者句柄,它带了一个具象化的msg并以智能指针的形式存在。格式如上,函数原型见:rclcpp/subscription.hpp
namespace {
constexpr char kHelloWorldTopic[] = "/hello_world";
constexpr int kInfiniteSubscriberQueueSize = 0;
} // namespace
private:
void HandleHelloWorldMessage(const std_msgs::msg::String::ConstSharedPtr& msg);
hello_world_subscriber_ptr_ = this->create_subscription<std_msgs::msg::String>
(kHelloWorldTopic, kInfiniteSubscriberQueueSize, std::bind(&HelloWorldSubscriber::HandleHelloWorldMessage, this, std::placeholders::_1));
再定义订阅者句柄,它带有三个形参。
第一个是topic_name,话题名字可以理解为发布者与订阅者找到彼此的唯一识别ID,只有ID对接上了,才能互通;
第二个是qos,它是ROS2通讯服务质量策略,用于控制消息传递的可靠性、历史记录大小、队列长度、发布频率等,传递int类型表示其他使用默认,队列长度为传递的大小;
第三个是回调函数,用于回调发布者的消息。
3.3 回调信息并使用
订阅器已经构建好了,那我们就来进行消息的回调吧。
void HelloWorldSubscriber::HandleHelloWorldMessage(const std_msgs::msg::String::ConstSharedPtr& msg) {
RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg->data.c_str());
}
4 测试
订阅者已构建完成了,让我们编译并与发布者一起运行一下吧。
./compiling.sh make
// 一个终端开启订阅程序
./install/communication/lib/communication/hello_world_subscriber_tutorial
// 另外一个终端开启发布程序
./install/communication/lib/communication/hello_world_publisher_tutorial
5 总结
本文我们讲解了ROS2程序的话题订阅,核心点在于创建订阅器和回调信息。