4、ROS基础回顾(二):Launch文件编写、参数服务器、常用命令行工具

好,咱们接着聊。上一章我们把ROS的节点、话题、服务这些核心概念捋了一遍。这一章,我带你看看实际干活时天天要用的三样东西:Launch文件、参数服务器,还有那几个命令行工具。

说实话,刚入门那会儿,我总觉得一个个开终端敲命令挺帅的。直到有一次调试一个六轴机械臂,需要同时启动十几个节点……嗯,从那以后,我再也不敢手动了。Launch文件就是干这个的。

4.1 Launch文件:一键启动的艺术

Launch文件说白了就是一个XML格式的启动脚本。它帮你把一堆节点的启动、参数配置、命名空间管理全包了。

4.1.1 基本结构

一个最简单的Launch文件长这样:

<launch>
    <node name="talker" pkg="my_package" type="talker_node.py" output="screen"/>
    <node name="listener" pkg="my_package" type="listener_node.py" output="screen"/>
</launch>

这里每个<node>标签对应一个节点。name是节点别名,pkg是功能包名,type是可执行文件名。output="screen"表示把日志打印到终端——调试时特别有用。

我的习惯:调试阶段一律加 output="screen"。等上线稳定了再去掉,改用rosout日志系统。

4.1.2 嵌套与复用

你想想看,一个机器人项目少说几十个节点,全写在一个文件里?那不乱套了。ROS支持用<include>标签嵌套其他Launch文件:

<launch>
    <include file="$(find my_robot_bringup)/launch/base.launch"/>
    <include file="$(find my_robot_navigation)/launch/nav.launch"/>
    
    <node name="custom_node" pkg="my_package" type="custom_node" />
</launch>

$(find pkg_name)这个语法很实用——它会自动找到功能包的路径。我当年刚入行时,傻乎乎地写路径,换台电脑就崩了。后来被老工程师骂了一顿,才学会用这个。

4.1.3 参数传递与重映射

Launch文件里还能直接设置参数和重映射话题名:

<launch>
    <param name="robot_name" value="my_robot"/>
    <remap from="/cmd_vel" to="/my_robot/cmd_vel"/>
    
    <node name="controller" pkg="my_robot_control" type="controller" />
</launch>
注意:重映射要小心。我曾经把一个话题重映射错了,结果机器人原地转圈了十分钟我才发现……排查了半天。

4.2 参数服务器:全局配置中心

参数服务器就像一个全局的键值对数据库。所有节点都能读写它。适合存放那些不常变但需要共享的配置——比如PID参数、传感器阈值、机器人模型路径等。

4.2.1 命令行操作

我最常用的几个命令:

# 获取参数
rosparam get /robot_name

# 设置参数
rosparam set /pid_p 1.5

# 列出所有参数
rosparam list

# 保存参数到文件
rosparam dump params.yaml

# 从文件加载参数
rosparam load params.yaml

rosparam dump和rosparam load这对组合特别实用。调试时调好一组参数,一键保存。下次启动直接加载,省得一个个敲。

4.2.2 在Launch文件中设置参数

除了命令行,Launch文件里也能设置参数:

<launch>
    <!-- 全局参数 -->
    <param name="use_sim_time" value="true"/>
    
    <!-- 从文件加载 -->
    <rosparam file="$(find my_robot)/config/pid.yaml" command="load"/>
    
    <!-- 私有参数(属于某个节点) -->
    <node name="motor_driver" pkg="my_robot" type="motor_driver">
        <param name="max_speed" value="0.5"/>
        <param name="acceleration" value="0.2"/>
    </node>
</launch>
关键区别:写在<node>标签内部的参数是私有参数,只有该节点能访问。写在外面的是全局参数,所有节点都能读。

4.3 常用命令行工具

这部分我挑几个最常用的讲。说实话,我每天跟它们打交道的时间比跟老婆说话的时间还长……

4.3.1 rostopic:话题的瑞士军刀

rostopic是调试时用得最多的工具。没有之一。

# 列出所有话题
rostopic list

# 查看话题消息内容(实时打印)
rostopic echo /odom

# 查看话题消息类型
rostopic type /cmd_vel

# 查看发布频率
rostopic hz /odom

# 手动发布消息(调试神器)
rostopic pub /cmd_vel geometry_msgs/Twist "linear:
  x: 0.5
  y: 0.0
  z: 0.0
angular:
  z: 0.1"

rostopic pub这个命令我特别喜欢。调试电机驱动时,直接发一个速度指令,看轮子转不转。比写测试节点快多了。

4.3.2 rosnode:节点管理

节点出问题了怎么办?用rosnode查:

# 列出所有节点
rosnode list

# 查看节点信息
rosnode info /motor_driver

# 测试节点是否存活
rosnode ping /motor_driver

# 杀掉节点
rosnode kill /motor_driver
避坑指南:我曾经遇到一个节点明明在运行,但rosnode list里看不到。后来发现是节点启动时没调用ros::init()。记住:不调用init,ROS系统就不认这个节点。

4.3.3 rosservice:远程过程调用

服务跟话题不同——它是同步的、有去有回的。适合那些需要立即响应的操作,比如重置里程计、切换模式等。

# 列出所有服务
rosservice list

# 查看服务类型
rosservice type /reset_odom

# 调用服务
rosservice call /reset_odom "{}"

# 查看服务参数
rosservice info /reset_odom

我个人习惯:把那些需要手动触发的操作都做成服务。比如校准IMU、切换导航模式、紧急停止等。这样调试时一个rosservice call就搞定,不用重启节点。

4.4 本章知识体系

下面这张图帮你理清这三样东西的关系:

ROS基础工具知识体系 Launch文件 参数服务器 命令行工具 节点启动 · 嵌套复用 · 参数传递 话题重映射 · 命名空间管理 rosparam get/set/list dump/load · 私有参数 · 全局参数 rostopic: echo/pub/hz/list rosnode: list/info/ping/kill rosservice: list/call/info 核心工作流 编写Launch文件 → 启动节点 → 用命令行工具调试 参数服务器贯穿始终,提供全局配置

这三样东西配合起来,就是ROS日常开发的铁三角。Launch文件负责启动,参数服务器负责配置,命令行工具负责调试。缺一个,干活都不顺手。

好了,这一章就到这里。记住:工具是死的,人是活的。多用、多试、多踩坑,慢慢就熟练了。

可可精品资料库