零基础入门ros

1.话题通信的简单介绍

  • 话题通信是ROS中使用频率最高的一种通信模式,话题通信是基于发布订阅模式的,也即:发布方发布消息,订阅方接收并处理消息。发布方通过特定的话题来发布消息,订阅者选择性订阅自己感兴趣的主题来接受相关的消息。

通俗来说就像是你在B站上点了追番或追剧,等这部番剧(电视剧)更新了会给你推送消息一样,你不点追番他那边的消息照常发,只是你这边没有接收(订阅)而已,发布者和订阅者之间并没有直接的依赖关系。

1.1作用

  • 用于不断更新的、少逻辑处理的数据传输场景。

2.话题通信的理论模型

  • 就是由rosmaster通过话题建立发布者和订阅者之间的连接
  • 先放图吓一下
    在这里插入图片描述
  • 这小图还有小英文(图中的词汇)根本看不懂->指博文作者本人
    下面我来系统的讲解一下这个小图:

0.talker先在rosmaster进行注册自己的话题“bar”,foo(远程调用地址)
1.listener在rosmaster注册自己关注的话题
2.rosmaster把发布者和订阅者的话题进行比对,一样的就会把发布者的地址发送给listener
3.listener通过rosmaster给的地址远程访问talker
4.talker响应listener其中包含了talker的TCP地址
5.listener就可以用这个TCP地址去访问talker
6.talker就可以发布消息给listener

  • **不懂?**没关系再看下面这个
    在这里插入图片描述

master——主人这里可以理解为中介,起到桥梁的作用
图中个人信息相当于话题名,手机号相当于PRC(远程调用地址)
微信号相当于TCP地址

  • 以上就是理论模型的介绍

3.话题通信基本操作

在模型实现中我们只需要关注三个点就好(很多已经被封装好了):
1.发布方
2.接收方
3.数据(此处为普通文本)

大致流程为:

  • 编辑发布方
  • 编辑订阅方
  • 编辑配置文件(格外小心)
  • 编译执行

3.1发布方实现

3.1.1编辑前准备

注:以下代码均以c++为例

  • 在工作空间中创建功能包并添加依赖

在这里插入图片描述

在这里插入图片描述

  • 添加依赖
    在这里插入图片描述
  • 创建cpp文件
    在这里插入图片描述
    这里名字自己想

3.1.2编辑发布方代码

  • 包含头文件
// 1.包含头文件 
#include "ros/ros.h"
#include "std_msgs/String.h" //普通文本类型的消息
#include <sstream>
  • 编写框架
int main(int argc, char  *argv[])
{   


  return 0;
}
  • 设置编码(目的是解决中文乱码)
 setlocale(LC_ALL,"");
  • 初始化节点
    //ROS 节点:命名(唯一)
    // 参数1和参数2 后期为节点传值会使用
    // 参数3 是节点名称,是一个标识符,需要保证运行后,在 ROS 网络拓扑中唯一
    ros::init(argc,argv,"xiaoshuai");
  • 创建节点句柄
 
    ros::NodeHandle nh;//该类封装了 ROS 中的一些常用功能
  • 创建发布者对象
    //泛型: 发布的消息类型
    //参数1: 要发布到的话题
    //参数2: 队列中最大保存的消息数,超出此阀值时,先进的先销毁(时间早的先销毁)
    ros::Publisher pub = nh.advertise<std_msgs::String>("fang",10);

队列其实就是一个缓冲区,当满了后先来的最先被销毁为后面的提供空间
advertise是一个创建发布者对象的一个函数
std_msgs::String这个就是泛型类型

  • 编写发布逻辑并发布数据(以10hz为例)
//创建被发布的消息
std_msgs::String msg;
//发布频率
ros::Rate rate(10);
//设置编号
int count = 0;
//编写循环,循环中发布数据
 while (ros::ok())
    {

        //使用 stringstream 拼接字符串与编号
        std::stringstream ss;
        ss << "hello ---> "<< count;
        msg.data = ss.str();
        //发布消息
        pub.publish(msg);
        //加入调试,打印发送的消息
        ROS_INFO("发送的消息:%s",msg.data.c_str());
        rate.sleep();
        count++;//循环结束前,让 count 自增
    }
       

