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);
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);
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