在 ROS 2 中,将节点参数保存为 YAML 文件可以通过两种方式实现:命令行工具导出或在代码中手动保存。以下是详细步骤和示例:
一、方法 1:使用 ROS 2 命令行工具导出参数(推荐)
ROS 2 提供了 ros2 param dump 命令,可以直接将运行中节点的所有参数导出为 YAML 文件,无需修改代码。
步骤:
-
确保节点正在运行
先启动你的 ROS 2 节点,例如:bash
-
ros2 run your_package your_node -
查看节点名称
用ros2 node list确认节点的完整名称(例如/my_controller_node):bash
-
ros2 node list -
导出参数到 YAML 文件
使用ros2 param dump命令,格式为:bash
ros2 param dump <节点名称> -o <输出文件路径>
示例:
bash
-
ros2 param dump /my_controller_node -o params.yaml执行后,当前目录会生成
params.yaml文件,包含节点的所有参数。
二、方法 2:在 C++ 代码中手动保存参数到 YAML
如果需要在节点运行过程中自动保存参数(例如在退出时或触发某个事件时),可以通过代码读取参数后写入 YAML 文件。需要依赖 yaml-cpp 库处理 YAML 格式。
步骤:
-
添加依赖
在package.xml中添加yaml-cpp依赖:xml
<depend>yaml-cpp</depend>
在 CMakeLists.txt 中添加:
cmake
-
find_package(yaml-cpp REQUIRED) target_link_libraries(your_node_name PRIVATE yaml-cpp) -
代码实现
在节点中添加参数保存逻辑,示例代码:cpp
运行
-
#include "rclcpp/rclcpp.hpp" #include "yaml-cpp/yaml.h" #include <fstream> #include <vector> class MyNode : public rclcpp::Node { public: MyNode() : Node("my_node") { // 声明参数(示例) this->declare_parameter("max_speed", 0.5); this->declare_parameter("robot_name", "my_robot"); this->declare_parameter("enable_sensor", true); this->declare_parameter("joint_limits", std::vector<double>{1.0, 2.0, 3.0}); // 触发保存参数(例如在节点关闭时) save_params_timer_ = this->create_wall_timer( std::chrono::seconds(10), // 每10秒保存一次,或按需修改触发条件 std::bind(&MyNode::save_params_to_yaml, this) ); } private: void save_params_to_yaml() { // 1. 读取所有参数名称 std::vector<std::string> param_names = this->list_parameters({}, 1000).names; // 2. 创建YAML文档 YAML::Node yaml_node; // 3. 遍历参数并写入YAML for (const auto& param_name : param_names) { // 处理参数类型(支持常见类型:double、int、bool、string、vector等) if (this->has_parameter(param_name)) { auto param_value = this->get_parameter(param_name).get_value<rclcpp::ParameterValue>(); if (param_value.get_type() == rclcpp::ParameterType::PARAMETER_DOUBLE) { yaml_node[param_name] = param_value.get<double>(); } else if (param_value.get_type() == rclcpp::ParameterType::PARAMETER_INTEGER) { yaml_node[param_name] = param_value.get<int>(); } else if (param_value.get_type() == rclcpp::ParameterType::PARAMETER_BOOL) { yaml_node[param_name] = param_value.get<bool>(); } else if (param_value.get_type() == rclcpp::ParameterType::PARAMETER_STRING) { yaml_node[param_name] = param_value.get<std::string>(); } else if (param_value.get_type() == rclcpp::ParameterType::PARAMETER_DOUBLE_ARRAY) { yaml_node[param_name] = param_value.get<std::vector<double>>(); } else if (param_value.get_type() == rclcpp::ParameterType::PARAMETER_INTEGER_ARRAY) { yaml_node[param_name] = param_value.get<std::vector<int>>(); } } } // 4. 写入YAML文件 std::ofstream fout("saved_params.yaml"); if (fout.is_open()) { fout << yaml_node << std::endl; RCLCPP_INFO(this->get_logger(), "参数已保存到 saved_params.yaml"); } else { RCLCPP_ERROR(this->get_logger(), "无法打开文件 saved_params.yaml"); } } rclcpp::TimerBase::SharedPtr save_params_timer_; }; int main(int argc, char* argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared<MyNode>()); rclcpp::shutdown(); return 0; } -
编译运行
编译后运行节点,会自动生成saved_params.yaml文件,包含所有参数。
三、YAML 文件格式说明
导出的 YAML 文件格式示例(包含不同类型的参数):
yaml
/my_node: # 节点名称(命名空间)
max_speed: 0.5
robot_name: "my_robot"
enable_sensor: true
joint_limits: [1.0, 2.0, 3.0]
- 节点名称作为顶级键,避免不同节点的参数冲突。
- 支持常见数据类型:数值、布尔值、字符串、数组等。
四、扩展:使用保存的 YAML 文件加载参数
保存的 YAML 文件可用于启动节点时加载参数:
bash
ros2 run your_package your_node --ros-args --params-file params.yaml
或在 launch 文件中引用:
python
运行
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
return LaunchDescription([
Node(
package="your_package",
executable="your_node",
parameters=["params.yaml"] # 加载YAML参数文件
)
])
总结
- 命令行导出:简单快捷,适合手动保存运行中节点的参数。
- 代码中保存:灵活可控,适合自动保存或复杂场景(如条件触发)。
根据需求选择合适的方法即可。
1076

被折叠的 条评论
为什么被折叠?



