ROS编程入门(C++ 及 思路)
使用Autolabor官方入门教程,笔记内容为注意事项
首页 - Autolabor开源ROS机器人底盘 - 官方网站
_______________________________________________________
一. ROS通信机制的解释
例如在生活中,我们在家里有一个放零食的箱子,而操作服务器就是这个箱子,无论是使用者还是开发者都可以共同使用他。
1.话题通信 是ROS中使用频率最高的一种通信模式,话题通信是基于发布订阅模式的,也即:一个节点发布消息,另一个节点订阅该消息
雷达------->导航(计算)-------->底盘
在传递消息和传递运动控制指令时,就使用了话题通信,那么
雷达就是发布, 导航是订阅发布,底盘是订阅。
简单的三要素,发布 - 订阅 - 中间要素
角色----> 流程 ----> 注意
(1)角色:
1. master -----> 管理者(媒婆)
2. talker ------>发布者 (男方)
3. listner ------->订阅者 (女方)
(2)流程 :
master 可以根据话题 建立发布者和订阅者之间的连接
0. 男方提交信息 (房,手机号) ——————发布者比订阅者信息多
1. 女方提交信息 (房)
2. 媒婆把男方电话发给女方
3. 女方打电话给男方(房 连接)
4. 男方响应(加微信/给微信)
5. 女方加男方微信
(3)注意:
1.使用的协议由RPC和TCP;
2.步骤1和步骤0没有顺序关系
3.talker 和 listener可以存在多个
4.建立连接后,master就可以关闭了
5.上述流程已经封装,直接调用就好
—————————————————————————
我们要设置 发布 和 订阅方(分别进行)- (我们的实操部分只进行C++实现案例)
接下来 将从头开始一一介绍(VScode的配置请参照上面的链接进行修改,否则无法正常调试)
一 : 发布框架+发布逻辑
-----------------
(1)建立工作空间
建立 demo02_ws 工作空间
键入 code. 可以直接用vs打开工作空间
--------------------
(2)添加包 (头文件)---第一次为文件名,第二次为我们添加的包(后面服务可作修改)
-----------------------------
(3)新建一个发布者文件(写代码的位置,在src目录下新建一个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();count++;//循环结束前,让 count 自增//暂无应用ros::spinOnce();}return 0;
}
------------------------
(4)在 CmakeLists 里面修改参数 (映射名字和定义名字最好一样)
修改下面两处
(1)
(2)
然后shift+ctrl+b调试看看有没出错
-----------------------------------------
(5)启动ros核心 roscore rosrun rostopic(下面还会有具体说明)
进入工作空间的方法:
————————————————————————————————————
二:订阅方
(1)新建订阅方文件(在src文件里)
具体内容:
/*需求: 实现基本的话题通信,一方发布数据,一方接收数据,实现的关键点:1.发送方2.接收方3.数据(此处为普通文本)消息订阅方:订阅话题并打印接收到的消息实现流程:1.包含头文件 2.初始化 ROS 节点:命名(唯一)3.实例化 ROS 句柄4.实例化 订阅者 对象5.处理订阅的消息(回调函数)6.设置循环调用回调函数*/
// 1.包含头文件
#include "ros/ros.h"
#include "std_msgs/String.h"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);//5.处理订阅的消息(回调函数)// 6.设置循环调用回调函数ros::spin();//循环读取接收的数据,并调用回调函数处理return 0;
}
-------------------------------
(2)修改 CmakeLists
与发布者相同,对比着上面修改一下名称即可
-------------------------------
(3)启动命令行
与上面相同,同时启动3个命令行
但是这次最后一个也是rosrun启动
---------------------------------
注意事项在所给的课件里面有提到
如果要使用计算图查看,就再建立一个命令行
就可以查看了
-----------------------------------------------
自定义话题通信: (前置步骤)
(1)在上面的基础上继续完成,建立一个新的文件夹和一个个人文件
(msg 与 person.msg)
内容如下:
(2)接着,进行配置 (两处)
package.xml
CmakeList
我们要配置依赖关系
接着编译一下,可以生成我们过程中需要的文件
——————————————————————————
发布方:
1.前置步骤 配置vscode
在终端中打开
(2)新建一个自定义发布文件(仍然在之前建立的plu包下的src文件)
具体内容如下:
#include "ros/ros.h"
#include "plumbing_pub_sub/Person.h"int main(int argc,char *aegv[])
{
setlocale(LC_ALL,"");
//1 初始化节点
ros::init(argc,argv,"banZhuRen");
//2 创建句柄
ros::NodeHandle nh;
//3 创立发布对象
ros::Pulisher pub = nh.advertise<plumbing_pub_sub::Person>("liaoTian",10);// 4-1 创建发布数据
plumbing_pub_sub::Person person;
person.name = "张三";
person.age = 1;
person.height = 1.73;
// 4-2 创建发布频率
ros::Rate rate(1);
// 4-3 循环发布
while(ros::ok())
{
//修改被发布数据
person.age+=1;
//数据发布
pub.publish(person);
ROS_INFO("发布消为:%s,%d,%.2f",person.name.c_str(),person,age.c_str(),person.height.c_str());
//休眠
rate.sleep();
// 最好写
ros::spinOnce();}return 0;
}
接下来的内容与上面一样,但是cmakelists里面多配置一个
添加完成后再编译一下
-----------------------
(3)运行
roscore
-------------------------------------------
对于订阅方也相同
新建一个文件,然后写内容
void doPerson(const plumbing_pub_sub::Person::ConstPtr& person)
{
ROS_INFO("订阅消息为:%s,%d,%.2f",person.name.c_str(),person,age.c_str(),person.height.c_str());
}
int main(int argc.char *argv[])
{
setlocale(LC_ALL,"");
ros::init(argc,argv,"jiaZhang");
ros::NodeHandle nh;
ros::Subscriber sub = nh/subscribe("liaoTian",10,doPerson);ros::spin();
}
Cmakelist的三个配置也一样
自定义与官方的区别在于,多了一个配置,其它的东西都是大同小异
—————————————————————————————————————
二- 服务通信
服务通信也是ROS中一种极其常用的通信模式,服务通信是基于请求响应模式的,是一种应答机制。也即: 一个节点A向另一个节点B发送请求,B接收处理请求并产生响应结果返回给A。
机器人巡逻过程中,控制系统分析传感器数据发现可疑物体或人... 此时需要拍摄照片并留存
定义srv 文件内的可用数据类型与 msg 文件一致,且定义 srv 实现流程与自定义 msg 实现流程类似:
步骤如下:
按照固定格式创建srv文件
编辑配置文件
编译生成中间文件
调用svc 文件,流程如下:
- 编写服务端实现
- 编写客户端实现
- 编辑配置文件
- 编译并执行
----------------------------------------------
接下来为详细操作:
(1)创建新的功能包
新建服务文件夹和文件(srv 与 Addints.srv)
package 和 Cmakelist下更改配置
--------------------------------------
在 src 目录下建立deno01_server.cpp
具体内容如下:
/*需求: 编写两个节点实现服务通信,客户端节点需要提交两个整数到服务器服务器需要解析客户端提交的数据,相加后,将结果响应回客户端,客户端再解析服务器实现:1.包含头文件2.初始化 ROS 节点3.创建 ROS 句柄4.创建 服务 对象5.回调函数处理请求并产生响应6.由于请求有多个,需要调用 ros::spin()*/
#include "ros/ros.h"
#include "demo03_server_client/AddInts.h"// bool 返回值由于标志是否处理成功
bool doReq(demo03_server_client::AddInts::Request& req,demo03_server_client::AddInts::Response& resp){int num1 = req.num1;int num2 = req.num2;ROS_INFO("服务器接收到的请求数据为:num1 = %d, num2 = %d",num1, num2);//逻辑处理if (num1 < 0 || num2 < 0){ROS_ERROR("提交的数据异常:数据不可以为负数");return false;}//如果没有异常,那么相加并将结果赋值给 respresp.sum = num1 + num2;return true;}int main(int argc, char *argv[])
{setlocale(LC_ALL,"");// 2.初始化 ROS 节点ros::init(argc,argv,"AddInts_Server");// 3.创建 ROS 句柄ros::NodeHandle nh;// 4.创建 服务 对象ros::ServiceServer server = nh.advertiseService("AddInts",doReq);ROS_INFO("服务已经启动....");// 5.回调函数处理请求并产生响应// 6.由于请求有多个,需要调用 ros::spin()ros::spin();return 0;
}
接下来再第一个CMakeList里面继续修改(也就是大包的Cmake)
(P137)----修改内容如下
P137
add_excutable(demo01_server src/demo01_server.cpp)P147
add_dependencies(demo01_server ${PROJECT_NAME}_gencpp)p150 开始 下面注释去掉
target_link_libraries(demo01_server${catkin_LIBRARIES})
配置完成后,打开三个命令行
roscorecd demo03_ws/
source ./devel/setup.bash
rosrun plumbing_server_client demo01_server
就可以使用了
---------------------------------
三 - 参数服务器
参数服务器实现是最为简单的,该模型如下图所示,该模型中涉及到三个角色:
- ROS Master (管理者)
- Talker (参数设置者)
- Listener (参数调用者)
ROS Master 作为一个公共容器保存参数,Talker 可以向容器中设置参数,Listener 可以获取参数。
(直接再虚拟机上操作)
---------------------------------------------------------------------------
实操控制乌龟运动
具体内容如下:
/*编写 ROS 节点,控制小乌龟画圆准备工作:1.获取topic(已知: /turtle1/cmd_vel)2.获取消息类型(已知: geometry_msgs/Twist)3.运行前,注意先启动 turtlesim_node 节点实现流程:1.包含头文件2.初始化 ROS 节点3.创建发布者对象4.循环发布运动控制消息
*/#include "ros/ros.h"
#include "geometry_msgs/Twist.h"int main(int argc, char *argv[])
{setlocale(LC_ALL,"");// 2.初始化 ROS 节点ros::init(argc,argv,"control");ros::NodeHandle nh;// 3.创建发布者对象ros::Publisher pub = nh.advertise<geometry_msgs::Twist>("/turtle1/cmd_vel",1000);// 4.循环发布运动控制消息//4-1.组织消息geometry_msgs::Twist msg;msg.linear.x = 1.0;msg.linear.y = 0.0;msg.linear.z = 0.0;msg.angular.x = 0.0;msg.angular.y = 0.0;msg.angular.z = 2.0;//4-2.设置发送频率ros::Rate r(10);//4-3.循环发送while (ros::ok()){pub.publish(msg);ros::spinOnce();}return 0;
}
修改CMakeList配置:
启动命令行运行:
-----------------------------------------------
订阅乌龟位姿(话题订阅)
-------准备工作-------
1. 新建launch文件(节点)
2. 启动launch节点
3. 通过命令方式获得位姿
-----------------------------
以程序方式来打印位姿
package配置
CmakeList配置
添加功能包
-----------
2.新建文件:test02_sub_pose
内容如下:
/* 订阅小乌龟的位姿: 时时获取小乌龟在窗体中的坐标并打印准备工作:1.获取话题名称 /turtle1/pose2.获取消息类型 turtlesim/Pose3.运行前启动 turtlesim_node 与 turtle_teleop_key 节点实现流程:1.包含头文件2.初始化 ROS 节点3.创建 ROS 句柄4.创建订阅者对象5.回调函数处理订阅的数据6.spin
*/#include "ros/ros.h"
#include "turtlesim/Pose.h"void doPose(const turtlesim::Pose::ConstPtr& p){ROS_INFO("乌龟位姿信息:x=%.2f,y=%.2f,theta=%.2f,lv=%.2f,av=%.2f",p->x,p->y,p->theta,p->linear_velocity,p->angular_velocity);
}int main(int argc, char *argv[])
{setlocale(LC_ALL,"");// 2.初始化 ROS 节点ros::init(argc,argv,"sub_pose");// 3.创建 ROS 句柄ros::NodeHandle nh;// 4.创建订阅者对象ros::Subscriber sub = nh.subscribe<turtlesim::Pose>("/turtle1/pose",1000,doPose);// 5.回调函数处理订阅的数据// 6.spinros::spin();return 0;
}
再次配置CMakeList
----------------------------------------
启动乌龟(启动launch文件)后,再新建命令行
cd demo02_ws/
source ./devel/setup.bash
rosrun plumbing_test test02_sub_pose
ROS编程入门(C++ 及 思路)相关推荐
- ROS编程入门教程(全过程示例代码)
ROS系统目前主流语言为C++/Python , Python需要安装vscode, 所以本文使用C++ .编译使用catkin (catkin和rosbuild都能用) 首先创建工作空间(worki ...
- 5. ROS编程入门--航迹推算(dead reckoning)
TASK 这篇教程主要是测量机器人的里程计误差的,让机器人重复的走固定的路线,在这里我让机器人走正方形,比较机器人的起始位置(理想状态是重合的) 以及 局部里程计(机器人自身测算得)和全局里程计的的位 ...
- 【OpenCV学习】 《OpenCV3编程入门》--毛星云 01 邂逅OpenCV(OpenCV基本概念与基本架构) ROS系统上的运用(python实现)
对 <OpenCV3编程入门>第一章的学习笔记:理解什么是计算机视觉,什么是OpenCV,以及其中的联系等等. PS:此书为2014年出版,opencv的版本和接口也与现在有些不一致了,作 ...
- 【一学就会的ROS基础入门教程 】03-1 ROS基础编程:ROS工作空间的创建、话题topic的发布与接收、以及话题消息的自定义使用
[一学就会的ROS基础入门教程 ]03-1 ROS基础编程:ROS工作空间的创建.话题topic的发布与接收.以及话题消息的自定义使用 文前白话 1.创建工作空间与功能包 关于工作空间的介绍 创建开发 ...
- python机器人编程教程入门_机器人操作系统(ROS)入门必备:机器人编程一学就会...
原标题:机器人操作系统(ROS)入门必备:机器人编程一学就会 ROS经过十几年的发展,已经得到了极大的推广和应用,尤其是在学术界.卡耐基梅隆大学机器人研究所的大部分实验室都是基于ROS编程的,现在所在 ...
- python编程求圆的面积案例_Python实用案例编程入门:第七章 调式手段
本章的主题为调试手段,这是程序开发必不可少的步骤,也是占用时间最多的环节.在程序员的正常开发工作中,调试工作至少占据1/3的时间,而实际编码工作相对占用实际比较少.因此,无论您是初学者,还是编程兴趣爱 ...
- mapreduce程序输出评分8.6分以上的书名和评分_如何选编程入门资料?光评分高怎么够|文末赠书...
说到编程入门,很多人第一想到的肯定是Python. 那么,编程零基础应当如何开始学 Python ,才不会入门即放弃?一开始的学习资料的选择尤为重要.那么,如何筛选适合自己的入门资料?这里和大家谈谈我 ...
- 脑残式网络编程入门(三):HTTP协议必知必会的一些知识
为什么80%的码农都做不了架构师?>>> 本文原作者:"竹千代",原文由"玉刚说"写作平台提供写作赞助,原文版权归"玉刚说&q ...
- plc维修入门与故障处理实例_电气控制基础+PLC编程入门+工程应用实例
以S7-300/400PLC为主线 电气控制基础+PLC编程入门+工程应用实例 点击图片 购买 编辑推荐1.西门子S7300/400PLC应用广.市场占有率高 2.本书通过大量的实验案例和真实的工程 ...
最新文章
- 跨网页的新手引导_IOS中新手引导页面的实现(新手引导,Guide)
- ABAP函数:SD_VBAP_READ_WITH_VBELN(根据销售订单读取表vbap中的信息)
- mysql 分组排序取前n_mysql分组排序取前N条记录的最简洁的单条sql ! | 学步园
- 试题 G: 外卖店优先级 第十届蓝桥杯
- SAP UI5 patternYYY : detailZZZ/{contextPath} - navigation test
- 求职信计算机工程师英语作文,开发工程师英文求职信范文
- 学数学但是不会计算机,数学差的人不配学计算机?布朗大学教授告诉你一毛钱关系都没有!...
- nvl,空时的推断和取值
- 有哪些激光雷达SLAM算法?
- 牛客网-《剑指offer》-二进制中1的个数
- win7/win10下sublime使用Monaco字体,出现边缘发虚的情况——解决方案
- u2 接口 服务器硬盘,M.2、U.2谁更好?主流硬盘接口都有哪些?
- win10计算机记录,Win10新版计算器用法介绍
- 2021最新软件测试面试题(含答案)
- Java报表导出有哪些技术_报表工具能实现怎么的导出效果?
- jmeter 接口测试 签名_JMeter处理接口签名(sign)
- EMC trainning杂谈
- vue 定位所在地_vue使用高德地图,精确定位ip定位,获取城市、地区位置
- 调研发现,CEO对全球经济增长的悲观情绪创新高
- 国行Switch Joy-Con手柄-摇杆漂移的官方解决方法(送修)
热门文章
- Ubuntu 20.04安装绿联PL2303串口驱动
- Thingworx自定义扩展开发(三)- echarts集成
- 进程子进程 线程子线程结束问题
- iOS之Category和Extention的区别
- 三阶魔方大中小魔公式_三阶魔方的入门玩法教程|魔方玩法|魔方视频教程|魔方公式图解|--想成为魔方高手就来魔方乐园吧...
- PVM振动测量2018~2020调研整理
- 测试人员怎样定位bug原因
- Arduino零基础入门
- 【观察】“专精特新”数智化国产替代,为何首选用友U9cloud?
- matlab转化成c语言,matlab转化成c语言的有关问题不会了