ros2学习笔记17--在类中使用参数(c++)(代码片段)

鸿_H 鸿_H     2022-12-04     802

关键词:

概要:这篇主要介绍在类中使用参数(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文件更改默认参数编写句子理解以及对应配置文件的内容的添加.

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

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

C++ - 我啥时候应该在类中使用指针成员

...指针成员【发布时间】:2010-11-1314:56:42【问题描述】:在学习C++(和Direct3D,但那是前段时间)时让我感到困惑的一件事是何时应该在类中使用指针成员。例如,我可以使用非指针声明:private:SomeClassinstance_;或者我可以使用指针 查看详情

ros2学习笔记25--ros2话题统计编写教程(c++)(代码片段)

概要:这篇内容主要介绍用c++编写能够统计话题的侦听器环境:ubuntu20.04,ros2-foxy,vscode最后如果没有陈述实操过程中碰到问题的话,则表示该章节都可被本人正常复现4.1ros2话题统计教程(C++)(... 查看详情

ros2学习笔记21--编写action服务器和客户端(c++)(代码片段)

概要:这篇内容主要介绍如何使用C++来编写动作服务器和客户端环境:ubuntu20.04,ros2-foxy,vscode最后如果没有陈述实操过程中碰到问题的话,则表示该章节都可被本人正常复现.3.2编写动作服务器和客户端(... 查看详情

c ++:使用模板在类中定义可变长度数组

】c++:使用模板在类中定义可变长度数组【英文标题】:c++:definingvariable-lengtharraywithinaclassusingtemplates【发布时间】:2014-01-3104:01:05【问题描述】:我正在尝试构建一个MapV2类。在课堂上,我希望有一个Cell对象数组作为私有成员... 查看详情

ros2学习笔记13--编写一个简单的发布器和侦听器(c++)(代码片段)

概要:这篇主要介绍编写发布器和侦听器的简单套路(C++)环境:ubuntu20.04,ros2-foxy,vscode最后如果没有陈述实操过程中碰到问题的话,则表示该章节都可被本人正常复现.2.2.3编写一个简单的发布器和... 查看详情

ros2学习笔记14--编写一个简单的服务器和客户端(c++)(代码片段)

概要:这篇主要介绍c++版本服务端和客户端的编写环境:ubuntu20.04,ros2-foxy,vscode最后如果没有陈述实操过程中碰到问题的话,则表示该章节都可被本人正常复现.2.2.5编写一个简单的服务器和客户端(C+... 查看详情

java方法重载学习笔记

java中方法的重载   (1)方法重载是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型。重载Overloading是一个类中多态性的一种表现。   (2)java的方法重... 查看详情

C++ Boost,在类中使用 thread_group

】C++Boost,在类中使用thread_group【英文标题】:C++Boost,usingthread_groupinaclass【发布时间】:2011-12-1605:04:30【问题描述】:classcpublic:intid;boost::thread_groupthd;c(intid):id(id)voidoperator()()thd.create_thread(c(1));cout<<id<<e 查看详情

c++学习笔记1:类的使用

[基本数据结构]()[类的使用]()[类的继承和派生]()[面向对象特征之一——多态]()[操作符重载]()[const关键字的使用]()1.类的定义与使用1.1类的定义最简单的类的申明:classStudent;在类的定义最后需要加上分号,这是和java不同的地方,... 查看详情

c++学习29重载[](下标运算符)

前面已经提到,下标操作符[]必须以类的成员函数的形式进行重载。在类中的声明格式如下:返回值类型&operator[](参数)或const返回值类型&operator[](参数)使用第一种声明方式,操作符重载函数不仅可以访问对象,同时还可以... 查看详情

c++中如何将子线程的参数传回主线程

...的内存空间供线程调用。以工作线程为例:线程函数首先在类中声明_beginthreadex(NULL,0,yourfunc,this,0,0);(this指向类本身,比如是C**Dlg类)线程函数UINTC**Dlg::yourfunc(void*pParam)中,pParam就为C**Dlg指针通过强制转换提取:C**Dlg*p=(C**Dlg*... 查看详情

ros2学习笔记10--使用ros2bag进行录制和回放数据(代码片段)

概要:这篇主要介绍使用ros2bag进行录制和回放数据环境:ubuntu20.04,ros2-foxy,vscode最后如果没有陈述实操过程中碰到问题的话,则表示该章节都可被本人正常复现.2.1.10录制和回放数据(原文:https://docs.ros.or... 查看详情

寒假学习笔记

2018.2.11类中的常成员关键字const,在类定义中声明数据成员使用关键字限定,声明时不能初始化。初始化列表,类中的任何函数都不能对常数据成员赋值,包括构造函数。为构造函数添加初始化列表是对常数据成员进行初始化的... 查看详情

如何在类中使用结构

】如何在类中使用结构【英文标题】:Howtouseastrucinaclass【发布时间】:2016-03-0516:12:42【问题描述】:所以我已经做了一段时间的c++,但我想知道如何在一个类中使用结构,假设我正在制作一个FPS游戏,我为枪创建了一个基本结... 查看详情

ros2学习笔记22--使用launch启动/监听多个node节点(代码片段)

概要:这篇内容主要介绍如何使用launch启动/监听多个node节点环境:ubuntu20.04,ros2-foxy,vscode最后如果没有陈述实操过程中碰到问题的话,则表示该章节都可被本人正常复现3.4使用launch启动/监听多个node节点ÿ... 查看详情

C++ main 可以在类中并调用派生类吗? [复制]

】C++main可以在类中并调用派生类吗?[复制]【英文标题】:CanC++mainbeinsideaclassandcalladerivedclass?[duplicate]【发布时间】:2013-02-1110:58:48【问题描述】:我不熟悉使用类/对象。我正在尝试写这样的东西:classC1main()C2::foo();;classC2:publicC... 查看详情

ros2学习笔记26--使用快速dds查找服务作为查找协议(社区贡献)(代码片段)

概要:这篇内容主要介绍使用快速DDS查找服务作为查找协议(社区贡献)环境:ubuntu20.04,ros2-foxy,vscode最后如果没有陈述实操过程中碰到问题的话,则表示该章节都可被本人正常复现4.2使用快速DDS查找服务作为... 查看详情

在类中访问结构对象变量 - C++

】在类中访问结构对象变量-C++【英文标题】:AccessStructObjectVariablewithinClass-C++【发布时间】:2014-03-2901:03:44【问题描述】:我会尽力解释这一点......基本上,我正在为GBA游戏编写此程序,并且我正在尝试从类中更改结构实例的成... 查看详情