跳到主要内容

RFrame CLI 用户手册

本文介绍 RFrame 对外提供的 rframe CLI 命令和工具,方便日常使用和调试。

1. 使用前:依赖与安装​

1.1. Deb 包及其依赖​

统一 CLI 由 robby-data-tools Deb 提供,安装后公开入口为 /usr/bin/rframe。

Deb 包是否必需用途
robby-data-tools必需提供 rframe 命令及录制、回放和诊断功能
r-frame必需基础通信组件
r-log必需日志组件
jsoncpp(如 robby-jsoncpp)必需,缺少时需要用户手动安装JSON 处理库;当前不会随本包自动安装
r-frame-plugin按需安装扩展 ROS2 通信、消息解析和发现能力;需要完整 ROS2 功能时建议安装
robby-yaml-cpp必需,缺少时需要用户手动安装YAML 处理库;echo、pub、service call 运行时需要,当前不会随本包自动安装

robby-data-tools 的 Deb Depends 仅声明 r-frame、r-log,APT 会从已配置的软件源解析这两项依赖。jsoncpp 和 yaml-cpp 均是运行所需的库,需用户自行准备,并确认版本、ABI 和动态库搜索路径兼容;安装本包不保证这两项依赖已就绪。r-frame-plugin 是可选包:只使用基础 SHM/Zenoh 功能时可以不安装;需要完整 ROS2 功能时再安装。建议所有 Robby Deb 使用同一发布版本。

1.2. 推荐安装方式​

先准备兼容的 jsoncpp 和 yaml-cpp;已配置对应软件源且交付环境使用 robby-jsoncpp、robby-yaml-cpp 时,可显式安装:

sudo apt install robby-jsoncpp robby-yaml-cpp

环境已提供兼容库时无需重复安装。依赖就绪后,从已配置的 Robby 软件源安装工具:

sudo apt install robby-data-tools

# 需要完整 ROS2 通信、消息解析和发现能力时安装
sudo apt install r-frame-plugin

如果收到的是单独的本地 Deb 文件,使用:

sudo apt install ./robby-data-tools_*.deb

# 需要完整 ROS2 通信、消息解析和发现能力时安装
sudo apt install r-frame-plugin

如果所有 Deb 均以文件形式离线交付,可让 apt 一次安装本地文件。以下使用交付的 robby-jsoncpp、robby-yaml-cpp;环境已有兼容库时可删除对应项:

sudo apt install \
./r-log_*.deb \
./r-frame_*.deb \
./robby-jsoncpp_*.deb \
./robby-yaml-cpp_*.deb \
./robby-data-tools_*.deb \
./r-frame-plugin_*.deb

最后一项 r-frame-plugin_*.deb 是可选包;不需要完整 ROS2 功能时从命令中删除。建议优先使用 apt,因为 dpkg -i 不会自动下载缺失依赖。

1.3. 安装后的路径与配置文件​

Deb 安装完成后,CLI 相关文件位于以下位置:

/usr/bin/
└── rframe # 用户直接运行的统一命令

/opt/robby/robby-data-tools/
├── setup.bash # Bash 环境和 Tab 补全入口
├── bin/ # rframe 启动程序;通常无需直接使用
├── libexec/rframe/ # 各子命令的内部程序;不要直接调用
├── config/replay/
│ ├── robby_recorder_player_config.json # bag record/play 配置模板
│ └── plugins.json # 插件加载配置,通常无需修改
├── share/bash-completion/completions/rframe
├── lib/ # 运行库
└── plugins/ # 随包安装的录制、回放插件

可用 dpkg -L robby-data-tools 查看当前版本实际安装的完整文件清单。

CLI 用户通常只需要关注以下文件:

  • /usr/bin/rframe:日常使用入口。直接执行即可,不需要进入 /opt/robby/robby-data-tools/bin/。
  • /opt/robby/robby-data-tools/setup.bash:需要在当前 Bash 中启用 Tab 补全或手动加载运行环境时使用。
  • /opt/robby/robby-data-tools/config/replay/robby_recorder_player_config.json:rframe bag record 和 rframe bag play 的默认配置模板,可设置录制范围、缓冲策略、回放速度、输出方式和日志选项。其主要是设置一些CLI入参无法设置的高级参数,一般不需要用户设置。只有CLI的入参无法满足用户需求时,才考虑通过config文件来配置。

建议不要直接修改 /opt 下的配置模板,因为安装或升级 Deb 时文件可能被新版本替换。需要自定义录制或回放配置时,先复制到自己的工作目录,再通过 --config 指定:

cp /opt/robby/robby-data-tools/config/replay/robby_recorder_player_config.json \
./my_rframe_bag_config.json

# 按需编辑配置后使用;--all 也可以换成具体 topic
rframe bag record --config ./my_rframe_bag_config.json --all
rframe bag play --config ./my_rframe_bag_config.json recording_00001.mcap

plugins.json 不是 rframe bag record/play --config 所使用的配置文件。普通 CLI 用户无需修改它;只有部署方调整插件安装位置或启用状态时才需要关注。

运行日志和录制生成的 MCAP 文件不属于 Deb 的安装文件:日志默认写到 $HOME/logs/rframe_cli/,MCAP 写到命令指定或当前工作目录下的输出路径。

安装或升级后进行基本验证:

command -v rframe
rframe --version # cli工具的build版本,并非rframe包的版本
rframe --help
rframe topic list --help
rframe topic info --help
rframe discovery snapshot --help

正常情况下 command -v rframe 输出 /usr/bin/rframe。

其中,rframe --version 输出 rframe CLI build <版本号>,表示 CLI 的编译版本,不是底层 r-frame 运行库版本,也不保证与 Deb 包版本相同。安装包版本可用 dpkg-query -W -f='${Version}\n' robby-data-tools 查询。

2. 命令概览​

rframe
├── bag
│ ├── record 录制 topic 到 MCAP
│ ├── play 回放 MCAP
│ └── info 查看 MCAP 信息
├── topic
│ ├── list 列出 topic 和发布/订阅数量
│ ├── info 查看指定 topic 的类型、通信方式和端点
│ ├── echo 输出 topic 消息
│ ├── stats 观测 topic 频率、大小和吞吐
│ └── pub 发布普通消息或原始字节消息
├── service
│ ├── list 列出 service
│ ├── info 查看 service 类型、通信方式和可用性
│ └── call 调用 service
└── discovery
├── monitor 实时查看 topic/service
└── snapshot 一次性查看 topic/service

查看帮助和版本:

rframe --help
rframe --version
rframe help bag
rframe help topic echo
rframe bag play --help

各命令按 Bag、Topic、Service、Discovery 分组介绍。所有长时间运行的命令均可通过 Ctrl+C 结束。

日志级别支持 off、error、warn、info、debug、trace。CLI 终端默认只输出命令结果,诊断日志级别为 off;文件日志默认仍保留到 info。可通过 --log-level 打开终端诊断日志,指定 debug/trace 时文件日志同步提升;discovery monitor 独占终端,诊断日志只写文件。

日志默认写入 $HOME/logs/rframe_cli/,按命令保存到 bag_record/、topic_echo/ 等子目录。可用 RFRAME_CLI_LOG_ROOT 修改根目录;指定目录不可写时会尝试默认目录及临时目录。

