【ROS2机器人入门到实战】参数之RCLCPP实现

2.参数之RCLCPP实现

写在前面

  1. 当前平台文章汇总地址:ROS2机器人从入门到实战
  2. 获取完整教程及配套资料代码,请关注公众号<鱼香ROS>获取
  3. 教程配套机器人开发平台:两驱版| 四驱版
  4. 为方便交流,搭建了机器人技术问答社区:地址 fishros.org.cn

上节我们通过参数控制了小乌龟模拟器的背景色,但是我们并不知道小乌龟模拟器是如何接收到参数并将其应用的,本节我们就学习使用ROS2的RCLCPP中参数相关的API实现对ROS2打印的日志级别控制。

ROS2将日志分为五个级别,在RCLCPP中通过不同的宏可以实现不同日志级别日志的打印,例程如下:

RCLCPP_DEBUG(this->get_logger(), "我是DEBUG级别的日志,我被打印出来了!");
RCLCPP_INFO(this->get_logger(), "我是INFO级别的日志,我被打印出来了!");
RCLCPP_WARN(this->get_logger(), "我是WARN级别的日志,我被打印出来了!");
RCLCPP_ERROR(this->get_logger(), "我是ERROR级别的日志,我被打印出来了!");
RCLCPP_FATAL(this->get_logger(), "我是FATAL级别的日志,我被打印出来了!");

有时候日志太多,会让人眼花缭乱找不到重要信息,所以我们需要对日志的级别进行过滤,比如只看INFO以上级别的,ROS2中可以通过已有的API设置日志的级别,RCLCPP中API如下:

this->get_logger().set_level(log_level);

1.创建功能包和节点

我们创建一个功能包和测试节点,声明参数并实现动态修改打印的日志级别功能。

mkdir -p chapt4/chapt4_ws/
ros2 pkg create example_parameters_rclcpp --build-type ament_cmake --dependencies rclcpp --destination-directory src --node-name parameters_basic --maintainer-name "fishros" --maintainer-email "fishros@foxmail.com"

parameters_basic.cpp

#include <chrono>
#include "rclcpp/rclcpp.hpp"

class ParametersBasicNode : public rclcpp::Node {
 public:
  explicit ParametersBasicNode(std::string name) : Node(name) {
    RCLCPP_INFO(this->get_logger(), "节点已启动:%s.", name.c_str());
  }
 private:
};

int main(int argc, char** argv) {
  rclcpp::init(argc, argv);
  /*创建对应节点的共享指针对象*/
  auto node = std::make_shared<ParametersBasicNode>("parameters_basic");
  /* 运行节点,并检测退出信号*/
  rclcpp::spin(node);
  rclcpp::shutdown();
  return 0;
}

构建测试

colcon build  --packages-select example_parameters_rclcpp
source install/setup.bash
ros2 run example_parameters_rclcpp parameters_basic

2.RCLCPP参数API

在RCLCPP的API中,关于参数相关的函数比较多些,但都是围绕参数获取参数设置参数描述列出参数添加移除参数回调事件。

3.使用参数控制节点日志级别

#include <chrono>
#include "rclcpp/rclcpp.hpp"
/*
    # declare_parameter	        声明和初始化一个参数
    # describe_parameter(name)  通过参数名字获取参数的描述
    # get_parameter	            通过参数名字获取一个参数
    # set_parameter	            设置参数的值
*/
class ParametersBasicNode : public rclcpp::Node {
 public:
  // 构造函数,有一个参数为节点名称
  explicit ParametersBasicNode(std::string name) : Node(name) {
    RCLCPP_INFO(this->get_logger(), "节点已启动:%s.", name.c_str());
    this->declare_parameter("rcl_log_level", 0);     /*声明参数*/
    this->get_parameter("rcl_log_level", log_level); /*获取参数*/
    /*设置日志级别*/
    this->get_logger().set_level((rclcpp::Logger::Level)log_level);
    using namespace std::literals::chrono_literals;
    timer_ = this->create_wall_timer(
        500ms, std::bind(&ParametersBasicNode::timer_callback, this));
  }

