ROS通信机制

目录

ROS中基本通信机制

一、遇到的问题及解决方法

二、理解内容总结


ROS中基本通信机制

话题通信 服务通信 参数服务器
模式 发布订阅 请求响应 参数共享
双方 发布方和订阅方 服务端(server)和客户端(client) 共享数据和节点
数量 都可以有多个 都可以存在多个
节点关系 多对多 一对多(一个server)
启动顺序 发布方和订阅方谁先启动都可以

服务端先启动

客户端后请求

(即客户端发起请求时客户端已启动)

关注点

master在其中起一个中间媒介连接的作用

0.流程已经被封装直接调用即可;1.话题;2.发布方、服务端;3.订阅方、客户端;4.数据载体

怎样联系 共同的话题 客户端先发起请求,服务端回应 先有一个容器放数据,可以从里边拿或放,是共享的
理解示例 APP选择关注方向,比如体育、科技(关注内容就是话题),关注之后就会自动推送你关注的内容 浏览器搜索,输入网址后回车就会响应一些相关信息 实验室有元器件,实验室的人都可以拿或放
案例演示 控制小乌龟做你想要的运动

获取乌龟位姿

在指定位置生成一只新的乌龟

改变乌龟窗口的背景颜色
代码实现 发布方发布的数据可以被订阅方接受到 两个数字求和 实现参数增删改查操作
应用场景 适用于不断更新(不间断)的数据传输 适用于对时时性有要求、具有一定逻辑处理的应用场景 适用于存在数据共享的一些应用场景
话题通信自定义msg

适用于当传输一些复杂的数据,比如: 激光雷达的信息(包含雷达的扫描角度,测出的障碍物距离),需要用到其他的消息类型如float;类似于C中的结构体

步骤

  • 创建功能包person.msg,设置要使用的字段(数据类型+名字)
  • package.xml中添加编译依赖与执行依赖
  • CMakeLists.txt编辑 msg 相关配置
  • 编译后会生成一些中间文件在devel中
自动生成的中间文件
  • include里面包含有头文件Person.h,以后想要调用弄好的自定义数据,如果使用C++定义就可以#include 包含进去了,调用时就可以直接使用了;如果使用python语言调用Person.py文件,这两个都是自动生成的
  • Person语言在lib目录下,运用同上
C++ Python
配置文件路径 避免代码误抛异常,将前面生成的 head 文件路径配置进vscode目录下的 c_cpp_properties.json  将前面生成的 Person.py 文件路径配置进vscode目录下的  settings.json
与内置的消息类型的区别
  • 消息类型是自定义的
  • 配置文件多一个依赖

一、遇到的问题及解决方法

1.自定义msg配置文件CMakeLists.txt时三处顺序,顺序错误会报错

#第一处
add_executable(person_pub src/person_pub.cpp)
add_executable(person_sub src/person_sub.cpp)

#第二处
#可以保证编译关系,配置这个后意味着会先编译自定义的Person.msg文件,再编译可执行的源文件person_pub.cpp和/person_sub.cpp 
add_dependencies(person_pub ${PROJECT_NAME}_generate_message_cpp )
add_dependencies(person_sub ${PROJECT_NAME}_generate_message_cpp )

#第三处
target_link_libraries(person_pub
  ${catkin_LIBRARIES}
)
target_link_libraries(person_sub
  ${catkin_LIBRARIES}
)

2.问题:使用自定义msg时,配置文件弄好了但还报错

ROS通信机制_第1张图片

解决方法:看vscode目录下的/home/interest/again2/.vscode/c_cpp_properties.json下的路径

 "includePath": [
        "/opt/ros/noetic/include/**",
        "/usr/include/**",       //**代表包含include下所有文件
        "/home/interest/again2/devel/include/**"                          //第一个
        //"/home/interest/again2/src/huati_tongxin/include/huati_tongxin" //第二个

      ],
        //第一个是/home/ubuntu名/工作空间/devel/include/**
        //第二个是/home/ubuntu名/工作空间/src/功能包名/include/功能包名(比较全的路径)
    //可以第一个和第二个试着弄,只用其中一个就能编译成功,具体哪一个要尝试

可以第一个和第二个试着弄,只用其中一个就能编译成功,具体哪一个要尝试

3.问题:Python代码和编译和配置文件都没有错,但运行时报了下列错误:

ROS通信机制_第2张图片

 解决方法:代码导包时是否少了路径/home/interest/again2/devel/lib/python3/dist-packages/huati_tongxin/msg下的.msg

#导包

import rospy
#from huati_tongxin import Person(错)
from huati_tongxin.msg import Person(对)

4.服务通信自定义消息类型生成中间文件时报错

问题:

解决办法: 会自动在c_cpp_properties.json改路径

ROS通信机制_第3张图片

5.问题:刷新环境变量报错

解决方法:必须在工作空间下

interest@interest:~/tongxin2$ cd ..
interest@interest:~$ source ./devel/setup.bash
bash: ./devel/setup.bash: 没有那个文件或目录
interest@interest:~$ cd tongxin2
interest@interest:~/tongxin2$ source ./devel/setup.bash 
interest@interest:~/tongxin2$ 

常用命令
命令行 作用
pwd 打印代码路径
rqt_graph

计算图查看

rosnode : 操作节点

rostopic : 操作话题

rosservice : 操作服务

rosmsg : 操作msg消息

rossrv : 操作srv消息

rosparam : 操作参数

