ROSTCP的使用和原理
背景:
ROS通信设计是基于TCP和UDP 实现的,使用频率最多的是ROSTCP,可以保持稳定的长链接,在日常使用中,开发者无需关心具体设计,但是随着研发的深入以及通信的问题暴露,了解ROS的通信设计显得越来越重要,本篇基于官方文档整理该部分的说明
1、ROSTCP
TCPROS is a transport layer for ROS Messages and Services. It uses standard TCP/IP sockets for transporting message data. Inbound connections are received via a TCP Server Socket with a header containing message data type and routing information
ROSTCP是基于标准的socket用来处理msg 和service 的传输层,通过头部的消息类型和路由信息来收发数据
1.1 ROSTCP的Header
Inbound connections to a TCPROS Server Socket are routed by information contained within the header fields. If the header contains the 'topic' field, it will be routed as a connection to a ROS Publisher. If it contains a 'service' field, it will be routed as a connection to a ROS Service.
rostcp 区分不同的连接,是根据topic 和service 两个字段区分,topic 对应的连接到publish 的tcp,service 对应的是连接到service 连接
ROSTCP 的头部信息额外包含:
- callerid: name of node sending data
- topic: name of the topic the subscriber is connecting to
- service: name of service the client is calling
- md5sum: md5sum of the message type
- type: message type
- message_definition: full text of message definition (output of gendeps --cat)
- error: human-readable error message if the connection is not successful
- persistent: sent from a service client to a service. If '1', keep connection open for multiple requests.
- tcp_nodelay: sent from subscriber to publisher. If '1', publisher will set TCP_NODELAY on socket if possible
- latching: publisher is in latching mode (i.e. sends the last value published to new subscribers)
不同的连接类型,如订阅者和发布者的header 就会不一样
特别注意的是 service 的有个ok 的字段出现在给请求中的响应中
如果ok 是 1 表示 后面必须跟service 的响应消息
如果ok 是 0 表示 序列化的错误消息
A TCPROS publisher is required to reply with the following fields on a successful connection:
- md5sum: md5sum of the message type
- type: message type
判断一个订阅是否成功的标识 是md5 和message type同时判断
2、ROSUDP
UDPROS is a transport layer (in development) for ROS Messages and Services. It uses standard UDP datagram packets to transport serialized message data. The UDPROS transport is useful when latency is more important than reliable transport. Examples in the robotics domain include teleoperation as well as streaming audio.
ROSUDP这里和ROSTCP类似,都是传输层,通过标准的udp数据包来传输序列化数据,目前主要远程控制和流式媒体,但是还在开发中
+---------------------------------+
| Connection ID |
+---------------------------------+
|Opcode | Msg ID | Block # |
+---------------------------------+
- Connection ID - This 32-bit value is determined during connection negotiation and is used to denote which connection the datagram is destined for. This parameter allows a single socket to service multiple UDPROS connections.
- Opcode - UDPROS supports multiple datagram types. The opcode specifies the datagram type. This 8-bit field can have the following possible values:
- DATA0 (0) - This opcode is sent in the first datagram of a ROS message
- DATAN (1) - All subsequent datagrams of a ROS message use this opcode
- PING (2) - A heartbeat packet is sent periodically to let the other side know that the connection is still alive
- ERR (3) - An error packet is used to signal that a connection is closing unexpectedly
- Message ID - This 8-bit value is incremented for each new message and is used to determine if datagrams have been dropped.
- Block # - This 16-bit value is 0 unless the opcode is DATA0, then this field contains the total number of UDPROS datagrams expected to complete the ROS message. When the opcode is DATAN, this field contains the current datagram number.
3、message
3.1 message 的file
msg files are simple text files for specifying the data structure of a message. These files are stored in the msg subdirectory of a package
msg file 是特殊消息格式的简单文本文件,存储在msg 子目录下
3.2 message type
Message types use standard ROS naming conventions: the name of the package + / + name of the .msg file
In addition to the message type, messages are versioned by an MD5 sum of the .msg file. Nodes can only communicate messages for which both the message type and MD5 sum match.
msg 的类型是包名+msg文件名字
msg的类型匹配,必须msg 匹配并且 msg文件的md5也匹配
3.3 building
msg 文件的build 会在devel 生成一个头文件,其中
namespace :msg 文件所属的package name
struct: msg 文件的name+下划线
以简单的msg 为例
namespace u_msgs { template <class ContainerAllocator> struct Source_ { typedef Source_<ContainerAllocator> Type; Source_() : source(0) { } Source_(const ContainerAllocator& _alloc) : source(0) { (void)_alloc; } typedef uint32_t _source_type; _source_type source; typedef boost::shared_ptr< ::u_msgs::Source_<ContainerAllocator> > Ptr; typedef boost::shared_ptr< ::u_msgs::Source_<ContainerAllocator> const> ConstPtr; }; // struct Source_
3.4 header
A message may include a special message type called 'Header', which includes some common metadata fields such as a timestamp and a frame ID. The ROS Client Libraries will automatically set some of these fields for you if you wish, so their use is highly encouraged.
msg 可能包含头部信息,这些头部信息包含帧ID和时间戳等信息
3.5 msg 的回调
在回调中,分为单线程回调和多线程回调,可以设置队列,根据接收的频繁程度来设定队列的长度
单线程回调如何保证数据的顺序性:
多线程回调:
ros::AsyncSpinner spinner(4); //可以设置4个核
设置SubscribeOptions的allow_concurrent_callbacks为true。可以订阅同一个topic
4、service
service 是通过 srv 文件规定请求和回复的格式
4.1 build
srv 文件会生成三个头文件,分别是srv.name 、srv.name+"Request"和srv.name+"Response"
4.2 type
service 的type 和topic 类似,是package name + name of .srv file
In addition to the service type, services are versioned by an MD5 sum of the .srv file. Nodes can only make service calls if both the service type and MD5 sum match. This ensures that the client and server code were built from a consistent codebase.
和msg 类似,版本匹配也是通过md5来做校验
参考:
http://wiki.ros.org/ROS/TCPROS
https://levelup.gitconnected.com/ros-spinning-threading-queuing-aac9c0a793f

浙公网安备 33010602011771号