所有命令均可使用 -h / --help 查看参数。脚本采集优先使用命令提供的 --json,不要依赖文本表格的空格列宽。Topic/Service 查询默认只显示概要,--verbose 增加详情;各命令的具体输出见下文。

2.1. 运行环境和 Tab 补全​

Deb 正常安装后,直接运行 rframe 不要求提前 source:/usr/bin/rframe 启动入口会为本次命令加载 ROS2 和运行库路径。

如需在当前 Bash 中启用 group、action、参数值和 MCAP/JSON 文件的 Tab 补全,建议执行:

source /opt/robby/robby-data-tools/setup.bash

setup.bash 会按当前 ROS_DISTRO(未设置时默认 humble)尝试加载 ROS2、设置 RobbyDataTools 的 PATH/LD_LIBRARY_PATH,并注册 rframe Bash 补全。ROS2 不存在时会保留非 ROS2 功能,只输出警告。必须在 Bash 中使用 source;直接执行脚本不会把环境变量和补全函数保留到当前 shell。

只想加载补全、不修改当前 shell 的其他环境时,可以执行:

source /opt/robby/robby-data-tools/share/bash-completion/completions/rframe

上述设置只对当前终端生效;新开终端后需要重新 source。需要长期启用时,可将第一条命令加入用户的 ~/.bashrc。补全功能面向 Bash,加载后可用下面的方式检查:

rframe <Tab> # 补全 bag、topic、service、discovery
rframe bag <Tab> # 补全 record、play、info
rframe topic <Tab> # 补全 list、info、echo、stats、pub
rframe service <Tab> # 补全 list、info、call(以当前构建可用命令为准)
rframe bag play --transport <Tab> # 补全输出 transport
rframe bag play file<Tab> # 补全 .mcap 文件

2.2. 类型加载​

当前RobbyAnt机器人,内部定义和使用的类型,基本都在一个包里,涉及到这些类型时,在运行CLI工具前执行:

source /opt/robby/r-types/setup.bash

用户使用自定义类型时,在运行CLI工具前执行:

source /path/to/message_workspace/install/setup.bash # 自定义类型时

2.3. 快速上手​

source /opt/robby/robby-data-tools/setup.bash # 提供tab补全
source /opt/robby/r-types/setup.bash # R2机器人自定义类型
source /path/to/message_workspace/install/setup.bash # 自定义类型时
rframe xxx # 执行实际指令

3. 录制回放与文件信息:rframe bag​

3.1. 录制:rframe bag record​

3.1.1. 用法​

订阅指定或自动发现的 topic,并写入 MCAP 文件。支持录制 ROS2、SHM 和 Zenoh 数据;Zenoh 发现默认开启。

rframe bag record [options] <topic1> [topic2 ...]

至少需要指定位置 topic、--regex、--all,或提供包含录制范围的配置文件。

3.1.2. 参数​

参数说明
<topic>...精确指定一个或多个 topic;可同时录制多个名称
-o, --output <file>录制基础路径,不是最终文件名;会去掉最后一个扩展名并追加五位分段编号和 .mcap
-a, --all录制全部发现到的 topic,但仍应用黑名单和系统 topic 排除规则
-k, --black-list <topic>排除一个 topic;可重复指定,优先级高于其他筛选条件
-x, --regex <pattern>包含匹配 topic 的 ECMAScript 正则;对完整 topic 名进行匹配,与位置 topic 取并集,可用 .*text.* 匹配中间片段;最长 200 字符,无效或超长正则会在录制前报错退出
-t, --time <seconds>首条匹配消息成功接收后的录制时长,单位秒,可输入非负小数,如 0.5、60;0 表示不自动停止,默认 0,不接受 ms/m 等后缀
--wait-timeout <seconds>等待首条匹配消息的最长时间,单位秒,可输入非负小数;默认 0 表示无限等待;超时仍未收到匹配消息时,报错并结束录制(退出码为 1,表示失败)
--exclude-system-topics排除配置中的系统 topic,默认为 /parameter_events 和 /rosout
--no-exclude-system-topics允许录制系统 topic
-m, --segment-size <MB>单个分段的容量阈值,输入非负整数 MB;达到阈值后创建下一段,0 表示关闭容量分段
-i, --segment-interval <s>单个分段的最长录制时长,输入非负整数秒;达到阈值后创建下一段,0 表示关闭时间分段
-c, --compress <type>MCAP Chunk 压缩方式:default(当前为 Zstd)、none、lz4 或 zstd
-S, --shm-size <KB>SHM reader 内存大小覆盖值,输入非负整数 KB;通常仅在发现信息缺失或诊断时设置
--buffer-policy <policy>缓冲区满时使用 block、drop-old 或 drop-new;默认 drop-new
--buffer-size <count>缓冲区消息数量上限,输入非负整数;0 或未设置时默认使用 1000,与字节上限任一先到即视为缓冲区满
--buffer-bytes <MB>缓冲区数据量上限,输入非负整数 MB;0 或未设置时默认使用 512 MB,与消息数上限共同生效
--enable-zenoh-discovery启用 Zenoh 设备发现;当前已默认开启
--disable-zenoh-discovery禁用 Zenoh 设备发现;仅在确定不录制 Zenoh 数据时使用
--config <path>读取指定 JSON 高级配置;未指定时自动查找默认配置,详见 2.4 节
--log-level <level>终端诊断日志级别,默认 off

3.1.3. 文件名与分段​

--output 指定的是基础路径,不是最终文件名。即使没有发生分段,生成的文件名也会包含 _00001:

-o sensors.mcap -> sensors_00001.mcap
-o sensors -> sensors_00001.mcap

路径最后一个扩展名会先被去掉,再追加编号和 .mcap。发生容量或时间轮转时,后续文件依次为:

sensors_00001.mcap
sensors_00002.mcap
sensors_00003.mcap

未指定 -o 时,基础名形如 output_YYYYMMDD_HHMMSS_ffffff.mcap,实际首段仍带 _00001。启动日志中的 Recording to: 会显示当前实际文件路径。

注意:输出目录需要事先存在且可写。回放时应传入实际带编号的文件;完整回放分段录制时,要按编号传入全部分段。不要复用已有基础名,以免同名分段文件被覆盖。

3.1.4. 筛选和缓冲规则​

  • 黑名单优先级最高。
  • --all 表示除黑名单和默认系统 topic 外全部录制;与位置 topic/正则同时使用时,包含条件会被忽略并给出警告。
  • 未使用 --all 时,位置 topic 与正则匹配结果取并集。
  • block 会等待缓冲区空闲,但不保证完全不丢消息;drop-old 保留新数据;drop-new 保留已排队数据。
  • 同时设置 --segment-size 和 --segment-interval 时,任一阈值先达到都会轮转;它们只控制分段,不控制录制总时长。总时长由 --time 控制。
  • --segment-size 是轮转触发阈值,不是严格的文件大小上限;正在写入的消息或 MCAP Chunk 可能使最终文件略大于设定值。
  • --time 从任意匹配 topic 的首条消息成功接收后开始计时,不包含此前等待时间。例如 --time 10 --wait-timeout 30 表示最多等待首条消息 30 秒,收到后录制 10 秒;不设置 --wait-timeout 时会无限等待。--segment-interval 仍从分段开始计时;两者均不按消息自身的时间戳计算,实际停止时间可能有少量系统调度误差。
  • 建议用 Ctrl+C 正常停止并等待缓冲区完成收尾,不要直接强制终止进程。
  • 输出路径无法创建或发生磁盘满等不可恢复写入错误时,会报错并停止受影响的录制;多输出配置只停用失败输出,其余继续。命令最终退出码为 1,表示录制失败。错误信息会给出文件路径和原因,未完成的 MCAP 不应视为正常录制结果。