动态命令,终端命令行启动后使用

区别:

rosnode info /节点

rostopic info 话题

注意:

查看自定义的消息要进入相应的工作空间

rostopic echo +话题名 获取指定话题当前发布的消息
rosservice call 话题 tab补齐 服务通信查看数据
rosparam list 列出一系列参数
rosparam get /键名 获取对应键名的值
rosmsg list | grep -i 自定义消息名 查看自己定义的消息类型

二、理解内容总结

1.ros节点名称要保证唯一性,不然启动下一个后前一个会被盖掉

2.回调函数doMsg

特点:每订阅一条信息都会执行一它

 回调函数与一般函数的最大区别:

  • 一般(自己写的)调用函数,代码执行,执行到它就直接去调用这个函数了;函数什么时候被调用时可以掌控的,有需要就去调用执行了;像一颗子弹小鬼子过来了我就开枪打小鬼子
  • 回调函数在从上到下执行程序的过程中不一定被执行,语法上虽然出现这个函数名了,但不是马上执行,而是等待外部的一个时机,等到外部有一个消息msgs传递过来了msgs就像一个铃铛一样提醒回调函数一下该执行了;是由外部消息控制的;像一个地雷提前埋好,小鬼子过来踩着(外部消息)了就打着小鬼子了

3.说软启动,就是延迟启动,开机后延缓一会才启动,相当于有一个缓冲区;可以加上休眠函数解决

4.rqt_graph要在数据显示时(执行相关源文件后)再使用

椭圆里是节点名,箭头上方是共同的话题,箭头指向代表消息传递的顺序

ROS通信机制_第4张图片

 5.ros当中极其重要的特点:节耦合

尽管使用不同的语言写的节点也可以实现数据交换,只要保证话题一样即可。

6.服务通信涉及到int main(int argc, char *argv[])参数问题

具体详解见http://t.csdn.cn/H3Syr

7.python中try ... except ... as...的作用  http://t.csdn.cn/TAq37

8.实操内置小乌龟运行

roscore

rosrun turtlesim turtlesim_node

rosrun turtlesim turtle_teleop_key

(一)需求描述:编码实现乌龟运动控制,让小乌龟做圆周运动。

rostopic list  和rqt_graph   得到乌龟运动话题是/turtle1/cmd_vel

rostopic type /turtle1/cmd_vel   获取消息类型

rostopic info /turtle1/cmd_vel   得到消息类型,发布方,订阅方

rosmsg show geometry_msgs/Twist    得到消息格式

         有乌龟运动(偏航)的线(x有值)速度(linear)和角(z有值)速度(angular)

                  线速度主要和直线上前进后退的速度有关,角速度主要和拐弯的速度有关

线速度

在空间直角坐标系下

x 线走
y 垂直着走
z 上下方向走

注: 麦克纳母轮有y方向速度,无人机有y,z方向速度

角速度

欧拉角

再转换成

四元素

x 翻滚(相当于半打滚的左晃右晃) roll
y 俯仰(抬头低头) pitch
z 偏航(左右移动,平面的垂直方向进行左拐右拐) yaw

rostopic echo /turtle1/cmd_vel        打印乌龟运动(键盘控制)速度消息

命令行做圆周运动

interest@interest:~$ rostopic pub -r 10 /turtle1/cmd_vel geometry_msgs/Twist "
linear:
  x: 1.0      //只有x方向上有速度
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 2.0"      //只有z轴方向上有速度,值越大圆的半径越小

还有代码实现(比较灵活)

(二)需求描述: 已知turtlesim中的乌龟显示节点,会发布当前乌龟的位姿(窗体中乌龟的坐标以及朝向),要求控制乌龟运动,并时时打印当前乌龟的位姿。

获取话题:/turtle1/pose
rostopic list

获取消息类型:turtlesim/Pose
rostopic type /turtle1/pose

获取消息格式:
rosmsg info turtlesim/Pose

响应结果:
​float32 x
float32 y          //x,y是位姿
float32 theta      //theta是方向(朝向)
float32 linear_velocity
float32 angular_velocity

//朝向是以弧度为单位的rad,逆时针转为递增,顺时针转为递减

(三)需求描述:编码实现向 turtlesim 发送请求,在乌龟显示节点的窗体指定位置生成一乌龟,这是一个服务请求操作。

获取话题:/spawn
rosservice list

获取消息类型:turtlesim/Spawn
rosservice type /spawn

获取消息格式:
rossrv info turtlesim/Spawn

响应结果:
float32 x         
float32 y         //x、y是位姿 
float32 theta     //朝向,180°=3.14;90°=3.14/2=1.57
string name
---            //将请求(上面)和响应(下面)分开了
string name

(四)需求描述: 修改turtlesim乌龟显示节点窗体的背景色,已知背景色是通过参数服务器的方式以 rgb 方式设置的。

获取参数列表:
rosparam list

响应结果:
/turtlesim/background_b
/turtlesim/background_g
/turtlesim/background_r

//查看颜色具体值
rosparam get /turtlesim/background_r
69
//改变颜色值
rosparam set /turtlesim/background_g
255

R(red)G(green)B(blue)的值都是0-255

b=255,g=0,r=0      是黑色

b=0,g=255,r=0      是绿色

b=0,g=0,r=255      是红色

b=0,g=0,r=0      是白色

9.学习了入门之后ROS通信机制的进阶最好去官方了解学习

你可能感兴趣的:(学习)