ROS1(三):ROS1相关工具


目录:

ROS1相关工具

rosbag

在 ROS 系统中,可以使用 bag 文件来保存和恢复系统的运行状态,比如录制雷达和相机话题的 bag 包,然后回放用来进行联合外参标定。

rosbag 基本作用

rosbag 工具可以录制一个包、从一个或多个包中重新发布消息、查看一个包的基本信息、检查一个包的消息定义,基于 Python 表达式过滤一个包的消息,压缩和解压缩一个包以及重建一个包的索引。

rosbag 目前常用的命令如下:

  • record:用指定的话题录制一个 bag 包。
  • info:显示一个 bag 包的基本信息,比如包含哪些话题。
  • play:回放一个或者多个 bag 包。
  • check:检查一个 bag 包在当前的系统中是否可以回放和迁移。
  • compress:压缩一个或多个 bag 包。
  • decompress:解压缩一个或多个 bag 包。
  • reindex:重新索引一个或多个损坏 bag 包。

在目前项目的使用中,用的最多的就是 record、info 以及 play 功能,先录制想要的话题包,录制完毕检查下包的信息,最后再回放作为算法的输入。

官方文档:http://wiki.ros.org/rosbag/Commandline

rosbag record

官方文档:http://wiki.ros.org/Bags/Format/2.0

rosbag 文件结构:

#ROSBAG V2.0
<record 1><record 2>....<record N>

Version 2.0的ROS bag文件格式增加了一些新特点:

  • 1) 压缩: 消息(message)存储在块(chunk)中,可以单独压缩,同时仍然允许随机访问;
  • 2) 高级索引: 第二级索引允许工具快速收集包文件的统计信息;
  • 3) 面向连接: 消息通过连接(connection)存储,使得重新发布记录的消息更加可信;
  • 4) 精简: 格式已被精简,例如,消息时间戳(message timestamp)的存储大小几乎是以前的一半;消息记录不包含重复的主题(topic)和连接(connection)信息。

其中 record 的结构如下:

<header_len><header><data_len><data>

其中 header 的结构如下:

<field1_len><field1_name>=<field1_value><field2_len><field2_name>=<field2_value>...<fieldN_len><fieldN_name>=<fieldN_value>

例如一个简单的 record 数据:

<header_len><field1_len>op=0x02<field2_len>conn=0<field3_len>time=<message_time><data_len><serialized_message_data>

每个记录头 (header) 由 N 个 field 组成(name = value 字段序列),其中 op 属性的 field 是每个 record 必须的,其它一些 field 是可选的。

fieldX_name = fieldX_value 的总长度包括’=’字符,是 fieldX_len 字段。这个头序列的总长度(包括名称、’=’字符、值长度和值)是 header_len 字段。

header 中的各个字段 field 可以以任何顺序出现。字段名(fieldX_name)可以包含任何可打印的ASCII字符(0x20 - 0x7e), ‘=’ (0x3d)除外。

字段值(fieldX_value)可以包含任何数据(包括嵌入空值、换行符等的二进制数据)。

通过 op field 可以指定 record 的类型,一共有6种不同的 op field 属性,对应6种不同的 record。注意每种 record 除了op field 之外,还包括自己特定的 field。op字段用于区分不同类型的记录,下面的op值是有效的(按它们第一次出现在bag中的顺序列出):

  • Bag header:存储关于整个bag的信息,比如到第一个索引数据记录的偏移量(offset),以及块(chunk)和连接(connection)的数量。
  • Chunk. 存储(可能是压缩的)连接和消息记录。
  • Connection:存储ROS连接的头信息,包括主题名称(topic name)和消息定义(message definition)的全文。
  • Message data:使用连接的 ID 存储序列化的消息数据,可以是零长度。(Stores the serialized message data with the ID of the connection)
  • Index data:在前一个块的单个连接中存储消息索引。(Stores an index of messages in a single connection of the preceding chunk)
  • Chunk info:将有关消息的信息存储在一个块中。

接下来详细介绍:

Bag header

bag header 作为第一条 record 记录在文件中出现一次。 以下字段必须出现在bag header记录中(op=0x03):

  • index_pos:块部分后第一条记录的偏移量。
  • conn_count:文件中唯一连接的数量。
  • chunk_count:文件中的块记录数。

包头记录(Bag header record)先用ASCII空格字符(0x20)填充,包头总长度为 4096 Bytes(header_len+data_len)。之所以先填充的原因为在写入后面的数据后,可以方便的修改包头记录。

Chunk

以下字段必须出现在 chunk 记录中(op=0x05):

  • compression:数据的压缩类型。
  • size:未压缩块的字节大小。

支持的压缩类型为“none”和“bz2”。 块的压缩大小可以在 record 的 data_len 字段中找到。 chunk 记录的 data 部分由消息数据(message)和连接记录(connection)组成,使用chunk 的 header 中指定方法压缩。

Connection

以下字段必须出现在 connection 记录的 header 部分(op=0x07):

  • conn:唯一连接 ID。
  • topic:存储消息的主题。

数据由一个字符串组成,该字符串包含与包记录头(bag record header)格式相同的连接头(the connection header)。 以下字段必须出现在连接头中:topic、type、md5sum、message_definition。 可选字段包括:callerid、latching。 存在两个 topic 字段(分别在 data 和 header 中),这是因为消息可以写入与最初发布的 topic 不同的 bag 文件。

Message data

以下字段必须出现在消息数据的header部分(op=0x02):

  • conn:消息到达的连接ID。
  • time:收到消息的时间。

这些记录中的数据是ROS序列化消息数据。

Index data