3.1.5. 示例​

# 录制指定 topic
rframe bag record /camera/image /imu/data -o sensors.mcap
# 实际首段:sensors_00001.mcap

# 录制全部已发现 topic,默认排除系统 topic
rframe bag record -a -o all.mcap

# 按正则录制 camera 命名空间
rframe bag record -x '^/camera/.*' -o camera.mcap

# 最多等待首条匹配消息 30 秒,收到后录制 60 秒;等待超时则报错退出
rframe bag record -a -t 60 --wait-timeout 30 -o one_minute.mcap

# 每 1024 MB(1 GiB)或每 10 分钟轮转一次,先达到任一条件即生成下一段
rframe bag record -a -o long_run.mcap -m 1024 -i 600

典型输出(时间戳、topic 和统计值随现场变化):

Recording to: sensors_00001.mcap
Buffer policy: drop-new
Subscribed topic: /camera/image
Subscribed topic: /imu/data
Recording started. Press Ctrl+C to stop.
Receiving topic: /camera/image
Receiving topic: /imu/data

Recording stopped.
Summary:
Duration: 10.012 s
Messages: 301 written
Data: 11.80 MiB
Topics: 2
Files:
sensors_00001.mcap (301 messages, 11.80 MiB)
Topic statistics:
/camera/image: 300 messages, 11.79 MiB, 30.00 Hz
/imu/data: 1 messages, 256 B

Subscribed topic: 表示已经开始订阅该 topic;Receiving topic: 表示已经收到该 topic 的第一条消息。尚未发现匹配的发布者时会显示 Waiting for matching publishers...。退出时会显示录制汇总;如果没有收到消息,会显示 No messages were received.;发生丢弃或写入失败时也会给出数量并返回失败状态。需要进一步排查时可增加 --log-level debug。

3.2. 回放:rframe bag play​

3.2.1. 用法​

按 MCAP 的 log_time(录制时间)顺序回放一个或多个 MCAP 文件,支持 topic 筛选、时间范围、速率、循环和通信方式选择。无法按录制时间排序时,改按文件写入顺序回放。

rframe bag play [options] <file1> [file2 ...]

录制生成的是带编号文件,例如 sensors_00001.mcap。如果录制已轮转成多段,应传入全部实际文件:

rframe bag play sensors_00001.mcap sensors_00002.mcap

3.2.2. 参数​

参数说明
<file>...一个或多个实际 MCAP 文件;多个文件作为同一回放输入处理
-a, --all显式回放全部 topic;未设置包含筛选时默认也是全量回放
-w, --white-list <topic>只包含一个 topic;可重复指定,并与正则结果取并集
-k, --black-list <topic>排除一个 topic;可重复指定,优先级最高
-x, --regex <pattern>使用 ECMAScript 正则对完整 topic 名进行匹配;可用 .*text.* 匹配中间片段
-l, --loop播放完所选时间范围后重新开始
-r, --rate <factor>时间轴倍速;1.0 为原速、2.0 为 2 倍速、0.5 为半速,默认 1.0;默认范围 0.1~10.0,可由 JSON 的 rate_min/rate_max 调整
-d, --delay <seconds>Player 启动后、发送第一条消息前的额外等待时间,单位秒,接受非负小数;0 表示不延迟,不接受单位后缀
-b, --begin <time>回放起点,边界消息包含在内;未设置则从所选输入的第一条消息开始,格式见下文
-e, --end <time>回放终点,边界消息包含在内;未设置则播放到所选输入末尾,格式见下文,且不能早于起点
-p, --preload <seconds>发送开始前,先从所选起点向后读取这段时长的数据到播放缓冲区;单位秒,接受非负小数;0 表示关闭,默认 0,不接受单位后缀
-T, --transport <type>设置全局回放通信方式;JSON 中单独指定的 topic 通信方式优先,可选值见下文
--route-mode <mode>组合输出的发送策略:static 固定发送,dynamic 根据订阅者自动选择;要求全局输出为组合通信方式,可由 --transport 或 JSON 配置指定
-S, --shm-size <KB>设置 SHM 发送缓冲区大小,输入非负整数 KB;通常无需设置,录制信息缺失时默认使用 1 MB
--buffer-size <count>播放缓冲区消息数量上限,输入非负整数;0 或未设置时默认使用 1000
--buffer-bytes <MB>播放缓冲区数据量上限,输入非负整数 MB;0 或未设置时默认使用 512 MB;与消息数上限任一先到即视为缓冲区满
--config <path>读取指定 JSON 高级配置;未指定时自动查找默认配置,详见 2.4 节
--log-level <level>RFrame 控制台诊断级别,默认 off;文件日志默认仍保留到 info,指定 debug/trace 时文件同步提升

3.2.3. Topic 和时间范围​

黑名单优先级最高。显式 --all 会忽略白名单和正则;否则白名单与正则结果取并集。

--begin 和 --end 是唯二支持时间单位后缀的参数,支持:

  • 相对输入中首条消息时间戳的秒数,如 10、60.5;裸数字始终按秒处理;
  • 带单位的相对时间,如 1h30m、1m30s、2.5s、500ms;单位须按 h、m、s、ms 的顺序书写,不能包含空格;
  • 当前机器本地时区的绝对时间,如 2026-08-20-14:30:00,格式固定为 YYYY-MM-DD-hh:mm:ss,精度为秒。

-b 10 -e 60 表示播放从输入首条消息时间戳后 10 秒到 60 秒的闭区间。相对时间的参照点是输入 MCAP 的首条消息,不是执行命令的当前时间。与 --loop 一起使用时,只循环所选区间。

日期或时间表达式无效、起点晚于终点时,会报错退出,不会按全量回放;未指定的起点或终点按文件边界参与校验。校验通过后,超出 MCAP 时间范围的边界会收敛到文件范围。

--delay 是真实等待时间,不会改变 MCAP 时间范围;--preload 是读取范围,不是额外等待指定秒数。预加载仍受 --buffer-size 和 --buffer-bytes 限制。

3.2.4. --transport 输出传输​

未通过命令行或 JSON 配置指定输出通信方式时,每个 topic 沿用录制时的通信方式。--transport 设置全局输出;JSON 中为单个 topic 设置的 specified_channel 优先于全局设置。可选值如下:

写法效果
--transport ros2只通过 ROS2 发布
--transport shm只通过 SHM 发布
--transport zenoh只通过 Zenoh 发布
--transport shm,ros2同时支持 SHM 和 ROS2
--transport shm,zenoh同时支持 SHM 和 Zenoh

不支持 ROS2+Zenoh 或 SHM+ROS2+Zenoh 组合。组合输出必须包含 SHM,并搭配 ROS2 或 Zenoh。

