ROS笔记三:话题

目录

简要介绍

ROS话题通信机制的一些核心概念和流程:

话题通信的流程如下

ROS常见的topic命令行指令

发布话题

1.创建ROS节点并初始化

2.创建话题发布者

3.创建消息实例并设置内容

4.将消息发布出去

5.保持节点运行

订阅话题

初始化ROS节点和创建NodeHandle

创建订阅者并指定回调函数

编写消息回调函数

保持节点运行:

自定义消息类型数据

创建消息文件

在CMakeLists.txt中添加消息依赖

编译和构建

使用自定义消息类型

注意点


简要介绍

在ROS中,话题(topics)是最常用的通信机制之一,它允许节点之间以异步的方式进行消息的发布和订阅。一个节点可以发布某个话题的消息,而其他节点则可以订阅该话题以接收相应的消息。

话题通信机制是一种:一(发布者)对多(订阅者)、异步的通信机制

ROS话题通信机制的一些核心概念和流程:

1.消息类型(Message type):在ROS中,每个话题都有一个特定的消息类型,该消息类型定义了该话题所传递的数据结构和内容。例如,一个表示激光雷达扫描数据的消息类型可能包括激光雷达的位置、角度、距离等信息。

2.发布者(Publisher):发布者是一个ROS节点,它可以将特定消息类型的数据发布到某个话题中,其他节点可以通过订阅该话题来接收该消息。一个节点可以同时作为多个话题的发布者。

3.订阅者(Subscriber):订阅者是一个ROS节点,它可以从某个话题中接收特定消息类型的数据,从而实现对该话题的订阅。一个节点可以同时订阅多个话题。

4.话题名称(Topic name):话题名称是一个字符串,用来标识某个话题在ROS系统中的唯一性。在进行订阅或发布操作时,节点需要指定要订阅或发布的话题名称。

5.消息队列(Message queue):消息队列是一个缓存区,用来存储已发布但未被订阅者接收的消息。当节点订阅某个话题时,如果该话题之前已经有消息发布,那么这些消息会首先被放入消息队列中,等待订阅者进行接收。

话题通信的流程如下

1.发布者创建一个话题,并将特定消息类型的数据发布到该话题中。

2.订阅者订阅特定话题,等待接收该话题中的消息。

3.如果在订阅者订阅之前已经有消息发布到该话题中,那么这些消息会被放入消息队列中,等待订阅者进行接收。

4.当发布者发布新的消息时,订阅者会收到该消息并进行处理。

ROS常见的topic命令行指令

  1. rostopic echo :该命令可以用于打印某个话题的消息内容,从而实时监测该话题的状态和数据。例如,使用rostopic echo /scan可以实时显示激光雷达数据。

  2. rostopic hz :该命令可以用于查看某个话题的发布频率,从而评估系统的性能和稳定性。例如,使用rostopic hz /scan可以显示激光雷达数据的发布频率。

  3. rostopic info :该命令可以用于查看某个话题的详细信息,包括其名称、数据类型、发布者和订阅者等内容。例如,使用rostopic info /scan可以显示激光雷达数据的相关信息。

  4. rostopic list :该命令可以列举出当前ROS系统中所有可用的话题名称,从而方便用户查看和选择特定话题。例如,使用rostopic list可以显示所有可用的话题名称。

  5. rostopic pub :该命令可以用于往某个话题中输入特定的消息内容,从而模拟某些场景下的数据输入。例如,使用rostopic pub /cmd_vel geometry_msgs/Twist "{linear: {x: 0.1}, angular: {z: 0.5}}"可以向/cmd_vel话题发送一个Twist消息。

  6. rostopic bw :该命令可以用于查看某个话题的带宽使用情况,从而评估系统网络和性能瓶颈。例如,使用rostopic bw /scan可以显示激光雷达数据的带宽使用情况。

  7. rostopic find :该命令可以根据数据类型查找符合条件的话题名称,从而方便用户快速定位到特定话题。例如,使用rostopic find std_msgs/String可以查找所有数据类型为std_msgs/String的话题名称。

  8. rostopic type :该命令可以用于查看某个话题的数据类型,从而帮助用户了解该话题所传递的数据结构和内容。例如,使用rostopic type /scan可以显示激光雷达数据的数据类型。

发布话题

发布话题是指将消息发送到特定的话题,以便其他节点可以接收和处理这些消息。话题是一种基于发布-订阅模式的通信机制,它允许不同的节点之间进行异步的消息传递。

1.创建ROS节点并初始化

在开始发布消息之前,需要先创建一个ROS节点,并进行初始化。这个节点将负责发布消息到指定的话题。

cpp 复制代码
#include "ros/ros.h"

int main(int argc, char **argv)
{
    // 初始化ROS节点
    ros::init(argc, argv, "publisher_node");

    // 创建NodeHandle对象
    ros::NodeHandle nh;

    // 在这里编写发布者的代码

    return 0;
}

2.创建话题发布者

在ROS节点中,你需要创建一个话题发布者对象。话题发布者用于将消息发送到特定的话题。你需要指定话题的名称和消息类型作为发布者的参数。

ros::Publisher pub = nh.advertise<消息类型>("话题名称", 队列大小);

e.g如果要发布字符串消息到名为/chatter的话题上

cpp 复制代码
ros::Publisher pub = nh.advertise<std_msgs::String>("/chatter", 10);

3.创建消息实例并设置内容

在发布消息之前,需要创建一个对应消息类型的实例,并设置其内容。

消息类型 message;

message.字段 = 值;
e.g.

对于std_msgs::String消息类型,可以这样创建一个消息实例,并将其内容设置为"Hello, World!":

std_msgs::String message;

message.data = "Hello, World!";

4.将消息发布出去

