当前位置: 首页 > news >正文

【Ros2学习】话题的发布与请求

文章目录

  • 前言
  • 一、订阅发布完整流程
  • 二、 工作区结构准备
    • 步骤 1:创建工作区目录结构
    • 步骤 2:创建功能包
  • 三、 创建发布者流程
    • 步骤 1:创建发布者节点
    • 步骤 2:创建发布者源文件
    • 步骤 3:创建订阅者节点
    • 步骤 4:创建订阅者源文件
    • 步骤 5:创建main
  • 四、 修改编译文件
    • 步骤 1:修改 CMakeLists.txt
    • 步骤 2:修改 package.xml
  • 五、 编译工作区
    • 步骤1:编译功能包
    • 步骤2:加载工作区环境
    • 步骤3:运行节点


前言

学习记录Ros2中订阅发布主题的操作步骤


一、订阅发布完整流程

以下图是大致的流程图:
在这里插入图片描述

二、 工作区结构准备

步骤 1:创建工作区目录结构

mkdir -p ~/ros2_ws/src
cd ~/ros2_ws/src

步骤 2:创建功能包

ros2 pkg create pub_sub_demo --build-type ament_cmake --dependencies rclcpp std_msgs

三、 创建发布者流程

步骤 1:创建发布者节点

# 创建头文件目录和源文件
mkdir -p ~/ros2_ws/src/pub_sub_demo/include/pub_sub_demo
mkdir -p ~/ros2_ws/src/pub_sub_demo/src# 创建发布者头文件
nano ~/ros2_ws/src/pub_sub_demo/include/pub_sub_demo/publisher_node.hpp

publisher_node.hpp

#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"class PublisherNode : public rclcpp::Node {
public:PublisherNode() : Node("publisher_node"), count_(0) {// 1. 创建发布者publisher_ = this->create_publisher<std_msgs::msg::String>("chatter", 10);// 2. 创建定时器定期发布消息timer_ = this->create_wall_timer(std::chrono::seconds(1),[this]() {// 3. 创建消息auto message = std_msgs::msg::String();message.data = "Hello ROS 2: " + std::to_string(count_++);// 4. 发布消息publisher_->publish(message);RCLCPP_INFO(this->get_logger(), "发布: '%s'", message.data.c_str());});}private:rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;rclcpp::TimerBase::SharedPtr timer_;size_t count_;
};

步骤 2:创建发布者源文件

nano ~/ros2_ws/src/pub_sub_demo/src/publisher_node.cpp

publisher_node.cpp:

#include "pub_sub_demo/publisher_node.hpp"PublisherNode::PublisherNode()
: Node("publisher_node"), count_(0)
{// 创建发布者,主题名为 "chatter",队列大小为10publisher_ = this->create_publisher<std_msgs::msg::String>("chatter", 10);// 创建定时器,每秒发布一次消息timer_ = this->create_wall_timer(std::chrono::seconds(1),std::bind(&PublisherNode::timer_callback, this));RCLCPP_INFO(this->get_logger(), "发布者节点已启动");
}void PublisherNode::timer_callback()
{// 创建消息auto message = std_msgs::msg::String();message.data = "Hello ROS 2 - 消息编号: " + std::to_string(count_++);// 发布消息publisher_->publish(message);// 打印日志RCLCPP_INFO(this->get_logger(), "发布消息: '%s'", message.data.c_str());
}

步骤 3:创建订阅者节点

nano ~/ros2_ws/src/pub_sub_demo/include/pub_sub_demo/subscriber_node.hpp

subscriber_node.hpp:

#ifndef PUB_SUB_DEMO__SUBSCRIBER_NODE_HPP_
#define PUB_SUB_DEMO__SUBSCRIBER_NODE_HPP_#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"class SubscriberNode : public rclcpp::Node
{
public:SubscriberNode();private:void message_callback(const std_msgs::msg::String::SharedPtr msg) const;rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;
};#endif  // PUB_SUB_DEMO__SUBSCRIBER_NODE_HPP_

步骤 4:创建订阅者源文件

nano ~/ros2_ws/src/pub_sub_demo/src/subscriber_node.cpp

subscriber_node.cpp:

#include "pub_sub_demo/subscriber_node.hpp"SubscriberNode::SubscriberNode()
: Node("subscriber_node")
{// 创建订阅者subscription_ = this->create_subscription<std_msgs::msg::String>("chatter",  // 主题名10,         // 队列大小// Lambda 回调函数[this](const std_msgs::msg::String::SharedPtr msg) {this->message_callback(msg);});RCLCPP_INFO(this->get_logger(), "订阅者节点已启动,等待消息...");
}void SubscriberNode::message_callback(const std_msgs::msg::String::SharedPtr msg) const
{RCLCPP_INFO(this->get_logger(), "收到消息: '%s'", msg->data.c_str());
}

步骤 5:创建main