组合输出策略:

  • static:默认值,固定通过选定的两种方式发送。
  • dynamic:根据当前发现的订阅者自动选择发送方式;如果订阅者未被发现,数据可能不会从预期链路发出。

--route-mode 要求全局输出为 shm,ros2 或 shm,zenoh,可通过 --transport 或 JSON 配置指定。

使用 Zenoh 回放时,通常不需要额外配置:

  • 原本通过 Zenoh 录制的数据,会按录制时的信息回放。
  • ROS2 或 SHM 录制的数据,如果文件中包含完整的 ROS2 消息类型,可通过 Zenoh 发给兼容的 ROS2 Zenoh 节点。
  • 原始字节或类型未知的数据会按原始数据发送,只适合能够识别这类数据的接收端;工具不会自动把它转换成其他消息类型。
  • 与 ROS2 Zenoh 节点通信时,两端应使用相同的 ROS_DOMAIN_ID。未单独配置时,回放命令使用当前终端中的 ROS_DOMAIN_ID。

以上 Zenoh 回放功能不要求安装可选的 r-frame-plugin。如果不确定如何选择,优先不设置 --transport,按录制信息回放。

3.2.5. 播放中按键​

按键功能
Space暂停或继续
↑加速一个配置步长,默认 0.1 倍
↓减速一个配置步长,默认 0.1 倍
→仅在暂停状态下发送下一条消息;运行中或已无数据时不执行
Ctrl+C停止并退出

单步使用方式:先按 Space 进入暂停,再按 →。成功时显示 Stepped;未暂停或没有剩余数据时显示 Step: not paused or no data。注意单步发送,是按时间顺序一条一条消息发送的,而不是每个topic发送一条数据。如果mcap文件中有多个topic的数据,每次step,也只会发送其中一个topic的一条信息。

3.2.6. 示例​

# 按录制信息回放全部 topic
rframe bag play recording_00001.mcap

# 只回放两个 topic
rframe bag play recording_00001.mcap \
-w /camera/image -w /imu/data

# 2 倍速循环回放
rframe bag play recording_00001.mcap -r 2.0 -l

# 从文件首条消息后的 10 秒开始,播放到 60 秒
rframe bag play recording_00001.mcap -b 10 -e 60

# 固定通过 SHM 和 ROS2 发送(默认策略)
rframe bag play recording_00001.mcap --transport shm,ros2 --route-mode static

# 根据订阅者情况,在 SHM 和 Zenoh 之间自动选择
rframe bag play recording_00001.mcap --transport shm,zenoh --route-mode dynamic

典型输出:

Transport plan: requested=shm planned=shm
Playing 1 file(s)
- recording_00001.mcap
Rate: 1x

Keyboard Controls:
SPACE - Pause/Resume
UP/DOWN - Adjust rate (±0.1x, range: 0.1-10x)
RIGHT/→ - Step forward one message
Ctrl+C - Stop and exit
Playback started.
Publishing topic: /camera/image

Playback stopped.

Playback summary:
Duration: 10.012 s
Messages: 300 published
Data: 1.25 MiB
Topics: 1
Topic statistics:
/camera/image: 300 messages, 1.25 MiB, 29.97 Hz

Publishing topic: 表示该 topic 已经成功发出第一条消息。停止、自然播放结束或按 Ctrl+C 退出时都会打印汇总;没有成功发布消息时会显示 No messages were published.。需要进一步排查问题时,可增加 --log-level debug。

3.3. 文件信息:rframe bag info​

查看一个或多个 MCAP 文件的大小、时间范围、消息数量、topic 类型和录制来源。该命令需要扫描文件,因此大文件可能需要较长时间。

rframe bag info recording_00001.mcap
rframe bag info recording_00001.mcap recording_00002.mcap --json
参数说明
<file.mcap>...至少一个 MCAP 文件;多个文件分别输出,不自动合并为一个时间轴
--json输出 schema_version=1 的 JSON,适合脚本采集

典型输出:

File: recording_00001.mcap
Bag size: 12.34 MiB
Payload size: 11.80 MiB
Storage id: mcap
Duration: 10.000000000 s
Start: 2026-08-21 10:20:30.123456789 (1787288430.123456789)
End: 2026-08-21 10:20:40.123456789 (1787288440.123456789)
Messages: 301
Topics: 2
Indexed: yes
Transports: shm, ros2

Topic information:
Topic: /camera/image | Type: sensor_msgs/msg/Image | Count: 300 | Serialization Format: cdr | Transport: shm
Topic: /tf_static | Type: tf2_msgs/msg/TFMessage | Count: 1 | Serialization Format: cdr | Transport: ros2

文件级 Transports 表示该文件中的数据最初通过哪些通信方式录制;每个 topic 的 Transport 表示该 topic 的录制来源,不代表回放时将使用的方式。旧文件缺少这项信息时显示 -。

日常查看使用默认文本即可;脚本处理或问题排查可增加 --json。如果文件缺少消息类型或编码信息,命令会显示提示,相关 topic 可能无法正常回放或解析;请先检查录制端的类型和编码信息。同一 topic 在文件中存在不一致的类型或格式时也会告警,建议先确认数据来源再回放。

3.4. JSON 配置​

bag record 和 bag play 未指定 --config 时,会使用找到的第一个配置文件:

  1. ./robby_recorder_player_config.json
  2. ./config/replay/robby_recorder_player_config.json
  3. /opt/robby/robby-data-tools/config/replay/robby_recorder_player_config.json

--config <path> 用于指定其他配置文件。命令行中显式提供的参数会覆盖配置文件中的对应设置。多输出组、自定义 Zenoh key 等高级功能只能通过 JSON 配置。

默认配置已包含有效录制范围时,bag record 可不传 topic 或 --config 直接启动;配置和命令行均未指定录制范围时会报错。

主要是设置一些CLI入参无法设置的高级参数,一般不需要用户设置。只有CLI的入参无法满足用户需求时,才考虑通过config文件来配置。

安装目录中的文件是随 Deb 提供的默认模板。推荐复制后修改,并通过 --config 显式指定;这样配置不依赖运行命令时所在的目录,也不会在软件升级时被替换。配置文件的用途和复制示例见前文“安装后的路径与配置文件”。

4. 话题查看与收发:rframe topic​

先用 list/info 查找话题和类型,再用 echo/stats 验证消息,用 pub 发布消息。list/info 不订阅业务消息,也不要求本机安装该消息定义。

list/info 默认收集 1 秒发现信息;结果偏少时可增加 --resolve-timeout。发现发布者不代表正在发送消息,发布/订阅数量也不等于业务节点数。

4.1. 列出话题:rframe topic list​

默认显示名称、通信方式和发布/订阅数量,包括只有订阅者的话题。加 --verbose 显示类型和各通信方式数量,不展开端点。

rframe topic list
rframe topic list --filter camera --transport ros2
rframe topic list --type sensor_msgs/msg/Image --verbose
rframe topic list --json
参数说明
--filter <text>按名称、类型、通信方式或 key 做不区分大小写的子串筛选
--type <message_type>按消息类型精确筛选,例如 std_msgs/msg/String
`--role <pubsub>`
--verbose补充类型和各通信方式数量
`--transport <shmros2
`--locality <localremote
--resolve-timeout <seconds>发现等待时间,默认 1 秒,范围 0~60 秒,支持小数
--json以 JSON 输出,信息层级与文本一致,schema_version=2
--log-level <level>诊断日志级别,默认 off

