一、调参利器:参数波动图

控制调参时,参数众多且相互耦合,单靠"改一个跑一次"效率较低。这里分享一个实用思路:

用 AI 写一个参数记录脚本,在导航运行时自动采集每个参数在每个时刻的值,最终将各时刻的参数值连线,生成一张 "参数波动图"

如此可清晰观察到每个参数在导航过程中的动态变化趋势,快速定位哪个参数在什么阶段出现异常波动。

实现思路参考:

# 伪代码示意(可让AI生成完整版本)
import rclpy
from rclpy.node import Node
import csv, time

class ParamLogger(Node):
    def __init__(self):
        super().__init__('param_logger')
        self.timer = self.create_timer(0.5, self.log_params)  # 每0.5s采集一次
        self.csv_file = open('param_log.csv', 'w', newline='')
        # 通过 ros2 param 接口动态读取目标节点的参数
        ...

    def log_params(self):
        # 记录时间戳 + 各参数当前值
        ...

采集完成后,用脚本将数据绘制为多子图折线图,横轴为时间,纵轴为参数值,很清晰。


二、系统意外重启?启用 journald 持久化存储

调试机器人时最怕的就是系统突然崩溃/断电,日志全丢,根本不知道崩溃前发生了什么。解决方案:启用 systemd-journald 的持久化存储,实时追踪系统日志,即使意外关机也能保留本次启动的完整日志。

2.1 开启持久化

# 创建持久化日志目录
sudo mkdir -p /var/log/journal

# 设置正确的权限和属性
sudo systemd-tmpfiles --create --prefix /var/log/journal

# 重启 journald 使配置生效
sudo systemctl restart systemd-journald

2.2 验证是否生效

# 检查日志存储位置(应显示 /var/log/journal/... 而非 /run/log/journal/...)
journalctl --header | head -5

补充:如果路径是 /run/log/journal,说明仍在内存中,重启即丢失;看到 /var/log/journal 才表示持久化成功。

2.3 崩溃后查看上一次启动的日志

# 查看上一次启动的完整日志
journalctl -b -1

# 查看上次启动的最后 200 条错误日志(warning 及以上),逆序,不分页
journalctl -b -1 -p warning..emerg -n 200 -r --no-pager

# 从崩溃点往前追溯(逆序查看最后 200 条)
journalctl -b -1 -r -n 200 --no-pager

更多实用命令:

# 按时间范围查看
journalctl -b -1 --since "2026-07-21 14:00" --until "2026-07-21 14:30"

# 只看某个服务的日志
journalctl -b -1 -u nav2_controller

# 实时跟踪当前日志(类似 tail -f)
journalctl -f

# 查看磁盘上日志占用空间
journalctl --disk-usage

# 手动清理,只保留最近 3 天
sudo journalctl --vacuum-time=3d

三、journald 常用配置

主配置文件路径:/etc/systemd/journald.conf

[Journal]
# 日志最大占用磁盘空间(所有 journal 文件总和)
SystemMaxUse=2G

# 磁盘至少保留的可用空间(防止日志撑满磁盘)
SystemKeepFree=1G

# 日志最长保留时间(超期自动清理)
MaxRetentionSec=30day

# 刷盘间隔(日志从内存缓冲写入磁盘的频率)
SyncIntervalSec=5min

# 是否压缩旧日志(节省磁盘空间,推荐开启)
Compress=yes

修改后重启生效:

sudo systemctl restart systemd-journald

验证当前运行配置:

journalctl --show-cursor --header | head -10

补充:机器人主控(如树莓派、RK3576 等)磁盘空间有限,建议将 SystemMaxUse 设为 500M~1GMaxRetentionSec 设为 7day,避免日志撑爆存储。


四、流式传感器 QoS 设置:BEST_EFFORT vs RELIABLE

深度摄像头、激光雷达等流式传感器在 ROS2 中发布话题时,QoS 的 Reliability 策略选择非常关键:

策略 行为 适用场景
RELIABLE 保证每帧数据送达,丢包会重传 配置参数、服务调用、低频关键指令
BEST_EFFORT 尽最大努力交付,丢就丢,不重传 深度图、点云、IMU 等高频流式数据

为什么流式传感器要用 BEST_EFFORT?

        避免卡顿:RELIABLE 模式下,一旦网络抖动丢包,DDS 会等待重传,导致数据堆积、回调阻塞,rviz中画面卡死。

        保证实时性:传感器 30fps 持续出数据,我们只关心最新一帧。RELIABLE 模式可能让你收到的是几百毫秒前的"旧帧",而 BEST_EFFORT 直接丢弃过期数据,拿到的是最新的。

        降低 CPU/内存开销:无需维护重传队列和确认机制。

代码示例

from rclpy.qos import QoSProfile, ReliabilityPolicy, HistoryPolicy

# 订阅深度图像时使用 BEST_EFFORT
sensor_qos = QoSProfile(
    reliability=ReliabilityPolicy.BEST_EFFORT,
    history=HistoryPolicy.KEEP_LAST,
    depth=1  # 只保留最新1帧,进一步降低延迟
)

self.subscription = self.create_subscription(
    Image,
    '/camera/depth/image_raw',
    self.depth_callback,
    sensor_qos
)

补充:如果发布端用 BEST_EFFORT,订阅端用 RELIABLE,两者 QoS 不兼容,订阅端将收不到任何消息且不会报错!排查"话题有数据但订阅不到"时,记得检查下 QoS 是否匹配。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