3.1.3配置cmakelists文件

在这里插入图片描述

  • 这里元素1是映射节点名称建议跟创建的文件名一样,元素2是cpp文件名

在这里插入图片描述

  • 把上面的映射名称写在这就行了

  • 编译(ctrl+shift+B)成功了就是配置的没什么问题

3.1.4测试一下代码执行

  • 打开终端(Ctrl+Alt+T)输入命令

在这里插入图片描述

  • 以上就是基本的发布方实现

3.2订阅方实现

  • 前面的步骤和发布者一样我们直接从编辑代码开始

3.2.1编辑订阅者代码

  • 框架和发布者也是一样的,我们来看创建订阅者对象
 ros::Subscriber sub = nh.subscribe<std_msgs::String>("fang",10,doMsg);
 //doMsg是一个回调函数用来处理订阅到的数据
  • 处理订阅到的消息(编辑回调函数doMsg)
void doMsg(const std_msgs::String::ConstPtr &msg)
{
	//通过msg获取并操作订阅到的数据
    ROS_INFO("小美订阅的数据:%s",msg->data.c_str());
  
}
  • 设置循环调用回调函数
ros::spin();//循环读取接收的数据,并调用回调函数处理

3.2.2编辑cmakelists

在这里插入图片描述
在这里插入图片描述

编译—看看是否通过

4.执行

  1. 打开终端输入

roscore

  1. 直接分割终端或者再打开两个,到工作空间下命令(cd+你自己的工作空间/)
  2. 配置环境

source ./devel/setup.bash

  1. 执行命令分别输入

rosrun + 你的功能包+你的发布者或订阅者文件

  1. 下面是结果:
    在这里插入图片描述

先运行哪个都没有关系,运行成功后master就算关闭也没有什么影响

成功后可以用

rqt_graph
查看节点之间的关系
在这里插入图片描述

  • 下面是cpp完整版代码

发布者

#include "ros/ros.h"
#include "std_msgs/String.h" //普通文本类型的消息


int main(int argc, char  *argv[])
{   
    setlocale(LC_ALL,"");
    //ROS 节点:命名(唯一)
    // 参数1和参数2 后期为节点传值会使用
    // 参数3 是节点名称,是一个标识符,需要保证运行后,在 ROS 网络拓扑中唯一
    ros::init(argc,argv,"xiaoshuai");
    ros::NodeHandle nh;//该类封装了 ROS 中的一些常用功能
 	//泛型: 发布的消息类型
    //参数1: 要发布到的话题
    //参数2: 队列中最大保存的消息数,超出此阀值时,先进的先销毁(时间早的先销毁)
    ros::Publisher pub = nh.advertise<std_msgs::String>("fang",10);
    //创建被发布的消息
    std_msgs::String msg;
    //发布频率
    ros::Rate rate(10);
  	//设置编号
  	int count = 0;
  	//编写循环,循环中发布数据
    while (ros::ok())
    {

        //使用 stringstream 拼接字符串与编号
        std::stringstream ss;
        ss << "hello ---> "<< count;
        msg.data = ss.str();
        //发布消息
        pub.publish(msg);
        //加入调试,打印发送的消息
        ROS_INFO("发送的消息:%s",msg.data.c_str());
        rate.sleep();
        count++;//循环结束前,让 count 自增
    }
     return 0;
}

订阅者

#include "ros/ros.h"
#include "std_msgs/String.h" //普通文本类型的消息
#include <sstream>

void doMsg(const std_msgs::String::ConstPtr &msg)
{
	//通过msg获取并操作订阅到的数据
    ROS_INFO("小美订阅的数据:%s",msg->data.c_str());
  
}


int main(int argc, char  *argv[])
{   
     setlocale(LC_ALL,"");
     ros::init(argc,argv,"xiaomei");
     ros::NodeHandle nh;
     ros::Subscriber sub = nh.subscribe<std_msgs::String>("fang",10,doMsg);
     //doMsg是一个回调函数用来处理订阅到的数据
     ros::spin();
  return 0;
}
  • 主笔:@famgke
    修正:dym踏雪寻梅,Kyuno_wh
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值