典型输出:

Topics (2)
Name Transports Publishers Subscribers
------------- ---------- ---------- -----------
/camera/image shm 1 2
/commands shm 0 1

--type、--filter 选择整条话题,--role、--transport、--locality 则限定端点范围。例如 --role sub 的发布者数量为 0。存在多个消息类型时显示 [CONFLICT],请用 info 检查。

JSON 列表从 .topics[] 读取;需要类型时加 --verbose。空列表正常退出,退出码为 0。

# 需要本机安装 jq
rframe topic list --json | jq -r '.topics[].name'

4.2. 查看话题详情:rframe topic info​

显示指定话题的类型、发布/订阅总数和各通信方式数量;--verbose 增加逐个端点详情。

rframe topic info /camera/image
rframe topic info camera/image --transport shm --verbose
rframe topic info /camera/image --json
参数说明
<topic>必填,精确话题名;可省略开头的 /
--verbose展开发布者、订阅者的通信方式、类型、PID 等详情
`--transport <shmros2
`--locality <localremote
--resolve-timeout <seconds>发现等待时间,默认 1 秒,范围 0~60 秒,支持小数
--json以 JSON 输出,信息层级与文本一致,schema_version=2
--log-level <level>诊断日志级别,默认 off

info 不接受列表专用的 --filter、--type、--role。类型未知显示 -;PID 未知时文本显示 unknown,JSON 为 0。

JSON 从 .topic 读取,只有加 --verbose 才包含 .topic.endpoints:

rframe topic info /camera/image --json | jq '.topic.backends'
rframe topic info /camera/image --json --verbose | jq '.topic.endpoints'

成功退出码为 0;指定范围内未发现话题或运行失败为 1;参数错误为 2。未发现目标时 stdout 为空,错误写入 stderr。

4.3. 查看消息:rframe topic echo​

订阅一个 topic 并打印消息内容。默认使用 auto 自动查找可用的 SHM、ROS2 或 Zenoh 发布者,并识别消息类型。

# 自动解析,收到一条后退出
rframe topic echo /chatter --once

# publisher 尚未启动时显式给出类型
rframe topic echo /chatter std_msgs/msg/String --once

# 打印 5 条 JSON 风格消息
rframe topic echo /chatter --type std_msgs/msg/String --limit 5 --json

# 强制使用 SHM 或 Zenoh
rframe topic echo /shm_chatter --transport shm --type std_msgs/msg/String --once
rframe topic echo /zenoh_chatter --transport zenoh --type std_msgs/msg/String --once
参数说明
<topic>必填,要订阅的 topic
[message_type]可选消息类型,等价于 --type
--type <T>指定消息类型;按已知类型匹配发布者,无类型信息时用于补全,不能覆盖已知类型冲突
--transport <mode>auto、ros2、shm、zenoh、shm,ros2 或 shm,zenoh,默认 auto;auto 的选择顺序见下文
--once输出一条消息后退出
--limit <N>收到并输出 N 条消息后退出;N 为非负整数,0 表示不限制、持续运行
--json每条消息输出一个独立 JSON value;多条消息构成 JSON stream,stdout 可直接交给 jq 逐条处理
--raw不解析消息内容,直接以十六进制显示原始字节;用于查看非标准或未知类型的数据
`--zenoh-protocol <autonative
--resolve-timeout <seconds>启动时等待发布者和消息类型的最长时间,单位为非负整数秒,默认 10;0 表示立即检查、不等待
--shm-size <KB>覆盖 SHM 接收内存大小,输入非负整数 KB;不得小于已发现的 SHM 区域,仅用于诊断或发现信息不足场景
--log-level <level>终端诊断日志级别,默认 off

--once 与 --limit 不能同时使用,--raw 与 --json 也不能同时使用。如果消息无法按指定类型解析,有限次模式会报错退出。组合通信方式的用法见 3.6 节。

命令启动时默认最多等待 10 秒以发现发布者和消息类型。发布者尚未启动,或自动识别不到类型时,可通过 --type 明确指定。--resolve-timeout 只影响启动等待,不会限制后续接收消息的时长。

典型输出:

Subscribed via ZENOH to [/chatter] (type=std_msgs/msg/String)
Waiting for messages...

[2026-08-21 10:20:30.123] type: std_msgs/msg/String
data: hello

Received 1 messages

4.4. 数据流统计:rframe topic stats​

订阅一个 topic,持续统计最近 N 条消息的接收频率、间隔、消息大小和吞吐量。消息总数和总数据量只表示本次命令运行期间实际收到的内容。

# 自动解析 topic
rframe topic stats /camera/image

# 使用最近 20 条消息作为统计窗口
rframe topic stats /camera/image --window 20

# 强制指定 transport 和类型
rframe topic stats /camera/image \
--transport zenoh --type sensor_msgs/msg/Image --window 10
参数说明
<topic>必填,要统计的 topic
--window <N>计算周期时使用的最近 N 条消息滑动窗口,N 为非负整数,默认 100;输入 0 或 1 时按 2 处理
--type <T>指定消息类型;按已知类型匹配发布者,无类型信息时用于补全,不能覆盖已知类型冲突
--transport <mode>auto、ros2、shm、zenoh、shm,ros2 或 shm,zenoh,默认 auto;auto 的选择顺序见下文
`--zenoh-protocol <autonative
--resolve-timeout <seconds>启动时等待发布者和消息类型的最长时间,单位为非负整数秒,默认 10;0 表示立即检查、不等待
--shm-size <KB>覆盖 SHM 接收内存大小,输入非负整数 KB;不得小于已发现的 SHM 区域
--log-level <level>终端诊断日志级别,默认 off

窗口越小,对瞬时变化越敏感;窗口越大,结果越平滑。窗口表示消息条数,不是秒数。--resolve-timeout 只作用于启动解析阶段,工具开始订阅后会持续统计,直到 Ctrl+C。

典型运行输出:

Subscribed via SHM to [/camera/image] (type=sensor_msgs/msg/Image)
Waiting for messages...
average rate: 29.997 Hz (window: 20 messages)
interval: min 0.033 s, max 0.034 s, std dev 0.000 s
message size: avg 1.76 MB, min 1.76 MB, max 1.76 MB
throughput: 52.73 MB/s

按 Ctrl+C 后输出本次观测汇总:

Final stats:
total messages: 328
total data: 576.56 MB
average rate: 29.998 Hz (window: 20 messages)
interval: min 0.033 s, max 0.034 s, std dev 0.000 s
message size: avg 1.76 MB, min 1.76 MB, max 1.76 MB
throughput: 52.73 MB/s

std dev 是统计窗口内“相邻消息到达间隔”的标准差,单位为秒。数值越小表示接收周期越稳定;它反映的是观测到的时序抖动,不是消息内容的偏差。

4.5. 发布消息:rframe topic pub​

