话题通信是ROS中使用频率最高的一种通信模式,话题通信是基于发布订阅模式的,也即:一个节点发布消息,另一个节点订阅该消息,用于不断更新的、少逻辑处理的数据传输场景。
1.1 话题通信理论模
话题通信实现模型是比较复杂的,该模型如下图所示,该模型中涉及到三个角色:
ROS Master (管理者)
Talker (发布者)
Listener (订阅者)
ROS Master 负责保管 Talker 和 Listener 注册的信息,并匹配话题相同的 Talker 与 Listener,帮助 Talker 与 Listener 建立连接,连接建立后,Talker 可以发布消息,且发布的消息会被 Listener 订阅。
0)Talker注册
Talker启动后,会通过RPC在ROS Master中注册自身信息,其中包含所发布消息的话题名称。ROS Master会将节点的注册信息加入到注册表中。
1)Listener注册
Listener启动后,也会通过RPC在ROS Master中注册自身信息,包含需要订阅消息的话题名。ROS Master会将节点的注册信息加入到注册表中。
2)ROS Master实现信息匹配
ROS Master会根据注册表中的信息匹配Talker和Listener,并通过RPC向Listener发送Talker的RPC地址信息。
3)Listener向Talker发送请求
Listener根据接收到的RPC地址,通过RPC向Talker发送连接请求,传输订阅的话题名称、消息类型以及通信协议(TCP/UDP)。
4)Talker确认请求
Talker接收到Listener的请求后,也是通过RPC向Listener确认连接信息,并发送自身的TCP地址信息。
5)Listener与Talker件里连接
Listener根据步骤4返回的消息使用TCP与Talker建立网络连接。
6)Talker向Listener发送消息
连接建立后,Talker开始向Listener发布消息。
注意1:上述实现流程中,前五步使用的RPC协议,最后两步使用的是TCP协议;
RPC:远程过程调用(Remote Procedure Call)
TCP:传输控制协议(Transmission Control Protocol)
注意2:Talker与Listener的启动无先后顺序要求;
注意3:Talker与Listener都可以有多个;
注意4:Talker与Listener连接建立后,不再需要ROS Master,即便关闭ROS Master,Talker与Listern照常通信。
1.2 话题通信基本操作(C++)
1.3 话题通信基本操作(Python)
1.4 话题通信自定义msg
在 ROS 通信协议中,数据载体是一个较为重要组成部分,ROS 中通过 std_msgs 封装了一些原生的数据类型,比如:String、Int32、Int64、Char、Bool、Empty.... 但是,这些数据一般只包含一个 data 字段,结构的单一意味着功能上的局限性,当传输一些复杂的数据,比如: 激光雷达的信息... std_msgs 由于描述性较差而显得力不从心,这种场景下可以使用自定义的消息类型。
msgs只是简单的文本文件,每行具有字段类型和字段名称,可以使用的字段类型有:
int8, int16, int32, int64 (或者无符号类型: uint*)
float32, float64
string
time, duration
other msg files
variable-length array[] and fixed-length array[C]
ROS中还有一种特殊类型:Header,标头包含时间戳和ROS中常用的坐标帧信息。会经常看到msg文件的第一行具有Header标头。
1.4.1 定义 msg 文件
功能包下新建 msg 目录,添加文件 Person.msg
string name
uint16 age
float64 height
1.4.2 编辑配置文件
package.xml中添加编译依赖与执行依赖
<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
CMakeLists.txt编辑 msg 相关配置
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
message_generation)
需要加入 message_generation,必须有 std_msgs
配置 msg 源文件
add_message_files(
FILES
Person.msg)
生成消息时依赖于 std_msgs
generate_messages(
DEPENDENCIES
std_msgs)
执行时依赖
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES demo02_talker_listener
CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
# DEPENDS system_lib)
1.4.3 编译
编译后的中间文件查看:
C++ 需要调用的中间文件(.../工作空间/devel/include/包名/xxx.h)
Python 需要调用的中间文件(.../工作空间/devel/lib/python3/dist-packages/包名/msg)
后续调用相关 msg 时,是从这些中间文件调用的
1.5 话题通信自定义msg调用(C++)
vscode 配置:将前面生成的 head 文件路径配置进c_cpp_properties.json的 includepath属性;
1.6 话题通信自定义msg调用(Python)
vscode配置:将前面生成的 python 文件路径配置进 settings.json的extraPaths的属性;