ROS2学习笔记17--在类中使用参数(C++)

Posted 鸿_H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ROS2学习笔记17--在类中使用参数(C++)相关的知识,希望对你有一定的参考价值。

概要:这篇主要介绍在类中使用参数(C++)

环境:ubuntu20.04,ros2-foxy,vscode

最后如果没有陈述实操过程中碰到问题的话,则表示该章节都可被本人正常复现.

2.2.9在类中使用参数(C++)(原文:https://docs.ros.org/en/foxy/Tutorials/Using-Parameters-In-A-Class-CPP.html

>>教程>>在类中使用参数(C++)

你正阅读的是ros2较老版本(Foxy),但仍然支持的说明文档.想查看最新版本的信息,请看galactic版本链接( https://docs.ros.org/en/galactic/Tutorials.html

在类中使用参数(C++)

目标:使用c++创建带有ros参数的类

课程等级:初级

时长:20min

目录:

1.背景
2.预备知识
3.步骤
3.1创建一个包
3.2写一个c++节点
3.3编译运行
4.总结
5.下一步

1.背景

在操作节点时,你有时需要通过launch文件来设置参数.

这节课就是向你展示创建带有参数的c++类,和如何在launch文件里面设置这些参数.

2.预备知识

在前面课程中,你学了如何创建工作空间和包.你也学习了ros2系统里面的参数和它们的函数.

3.步骤

3.1创建一个包

新开一个终端,source一下ros2安装位置以保证ros2指令都没问题.

进入之前课程创建的dev_ws工作空间目录.

回忆一下,包应该创建在src目录下,并不是工作空间的根目录.进入dev_ws/src目录,新建一个包:

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

你的终端返回信息表示你的cpp_parameters包以及相关的必要文件都创建完成.

--dependencies参数会自动添加必要的依赖行到package.xmlCMakeLists.txt文件中.

3.1.1更新package.xml文件

由于创建包时使用了--dependencies操作,你不必在package.xmlCMakeLists.txt文件手动添加依赖.

往常一样,确定在package.xml文件中添加了description, maintainer email and namelicense内容.

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

3.2写一个c++节点

dev_ws/src/cpp_parameters/src目录里面,创建一个cpp_parameters_node.cpp文件,把下面代码复制进去:

#include <rclcpp/rclcpp.hpp>
#include <chrono>
#include <string>
#include <functional>

using namespace std::chrono_literals;

class ParametersClass: public rclcpp::Node
{
  public:
    ParametersClass()
      : Node("parameter_node")
    {
      this->declare_parameter<std::string>("my_parameter", "world");
      timer_ = this->create_wall_timer(
      1000ms, std::bind(&ParametersClass::respond, this));
    }
    void respond()
    {
      this->get_parameter("my_parameter", parameter_string_);
      RCLCPP_INFO(this->get_logger(), "Hello %s", parameter_string_.c_str());
    }
  private:
    std::string parameter_string_;
    rclcpp::TimerBase::SharedPtr timer_;
};

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

3.2.1代码解析

顶部的#include句子表示包的依赖.

接着的代码片段是类和构造函数.构造函数第一行(表示)创建我们的参数.我们的参数的名字是 my_parameter,并且参数的默认值指定为world.接着timer_定时器初始化,这引起respond响应函数每秒被执行一次.

class ParametersClass: public rclcpp::Node
{
  public:
    ParametersClass()
      : Node("parameter_node")
    {
      this->declare_parameter<std::string>("my_parameter", "world");
      timer_ = this->create_wall_timer(
      1000ms, std::bind(&ParametersClass::respond, this));
    }

respond函数的第一行是从节点获取参数my_parameter,并且存储到parameter_string_里面.RCLCPP_INFO函数保证了消息被记录下来.

void respond()
{
  this->get_parameter("my_parameter", parameter_string_);
  RCLCPP_INFO(this->get_logger(), "Hello %s", parameter_string_.c_str());
}

最后是timer_parameter_string_的声明

private:
  std::string parameter_string_;
  rclcpp::TimerBase::SharedPtr timer_;

我们的主函数main用到ParametersClass类.这里ros2被初始化了,并且rclcpp::spin开始处理来自节点的数据.

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

3.2.2添加executable

现在打开CMakeLists.txt,在find_package(rclcpp REQUIRED)依赖下面,添加以下几行代码:

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

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

3.3编译运行

编译前,在工作空间dev_ws根目录下面运行rosdep查找所缺少的依赖是一个不错的操作.

linux:

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

返回dev_ws工作空间的根目录,编译你的新包:

colcon build --packages-select cpp_parameters

新开一个终端,进入dev_ws,source一下配置文件:

linux:

. install/setup.bash

然后运行节点:

ros2 run cpp_parameters parameter_node

终端每秒会返回一次下面信息:

[INFO] [parameter_node]: Hello world

现在你可以看到你的参数的默认值,但是你想能够自己来设置它(参数).这里有两种方式可以实现.

3.3.1通过改变控制台

这部分用到你在参数教程学习到的知识,运用到你刚刚创建的节点上面.

保证节点在运行中:

ros2 run cpp_parameters parameter_node

新开另外一个终端,进入dev_wssource一下环境变量,输入下面这行指令:

ros2 param list

你会看到自定义参数my_parameter.在控制台简单运行下面指令来更改它:

ros2 param set /parameter_node my_parameter earth

如果你看到输出Set parameter successful,这表示参数设置成功.如果你看一下其他终端,你应该看见输出更改为[INFO] [parameter_node]: Hello earth

3.3.2通过launch文件进行修改

你也可以在launch文件里面设置参数,但首先你得添加一个launch目录.在dev_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="parameter_node",
            name="custom_parameter_node",
            output="screen",
            emulate_tty=True,
            parameters=[
                {"my_parameter": "earth"}
            ]
        )
    ])