发布 topic 消息。普通模式根据消息类型把 JSON 或 YAML 内容转换为可发送的消息;发送自定义原始字节时需要显式使用 --raw。

# 类型化 SHM 消息
rframe topic pub /chatter std_msgs/msg/String '{"data":"hello"}' --transport shm --once

# YAML 写法
rframe topic pub /chatter std_msgs/msg/String '{data: hello}' --transport shm --once

# 类型化 ROS2 消息
rframe topic pub /cmd_vel geometry_msgs/msg/Twist \
'{"linear":{"x":1.0}}' --transport ros2

# 原始测试数据,同时通过 SHM 和 Zenoh 发送
rframe topic pub /diagnostic/probe --raw --size 1024 --transport shm,zenoh --count 20 --wait-subscriber 0
参数说明
<topic>必填,发布 topic
<message_type>类型化模式必填,例如 std_msgs/msg/String
[message]可选,JSON 或 YAML 正文,默认 {};用引号包住整个正文
--结束选项解析;所有选项放在它前面
--transport <mode>shm、ros2、zenoh、shm,ros2 或 shm,zenoh,默认 shm
--raw发布工具生成的原始测试字节;只支持 SHM 和 Zenoh
--size <bytes>原始消息的字节数,最小 24,默认 64
--rate <Hz>发送频率,单位 Hz,范围 [0.001, 1000000],默认 1;最低频率对应 1000 秒周期
--count <N>发送 N 条后退出;默认 0,表示持续到 Ctrl+C
--once发送一条后退出,等价于 --count 1;不能与 --count 同时指定
--wait-subscriber <seconds>发布前等待匹配订阅者;--once 和 --count N(N > 0)默认一直等待,显式正数设置超时,设为 0 可立即发送;持续发布默认不等待
--type <name>消息类型的位置参数替代形式
--key-expr <expr>原始 Zenoh 消息使用的自定义 key;一般不需要设置
--shm-size <KB>SHM 区域大小,单位整数 KB,默认 1024
--log-level <level>终端诊断日志级别,默认 off

可用组合:

模式可用 transport说明
普通消息shm、ros2、zenoh、shm,ros2、shm,zenoh按 <message_type> 解析 JSON/YAML,可被相同类型的订阅者读取
原始消息shm、zenoh、shm,zenoh发送工具生成的测试字节,只能由支持原始数据的订阅者读取

--once 等价于 --count 1,但两者不能同时指定。--size、--key-expr 只对 --raw 有效。JSON/YAML 内容与消息类型定义不匹配时,命令会在发送前报错。

通过 Zenoh 发布普通 ROS2 消息时,应确保发布端和订阅端使用相同的 ROS_DOMAIN_ID。使用 shm,ros2 时,如果 ROS2 功能不可用,命令会只使用 SHM;如果明确选择 ros2,则会报错。原始消息应使用 topic echo --raw 查看,不能按普通 ROS2 消息解析。

使用 --once 或有限的 --count N 时,命令默认会在发送第一条消息前等待匹配的订阅者。可以用 --wait-subscriber <seconds> 设置最长等待时间,或设为 0 立即发送。等待超时仍未发现匹配订阅者时,命令报错退出,不发送消息。该等待只能确认订阅者已被发现,不能保证对方已经处理消息。

典型输出:

Transport plan: requested=shm effective=shm
Publishing CDR: topic=/chatter transport=shm type=std_msgs/msg/String size=14 bytes rate=1 Hz count=1
Waiting for a matching subscriber (Ctrl+C to cancel)...
Published 1 message(s), 14 payload bytes

JSON/YAML 正文须为单个对象,字段与消息类型一致;省略的字段使用默认值。数字或布尔值作为字符串发送时,需在正文内加引号,例如 '{data: "1000"}'。bag record/play --config 仍使用 JSON。

4.6. 通信方式选择​

echo/stats 默认使用 auto,优先 SHM,其次 ROS2,再尝试 Zenoh。无法自动识别类型时可加 --type。

尚未发现发布者但已指定类型时,auto 默认按 ROS2 等待;等待 SHM 或 Zenoh 发布者时,应显式指定 --transport shm 或 --transport zenoh。同名话题有多种通信方式、需要检查某一条链路时,也应显式指定。

echo/stats 的组合方式为 shm,ros2 和 shm,zenoh,原 hybrid 已移除。组合允许当前只有一种通信方式可用,优先 SHM;组合内已知类型不一致时会报错,可显式选择单一通信方式。当前组合模式在发布者先启动、订阅者后启动的纯 ROS2 场景下可能无法正常接收,跨通信方式自动切换也有限制;需要固定链路时使用 shm、ros2 或 zenoh。

--type 只选择类型匹配的发布者;候选发布者均未提供类型或尚无发布者时才用于补全。已知类型均不匹配时,不能通过未知类型发布者绕过冲突;auto 会继续查找其他通信方式下的匹配发布者。

pub 默认使用 SHM,支持的组合见 3.5 节。SHM/Zenoh 可独立使用;明确选择 ROS2 时,环境需提供相应 ROS2 功能。

echo/stats 可用 --transport zenoh --zenoh-protocol <auto|native|rmw> 指定 Zenoh 协议(也适用于 --transport shm,zenoh):auto 默认自动识别,未发现发布端时按 Native 连接;native 用于 RFrame Native 发布端,rmw 用于 RMW 发布端。无发现信息时使用 rmw 还需指定 --type;仅指定消息类型不会切换协议。同一协议下有多个不同类型的发布者时,用 --type 选择类型匹配的发布者。

rframe topic echo /chatter --transport zenoh --zenoh-protocol rmw \
--type std_msgs/msg/String --once

pub 的普通消息使用 RMW 协议,--raw 使用 Native 协议,无需设置此参数。

5. 服务查看与调用:rframe service​

先用 list/info 查找服务和完整调用路径,再用 call 调用。list 默认收集 3 秒,info 默认最多等待 5 秒,结果偏少时可用 --resolve-timeout 8 延长;查询 SHM/Zenoh 方法可能增加等待时间。

5.1. 列出服务:rframe service list​

