zl程序教程

您现在的位置是:首页 >  其他

当前栏目

ROS2机器人编程简述humble-第二章-Parameters .3.4

2023-03-07 09:06:05 时间

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

更多案例如下:

  1. ros2 run demo_nodes_cpp talker --ros-args -r __ns:=/demo -r __node:=my_talker -r chatter:=my_topic
  2. ros2 run composition manual_composition --ros-args -r talker:__node:=my_talker -r listener:__node:=my_listener
  3. 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
  4. ros2 run package_name executable_name --ros-args -p param_name:=param_value
  5. 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]"
  6. ros2 run demo_nodes_cpp parameter_blackboard --ros-args --params-file demo_params.yaml