一、前言

在机器人开发中,导航、底盘、雷达等多个节点会共用车辆尺寸、雷达阈值等全局配置,如果每个节点硬编码会极难维护。参数服务就是 ROS2 提供的全局共享配置通信方案,底层封装服务通信,实现参数统一存储、跨节点读写修改,类似程序全局变量。

本文基于课程 2.5 参数服务章节,从零搭建cpp04_paramC++ 功能包,完整实现参数服务端,同时解决新手编译踩坑问题。

二、参数服务核心概念

1. 定义

参数服务是请求 - 应答模式通信:

  • 参数服务端:存储所有共享参数的节点;
  • 参数客户端:查询 / 修改服务端参数的节点;
  • 底层:自动封装get_parameters/set_parameters服务,无需自定义 srv 文件。

2. ROS2 支持参数类型

字符串、整型、浮点、布尔、数组(int/float/string/byte 数组),C++ 中使用rclcpp::Parameter类封装参数。

3. 典型使用场景

移动机器人底盘长宽、导航最大速度、激光雷达检测距离、相机曝光参数等全局配置。

三、环境与前置准备

  1. ROS2 Jazzy/Humble 系统,已配置ros2_ws工作空间; 2 安装构建工具:sudo apt install ros-jazzy-rclcpp colcon-common-extensions; 3 工作空间目录规范(必须严格遵守):
ros2_ws/
├─ src/
│  └─ cpp04_param/       # 参数功能包
│     ├─ src/            # C++源码目录
│     ├─ CMakeLists.txt  # 编译配置
│     └─ package.xml     # 包依赖配置
├─ build/ (编译自动生成,禁止手动放入包内)
├─ install/
└─ log/

四、从零创建参数功能包

步骤 1:进入 src 创建包

cd ~/ros2_ws/src
# 创建C++参数包,依赖rclcpp核心库
ros2 pkg create cpp04_param --build-type ament_cmake --dependencies rclcpp

执行完成自动生成基础文件。

步骤 2:编写参数服务端代码

进入源码目录,创建demo01_param_server.cpp

cd cpp04_param/src
nano demo01_param_server.cpp

完整代码(创建、读取、打印参数):

#include "rclcpp/rclcpp.hpp"

int main(int argc, char * argv[])
{
    // 初始化ROS2
    rclcpp::init(argc, argv);
    // 创建参数服务节点
    auto node = rclcpp::Node::make_shared("param_server");

    // 1. 创建不同类型参数
    rclcpp::Parameter car_name("car_name", "Tiger");   // 字符串
    rclcpp::Parameter car_width("width", 0.15);        // 浮点
    rclcpp::Parameter wheel_num("wheels", 2);          // 整型

    // 2. 打印参数值
    RCLCPP_INFO(node->get_logger(), "车辆名称:%s", car_name.as_string().c_str());
    RCLCPP_INFO(node->get_logger(), "车辆宽度:%.2f m", car_width.as_double());
    RCLCPP_INFO(node->get_logger(), "车轮数量:%ld 个", wheel_num.as_int());

    // 3. 获取参数名称、数据类型
    RCLCPP_INFO(node->get_logger(), "参数car_name键名:%s", car_name.get_name().c_str());
    RCLCPP_INFO(node->get_logger(), "car_name数据类型编号:%d", static_cast<int>(car_name.get_type()));

    // 节点持续运行,等待外部指令修改参数
    rclcpp::spin(node);
    rclcpp::shutdown();
    return 0;
}

步骤 3:修改 CMakeLists.txt(无报错完整版)

cd ~/ros2_ws/src/cpp04_param
nano CMakeLists.txt

全量替换下面代码(严格顺序:先创建程序,再绑定依赖,解决ament_target_dependencies报错):

cmake_minimum_required(VERSION 3.8)
project(cpp04_param)

# 查找依赖包
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)

# 生成可执行程序,目标名和cpp文件名对应
add_executable(demo01_param_server src/demo01_param_server.cpp)
# 绑定依赖,第一个参数必须和上方目标名一致
ament_target_dependencies(demo01_param_server rclcpp)