nano ~/ros2_ws/src/pub_sub_demo/src/main.cpp

main.cpp:

#include "rclcpp/rclcpp.hpp"
#include "pub_sub_demo/publisher_node.hpp"
#include "pub_sub_demo/subscriber_node.hpp"int main(int argc, char * argv[])
{// 初始化 ROS 2rclcpp::init(argc, argv);// 创建节点auto publisher_node = std::make_shared<PublisherNode>();auto subscriber_node = std::make_shared<SubscriberNode>();// 创建执行器(单线程)auto executor = std::make_shared<rclcpp::executors::SingleThreadedExecutor>();// 添加节点到执行器executor->add_node(publisher_node);executor->add_node(subscriber_node);RCLCPP_INFO(publisher_node->get_logger(), "开始执行...");try {// 运行执行器(阻塞调用)executor->spin();} catch (const std::exception& e) {RCLCPP_ERROR(rclcpp::get_logger("main"), "执行器异常: %s", e.what());}// 清理资源executor->remove_node(publisher_node);executor->remove_node(subscriber_node);rclcpp::shutdown();return 0;
}

四、 修改编译文件

步骤 1:修改 CMakeLists.txt

cmake_minimum_required(VERSION 3.8)
project(pub_sub_demo)# 设置 C++ 标准
if(NOT CMAKE_CXX_STANDARD)set(CMAKE_CXX_STANDARD 17)
endif()# 查找依赖
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)# 包含头文件目录
include_directories(include)# 创建可执行文件
add_executable(pub_sub_demo_nodesrc/publisher_node.cppsrc/subscriber_node.cppsrc/main.cpp
)# 添加依赖
ament_target_dependencies(pub_sub_demo_noderclcppstd_msgs
)# 安装
install(TARGETSpub_sub_demo_nodeDESTINATION lib/${PROJECT_NAME}
)install(DIRECTORY include/DESTINATION include/
)# 导出
ament_export_include_directories(include)
ament_export_dependencies(rclcpp std_msgs)# 必须在最后
ament_package()

步骤 2:修改 package.xml

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypelayout="1.0"?>
<package format="3"><name>pub_sub_demo</name><version>0.0.0</version><description>ROS 2 发布订阅示例</description><maintainer email="you@example.com">Your Name</maintainer><license>Apache-2.0</license><buildtool_depend>ament_cmake</buildtool_depend><depend>rclcpp</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>

五、 编译工作区

步骤1:编译功能包

# 进入工作区根目录
cd ~/ros2_ws# 编译工作区
colcon build --packages-select pub_sub_demo# 或者使用符号链接安装(推荐用于开发)
colcon build --packages-select pub_sub_demo --symlink-install

步骤2:加载工作区环境

# 加载工作区设置
source ~/ros2_ws/install/setup.bash# 验证包是否可找到
ros2 pkg list | grep pub_sub_demo

步骤3:运行节点

# 运行包含两个节点的可执行文件
ros2 run pub_sub_demo pub_sub_demo_node

运行结果如下:
在这里插入图片描述

http://www.dtcms.com/a/569953.html

相关文章:

  • 肥猫网站建设广西省河池建设局网站
  • CentOS7安装docker教程
  • 论文网站建设与运营拖曳式网站建设
  • Jenkins持续集成入门指南:自动化构建与部署的最佳实践
  • 山西省建设信息网站汇点远程app下载安装
  • 阿里云手机网站建设打电话拉客户用网站做广告怎么做 好做吗
  • hexo做网站wordpress内容分页在哪改
  • 游戏网站后台建设美橙云建站
  • 数据备份策略:全量 / 增量 / 差异备份、备份周期规划
  • LeetCode 322. 零钱兑换
  • Redis黑马点评 Feed流
  • 域名后缀cn做网站河北手机网站建设
  • U-Net保姆级教程:从原理到医学细胞分割实战(PyTorch版)!
  • mini-bitcask学习笔记
  • 东莞网站建设公司哪家好电商平面设计主要做什么
  • 解决远程调用微服务之后无法通过上下文获取用户id问题
  • 网站代付系统怎么做大型网站seo策略
  • 国家住房城乡建设部网站住房和城乡建设部网站北京
  • 制作网站的程序网站查找工具
  • 网站建设 图片压缩网站开发多少费用
  • React Native App 自动检测版本更新完整实现指南
  • 网站建站是 什么企业网站托管运营
  • 字母象形的力量:单词速记之多种意象融合一体
  • xtuoj Binary
  • 南沙网站开发企业网站建设需要多少钱知乎
  • python 包 检测自己是否为 editable 模式安装的
  • ToB销售获客策略全解析:实现精准客户开发方法论
  • 成都医院手机网站建设湖北做网站找谁
  • 网站需求分析怎么写设计网站大全湖南岚鸿设计
  • css 画一个圆角渐变色边框