ROS话题中的发布和订阅

1.创建Publisher

Publisher的主要作用是针对制定话题发布特定数据类型的消息。我们用代码实现一个节点,并且在节点中创建一个Publisher并发布字符串“Hello World”,代码如下:

#include <sstream>
#include "ros/ros.h"
#include "std_msgs/String.h"

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

     //创建节点句柄
ros::NodeHandle n;

     //创建一个Publisher,发布名为chatter的topic,消息类型为std_msgs::String
ros::Publisher chatter_pub =n.advertise<std_msgs::String>("chatter",1000);

      //设置循环的频率
ros::Rate loop_rate(10);

int count = 0;

while (ros::ok())
{
     // 初始化std_msgs::String类型的消息
      std_msgs::String msg;
      std::stringstream ss;
      ss <<"hello world" << count;
      msg.data = ss.str();
  
    //发布消息
      ROS_INFO("%s",msg.data.c_str());
      chatter_pub.publish(msg);
      

      //循环等待回调函数
      ros::spinOnce();

      //按照循环频率延时
       loop_rate.sleep();
       ++count;
}
return 0;
}

2.创建Subscriber

下面创建一个Subscriber以订阅Publisher节点发布的“Hello World”字符串,实现代码如下:

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

 //接收到订阅的消息后,会进入消息回调函数

void chatterCallback(const std_msgs::String::ConstPtr& msg)
{
         //将接收到的信息打印出来
        ROS_INFO("I heard: [%s]",msg->data.c_str());
}

int main (int argc, char **argv)
{
        //初始化ROS节点

       ros::init(argc,argv,"listener");
     
       //创建节点句柄
       ros::NodeHandle n;

   //创建一个Subscriber,订阅名为chatter的话题,注册回调函数chatterCallback

    ros::Subscriber sub=n.subscribe("chatter",1000,chatterCallback);
    
     //循环等待回调函数
   
     ros::spin();

      return 0;
}

3.编译功能包

我们使用C++语言来编写,所以需要使用CMaker编译器进行编译,编译规则通过功能包中的CMakerLists.txt文件设置,使用catkin命令创建,我们需要对部分内容进行更改;

打开功能包中的CMakerLists.txt文件,找到以下配置项,去掉注释并稍作修改:

## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)
##add_executable(hello ~/Alltest/catkin_ws/src/learning_communication/src/hello.cpp)

add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
add_dependencies(talker ${PROJECT_NAME}_generate_messages_cpp)

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
add_dependencies(listener ${PROJECT_NAME}_generate_messages_cpp)

4.运行PublisherSubscriber

在工作空间根目录设置环境变量并编译:

source devel/setup.bash
catkin_make

a.启动ROS Master

roscore

b.启动Publisher

source devel/setup.bash
rosrun learning_communication talker

c.启动Subscriber

source devel/setup.bash
rosrun learning_communication listener

这样就运行起来了,效果如下:

 

ROS(Robot Operating System)是一种用于机器人开发的开源框架,其中“话题”(Topic)机制是一个非常重要的通信手段。通过发布订阅的方式,节点之间可以实现异步、解耦的消息传递。 ### ROS话题发布订阅简介 1. **话题的概念** 在ROS中,“话题”是一条消息总线,它允许多个节点共享某种类型的实时数据流。每个话题都有唯一的名称,并且只允许一种特定的数据类型(如`std_msgs/String`, `sensor_msgs/Image`等)。如果某个节点需要发送信息给其他节点,则可以通过将该信息作为一条消息发布到指定的话题上来完成;而希望接收此信息的其他节点则需对该主题进行订阅操作。 2. **发布者与订阅者的角色** - 发布者(Publisher):负责向某话题发布数据的进程称为发布者。它可以周期性地广播某些传感器读数或其他计算结果。 ```python # 示例 (Python): 创建一个名为 'chatter' 的 String 类型话题并持续发布 "Hello World" 消息 import rospy from std_msgs.msg import String def talker(): pub = rospy.Publisher('chatter', String, queue_size=10) rospy.init_node('talker', anonymous=True) rate = rospy.Rate(1) # 定义频率为每秒一次 while not rospy.is_shutdown(): hello_str = "hello world %s" % rospy.get_time() rospy.loginfo(hello_str) pub.publish(hello_str) rate.sleep() if __name__ == '__main__': try: talker() except rospy.ROSTimeoutException as e: pass ``` - 订阅者(Subscriber):监听某一话题的所有更新内容并将它们处理掉的过程即被称为订阅动作。一旦有新消息到达对应队列里时,回调函数就会被执行来获取这条最新收到的信息。 ```python # 示例 (Python): 监听由上面示例产生的 chatter 主题上所发布的字符串值 import rospy from std_msgs.msg import String def callback(data): rospy.loginfo(rospy.get_caller_id() + ": I heard '%s'", data.data) def listener(): rospy.init_node('listener', anonymous=True) rospy.Subscriber("chatter", String, callback) rospy.spin() if __name__ == '__main__': listener() ``` 3. **特点总结** - 异步通讯模型——无需等待对方回应即可继续运行; - 支持一对多或多对一模式下的交互场景构建; - 数据交换形式多样包括但不限于图像帧序列化传输等等丰富应用领域内的需求满足情况良好。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值