rframe service list
rframe service list --type example_interfaces/srv/AddTwoInts
rframe service list --transport ros2 --filter robotic
rframe service list --json
参数说明
--type <service_type>按规范化后的 service 类型精确过滤
--filter <text>对 service 名、类型和已知/补全的方法路径做不区分大小写的子串过滤
`--transport <ros2shm
--resolve-timeout <seconds>输出前收集 discovery 的时间,范围 0~60 秒,默认 3
--verbose补充服务/方法类型和各通信方式数量,不展开端点;显示查询告警
--no-resolve-methods跳过主动 RPC 方法查询;仍保留 discovery 已知的方法
--json输出 schema_version=2 的 JSON,信息层级与文本一致
--log-level <level>终端诊断日志级别,默认 off

默认列表显示服务名、通信方式、Servers/Clients 数量和已知方法树,不显示类型。使用 --verbose 时,在同一张表中补充完整服务/方法类型和各 transport 数量,不展开原始端点;端点详情请使用 service info --verbose。

典型输出(数量随现场变化):

Services (2)
Name Transports Servers Clients
------------------- ---------- ------- -------
/ shm 1 1
└─ /test/echo_text
/demo shm,zenoh 2 0
└─ /demo/echo

同名服务在多种通信方式下合并显示。Servers/Clients 是当前范围内各通信方式数量之和,不代表业务实例数;方法子行不重复显示数量。Clients 也包含其他进程用于查询方法的客户端,--no-resolve-methods 不保证该数量为 0。调用时使用完整方法路径,普通 ROS2 服务名本身就是调用路径。

默认查询 SHM/Zenoh 方法;--filter 也可按方法路径筛选所属服务。不需要方法补全时使用 --no-resolve-methods。服务不支持方法查询或查询失败时,列表可能没有方法或类型;加 --verbose 查看告警。同一方法出现多个类型时显示 [CONFLICT],不同方法类型不同不算冲突。

JSON 从 .services[] 读取,默认不包含类型;--verbose 增加类型及各通信方式的数量,均不展开端点。

rframe service list --filter /demo/echo
rframe service list --json | jq -r '.services[].name'

5.2. 查看服务详情:rframe service info​

rframe service info /test/add
rframe service info /test/add --transport ros2 --verbose
rframe service info /test/add --json
参数说明
<service_name>必填,逻辑 service 名或已知方法的完整调用路径;输入不带 / 时会规范化为绝对路径
`--transport <ros2shm
--resolve-timeout <seconds>发现等待上限,可输入小数,范围 0~60 秒,默认 5;0 表示立即读取当前缓存
--verbose文本增加原始端点明细;JSON 增加 raw_endpoints;方法查询失败时向 stderr 告警
--no-resolve-methods跳过主动 RPC 方法查询;仍保留 discovery 已知的方法
--json输出 schema_version=2 的 JSON,信息层级与文本一致
--log-level <level>终端诊断日志级别,默认 off

service info 不接受只用于列表筛选的 --type 和 --filter;service 名本身就是精确选择条件。

info --transport ros2 查询普通 ROS2 服务时,目标服务端和类型已发现且信息稳定后可提前返回。--resolve-timeout 不包含运行时启停和主动方法查询耗时,不是整个命令的耗时上限。

默认显示 service 名、类型、可用性,以及各通信方式下的服务端和客户端数量;查询容器且方法已知时显示 Methods;查询具体方法时只展示目标,不列出兄弟方法。需要排查发现或类型冲突问题时,再增加 --verbose 查看详细连接信息。

Service: /test/add
Type(s): example_interfaces/srv/AddTwoInts
Available: yes

Transport Type(s) Servers Clients
--------- ---------------------------------- ------- -------
ros2 example_interfaces/srv/AddTwoInts 1 0

Available: yes 表示已发现服务端,不保证业务请求一定成功。未显示方法或类型时,可增加发现等待时间,或加 --verbose 查看告警。

查询容器(如 /demo)显示已知方法列表;查询完整方法路径(如 /demo/echo)只显示该方法。输出 Count scope: service container 时,数量属于整个服务容器,不是该方法的独立实例数。

JSON 返回 {"schema_version":2,"service":{...}}。从 .service 读取服务,只有 --verbose 才包含 .service.raw_endpoints;旧版脚本需调整取值路径。

rframe service info /demo/echo --verbose
rframe service info /test/add --json | jq -r '.service.name'
rframe service info /test/add --json --verbose | jq '.service.raw_endpoints'

5.3. 调用服务:rframe service call​

service 类型通常可以自动识别;按目标方法及所选通信方式确定,不受同一容器中其他方法类型的影响:

rframe service call /add_two_ints '{"a": 5, "b": 7}'

无字段请求可以省略正文,默认使用 {}:

rframe service call /trigger example_interfaces/srv/Trigger

同一目标方法在不同通信方式下类型不同时,auto 按优先级选择兼容方式;需要固定通信方式时使用 --transport。发现信息不完整或需要显式指定类型时,可使用:

rframe service call \
/add_two_ints \
example_interfaces/srv/AddTwoInts \
'{"a": 5, "b": 7}' \
--transport ros2 \
--timeout 5000
参数说明
<service_name>必填,service 绝对路径
[service_type]可选,ROS2 service 类型;省略时自动识别
[request]可选,JSON 或 YAML 请求内容,默认 {};建议使用单引号包住整个正文
--结束选项解析;所有选项放在它前面
--transport <mode>auto、ros2、shm、zenoh 或 shm,ros2,默认 auto
--resolve-timeout <seconds>启动时等待发现 service 和类型的时间,范围 0~60 秒,默认 1
--shm-service-prefix <prefix>指定真实 SHM 容器前缀,仅限 --transport shm;省略时自动解析,字面 / 与空字符串表示同一根容器;方法参数传完整调用路径
--timeout <ms>单次查询或业务响应超时,正整数毫秒,默认 3000;不是命令总耗时上限
--jsonstdout 只输出 JSON response,便于脚本处理;诊断和错误仍写入 stderr
--log-level <level>终端诊断日志级别,默认 off

auto 根据发现结果按 SHM → ROS2 → Native Zenoh 选择类型兼容的通信方式;shm,ros2 只在 SHM 和 ROS2 中选择,优先 SHM。请求只发送一次,响应超时不会换通信方式重发。原 hybrid 已移除。ros2、shm 和 zenoh 固定使用指定方式;这里的 Zenoh 为 RFrame Native RPC,通常需要显式提供 [service_type]。

SHM 调用默认自动查找服务容器。通常只需提供完整调用路径和类型;多个容器匹配同一路径时会报歧义,需用 --transport shm --shm-service-prefix <prefix> 明确选择。

例如,服务容器 /robot 注册了 echo,其类型为 example_interfaces/srv/SetBool:

# 自动解析 SHM 容器前缀
rframe service call /robot/echo example_interfaces/srv/SetBool \
'{"data":true}' --transport shm

# 多个容器匹配同一路径时,明确指定容器
rframe service call /robot/echo example_interfaces/srv/SetBool \
'{"data":true}' --transport shm --shm-service-prefix /robot

--shm-service-prefix 仅用于 --transport shm,方法参数仍传完整调用路径。空字符串 '' 和 / 表示同一根容器,/robot 与 /robot/ 也表示同一容器。自动识别不到 service 类型时,仍需显式提供 [service_type]。

--resolve-timeout 控制启动发现等待,--timeout 控制单次查询或业务响应等待,两者都不是整个命令的总耗时上限。显式选择 SHM 但目标无法确定时会报错;auto 可继续检查 ROS2、Zenoh,shm,ros2 可继续检查 ROS2。业务请求超时后不会改用其他容器重发。

显式请求支持 JSON 或 YAML,例如 '{"data": true}' 和 '{data: true}';正文规则见 3.5 节。省略请求等价于传入 {}。自动发现不到类型或发现多个冲突类型时,命令会要求显式提供 [service_type],不会随机选择。

典型输出:

Request: {"a": 5, "b": 7}
Transport selection: requested=auto effective=ros2
Response:
{
"sum": 12
}

Transport selection 显示请求策略(requested)和实际通信方式(effective),写入 stderr。使用 --json 时,stdout 不带 Response: 前缀:

{
"sum": 12
}