以下字段必须出现在索引数据的header部分(op=0x04):

  • ver:索引数据记录版本。
  • conn:连接ID。
  • count:前一个块中 conn 上的消息数。

这些记录中的 data 取决于文件头中的版本,如果版本号为1,还包括以下字段。

  • time:收到消息的时间。
  • offset:未压缩块数据中消息数据记录的偏移量。
Chunk info

以下字段必须出现在块信息的 header 部分(op=0x06):

  • ver:块信息记录版本。
  • chunk_pos:块记录的偏移量。
  • start_time:块中最早消息的时间戳。
  • end_time:块中最新消息的时间戳。
  • count:块中的连接数。

这些记录中的data取决于文件头中的版本,如果版本号为1,还包括以下字段。

  • conn:连接ID。
  • count:块中到达此连接的消息数。

rosbag 常用命令

rosbag record

使用 record 订阅指定主题并生成一个 bag 文件,其中包含有关这些主题的所有消息,常见用法如下。

用指定的话题 topic_names 来录制 bag 包:

rosbag record <topic_names>

比如录制 rosout、tf、cmd_vel 3 个话题,录制的 bag 包以时间命名:

rosbag record rosout tf cmd_vel

录制完保存 bag 包名称为 session1 + 时间戳.bag 格式:

rosbag record -o session1 /chatter

录制完保存为指定文件名 session2_090210.bag

rosbag record -O session2_090210.bag /chatter

录制系统中所有的话题:

rosbag record -a

使用 -h 查看 record 使用方法,很多命令都可以用这个:

rosbag record -h
rosbag info

rosbag info 显示包文件内容的可读摘要,包括开始和结束时间,主题及其类型,消息计数、频率以及压缩统计信息,常见用法如下:

显示一个 bag 包的信息:

rosbag info name.bag
$ rosbag info foo.bag
path:        foo.bag
version:     2.0
duration:    1.2s
start:       Jun 17 2010 14:24:58.83 (1276809898.83)
end:         Jun 17 2010 14:25:00.01 (1276809900.01)
size:        14.2 KB
messages:    119
compression: none [1/1 chunks]
types:       geometry_msgs/Point [4a842b65f413084dc2b10fb484ea7f17]
topics:      /points   119 msgs @ 100.0 Hz : geometry_msgs/Point

查看常用命令:

rosbag info -h

输出 YAML 格式的信息:

rosbag info -y name.bag

输出 bag 中指定域的信息,比如只显示持续时间:

rosbag info -y -k duration name.bag
rosbag play

rosbag play 读取一个或多个 bag 文件的内容,并以时间同步的方式回放,时间同步基于接收消息的全局时间。回放开始后,会根据相对偏移时间发布消息。

如果同时回放两个单独的 bag 文件,则根据时间戳的间隔来播放。比如我先录制一个 bag1 包,等待一个小时,然后录制另一个 bag2 包,那我在一起回放 bag1 和 bag2 时,在回放的中间会有 1 个小时的停滞期,也就是先回放 bag1,然后需要等待 1 个小时才能回放 bag2。

在回放过程中按空格暂停,常见用法如下

回放单个 bag:

rosbag play record.bag

回放多个 bag,基于全局时间间隔播放:

rosbag play record1.bag record2.bag

开始播放立刻暂停,按空格继续:

rosbag play --pause record.bag

以录制的一半频率回放:

rosbag play -r 0.5 --pause record.bag

指定回放频率,默认 100HZ:

rosbag play --clock --hz=200 record.bag

循环播放:

rosbag play -l record.bag
rosbag check

检查一个 bag 在当前系统中是否可以回放:

rosbag check xxx.bag
rosbag compress

如果录制的 bag 很大,我们可以压缩它,默认的压缩格式是 bz2:

rosbag compress xxx.bag

你也可以添加 -j 手动指定压缩格式为 bz2:

rosbag compress -j xxx.bag

也可以使用 LZ4 来压缩数据:

rosbag compress --lz4 xxx.bag
rosbag decompress

压缩完后,使用需要解压缩:

rosbag decompress xxx.bag
rosbag reindex

如果回放遇到问题,提示 reindex 的话,直接执行即可,这个会自动生成一个原 bag 的备份:

rosbag reindex xxx.bag
回放

常用的是以暂停的方式启动,防止跑掉数据:

rosbag play --pause record.bag

也可以直接回放:

rosbag play record.bag

设置以 0.5 倍速回放,也就是以录制频率的一半回放:

rosbag play -r 0.5 record.bag

回放完后,会用 rostopic list 查看下发布的主题,确保是需要的:

rostopic list
rosbag reinde

在回放包的时候报错,提示需要 reindex,执行一下即可,不过数据好像会少一些:

rosbag reindex xxx.bag

下面是完整的 rosbag 用法,需要的可以查找下。

rosrun

rosrun 允许使用包名直接运行包内的节点(无需知道包路径)

使用格式:

rosrun [package_name] [node_name]

可以首先使用 rosnode 命令来查询对应的node信息:

rosnode list

rqt_graph

rqt_graph 可以以界面的形式展示当前 node 之间的相互关系。

rosnode

rosnode 提供和 node 相关的命令,可以使用 -h 来查看具体的使用:

  • rosnode list:列出所有的节点
  • rosnode info node_name:查看 node_name 的详细信息

rostopic

rostopic 提供和 topic 相关的命令,可以使用 -h 来查看具体的使用:

  • rostopic list:列出所有的topic
  • rostopic pub topic_name 消息结构 消息内容:向指定的topic来发布数据

rosmsg

rosmsg 提供和 mag 相关的命令,可以使用 -h 来查看具体的使用:

  • rosmsg show msg_name:展示消息定义的格式