ROS实践笔记3

ROS话题通信模型

角色:

1. master---->管理者
2. talker---->发布者
3. listener---->订阅者

流程:

管理者可以通过话题建立发布者与订阅者之间的连接

流程实现:

1. 发布者将话题与RPC地址发送给管理者进行注册。
2. 订阅者在管理者处注册自己关注的话题。
3. 将发布者和订阅者的话题进行对比,如果二者一致,则将发布者的RPC地址发送给订阅者。
4. 订阅者根据RPC地址访问发布者
5. 发布者对订阅者的访问进行响应,并将自己的TCP地址发送给订阅者。
6. 订阅者根据TCP地址访问发布者。
7. 发布者将消息发送至订阅者

注意:

1. 使用的协议有RPC和TCP
2. 步骤1和步骤2没有顺序关系
3. talker 和listener 都可以存在很多个
4. talker 和listener 建立连接后,master就可以关闭

话题通信应用时的关注点:

1. 大部分实现已经被封装
2. 话题设计
3. 发布者实现
4. 订阅者实现
5. 消息载体

ROS中文本消息需要使用头文件

std_msgs/String.h

c++

创建一个发布者的流程:

  1. 包含头文件。
    ros/ros.h
    //消息类型的头文件,下面是文本文件的消息类型
     std_msgs/String.h
    
  2. 初始化ROS节点
  3. 创建节点句柄 NodeHandle
  4. 创建发布者对象,使用advertise函数需要范型,话题名称和队列长度为函数的参数
  5. 创建发布的消息内容并发布
    代码如下
# include"ros/ros.h"
# include"std_msgs/String.h"

int main(int argc, char  *argv[])
{
    ros::init(argc,argv,"pub");
    ros::NodeHandle nh;
    ros::Publisher pub=nh.advertise<std_msgs::String>("topic",10);
    std_msgs::String msg;
    ros::Duration(3).sleep();
    while(ros::ok())
    {
        msg.data="hello";
        pub.publish(msg);
    }
    return 0;
}

其中

ros::Duration(3).sleep();

用来延迟第一条数据的发送三秒钟

使用rostopic echo 话题名称,可以打印出发布者发布的信息

rostopic echo topic

订阅方实现

  1. 包含头文件,其中需要包含订阅的消息类型
  2. 初始化ROS节点
  3. 创建节点句柄
  4. 创建订阅者对象
  5. 处理订阅到的数据 需要手写函数
  6. spin()函数(回头,调用回调函数);
    代码如下:
# include"ros/ros.h"
# include"std_msgs/String.h"
# include<sstream>
void Domsg(const std_msgs::String::ConstPtr &msg)
{
    ROS_INFO("topic is %s",msg->data.c_str());
    return ;
}
int main(int argc, char *argv[])
{
    ros::init(argc,argv,"sub");
    ros::NodeHandle nh;
    ros::Subscriber sub=nh.subscribe("topic",10,Domsg);
    ros::spin();
    return 0;
}

使用rqt_graph命令,可以画出通信图

rqt_graph

python

发布者实现:

#! /usr/bin/env python

from ast import While
import rospy
from std_msgs.msg import String #发布消息的类型

if __name__=="__main__":
    rospy.init_node("pub") #传入节点名称
    pub=rospy.Publisher("topic",String,queue_size=10) #创建发布者对象
    msg=String() #创建消息对象
    rate=rospy.Rate(1) #制定发布频率
    count=1 #计数器
    rospy.sleep(3)
    while not rospy.is_shutdown():
        msg.data="topic"+str(count) #将数字转化为字符串
        pub.publish(msg)
        rospy.loginfo("topic is %s---->",msg.data)
        rate.sleep()
        count+=1
    #创建并发布消息

订阅者实现:

#! /usr/bin/env python

import rospy
from std_msgs.msg import String

def DoMsg(msg):# 回调函数
    rospy.loginfo("topic is -----> %s",msg.data)

if __name__=="__main__":
    rospy.init_node("sub") #初始化节点
    sub=rospy.Subscriber("topic",String,DoMsg,queue_size=10)
    rospy.spin()

其中 python 发布者中的

rospy.sleep(3)

与 c++ 发布者中的

ros::Duration(3).sleep();

作用都是让程序在发布第一条信息之前休眠3秒,使其完成注册后再发布信息,防止订阅者错过信息。

posted @   一心如旧  阅读(124)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示