ROS2 入门应用 发布和订阅(C++)
-
1. 创建功能包
2. 创建源文件
2.1. 话题发布
2.2. 话题订阅
3. 添加依赖关系
4. 添加编译信息
4.1. 添加搜索库
4.2. 增加可执行文件
4.3. 增加可执行文件位置
5. 编译和运行
1. 创建功能包
在《ROS2 入门应用 工作空间》中已创建和加载了ros2_ws
工作空间
在《ROS2 入门应用 元功能包(C++)》中已创建和加载了my_package
功能包
那么就创建一个独立的cpp_pubsub
功能包来做话题发布和订阅的功能
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_cmake cpp_pubsub
2. 创建源文件
进入cpp_pubsub
功能包的src
文件夹
cd ~/ros2_ws/src/cpp_pubsub/src
2.1. 话题发布
新建publisher_member_function.cpp
话题发布源文件
nano publisher_member_function.cpp
复制 ROS2 官方例程 的内容到文件中:
#include <chrono>
#include <functional>
#include <memory>
#include <string>
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
/* 方便表示时间 */
using namespace std::chrono_literals;
/* This example creates a subclass of Node and uses std::bind() to register a
* member function as a callback from the timer. */
/* 继承rclcpp:: node创建节点类MinimalPublisher */
class MinimalPublisher : public rclcpp::Node
{
public:
/* 公共构造函数将节点命名为minimal_publisher,并将count_初始化为0 */
MinimalPublisher()
: Node("minimal_publisher"), count_(0)
{
/* 初始化发布者publisher_ ,使用String消息类型、主题名称topic和在发生备份时限制消息所需的队列大小10 */
publisher_ = this->create_publisher<std_msgs::msg::String>("topic", 10);
/* 初始化timer_,设置timer_callback函数每500ms执行一次 */
timer_ = this->create_wall_timer(500ms, std::bind(&MinimalPublisher::timer_callback, this));
}
private:
/* 定义定时器回调函数 */
void timer_callback()
{
/* 打印并发布字符串信息 */
auto message = std_msgs::msg::String();
message.data = "Hello, world: " + std::to_string(count_++);
RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());
publisher_->publish(message);
}
/* 计时器、发布者和计数器字段的声明 */
rclcpp::TimerBase::SharedPtr timer_;
rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;
size_t count_;
};
int main(int argc, char * argv[])
{
/* 初始化ROS2 */
rclcpp::init(argc, argv);
/* 运行节点MinimalPublisher */
rclcpp::spin(std::make_shared<MinimalPublisher>());
/* 退出ROS2 */
rclcpp::shutdown();
return 0;
}
2.2. 话题订阅
新建subscriber_member_function.cpp
话题订阅源文件
nano subscriber_member_function.cpp
复制 ROS2 官方例程 的内容到文件中:
#include <memory>
#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"
/* 占位符,代替回调函数中的第一个参数 */
using std::placeholders::_1;
/* 继承rclcpp:: node创建节点类MinimalSubscriber */
class MinimalSubscriber : public rclcpp::Node
{
public:
/* 公共构造函数将节点命名为minimal_subscriber */
MinimalSubscriber()
: Node("minimal_subscriber")
{
/* 初始化订阅者subscription_ ,使用String消息类型、主题名称topic和在发生备份时限制消息所需的队列大小10,
订阅话题回调函数topic_callback */
subscription_ = this->create_subscription<std_msgs::msg::String>(
"topic", 10, std::bind(&MinimalSubscriber::topic_callback, this, _1));
}
private:
/* 定义订阅话题回调函数 */
void topic_callback(const std_msgs::msg::String & msg) const
{
/* 打印话题消息的字符串信息 */
RCLCPP_INFO(this->get_logger(), "I heard: '%s'", msg.data.c_str());
}
/* 订阅者字段的声明 */
rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
};
int main(int argc, char * argv[])
{
/* 初始化ROS2 */
rclcpp::init(argc, argv);
/* 运行节点MinimalSubscriber*/
rclcpp::spin(std::make_shared<MinimalSubscriber>());
/* 退出ROS2 */
rclcpp::shutdown();
return 0;
}
3. 添加依赖关系
在package.xml
清单文件中
找到<buildtool_depend>ament_cmake</buildtool_depend>
依赖项,在其下面添加源文件所需的依赖(depend):
<depend>rclcpp</depend>
<depend>std_msgs</depend>
这声明了功能包在执行代码时需要rclcpp和std_msgs
4. 添加编译信息
在CMakeLists.txt
编译文件中
4.1. 添加搜索库
首先,找到find_package(ament_cmake REQUIRED)依赖项,在其下面添加搜索源文件所需(REQUIRED)的库:
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
4.2. 增加可执行文件
然后,再增加可执行文件,src/publisher_member_function.cpp
命名为talker
可执行文件,src/subscriber_member_function.cpp
命名为listener
可执行文件,
并添加目标依赖关系:
add_executable(talker src/publisher_member_function.cpp)
ament_target_dependencies(talker rclcpp std_msgs)
add_executable(listener src/subscriber_member_function.cpp)
ament_target_dependencies(listener rclcpp std_msgs)
4.3. 增加可执行文件位置
最后,增加可执行文件位置,这样ROS2就可以找到现在的可执行文件:
install(TARGETS
talker
listener
DESTINATION lib/${PROJECT_NAME})
5. 编译和运行
进入工作空间根目录
cd ~/ros2_ws
在编译之前检查缺失的依赖项(可跳过):
rosdep install -i --from-path src --rosdistro humble -y
编译:
colcon build --packages-select cpp_pubsub
打开一个新终端,运行话题发布节点:
ros2 run cpp_pubsub talker
# [INFO] [minimal_publisher]: Publishing: 'Hello World: 0'
# [INFO] [minimal_publisher]: Publishing: "Hello World: 1"
# [INFO] [minimal_publisher]: Publishing: 'Hello World: 2'
谢谢
评论(0)
您还未登录,请登录后发表或查看评论