5.4. 运行环境​

  • 查看 service 列表和详情不要求启用 ROS2;SHM、Zenoh 服务仍可正常显示。
  • 调用 SHM 服务不要求启用 ROS2,但系统必须能找到对应的 service 消息定义。如果提示类型构造失败,请先加载提供该类型的 ROS2、r-types 或用户工作空间环境。
  • 自动识别不到 service 类型时,请在命令中显式提供 [service_type]。
  • 明确选择 --transport ros2 时,需要安装并启用相应的 ROS2 扩展;否则命令会报错。组合模式在 ROS2 不可用时可能只使用 SHM。

6. 资源发现:rframe discovery​

monitor 用于实时浏览,snapshot 用于一次性查询和导出。两者显示 Topic/Service,不提供 ROS2 node 列表。

6.1. 实时查看:rframe discovery monitor​

以终端交互界面实时显示当前发现的 topic 和 service,包括 SHM、ROS2 和 Zenoh。

# 使用默认 500 ms 刷新间隔
rframe discovery monitor

# 每 200 ms 刷新
rframe discovery monitor --refresh 200
参数说明
--refresh <ms>页面刷新周期,单位为正整数毫秒,默认 500;例如 200 表示每 0.2 秒刷新一次,必须大于 0
--log-level <level>设置诊断日志详细度;TUI 独占终端,运行日志不直接写控制台,文件默认至少保留到 info

6.1.1. 交互按键​

按键功能
↑ / ↓移动选择
Enter查看 topic/service 详情;过滤编辑时提交过滤条件
/进入过滤编辑;编辑时可作为普通 / 字符输入
Backspace删除过滤字符
Esc取消编辑、清除已提交过滤,或从详情返回列表
Ctrl+C退出

过滤不区分大小写,可匹配名称中的任意一段字符。资源列表按 topic/service 名过滤;详情页还可以按通信方式、角色、PID、key 和类型过滤。详情页按 Esc 返回列表,再按一次 Esc 清除过滤条件。

如果看不到 Zenoh 发布者,请确认发布端已启用发现功能,并检查两端网络是否允许 Zenoh 发现通信。

主页面典型显示:

=== RFrame Discovery Monitor ===
Topics: 2/2 | Services: 1/1

Name Kind Publishers Subscribers Servers Clients
> /camera/image Topic 1 2 - -
/localization/pose Topic 1 1 - -
/robot/control Service - - 1 1

Keys: Up/Down=Navigate | /=Filter | Enter=Select | Ctrl+C=Exit

进入 /camera/image 详情后,可以查看每个发布者或订阅者的通信方式、角色、PID、endpoint ID 和消息类型。选中 Zenoh endpoint 时,页面底部还会显示实际 key_expr、wire protocol 与 payload encoding;元数据缺失时显示 unavailable。终端宽度不足时,较长字段可能被截断。

6.2. 一次性查看:rframe discovery snapshot​

一次性输出当前发现的 topic 和 service,适合跨资源排查、脚本采集或附加到问题单。日常话题查询也可直接使用 topic list/info,两种入口均保留。默认分别显示 Topic 和 Service;需要连接详情时使用 --verbose,需要机器可读结果时使用 --json。

rframe discovery snapshot
rframe discovery snapshot /camera/image --verbose
rframe discovery snapshot --role rpc-server
rframe discovery snapshot --transport zenoh --locality remote --json
参数说明
[resource]可选,精确 topic 或 service;开头 / 不影响匹配
--filter <text>对资源名、类型、通信方式、key 和已知/补全的方法路径做不区分大小写的子串过滤;命中方法时保留所属服务及完整方法树
--role <role>pub/sub 只匹配逻辑 topic 的发布者/订阅者;rpc-server/rpc-client 只匹配聚合后的逻辑 service 角色
--transport <transport>shm、ros2 或 zenoh
--locality <value>按资源位置过滤:local 为本机进程,remote 为其他主机,unknown 为位置未知
--resolve-timeout <seconds>输出前收集 discovery 的时间,单位秒,可输入小数,范围 0~60,默认 3
--verbose文本增加完整服务/方法类型及端点详情;pid=0 表示进程号未知
--no-resolve-methods跳过主动 SHM/Zenoh 方法查询,仍保留被动发现已知的方法
--resolve-methods恢复主动方法查询,默认已开启
--json输出 schema_version=1 的完整 JSON,适合脚本处理;运行日志不混入结果
--log-level <level>终端诊断日志级别,默认 off

服务下方会展开已知方法,方法不单独计为服务;默认隐藏服务类型,--verbose 显示完整类型和端点。--filter 可匹配方法路径,命中时保留所属服务及方法树;按方法路径查询单个详情请使用 service info。

默认补全 SHM/Zenoh 方法,可能使总耗时超过 --resolve-timeout。只需被动发现结果时,加 --no-resolve-methods。没有方法列表只表示本次未获得方法,不代表服务没有方法。

--json 输出 schema_version=1 的完整快照,默认包含类型、端点和已知方法,不受 --verbose 限制;Topic/Service 的 list/info --json 则按详情层级输出,版本为 2。

默认输出:

Topics (1)
Name Type(s) Transports Publishers Subscribers
------------- --------------------- ---------- ---------- -----------
/camera/image sensor_msgs/msg/Image ros2,shm 2 1

Services (1)
Name Transports Servers Clients
-------------- ---------- ------- -------
/robot/control shm 1 1

Summary: 1 topic(s), 1 service(s), 4 endpoint(s)

多个筛选条件需同时满足。暂未发现资源时可延长 --resolve-timeout;方法查询失败时用 --verbose 查看告警。PID 为 0 表示未知,不影响通信。

快照只反映本次发现结果,不包含历史消息数、丢包数或历史断流统计。Snapshot/Monitor 的服务汇总数量与 service list 口径不同,应按通信方式查看明细,不要直接比较总数。

7. 常见问题​

7.1. topic 存在,但 echo 或 stats 启动失败​

先通过 rframe discovery monitor 确认发布者和通信方式。如果无法自动识别消息类型,补充 --type <package/msg/Type>;同名 topic 存在多种通信方式时,补充 --transport。

如果 topic echo 提示 schema is unavailable for [<package/msg/Type>],表示 topic 和类型已经发现,但当前终端找不到该消息定义;请 source 提供该类型的 ROS2、r-types 或用户工作空间后重试。

7.2. Recorder 没有录到某个 topic​

检查黑名单、系统 topic 排除和正则范围。Zenoh topic 还需确认 discovery monitor 中能看到发布者;如果使用了 --disable-zenoh-discovery,请移除该参数。

7.3. 动态回放没有走预期的通信方式​

动态模式依赖订阅者发现状态。先用 rframe discovery monitor 确认对应订阅者可见;如需固定通过两种方式发送,改用 --route-mode static。

7.4. jsoncpp 缺失或版本不兼容​

如果提示 libjsoncpp.so.*: cannot open shared object file,请检查兼容库是否已安装并位于动态库搜索路径中;出现涉及 Json:: 的未定义符号时,检查库版本和 ABI。当前包未声明 jsoncpp 依赖,apt install -f 不会据此自动补齐;自定义库目录需配置 LD_LIBRARY_PATH 或系统动态链接器。

7.5. 如何查看某个命令的权威参数列表​

rframe help <group> <command>
# 例如
rframe help bag record
rframe help discovery monitor