问题: 错误的网络配置
...
如果这样还不能解决问题的话, 那么很有可能是防火墙的缘故, 比如 hal 上的防火墙阻断了端口56171的所有入口流量. 大部分操作系统都会通过软件防火墙对 TCP 或 UDP 的流量进行限制, 甚至只开放很少的一部分端口, 比如 http 的 80 端口, ssh 的 22 端口等. 由于ROS的发布节点可能会使用任何端口, 而且同一时刻可能会有多个发布节点使用不同的端口, 因此 ROS 需要能够在主机的任意两个端口间进行双向的通信. 为了满足这个要求, 我们一般需要更改防火墙的配置, 使之允许所有端口的输入流量, 或者干脆把防火墙关掉.
如果你并不想更改防火墙的配置, 那也有一个办法, 就是在你的网络主机之间建立 VPN\(虚拟专用网络\). 因为 VPN 是认证且加密的, 因此 VPN 内主机就没有使用防火墙的必要了. 可供选择的 VPN 工具有很多, 最常用的开源工具是 OpenVPN, 这个工具可以创建一个虚拟的网络接口, 并且给主机分配一个新的IP 地址.如果你使用了 OpenVPN, 那么你就需要在所有的 ROS 主机上手动配置 ROS\_IP 变量, 确保每个主机上 ROS 使用的是 VPN 内的 IP 地址. VPN 的具体配置方法本书不做探讨, 你可以从网络上或其他计算机网络技术方面的书籍上获取必要的信息.
传感器融合: 使用 rviz
在前面的章节中, 我们讨论了有关ROS错误报告和连接处理方面的问题. 那么, 如果系统中的所有节点都连接正常, 也没有任何错误产生, 是否意味着机器人就可以正常工作了呢? 事实上, 机器人系统的调试比我们想象中还要复杂得多. 为了解决这一问题, ROS 提供了 rviz 工具, 我们可以使用它来对相关的传感器数据进行可视化, 从而简化调试过程. 打开 rviz 的方法很简单, 一行命令足矣:
具体要对哪些传感器进行可视化取决于你的应用程序. rviz 无疑是一个强大的工具, 并且拥有丰富的可配置性. 不过对 rviz 的详细讲解已经超出了本书的范围. 在此我们只提供几个使用 rviz 调试一些常见问题时的小技巧:
- 同时对多个传感器的数据进行可视化. 比如说, 你使用了一个激光雷达和一个立体相机, 那么就可以在同一个坐标系下对二者同时进行可视化, 然后通过观察数据的区别来调试可能的错误. 为了区分不同的传感器, 你还可以给 rviz 中的传感器上色.
- 适当延长传感器数据流的衰减时间. 这样做可以帮检查数据的一致性.例如在一个移动机器人上使用深度相机时, 你可以将深度相机点云的衰减时间设为5秒, 然后四处移动一下机器人, 在移动的过程中就很容易发现连续的几帧数据中可能存在的一致性问题.
- 对传感器处理流程中的每个阶段都进行可视化. 比如你在相机后级接了许多滤波器, 那么请对每级的输出(包括相机的原始输出)同时进行可视化, 这样可以立即看到传感器处理的结果, 从而快速定位错误.
- 你可以在代码中的任何地方对外发布可视化的调试信息, 消息类型为 visualization\_msgs/Marker. 这个消息类型允许你在 rviz 中创建, 修改或删除几何体, 并以一个箭头的形式发布位姿估计.
绘制数据图表: 使用 rqt_plot
通过 rivz, 我们可以从一个较高的层次上检查系统内传感器的状态. 不过, 有时候我们也需要针对个别的传感器进行局部检查. 比方说, 假如你在调试一个机械臂的某个位置控制器\(如某个关节的舵机\), 那么控制器的力矩-时间序列, 位置错误等物理量就变得很重要了. 为了便于我们对这些测量数据进行调试, ROS 提供了 rqt\_plot, 可用于绘制测量数据的二维图表.
Example21-1 展示了一个节点的代码. 这个节点会自动产生正弦数据, 并以 std\_msgs/Float64 的类型通过/sin 话题对外发布:
运行 sine-wave.py, 然后在另一个终端中运行 rqt-plot, 并使用命令行参数使其绘制从/sin 话题订阅的数据:
现在你就可以看到一个连续的正弦波图像了, 如图 21-7 所示:
图21-7 rqt-plot 的图形界面可以绘制出ROS 中任何对外发布的数值数据
同时对多个数据进行绘制, 并加以比较是一种常用的调试方法. Example21-2 展示了一个以 std-msgs/Float64 类型向/cos 话题发布余弦波的节点:
保持 sine-wave.py 继续运行, 现在在另一个终端中运行 cosine\_wave.py, 然后重启 rqt-plot, 这次同时提供两个话题作为命令行参数.
现在你就可以同时看到两个波形了. 并且正余弦间的相位差也符合预期, 如图21-8所示:
图 21-8: rqt-plot 的图形界面可以同时对多个数据进行可以可视化.
rqt-plot 的图形界面还提供了许多其他的功能, 包括数据绘制的开始和暂停, 图像的放缩, 子图的配置和图像的导出等.
数据记录和分析: 使用 rosbag 和 rqt_bag
作为实时数据可视化的一个补充, 数据记录和分析工具也是调试工作的一大利器. 在 ROS 中, 将数据记录在文件里, 供日后进行分析是一种普遍的做法. 一种直观的方法是自行编写一个 ROS 节点, 订阅你需要记录的话题, 然后把数据写入文件. 不过, 其实 ROS 已经提供了一个强大并且通用的工具--rosbag 来完成这项任务. rosbag 可以将任何 ROS 话题中的任意类型数据保存在记录文件中. 习惯上, 我们会使用".bag"作为这些文件的扩展名.
使用 rosbag 实现数据的记录和回放
先看看如何记录一个话题中的数据. 启动 roscore, 然后运行 rosbag, 让它去记录 /chatter 话题下的数据, 并将输出写入一个叫 chatter.bag 的文件中(这样主要是为了方便讲解, 正常使用时我们一般会让 rosbag 自动生成一个文件名).
在另一个终端中, 使用 rostopic pub 命令按照10Hz 的频率向 chatter 话题发布消息.
让该发布程序运行大约10秒钟, 然后同时终止发布程序和rosbag记录程序. 现在我们就有了一个名为 chatter.bag 的记录文件.该文件中存储着我们向 chatter 话题发布的消息. 可以打开该文件查看一下:
通过 rosbag info 命令, 我们可以查看.bag 文件的元数据, 包括记录的起止时间, 总时长, 记录的数据类型等等. 在上面的信息中可以看到, 我们在 chatter 话题下捕获了130条类型为 std/_msgs/String 的消息. 当然, 如果我们记录了更多的话题, 这些话题的记录信息也会被列出来.
对记录的数据进行回放也非常简单, 保持 roscore 运行, 然后执行 rostopic echo 命令, 准备输出记录的话题消息:
暂时没有任何输出. 因为还没有节点向 chatter 话题发布数据. 现在使用 rosbag play 命令读取.bag 文件并回放:
现在在运行 rostopic echo 的终端里, 我们就能看到回放的消息了:
rostopic echo 会一直打印回放的消息, 直到所有记录的数据被回放完. 回放完后, rosbag play 也会自动退出.
虽然上面的例子比较简单, 但是 rosbag 确实是一个非常强大的工具. 使用 rosbag, 你可以记录任何 ROS 话题的消息流, 并且在日后进行回放. 由于话题的订阅节点并不会区分发布者, 因此, 我们完全可以使用 bag 中记录的数据进行多次离线调试. 一种常见的调试方式就是使用 rosbag 回放数据, 并且在 rviz 中查看各个节点的行为.
rosbag 工具还提供了许多额外的选项. 下面是一些相关的使用技巧:
- 使用 rosbag -a 记录整个 ROS 系统的所有数据. 请小心使用这个选项, 因为如果你的 ROS 系统较大的话, 那么rosbag 记录的数据将会非常大, 甚至耗尽磁盘容量. 事实上, 订阅所有数据会对ROS系统的运行性能产生显著的影响. 尤其是对于那些对前后级的数据有依赖的节点(比如图像处理中的一环).
- bag 文件会对数据进行压缩, 以节省空间. 你可以使用 rosbag record -j /topic 命令在记录数据时使能数据压缩, 也可以使用 rosbag compress topic.bag 命令对已有的 bag 文件进行压缩. 压缩后的文件同样可以直接使用 rosbag play 回放, 回放时该文件会被自动解压.
- 使用 rosbag play -l topic.bag 命令循环回放某个 bag. 这个选项在调试有多个处理流程的 ROS 系统时十分有用.
- 使用 rosbag play --clock topic.bag 来给回放的数据加上时间戳. 增加--clock 选项后, 回放时rosbag 会额外向 /clock 话题发布一个时间戳, 代表当前回放数据的实际发布时间. 请注意, 由于/clock 话题下发布的是过去的时间, 因此如果要对这个时间做处理的话, 请务必保证你的程序在时间发生大幅度跳变时仍能保持稳定.
无论是调试机器人的一些异常行为, 还是对模型进行参数调整, rosbag 都将给你的开发和调试过程带来极大的便利.
使用 rqt_bag 实现数据包的可视化
除了一般的回放外, 对 bag 的内容进行可视化也是很必要的. ROS 提供了 rqt_bag 这个工具来完成这件任务. 使用方法也很简单, 直接输入 rqt-bag 命令并指明一个 bag 文件即可.
然后就会打开一个窗口, 如图 21-9 所示:
图21-9 你可以在 rqt_bar 的图形界面里完成对记录数据的可视化操作
使用rqt-bag, 你可以看到被记录的话题数量, 每个话题下消息的频率以及消息的内容. 还可以指定对整个或一部分记录进行回放, 甚至逐帧"单步"回放. 如果想要保存一部分记录为一个单独的bag, 也可以直接在 rqt-bag 里完成.
使用其他工具分析数据包: 借助 rostopic echo -b
在其他非 ROS 工具(如 gun-plot, GNU octave, MATLAB等)中使用 rosbag 中记录的数据是一种常见的做法. ROS 提供了 rostopic echo 这个工具来把 bag 转换为文本形式的数据文件. 使用方法也很简单, 输入 rostopic ehco -b 命令, 并指定一个需要转换的 bag 文件:
用这种方法得到的文本或许可读性较好, 但是却不容易被程序所解析. 可以加上-p 选项, 将输出转换为逗号分隔的格式. 输出的第一行是分隔表示中每一部分的含义.
将输出重定向到一个文件中:
然后你就可以用自己喜欢的工具解析这些数据了. 当然, 借助 rosbag 这个模块, 你也可以自己编写 Python 代码完成数据的解析工作. rosbag cookbook 中有几个可供参考的样例程序.
小结
本章中, 我们主要讲解了ROS 系统的一些调试工具和调试技巧. 由于机器人系统自身的复杂性和异步性, 缺乏有效的调试工具将会严重影响开发过程的效率. 因此 ROS 才提供了如此丰富的定制工具. 回到机器人调试的问题上来, 客观的讲, 调试机器人系统的一般原则其实跟其他系统的调试大同小异: 出现异常时, 首先要定位问题, 并确定造成问题的原因. 而对系统的可视化将会给这两样工作带来极大的帮助.事实上, 上文中所提到的各种工具, 实际上都是在进行"可视化".