ros topic

ROS Topic概念

ROS Node之间进行通信所利用的最重要的机制就是消息传递,在ROS中,消息有组织的放到Topic里进行传递。

Publisher

• 生成信息,通过ROS Topic与其它Node进行通信。

• 通常用于处理原始的传感器信息,如相机、编码器等。

Subscriber

• 接收信息,通过ROS Topic接收来自其它Node的信息,并通过回调函数处理

• 通常用于监测系统状态,如当机器人关节到达限位位置时触发运动中断

Topic通信过程

1, Publisher节点和Subscriber节点分别在Master进行注册
2, Publisher发布Topic
3, Subscriber在Master指挥下订阅Topic,从而建立起Pub-Sub之间的通信

注意:消息是直接从发布节点传递到订阅节点,并不经过Master。

下图是ROS Node和ROS Topic概念的图形化表示,可以看到两个Node(圆形)通过Topic(长方形)实现通信。

发布一个topic

发布一个 ROS topic 的步骤如下:

• 确定消息类型:首先,需要知道要发布的消息类型。例如,使用标准消息类型 std_msgs/String。

• 创建发布节点:需要一个 ROS 节点来发布消息。可以使用 Python 或 C++ 编写这个节点。

以下是 C++ 示例,创建一个发布节点并每秒发布一条字符串消息:

#include "ros/ros.h"
#include "std_msgs/String.h"

int main(int argc, char **argv) {
ros::init(argc, argv, "talker");
ros::NodeHandle n;
ros::Publisher pub = n.advertise<std_msgs::String>("chatter", 1000);
ros::Rate loop_rate(1); // 1 Hz

while (ros::ok()) {
std_msgs::String msg;
std::stringstream ss;
ss << "Hello, ROS! " << ros::Time::now();
msg.data = ss.str();

ROS_INFO("%s", msg.data.c_str()); // 打印消息到日志
pub.publish(msg); // 发布消息

ros::spinOnce(); // 处理回调
loop_rate.sleep(); // 按照设定频率休眠
}

return 0;
}

发布自定义数据

如果想同时发布字符和数组,可以使用自定义消息类型或者使用现有的消息类型,比如 std_msgs/String 和 std_msgs/Float64MultiArray,并将它们封装在一个自定义消息中。

定义自定义消息

在 ROS 包中创建一个 msg 文件夹,并定义一个新的消息类型,例如 CombinedMsg.msg,内容如下:

string text
std_msgs/Float64MultiArray array

修改 package.xml 和 CMakeLists.txt

确保在 package.xml 中添加 std_msgs 的依赖,并在 CMakeLists.txt 中添加消息生成的相关配置。

在 CMakeLists.txt 中添加以下内容:

find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
message_generation
)

add_message_files(
FILES
CombinedMsg.msg
)

generate_messages(
DEPENDENCIES
std_msgs
)

到工作空间后catkin_make编译一下包

示例

发布包含字符和数组的自定义消息:

#include "ros/ros.h"
#include "your_package_name/CombinedMsg.h"

int main(int argc, char **argv) {
ros::init(argc, argv, "combined_talker");
ros::NodeHandle n;
ros::Publisher pub = n.advertise<your_package_name::CombinedMsg>("combined_topic", 1000);
ros::Rate loop_rate(1); // 1 Hz

while (ros::ok()) {
your_package_name::CombinedMsg combined_msg;

// 填充字符和数组数据
combined_msg.text = "Hello, ROS!";
combined_msg.array.data = {1.0, 2.0, 3.0, 4.0, 5.0};

ROS_INFO("Text: %s", combined_msg.text.c_str());
ROS_INFO("Array: %f %f %f %f %f", combined_msg.array.data[0], combined_msg.array.data[1], combined_msg.array.data[2], combined_msg.array.data[3], combined_msg.array.data[4]);
pub.publish(combined_msg); // 发布消息

ros::spinOnce(); // 处理回调
loop_rate.sleep(); // 按照设定频率休眠
}

return 0;
}

运行发布节点:

rosrun your_package_name your_executable_name

可以使用 rostopic echo /combined_topic 来查看发布的字符和数组数据。

参考

[1] ROS Topic
[2] chatGPT

知识共享许可协议