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

CMakeLists Eigen FCPX GNU Gazebo Git Interest KDL Life Linux Matrix ODE ROS Ros UML Ubuntu VcXsrv algorithm algorithms axis-angle bode calibration chrome control cpp data_struct dots figure gdb latex launch life linux mac math matlab memory motor moveit operator optimal algorithm python robot robotics ros ros2 rtb simulation stl thread tools twist urdf velocity vim web work wsl
知识共享许可协议