使用话题发布者的publish()方法将消息发布到指定的话题上。

pub.publish(message);

5.保持节点运行

在发布消息后,一般需要调用ros::spin()或者ros::spinOnce()来保持节点处于运行状态,以便能够发送消息并接收其他节点发送的消息。

ros::spin();

// 或者

ros::spinOnce();

订阅话题

订阅者(Subscriber)用于接收和处理其他节点发布的消息。订阅者通过订阅特定的话题来接收消息,并在接收到消息后执行相应的回调函数进行处理。下面是订阅话题的详细步骤:

初始化ROS节点和创建NodeHandle

在开始订阅消息之前,首先需要初始化ROS节点并创建一个NodeHandle对象。

cpp 复制代码
#include "ros/ros.h"
int main(int argc, char **argv)
{
    ros::init(argc, argv, "subscriber_node");
    ros::NodeHandle nh;
    // 在这里编写订阅者的代码
    ros::spin();  // 保持节点运行
    return 0;
}

创建订阅者并指定回调函数

使用NodeHandle对象的subscribe<消息类型>("话题名称", 队列大小, 回调函数)方法创建一个订阅者,指定要订阅的消息类型、话题名称、队列大小以及接收到消息时要调用的回调函数。

ros::Subscriber sub = nh.subscribe("话题名称", 队列大小, 回调函数);

e.g如果要订阅名为/chatter的字符串消息,可以这样创建订阅者:

cpp 复制代码
void messageCallback(const std_msgs::String::ConstPtr& msg)
{
    ROS_INFO("Received message: %s", msg->data.c_str());
}

ros::Subscriber sub = nh.subscribe("/chatter", 10, messageCallback);

编写消息回调函数

消息回调函数是在接收到消息时被调用的函数,用于处理接收到的消息数据。

cpp 复制代码
void messageCallback(const 消息类型::ConstPtr& msg)
{
    // 处理接收到的消息
}

保持节点运行:

最后,在订阅消息后,通常需要调用ros::spin()或者ros::spinOnce()来保持节点处于运行状态,以便接收和处理消息。

完整的订阅者代码:

cpp 复制代码
#include "ros/ros.h"
#include "std_msgs/String.h"
void messageCallback(const std_msgs::String::ConstPtr& msg)
{
    ROS_INFO("Received message: %s", msg->data.c_str());
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "subscriber_node");
    ros::NodeHandle nh;

    ros::Subscriber sub = nh.subscribe("/chatter", 10, messageCallback);

    ros::spin();

    return 0;
}

自定义消息类型数据

创建消息文件

使用ROS消息描述语言(Message Description Language,简称msg)创建一个消息文件,该文件定义了自定义消息的结构和字段。通常,消息文件位于msg文件夹中。

e.g创建一个名为CustomMessage.msg的消息文件,其中包含一个字符串字段data

cpp 复制代码
string data

CMakeLists.txt中添加消息依赖

在ROS软件包的CMakeLists.txt文件中添加对自定义消息的依赖项。

cpp 复制代码
find_package(catkin REQUIRED COMPONENTS
  roscpp
  std_msgs
  message_generation   # 添加这行
)

add_message_files(
  FILES
  CustomMessage.msg   # 添加你创建的消息文件
)

generate_messages(
  DEPENDENCIES
  std_msgs
)

确保在CMakeLists.txtcatkin_package()函数之前添加了message_generation依赖。

编译和构建

运行catkin_make命令编译和构建ROS软件包。

cpp 复制代码
cd catkin_ws
catkin_make

使用自定义消息类型

在代码中使用自定义消息类型,包括订阅者和发布者。

cpp 复制代码
#include "ros/ros.h"
#include "package_name/CustomMessage.h"  // 替换成你的自定义消息类型

void messageCallback(const package_name::CustomMessage::ConstPtr& msg)
{
    ROS_INFO("Received message: %s", msg->data.c_str());
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "subscriber_node");
    ros::NodeHandle nh;

    ros::Subscriber sub = nh.subscribe("/chatter", 10, messageCallback);

    ros::spin();

    return 0;
}

上述将package_name替换为你的自定义消息所在的软件包名。CustomMessage是自定义消息类型的名称,需要根据实际情况进行替换。

确保在使用自定义消息之前,已经运行了catkin_make命令来编译和构建ROS软件包,以便让ROS能够正确识别和使用自定义消息类型。

注意点

在使用自定义消息之前,要确保订阅者和发布者都使用了相同的自定义消息类型,并且正确地引用了消息类型的头文件。

相关推荐
被制作时长两年半的个人练习生11 分钟前
【pytorch】权重为0的情况
人工智能·pytorch·深度学习
Elastic 中国社区官方博客26 分钟前
使用 Vertex AI Gemini 模型和 Elasticsearch Playground 快速创建 RAG 应用程序
大数据·人工智能·elasticsearch·搜索引擎·全文检索
说私域1 小时前
地理定位营销与开源AI智能名片O2O商城小程序的融合与发展
人工智能·小程序
alfiy1 小时前
Elasticsearch学习笔记(四) Elasticsearch集群安全配置一
笔记·学习·elasticsearch
向上的车轮1 小时前
Django学习笔记十一:部署程序
笔记·学习·django
Q_w77421 小时前
计算机视觉小目标检测模型
人工智能·目标检测·计算机视觉
创意锦囊1 小时前
ChatGPT推出Canvas功能
人工智能·chatgpt
知来者逆2 小时前
V3D——从单一图像生成 3D 物体
人工智能·计算机视觉·3d·图像生成
alfiy2 小时前
Elasticsearch学习笔记(五)Elastic stack安全配置二
笔记·学习·elasticsearch
pumpkin845142 小时前
CXO、CRO、CMO、CDMO相关概念
笔记