ROS2机器人编程简述humble-第二章-Launchers .3.3
机器人程序通常需要配置各类参数,官网和一些书中都有介绍。
概述
ROS中的参数与各个节点相关。参数用于在启动时(以及运行时)配置节点,而无需更改代码。参数的生存期与节点的生存期相关联(尽管节点可以实现某种持久性以在重新启动后重新加载值)。
参数由节点名称、节点名称空间、参数名称和参数名称空间寻址。提供参数命名空间是可选的。
每个参数由一个键、一个值和一个描述符组成。键是字符串,值是以下类型之一:bool、int64、float64、string、byte[]、bool[]、int64[]、float64[]或string[]。默认情况下,所有描述符都为空,但可以包含参数描述、值范围、类型信息和其他约束。
声明参数
默认情况下,节点需要声明在其生存期内将接受的所有参数。这样,在节点启动时就可以定义参数的类型和名称,这减少了以后错误配置的机会。有关从节点声明和使用参数的教程,请参阅在类(C++)中使用参数或在类(Python)中使用参数。
对于某些类型的节点,并非所有参数都会提前知道。在这些情况下,可以将allow_undeclaed_parameters设置为true来实例化节点,这将允许在节点上获取和设置参数,即使它们尚未声明。
参数类型
ROS 2节点上的每个参数都具有概述中提到的预定义参数类型之一。默认情况下,在运行时更改声明参数类型的尝试将失败。这可以防止常见错误,例如将布尔值放入整数参数。
如果参数需要是多个不同的类型,并且使用该参数的代码可以处理它,则可以更改此默认行为。声明参数时,应使用dynamic_typeing成员变量设置为true的ParameterDescriptor声明该参数。
示例:
#include <vector>
#include <string>
#include "rclcpp/rclcpp.hpp"
class LocalizationNode : public rclcpp::Node
{
public:
LocalizationNode()
: Node("localization_node")
{
declare_parameter("number_particles", 200);
declare_parameter("topics", std::vector<std::string>());
declare_parameter("topic_types", std::vector<std::string>());
get_parameter("number_particles", num_particles_);
RCLCPP_INFO_STREAM(get_logger(), "Number of particles: " << num_particles_);
get_parameter("topics", topics_);
get_parameter("topic_types", topic_types_);
if (topics_.size() != topic_types_.size()) {
RCLCPP_ERROR(
get_logger(), "Number of topics (%zu) != number of types (%zu)",
topics_.size(), topic_types_.size());
} else {
RCLCPP_INFO_STREAM(get_logger(), "Number of topics: " << topics_.size());
for (size_t i = 0; i < topics_.size(); i++) {
RCLCPP_INFO_STREAM(get_logger(), "\t" << topics_[i] << "\t - " << topic_types_[i]);
}
}
}
private:
int num_particles_;
std::vector<std::string> topics_;
std::vector<std::string> topic_types_;
};
int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
auto node = std::make_shared<LocalizationNode>();
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
•必须使用declare parameter等方法声明节点的所有参数。在声明中,指定参数名称和默认值。
•使用get parameter等函数获取其值,指定参数的名称和存储其值的位置。
•有一些方法可以分块实现。
•可以随时读取参数,甚至可以实时订阅修改。然而,在启动时读取它们会使代码更容易预测。
所有ROS节点都采用一组参数,允许重新配置各种属性。示例包括配置节点的名称/命名空间、使用的主题/服务名称以及节点上的参数。必须在--ROS args标志之后指定所有ROS特定参数:
ros2 run my_package node_executable --ros-args ...
ros2 run br2 basics param reader
ros2 run br2 basics param reader --ros-args -p number_particles:=300
ros2 run br2 basics param reader --ros-args -p number_particles:=300 -p topics:= ’[scan, image]’ -p topic types:=’[sensor msgs/msg/LaserScan, sensor msgs/msg/Image]’
使用launch配置参数:
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
param_reader_cmd = Node(
package='br2_basics',
executable='param_reader',
parameters=[{
'number_particles': 300,
'topics': ['scan', 'image'],
'topic_types': ['sensor_msgs/msg/LaserScan', 'sensor_msgs/msg/Image']
}],
output='screen'
)
ld = LaunchDescription()
ld.add_action(param_reader_cmd)
return ld
使用YAML文件配置参数:
install(DIRECTORY launch config DESTINATION share/${PROJECT_NAME})
localization_node:
ros__parameters:
number_particles: 300
topics: [scan, image]
topic_types: [sensor_msgs/msg/LaserScan, sensor_msgs/msg/Image]
加载:
import os
from ament_index_python.packages import get_package_share_directory
from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
pkg_dir = get_package_share_directory('br2_basics')
param_file = os.path.join(pkg_dir, 'config', 'params.yaml')
param_reader_cmd = Node(
package='br2_basics',
executable='param_reader',
parameters=[param_file],
output='screen'
)
ld = LaunchDescription()
ld.add_action(param_reader_cmd)
return ld
或者:
ros2 run br2 basics param reader --ros-args --params-file install/basics/share/basics/config/params.yaml
更多案例如下:
ros2 run demo_nodes_cpp talker --ros-args -r __ns:=/demo -r __node:=my_talker -r chatter:=my_topic
ros2 run composition manual_composition --ros-args -r talker:__node:=my_talker -r listener:__node:=my_listener
ros2 run composition manual_composition --ros-args -r talker:__node:=my_talker -r my_talker:chatter:=my_topic -r listener:__node:=my_listener -r my_listener:chatter:=my_topic
ros2 run package_name executable_name --ros-args -p param_name:=param_value
ros2 run demo_nodes_cpp parameter_blackboard --ros-args -p some_int:=42 -p "a_string:=Hello world" -p "some_lists.some_integers:=[1, 2, 3, 4]" -p "some_lists.some_doubles:=[3.14, 2.718]"
ros2 run demo_nodes_cpp parameter_blackboard --ros-args --params-file demo_params.yaml