学习地址

0、话题通讯理论模型

前言:

话题通信基本操作(C++)
注:启动roscore的时候rosmaster已经启动了,因此ROS master 不需要实现,而连接的建立也已经被封装了(因此连接也不需要被关注了),话题是在发布方和订阅方内部实现的时候设置的,因此需要关注的关键点有三个:
发布方
接收方
数据(此处为普通文本)

案例一

1、发布方实现(p42 p43)

1.1 建立工作空间

步骤参照之前的笔记贴

1.2创建功能包

右击工作空间下的src,选择Create Catkin Package。
输入功能包名字 plumbing_pub_sub 按enter
导入ros功能包 roscpp rospy std_msgs 按enter

1.3发布者代码编写

功能包创建完毕,开始进行发布者实现
在功能包下的src目录下建立一个c++源文件:右击src,新建文件,名为demo01_pub.cpp
代码如下,这次为发布方实现的代码


/*需求: 实现基本的话题通信,一方发布数据,一方接收数据,实现的关键点:1.发送方2.接收方3.数据(此处为普通文本)PS: 二者需要设置相同的话题消息发布方:循环发布信息:HelloWorld 后缀数字编号实现流程:1.包含头文件 2.初始化 ROS 节点:命名(唯一)3.实例化 ROS 句柄4.实例化 发布者 对象5.组织被发布的数据,并编写逻辑发布数据*/
// 1.包含头文件
#include "ros/ros.h"
#include "std_msgs/String.h" //普通文本类型的消息
#include <sstream>int main(int argc, char  *argv[])
{   //设置编码  防止中文的日志输出乱码setlocale(LC_ALL,"");//2.初始化 ROS 节点:命名(唯一)// 参数1和参数2 后期为节点传值会使用// 参数3 是节点名称,是一个标识符,需要保证运行后,在 ROS 网络拓扑中唯一ros::init(argc,argv,"talker");//3.实例化 ROS 句柄ros::NodeHandle nh;//该类封装了 ROS 中的一些常用功能//4.实例化 发布者 对象//泛型: 发布的消息类型//参数1: 要发布到的话题//参数2: 队列中最大保存的消息数,超出此阀值时,先进的先销毁(时间早的先销毁)ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",10);//5.组织被发布的数据,并编写逻辑发布数据//数据(动态组织)std_msgs::String msg;// msg.data = "你好啊!!!";std::string msg_front = "Hello 你好!"; //消息前缀int count = 0; //消息计数器//逻辑(一秒10次)ros::Rate r(1);//节点不死while (ros::ok()){//使用 stringstream 拼接字符串与编号std::stringstream ss;ss << msg_front << count;msg.data = ss.str(); //拼接上一行的数据流//发布消息pub.publish(msg);//加入调试,打印发送的消息ROS_INFO("发送的消息:%s",msg.data.c_str());//根据前面制定的发送贫频率自动休眠 休眠时间 = 1/频率;r.sleep(); //类始于单片机的delaycount++;//循环结束前,让 count 自增//暂无应用ros::spinOnce(); //这里的发布方没有回调函数,所以这个函数不起作用}return 0;
}

1.4配置CMakeLists.txt文件

CMakeLists.txt在与demo01_pub.cpp同级目录,一般在137行与150行
137行映射格式:add_executable(自定义映射名称 src/cpp的文件名称),配置后如下
add_executable(xixixi src/demo01_pub.cpp)
150行:将${PROJECT_NAME}换为自定的映射名称 即为xixixi

1.5命令行操作

在编写并且配置完发布方实现后,通过终端对所以发布方代码进行查看

第一步:启动roscore
命令行:roscore
第二步:启动功能包
命令行:cd demo04_ws/ 切换到工作空间
source ./devel/setup.bash
rosrun plumbing_pub_sub xixixi (plumbing_pub_sub是功能包名 xixixi是自定义的映射名)

           到这里就开始输出日志了

另外可以通过第三步
rostopic echo fang(fang是设置的主题)

2、订阅方实现(p44)

在上有的基础上创建demo01_sub.cpp,下面为订阅者实现的代码

/*需求: 实现基本的话题通信,一方发布数据,一方接收数据,实现的关键点:1.发送方2.接收方3.数据(此处为普通文本)消息订阅方:订阅话题并打印接收到的消息实现流程:1.包含头文件 2.初始化 ROS 节点:命名(唯一)  **也就是订阅放的ROS节点的命名不能与发布方相同**3.实例化 ROS 句柄4.实例化 订阅者 对象5.处理订阅的消息(回调函数)6.设置循环调用回调函数*/
// 1.包含头文件
#include "ros/ros.h"
#include "std_msgs/String.h"
/*这里是回调函数,函数参数是 订阅的发布消息的常量指针的引用,获取msg_p中的data*/
void doMsg(const std_msgs::String::ConstPtr& msg_p){ROS_INFO("我听见:%s",msg_p->data.c_str());// ROS_INFO("我听见:%s",(*msg_p).data.c_str());
}
int main(int argc, char  *argv[])
{setlocale(LC_ALL,"");//2.初始化 ROS 节点:命名(唯一)ros::init(argc,argv,"listener");//3.实例化 ROS 句柄ros::NodeHandle nh;//4.实例化 订阅者 对象ros::Subscriber sub = nh.subscribe<std_msgs::String>("chatter",10,doMsg);//std_msgs::String代表std_msgs库中的string类型//5.处理订阅的消息(回调函数)//     6.设置循环调用回调函数ros::spin();//循环读取接收的数据,并调用回调函数处理,否则main函数只执行一次return 0;
}

代码写完后ctrl+shift+B编译一下看看有没有问题
同样同发布方一样配置的配置方法。
配置终端后

就可以正常接受订阅方的消息了
如果想让终端一直发送和接受的消息停下来,按ctrl+c,关闭节点(也就是ros::ok()函数判定为不ok了)
这就是案例一的实现了

3.注意事项:P45

3.1一个常见问题描述

问题:先打开订阅方 ,再打开发布方,依然会有前面几条数据没有收到。
原因:为发布方还未在roscore完成注册。
解决方法:解决方法是给发布方一个延时的发送函数。在发送内容的函数前,加一个延时函数,如 ros::Duration(3.0).sleep(); 延时3s即可

3.2ros经常用到的回调函数,什么是回调函数

老师的描述:普通函数是子弹,看见鬼子来了就打一枪
回调函数是地雷,不由自己控制,由外界来触发
比较像单片机的中断触发

4.计算图 P45

计算图并没有扩展ros的功能,但是可以直观地让我们看到不同节点之前的关系
在发布订阅都实现后,新开一个终端,输入rqt_graph ,可以查看计算图。
命令行输入:

计算图:节点talker把主题chatter发送给订阅方节点listener

案例二

1 基础配置

1.1新建文件夹及写好固定格式

在plumbing_pub_sub功能包下右击新建文件夹,创建名为msg的文件夹,msg文件夹下建立名为Person的文件。

/**msg的格式类始于结构体**/
string name
int32 age
float32 height

2.1配置package.xml

加入这两行

2.2配置CMakeLists.txt

在find_package添加message_generation find_package:编译时依赖

取消add_message_files的注释并修改
删除掉原有的 Message1.msg和Message2.msg的示例,添如自建的msg,Person.msg

将generate_messages取消注释

添加message_runtime功能包 catkin_package编译时依赖

2.3.编译

Ctrl+Shift+B后编译报错 错误如下:
– Configuring incomplete, errors occurred!
See also “/home/zhaojianqiao/demo04_ws/build/CMakeFiles/CMakeOutput.log”.
See also “/home/zhaojianqiao/demo04_ws/build/CMakeFiles/CMakeError.log”.
make: *** [Makefile:558: cmake_check_build_system] Error 1
Invoking “make cmake_check_build_system” failed
编译问题解决方法地址
然后可以在得到C++ 需要调用的中间文件(…/工作空间/devel/include/包名/xxx.h)

2.4.vscode配置

目的:为了让vscode能够找到上一步生成的.h文件
操作步骤:右击Person.h,选择在集成终端中打开,输入命令行pwd,终端则会显示.h文件所在位置
打开c_cpp_properties.json 文件来配置 includepath属性:
相同的格式将.h文件进行配置, “/home/zhaojianqiao/demo04_ws/devel/include/**”

**表示包含include文件夹下的所有内容

3.发布方实现

/*需求: 循环发布人的信息*/#include "ros/ros.h"
#include "plumbing_pub_sub/Person.h"int main(int argc, char *argv[])
{setlocale(LC_ALL,"");//1.初始化 ROS 节点ros::init(argc,argv,"talker_person");//2.创建 ROS 句柄ros::NodeHandle nh;//3.创建发布者对象ros::Publisher pub = nh.advertise<plumbing_pub_sub::Person>("chatter_person",1000); //话题名称+队列长度  发布方要写一个泛型类型,泛型类型根据消息类型指定//4.组织被发布的消息,编写发布逻辑并发布消息plumbing_pub_sub::Person p;p.name = "sunwukong";p.age = 2000;p.height = 1.45;ros::Rate r(1);while (ros::ok()){pub.publish(p);p.age += 1;ROS_INFO("我叫:%s,今年%d岁,高%.2f米", p.name.c_str(), p.age, p.height);r.sleep();ros::spinOnce();}return 0;
}

在配置CMakeLists.txt时需多添加一个
add_dependencies(demo03_pub_person ${PROJECT_NAME}_generate_messages_cpp)
目的是为了防止在源文件已经编译,但msg还未被编译的情况发生。

4.订阅方实现

订阅方代码

/*需求: 订阅人的信息*/#include "ros/ros.h"
#include "plumbing_pub_sub/Person.h"void doPerson(const plumbing_pub_sub::Person::ConstPtr& person_p){ROS_INFO("订阅的人信息:%s, %d, %.2f", person_p->name.c_str(), person_p->age, person_p->height); //这里是回调函数
}int main(int argc, char *argv[])
{   setlocale(LC_ALL,"");//1.初始化 ROS 节点ros::init(argc,argv,"listener_person");//2.创建 ROS 句柄ros::NodeHandle nh;//3.创建订阅对象ros::Subscriber sub = nh.subscribe<plumbing_pub_sub::Person>("chatter_person",10,doPerson);//主题名称+队列长度+回调函数//4.回调函数中处理 person//5.ros::spin();ros::spin();    return 0;
}

