在ROS 2中,参数(Parameters)系统相比于ROS 1有了较大的改进。主要区别:
ROS 1 中的参数
- 在ROS 1中,参数主要是通过
rosparam
工具来设置和获取的,并且它们通常存储在一个中心化的服务器上,即rosparam
服务器。 - 参数通常是静态的,一旦设置后,在节点运行期间不容易更改,除非重启节点或重新设置参数。
- 参数可以以YAML格式存储在文件中,并通过
rosparam load_file
命令加载到系统中。 - 虽然有一些方法可以在运行时修改参数,但这通常需要编写特定的代码来处理这些情况。
ROS 2 中的参数
- 在ROS 2中,参数系统变得更加动态,允许在运行时更灵活地修改参数。
- 每个节点都有自己的参数接口,可以独立于其他节点管理其参数。
- 参数可以是异步更新的,并且可以为参数设置回调函数,当参数值改变时自动执行。
- 支持多种类型的参数,包括基本类型如int, double, string等,以及复杂类型如数组和嵌套结构。
- 提供了API来声明参数,获取参数值,检查参数是否存在,以及动态地添加或删除参数。
- 可以使用
rclcpp::Node::declare_parameter()
来声明一个参数,并使用get_parameter()
或get_parameter_or()
来获取它的值。 - 使用
set_parameters
或set_parameters_atomically
可以修改参数值,并且有机制确保原子性操作。 - 支持描述参数,比如提供描述信息、校验函数等,这使得参数更加易于理解和维护。
ROS2中Parameters操作接口
在ROS 2中,参数(Parameters)的操作接口主要通过rclcpp
库中的Node
类和其他相关的类来实现。以下是一些关键的接口函数,用于创建、查询、更新和删除参数:
创建节点时声明参数
- 声明参数:
declare_parameter
: 声明一个参数,并可指定默认值。
this->declare_parameter("example_param", 10);
-
获取参数
获取单个参数:
get_parameter
: 获取指定名称的参数对象。
get_parameter_or
: 获取指定名称的参数,如果不存在则返回默认值。
auto param = this->get_parameter("example_param");
int value = this->get_parameter_or("example_param", 10).as_int();
批量获取参数:
get_parameters
: 同时获取多个参数。
std::vector<rclcpp::Parameter> params = this->get_parameters({"param1", "param2"});
-
设置参数
设置单个参数:
set_parameters
: 设置一个或多个参数。
std::vector<rclcpp::Parameter> new_params = {
rclcpp::Parameter("example_param", 20)
};
auto result = this->set_parameters(new_params);
设置参数原子操作:
set_parameters_atomically
: 设置一个或多个参数,并保证操作的原子性。
auto result = this->set_parameters_atomically(new_params);
-
监听参数变化
监听参数变更:
add_on_set_parameter_callback
: 添加一个回调函数,当参数值发生变化时触发。
auto cb = [this](std::shared_ptr<rclcpp::ParameterEvent> event) {
RCLCPP_INFO(this->get_logger(), "Parameter changed: %s", event->name.c_str());
};
this->add_on_set_parameter_callback(cb);
-
其他相关功能
-
删除参数:
remove_parameter
: 删除指定名称的参数。
this->remove_parameter("example_param");
-
列出所有参数:
list_parameters
: 列出节点的所有参数。
std::vector<std::string> param_names = this->list_parameters({"*"}, 10);
ROS2中parameters操作实现逻辑
ROS2中的参数操作是基于服务通信实现的,每个节点进程在node创建过程时,需要建立如下六个和参数管理相关的基础服务:
-
/get_parameters
- 服务类型:
rcl_interfaces/srv/GetParameters
- 用途:获取一个或多个参数的当前值。
- 请求消息:包含一个字符串数组,代表要获取的参数名称。
- 响应消息:包含一系列
rclcpp::Parameter
对象,每个对象对应一个请求的参数及其值。
- 服务类型:
-
/set_parameters
- 服务类型:
rcl_interfaces/srv/SetParameters
- 用途:设置一个或多个参数的值。
- 请求消息:包含一系列
rclcpp::Parameter
对象,每个对象包含一个参数名称及其新值。 - 响应消息:包含一系列
rcl_interfaces/msg/SetParametersResult
对象,每个对象对应一个设置的结果(成功或失败)。
- 服务类型:
-
/set_parameters_atomically
- 服务类型:
rcl_interfaces/srv/SetParametersAtomically
- 用途:原子性地设置一组参数,这意味着要么全部参数都设置成功,要么都不设置。
- 请求消息:与
SetParameters
类似,但强调原子性。 - 响应消息:包含一个布尔值,指示是否所有参数都设置成功。
- 服务类型:
-
/list_parameters
- 服务类型:
rcl_interfaces/srv/ListParameters
- 用途:列出节点中已声明的参数。
- 请求消息:包含一个字符串数组作为前缀,以及一个整数作为递归深度(可选)。
- 响应消息:包含一个字符串数组,列出符合前缀条件的参数名称。
- 服务类型:
-
/describe_parameters
- 服务类型:
rcl_interfaces/srv/DescribeParameters
- 用途:获取一个或多个参数的描述信息。
- 请求消息:包含一个字符串数组,代表要获取描述的参数名称。
- 响应消息:包含一系列
rcl_interfaces/msg/ParameterDescriptor
对象,每个对象描述一个参数的信息。
- 服务类型:
-
/get_parameter_types
- 服务类型:
rcl_interfaces/srv/GetParameterTypes
- 用途:获取一个或多个参数的类型信息。
- 请求消息:包含一个字符串数组,代表要获取类型的参数名称。
- 响应消息:包含一个字符串数组,每个字符串代表一个参数的类型。
- 服务类型:
创建流程图如下所示: