8-在类中使用参数

本文介绍了如何在ROS2中创建C++节点,设置可从launch文件配置的参数,并演示了通过控制台和启动文件动态修改参数的方法。
摘要由CSDN通过智能技术生成

背景

    在构建自己的节点时,有时需要添加可以从launch文件设置的参数。
    本节将学习如何在c++类中创建这些参数,以及如何在启动文件中设置它们。

任务

1 创建一个包

    打开一个新的终端并source ROS 2,这样ros2命令就可以工作了。

    按照以下说明创建一个名为ros2_ws的新工作区。

    注意:创建包应该在src目录中创建,而不是在工作区的根目录中。进入到ros2_ws/src并创建一个新包:

ros2 pkg create --build-type ament_cmake cpp_parameters --dependencies rclcpp

    终端将返回一条消息,验证包cpp_parameters及其所有必要的文件和文件夹已创建。
    --dependencies参数会自动将必要的依赖行添加到package.xml和CMakeLists.txt中。

    因为在包创建过程中使用了--dependencies选项,所以不必再向package.xml或CMakeLists.txt添加依赖项。
    但是,与往常一样,请确保在package.xml中添加描述、维护人员电子邮件和名称以及许可信息。

<description>C++ parameter tutorial</description>
<maintainer email="you@email.com">Your Name</maintainer>
<license>Apache License 2.0</license>

2 编写C++节点

#include <chrono>
#include <functional>
#include <string>

#include <rclcpp/rclcpp.hpp>

using namespace std::chrono_literals;

class MinimalParam : public rclcpp::Node
{
public:
  MinimalParam()
  : Node("minimal_param_node")
  {
    this->declare_parameter("my_parameter", "world");

    timer_ = this->create_wall_timer(
      1000ms, std::bind(&MinimalParam::timer_callback, this));
  }

  void timer_callback()
  {
    std::string my_param = this->get_parameter("my_parameter").as_string();

    RCLCPP_INFO(this->get_logger(), "Hello %s!", my_param.c_str());

    std::vector<rclcpp::Parameter> all_new_parameters{rclcpp::Parameter("my_parameter", "world")};
    this->set_parameters(all_new_parameters);
  }

private:
  rclcpp::TimerBase::SharedPtr timer_;
};

int main(int argc, char ** argv)
{
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<MinimalParam>());
  rclcpp::shutdown();
  return 0;
}

2.1 代码释义

    顶部的#include是包的依赖项。
    下一段代码创建类和构造函数。这个构造函数的第一行创建了一个名为my_parameter的参数,默认值为world。参数类型是从默认值推断出来的,所以在这种情况下,它将被设置为字符串类型。接下来,将timer_初始化为1000ms的周期,这将导致timer_callback函数每秒执行一次。

class MinimalParam : public rclcpp::Node
{
public:
  MinimalParam()
  : Node("minimal_param_node")
  {
    this->declare_parameter("my_parameter", "world");

    timer_ = this->create_wall_timer(
      1000ms, std::bind(&MinimalParam::timer_callback, this));
  }

    timer_callback函数的第一行从节点获取参数my_parameter,并将其存储在my_param中。接下来,RCLCPP_INFO函数显示log信息。set_parameters函数然后将参数my_parameter设置回默认字符串值world。在用户外部更改参数的情况下,这确保它总是重置回原始值。

void timer_callback()
{
  std::string my_param = this->get_parameter("my_parameter").as_string();

  RCLCPP_INFO(this->get_logger(), "Hello %s!", my_param.c_str());

  std::vector<rclcpp::Parameter> all_new_parameters{rclcpp::Parameter("my_parameter", "world")};
  this->set_parameters(all_new_parameters);
}

    最后是timer_的声明:

private:
  rclcpp::TimerBase::SharedPtr timer_;

    MinimalParam之后是main函数。这里初始化ROS 2,构造MinimalParam类的一个实例,rclcpp::spin开始处理来自节点的数据。

int main(int argc, char ** argv)
{
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<MinimalParam>());
  rclcpp::shutdown();
  return 0;
}
2.1.1 添加参数描述

    可以为参数设置一个描述符,描述符允许您指定参数及其约束的文本描述,例如使其为只读,指定范围等。要使其生效,必须将构造函数中的代码更改为:

// ...

class MinimalParam : public rclcpp::Node
{
public:
  MinimalParam()
  : Node("minimal_param_node")
  {
    auto param_desc = rcl_interfaces::msg::ParameterDescriptor{};
    param_desc.description = "This parameter is mine!";

    this->declare_parameter("my_parameter", "world", param_desc);

    timer_ = this->create_wall_timer(
      1000ms, std::bind(&MinimalParam::timer_callback, this));
  }

    其余的代码保持不变。运行节点后,可以运行ros2 param describe /minimal_param_node my_parameter查看类型和描述。

2.2 添加可执行文件

    现在打开CMakeLists.txt文件。在依赖项find_package(rclcpp REQUIRED)下面添加以下代码行。

add_executable(minimal_param_node src/cpp_parameters_node.cpp)
ament_target_dependencies(minimal_param_node rclcpp)

install(TARGETS
    minimal_param_node
  DESTINATION lib/${PROJECT_NAME}
)

3 编译及运行

    在构建之前,在工作区的根目录(ros2_ws)中运行rosdep检查缺失的依赖项:

rosdep install -i --from-path src --rosdistro humble -y

    进入到工作区的根目录ros2_ws,并编译新包:

colcon build --packages-select cpp_parameters

    打开一个新终端,进入到ros2_ws,并source:

source install/setup.bash

    现在运行节点可执行文件:

ros2 run cpp_parameters minimal_param_node

    终端应该每秒返回以下消息:

[INFO] [minimal_param_node]: Hello world!

    现在可以看到参数的默认值,但如果我们希望能够自己设置它。有两种方法可以实现。

3.1通过控制台进行更改

    确保节点正在运行:

ros2 run cpp_parameters minimal_param_node

    打开另一个终端,再次从ros2_ws文件夹下source一下,并输入以下行:

ros2 param list

    在这里,您将看到自定义参数my_parameter。要更改它,只需在控制台中运行以下行:

ros2 param set /minimal_param_node my_parameter earth

    如果成功地获得了输出Set parameter successful,说明设置成功。如果在查看另一个终端,应该看到输出更改为[INFO] [minimal_param_node]: Hello earth!

3.2通过启动文件进行更改

    你也可以在launch文件中设置该参数,但首先需要添加launch目录。在ros2_ws/src/cpp_parameters/目录中,创建一个名为launch的新目录。在其中创建一个名为cpp_parameters_launch.py的新文件。

from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package="cpp_parameters",
            executable="minimal_param_node",
            name="custom_minimal_param_node",
            output="screen",
            emulate_tty=True,
            parameters=[
                {"my_parameter": "earth"}
            ]
        )
    ])

    在这里,您可以看到我们在启动节点minimal_param_node时将my_parameter设置为earth。通过添加下面的两行代码,我们可以确保在控制台中打印输出。

output="screen",
emulate_tty=True,

    现在打开CMakeLists.txt文件。在前面添加的代码行下面,添加以下代码行。

install(
  DIRECTORY launch
  DESTINATION share/${PROJECT_NAME}
)

    打开一个终端,进入到工作区的根目录ros2_ws,然后构建新包:

colcon build --packages-select cpp_parameters

    然后在一个新的终端中source:

source install/setup.bash

    现在使用我们刚刚创建的启动文件运行节点:

ros2 launch cpp_parameters cpp_parameters_launch.py

    终端应该每秒返回以下消息:

[INFO] [custom_minimal_param_node]: Hello earth!

总结

    本节创建了一个带有自定义参数的节点,可以从启动文件或命令行设置该参数。需要将依赖项、可执行文件和启动文件添加到包配置文件中,以便构建和运行节点,并查看参数的作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值