这里,你可以看到,当我们启动节点parameter_node时,会把my_parameter设置为earth.添加这两行,保证我们的输出可以打印到控制台.

output="screen",
emulate_tty=True,

现在,打开CMakeLists.txt,在之前已经添加过的地方下面添加几行代码:

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

开一个终端,进入dev_ws根目录,编译你的新包:

linux:

colcon build --packages-select cpp_parameters

在新终端里面source一下配置文件:

. install/setup.bash

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

ros2 launch cpp_parameters cpp_parameters_launch.py

终端应该会每秒返回一次以下信息:

[parameter_node-1] [INFO] [custom_parameter_node]: Hello earth

4.总结

你创建了一个带有自定义参数的节点,既可以使用launch文件,也可以使用命令行来设置(参数).添加依赖关系,可执行文件,launch文件到包配置文件,这样子,你就可以编译和运行它们了,并且可以看见(设置的)参数起作用了.

5.下一步

既然有了自己的一些包和ros2系统,下一个节课教你如何检查环境系统问题,以免你有问题(却不知道怎么折腾).

其他

个人认为重点:

c++参数node编写;添加内容后,配置文件的如何编写;使用launch文件更改默认参数编写句子理解以及对应配置文件的内容的添加.

这课程是在等毕业证那十几天搞的,室友问,现在在线翻译这么强大,为啥还在这里瞎折腾呢?我说,我的目地是好好认真看一下,了解一下,自己折腾,目前是我想到最好的办法来获得最佳效果,即使这翻译有点别扭,哈哈哈.

#####################
不积硅步,无以至千里
好记性不如烂笔头
感觉有点收获的话,麻烦大大们点赞收藏哈

以上是关于ROS2学习笔记17--在类中使用参数(C++)的主要内容,如果未能解决你的问题,请参考以下文章

ROS2学习笔记21--编写action服务器和客户端(C++)

ROS2学习笔记6--认识ros2参数parameters

C++:在类中使用静态成员函数

ROS2学习笔记13--编写一个简单的发布器和侦听器(C++)

ROS2学习笔记14--编写一个简单的服务器和客户端(C++)

C++学习 之 类中的特殊函数和this指针