 private:
  int log_level;
  rclcpp::TimerBase::SharedPtr timer_;

  void timer_callback() {
    this->get_parameter("rcl_log_level", log_level); /*获取参数*/
    /*设置日志级别*/
    this->get_logger().set_level((rclcpp::Logger::Level)log_level);
    std::cout<<"======================================================"<<std::endl;
    RCLCPP_DEBUG(this->get_logger(), "我是DEBUG级别的日志,我被打印出来了!");
    RCLCPP_INFO(this->get_logger(), "我是INFO级别的日志,我被打印出来了!");
    RCLCPP_WARN(this->get_logger(), "我是WARN级别的日志,我被打印出来了!");
    RCLCPP_ERROR(this->get_logger(), "我是ERROR级别的日志,我被打印出来了!");
    RCLCPP_FATAL(this->get_logger(), "我是FATAL级别的日志,我被打印出来了!");
  }
};

int main(int argc, char** argv) {
  rclcpp::init(argc, argv);
  /*创建对应节点的共享指针对象*/
  auto node = std::make_shared<ParametersBasicNode>("parameters_basic");
  /* 运行节点,并检测退出信号*/
  rclcpp::spin(node);
  rclcpp::shutdown();
  return 0;
}

代码解析

这里我们使用了三个参数相关的函数和一个设置节点日志级别的函数

  • declare_parameter,参数有两个参数名和参数值。
  • get_parameter,参数有两个,参数名和放入结果的变量。

设置日志级别

  • set_level,设置日志级别,ROS2的日志级别定义在文件/opt/ros/humble/include/rcutils/rcutils/logging.h的167-175行。

    /// The severity levels of log messages / loggers.
    enum RCUTILS_LOG_SEVERITY
    {
      RCUTILS_LOG_SEVERITY_UNSET = 0,  ///< The unset log level
      RCUTILS_LOG_SEVERITY_DEBUG = 10,  ///< The debug log level
      RCUTILS_LOG_SEVERITY_INFO = 20,  ///< The info log level
      RCUTILS_LOG_SEVERITY_WARN = 30,  ///< The warn log level
      RCUTILS_LOG_SEVERITY_ERROR = 40,  ///< The error log level
      RCUTILS_LOG_SEVERITY_FATAL = 50,  ///< The fatal log level
    };
    

4.编译测试

colcon build --packages-select example_parameters_rclcpp
source install/setup.bash
ros2 run example_parameters_rclcpp parameters_basic

运行后你会发现DEBUG级别的日志并没有被打印出来,原因在于我们将节点的日志级别设置为了0,0对应的日志级别为RCUTILS_LOG_SEVERITY_UNSET即未设置使用默认级别,节点默认的日志级别就是INFO级别的,所以只能打印INFO以上的日志信息。

在这里插入图片描述

运行节点的时候可以指定参数的值,我们尝试将log_level的值改成10DEBUG级别。

ros2 run example_parameters_rclcpp parameters_basic --ros-args -p rcl_log_level:=10

在这里插入图片描述

再试试其他级别-FATAL

在这里插入图片描述

除了在节点运行前通过CLI传递参数,在运动的过程中也可以动态的修改参数

#查看参数列表
ros2 param list 
#设置参数级别
ros2 param set /parameters_basic rcl_log_level 10

在这里插入图片描述

5.总结

上面我们通过参数实现了动态控制节点日志级别的功能,其实像这样的功能ROS2早已为我们准备好了,在运行任意节点时候可以通过CLI传递日志级别配置。

ros2 run package-name node-name --ros-args --log-level debug

除了命令行设置参数和查看日志,通过rqt也可以可视化设置和查看

在这里插入图片描述