# 安装规则,编译后放到运行目录
install(TARGETS
  demo01_param_server
  DESTINATION lib/${PROJECT_NAME}
)

# 包声明(必须放在末尾)
ament_package()

步骤 4:修复 package.xml(消除冗余依赖警告)

nano package.xml

完整标准内容,删除多余<depend>标签

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>cpp04_param</name>
  <version>0.0.0</version>
  <description>ROS2参数服务C++实现</description>
  <maintainer email="user@163.com">user</maintainer>
  <license>Apache-2.0</license>

  <!-- 构建工具依赖 -->
  <buildtool_depend>ament_cmake</buildtool_depend>
  <!-- 编译、运行依赖 -->
  <build_depend>rclcpp</build_depend>
  <exec_depend>rclcpp</exec_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

五、编译(避坑关键操作)

1. 清理所有旧缓存(解决路径错乱报错)

禁止把 build/install/log 放进功能包内部,先彻底删除残留文件:

# 1. 删除包内错误缓存(新手高频坑)
cd ~/ros2_ws/src/cpp04_param
rm -rf build install log
# 2. 回到工作空间根目录,清空全局编译文件
cd ~/ros2_ws
rm -rf build install log

2. 单包编译(只编译 cpp04_param,更快定位错误)

colcon build --packages-select cpp04_param

✅ 成功标志:终端输出绿色 Finished <<< cpp04_param,无红色 Error。

❌ 常见报错解决方案:

  1. ament_target_dependencies first argument invalid 原因:CMake 顺序颠倒;解决:先add_executable再写依赖绑定。
  2. package.xml 文件不存在 原因:在包内执行 colcon build;解决:必须在ros2_ws根目录编译。
  3. XML 解析 configure_file 报错 原因:package.xml 标签重复 / 中文符号;解决使用上文完整 xml 覆盖。

六、运行参数服务节点

1. 刷新环境变量(每次新开终端必须执行)

source install/setup.bash

2. 启动参数服务端

ros2 run cpp04_param demo01_param_server

正常输出日志:

[INFO] [xxx]: 车辆名称:Tiger
[INFO] [xxx]: 车辆宽度:0.15 m
[INFO] [xxx]: 车轮数量:2 个
[INFO] [xxx]: 参数car_name键名:car_name
[INFO] [xxx]: car_name数据类型编号:4

3. 终端命令行操作参数(ROS2 内置工具)

新开第二个终端,刷新环境后执行参数操作指令:

# 查看当前节点所有参数
ros2 param list /param_server

# 读取单个参数
ros2 param get /param_server car_name

# 动态修改参数
ros2 param set /param_server car_name "MiniRobot"

# 导出所有参数到yaml配置文件
ros2 param dump /param_server --output car_config.yaml

七、新手避坑总结

  1. 目录红线:build/install/log 只能存在ros2_ws根目录,功能包内不能出现;
  2. CMake 顺序add_executable必须在ament_target_dependencies前面;
  3. package.xml 规范 不要额外添加<depend>rclcpp</depend>,会报冗余警告;
  4. 编译路径colcon build只能在工作空间根目录执行;
  5. 文件匹配:CMake 中写的 cpp 文件名必须真实存在,大小写完全一致。

八、拓展:参数客户端开发思路

后续可新增demo02_param_client.cpp,通过服务调用远程读取、修改服务端参数,实现跨节点配置同步,完整覆盖增删改查全部参数操作,适配真实机器人多节点协同开发场景。

九、总结

参数服务是 ROS2 四大通信机制(话题 / 服务 / 动作 / 参数)中配置管理专用方案,无需自定义消息,开箱即用。本文搭建的cpp04_param包完全匹配课程 2.5 参数服务案例,配置文件无语法错误,清理缓存后可一键编译运行,适合机器人导航、底盘开发时统一管理全局硬件参数。

Logo

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

更多推荐