一样需要在CMakeLists.txt时需多添加一个

ros学习笔记_服务通讯相关推荐

  1. ROS学习笔记_创建工作空间(一)

    创建工作空间 mkdir -p ~/catkin_ws_2/src -p参数是将路径上的父子目录同时创建. $ cd ~/catkin_ws_2/ $ catkin_make 在工作空间的根目录下运行 ...

  2. ROS 学习笔记(三):自定义服务数据srv+server+client 示例运行

    ROS 学习笔记(三):自定义服务数据srv+Server+Client 示例运行 一.自定义服务数据: 1.向功能包添加自定义服务文件(AddTwoInts.srv) cd ~/catkin_ws/ ...

  3. ROS学习笔记十:用C++编写一个简单的服务和客户端

    ROS学习笔记十:用C++编写一个简单的服务和客户端 这一节主要介绍如何使用C++编写一个简单的服务和客户端节点. 编写服务节点 由于在前面的练习中,已经向beginner_tutorials软件包中 ...

  4. ROS学习笔记六:理解ROS服务和参数

    ROS学习笔记六:理解ROS服务和参数 主要介绍ROS服务和参数,同时使用命令行工具rosservice和rosparam. ROS service service是节点之间互相通信的另一种方式,se ...

  5. ROS学习笔记基础2(基础知识和ROS架构)

    ROS学习笔记1(基础知识和ROS架构) 文章目录 ROS学习笔记1(基础知识和ROS架构) 1. 什么是ROS 2. ROS和其他机器人平台有什么不同 3. ROS架构组成 3.1 文件系统级别 3 ...

  6. ROS学习笔记(八): ROS通信架构

    ROS学习笔记(八): ROS通信架构 文章目录 01 Node & Master 1.1 Node 1.2 Master 1.3 启动master和node 1.4 rosrun和rosno ...

  7. ROS学习笔记八:创建ROS msg和srv

    ROS学习笔记八:创建ROS msg和srv 本节主要讲述了如何创建和建立ROS msg和srv,同时使用命令行工具rosmsg.rossrv和roscp. msg和srv简介 msg:描述ROS m ...

  8. ROS学习笔记五:理解ROS topics

    ROS学习笔记五:理解ROS topics 本节主要介绍ROS topics并且使用rostopic和rqt_plot命令行工具. 例子展示 roscore 首先运行roscore系列服务,这是使用R ...

  9. ROS学习笔记四:理解ROS节点

    ROS学习笔记四:理解ROS节点 本节主要介绍ROS图形概念,讨论ROS命令行工具roscore.rosnode和rosrun. 要求 要求已经在Linux系统中安装一个学习用的ros软件包例子: s ...

最新文章

  1. docker安装问题:E: Package 'docker-ce' has no installation candidate
  2. NetTier模板生成的代码框架用法 (转)
  3. linux编辑文档windows,1.9vim编辑器linux内核的底层文本编辑器,跟windows系统上的文本文档类似,大部分用这个工具进行文本的编辑,这个工具的操作方式基本上用不到鼠标,多是...
  4. Java常见面试知识点:继承、接口、多态、代码块
  5. 一款JS+CSS实现的无缝平滑图片滚动代码
  6. Emmet插件比较实用常用的写法
  7. paper 134:结构张量structure tensor(二)
  8. 一体机or复合机?企业文印设备该怎么选
  9. 铺铜规则在哪设定_干货丨PCB layout结合生产设计必须遵循这六大规则!
  10. 小说Symbian的签名
  11. 自举电容充电回路分析
  12. android 拍照水印日期,胶片日期水印app安卓版-胶片日期水印手机版预约v1.0-发卡屋...
  13. 微型计算机的指令集,窥视灵魂深处 AMD新一代SIMD指令集剖析
  14. Unity实现动态修改模型材质球
  15. 遇见你,是最美的意外
  16. mysql保留小数位数函数
  17. neogeo模拟器 linux,neogeo模拟器
  18. golang 格式化占位符相关
  19. 服务搭建篇(七) Elasticsearch单节点部署以及多节点集群部署
  20. 高德WMTS图层 调用天地图瓦片地图

热门文章

  1. 相约上海,以边缘计算之名!
  2. 国际域名相关仲裁政策法规
  3. 原生JS中DOM节点相关API合集
  4. avast! 2014正式版下载
  5. 数显倾角传感器的应用
  6. 新年礼物送什么好?五款高颜值的蓝牙耳机盘点
  7. stdlib.h和stdio.h有什么区别
  8. 如何最简单把pdf转cad格式操作呢?
  9. Typora+PicGo-Core搭建个人在线笔记
  10. java jai例子_java – 使用JAI将swing组件写入大型TIFF图像