### 回答1: `RCLCPP_DEBUG_STREAM` 是 ROS 2 中 rclcpp 库中的一个宏,用于在调试时输出调试信息。该宏接受一个参数,即一个 `std::ostream` 类型的对象,将该对象的输出作为调试信息输出到 ROS 2 的日志中。 下面是一个示例,演示如何使用 `RCLCPP_DEBUG_STREAM` 宏输出调试信息: ```cpp #include "rclcpp/rclcpp.hpp" int main(int argc, char **argv) { rclcpp::init(argc, argv); auto node = rclcpp::Node::make_shared("my_node"); int a = 10; double b = 3.14; RCLCPP_DEBUG_STREAM(node->get_logger(), "a = " << a << ", b = " << b); rclcpp::shutdown(); return 0; } ``` 在上面的示例中,我们首先初始化 ROS 2 节点,并创建一个名为 "my_node" 的节点。然后定义两个变量 `a` 和 `b`,并使用 `RCLCPP_DEBUG_STREAM` 宏输出这两个变量的值。最后,我们关闭节点并结束程序。 在输出的日志中,会显示类似下面的内容: ``` [DEBUG] [my_node]: a = 10, b = 3.14 ``` 其中 `[DEBUG]` 表示日志级别为调试信息,`[my_node]` 表示该日志来自名为 "my_node" 的节点。 ### 回答2: RCLCPP_DEBUG_STREAM是ROS 2中用于输出调试信息的宏。RCLCPP表示ROS 2的C++客户端库,DEBUG表示调试级别,STREAM表示输出流。 在ROS 2中,调试信息是用来帮助开发者在开发过程中找到程序错误的一个重要工具。RCLCPP_DEBUG_STREAM宏可以用于输出调试信息到ROS 2的日志系统。它的使用十分简单,只需要在代码中调用RCLCPP_DEBUG_STREAM宏并传入需要输出的信息即可。 RCLCPP_DEBUG_STREAM宏输出的调试信息可以在终端或者日志文件中找到,可以帮助开发者追踪和调试程序中的问题。调试信息包含了程序中特定位置的变量值、函数调用情况、条件判断结果等,有助于开发者分析程序运行时的行为。具体信息的输出方式和位置可以通过ROS 2的参数进行配置。 总之,RCLCPP_DEBUG_STREAM是ROS 2中用于输出调试信息的宏,能够帮助开发者更好地调试程序。通过使用RCLCPP_DEBUG_STREAM宏,开发者可以在开发过程中获得更多有用的信息,从而更快地找到和解决程序中的问题。 ### 回答3: RCLCPP_DEBUG_STREAM是一个ROS 2中的函数宏,用于在调试时输出消息到日志文件。它可以在源代码中通过使用RCLCPP_DEBUG_STREAM宏来实现。 调试是一种重要的开发技术,可以帮助我们了解程序运行中的细节和问题。RCLCPP_DEBUG_STREAM宏的作用就是在我们开发ROS 2程序时,通过输出一些调试信息来帮助我们理解程序的运行状态。 使用RCLCPP_DEBUG_STREAM宏时,我们可以在日志文件中输出特定的消息。这些消息可以包含各种调试信息,例如变量的值、函数的输出等。通过在关键位置插入RCLCPP_DEBUG_STREAM宏,我们可以在需要的地方输出自定义的调试信息。这样,当我们运行程序时,日志文件中将会包含这些输出的调试信息。 RCLCPP_DEBUG_STREAM宏的使用方法很简单。我们只需要在源代码中的某个位置插入宏,并将需要输出的信息作为参数传入即可。这些信息可以是字符串、变量、函数返回值等。当程序运行到插入宏的位置时,输出的信息将会被写入到日志文件中。 总结来说,RCLCPP_DEBUG_STREAM是ROS 2中的一个函数宏,用于输出调试信息到日志文件。通过在需要的地方插入这个宏,并传入相应的参数,我们可以在运行程序时输出自定义的调试信息。这样,我们可以更好地理解和调试我们的ROS 2程序。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值