Przeglądaj źródła

[feat]:完成4.2-get_startedRCLCPP参数

鱼香ROS 3 lat temu
rodzic
commit
2413105bf3

+ 4 - 0
docs/humble/chapt2/get_started/1.ROS2节点介绍.md

@@ -90,7 +90,11 @@ ros2 node info <node_name>
 ros2 run turtlesim turtlesim_node --ros-args --remap __node:=my_turtle
 ```
 
+运行节点时设置参数
 
+```
+ros2 run example_parameters_rclcpp parameters_basic --ros-args -p rcl_log_level:=10
+```
 
 ## 5.总结
 

+ 2 - 2
docs/humble/chapt4/get_started/1.参数(Param)通信.md

@@ -1,11 +1,11 @@
 # 1.ROS2参数通信介绍
 
-## 1.参数通信是什么?
-
 大家好,我是爱吃瓜皮的小鱼。在前面的机器人控制示例中我们,机器人每移动一步休息500ms,加入我们想让机器人休息时间少一些,就需要手动的修改源码减少其值,这非常的不方便。
 
 在机器人开发中,会有很多参数和设置可以后期需要调整的,如果都放到源码里很难实现动态修改和管理,ROS2为了解决这一问题,提出了参数这一通信机制。
 
+# 1.参数通信是什么?
+
 ### 1.1 参数定义
 
 ROS2官方对参数的定义是:

+ 127 - 27
docs/humble/chapt4/get_started/2.参数之RCLCPP实现.md

@@ -1,8 +1,8 @@
-2.参数之RCLCPP实现
+# 2.参数之RCLCPP实现
 
 上节我们通过参数控制了小乌龟模拟器的背景色,但是我们并不知道小乌龟模拟器是如何接收到参数并将其应用的,本节我们就学习使用ROS2的RCLCPP中参数相关的API实现对ROS2打印的日志级别控制。
 
-ROS2将日志分为五个级别,在CPP中通过不同的宏可以实现不同日志级别日志的打印,例程如下:
+ROS2将日志分为五个级别,在RCLCPP中通过不同的宏可以实现不同日志级别日志的打印,例程如下:
 
 ```cpp
 RCLCPP_DEBUG(this->get_logger(), "我是DEBUG级别的日志,我被打印出来了!");
@@ -18,55 +18,94 @@ RCLCPP_FATAL(this->get_logger(), "我是FATAL级别的日志,我被打印出
 this->get_logger().set_level(log_level);
 ```
 
-
-
-1.创建功能包和节点
+## 1.创建功能包和节点
 
 我们创建一个功能包和测试节点,声明参数并实现动态修改打印的日志级别功能。
 
-```
+```shell
 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**
+
+```c++
 #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;
+}
+```
+
+构建测试
+
+```shell
+colon build  --packages-select example_parameters_rclcpp
+source install/setup.bash
+ros2 run example_parameters_rclcpp parameters_basic
+```
+
+## 2.RCLCPP参数API
+
+在RCLCPP的API中,关于参数相关的函数比较多些,但都是围绕[参数获取](https://docs.ros2.org/latest/api/rclcpp/classrclcpp_1_1Node.html#a25890d01a2cd47ce99af887f556c529b)、[参数设置](https://docs.ros2.org/latest/api/rclcpp/classrclcpp_1_1Node.html#a7d8af4dc449c7130ccc396814b86c14d)、[参数描述](https://docs.ros2.org/latest/api/rclcpp/classrclcpp_1_1Node.html#adbfb47c0983e14482c39159b274f6308)、[列出参数](https://docs.ros2.org/latest/api/rclcpp/classrclcpp_1_1Node.html#a37aa95886a706c174db77c2b160f6d7d)、[添加](https://docs.ros2.org/latest/api/rclcpp/classrclcpp_1_1Node.html#a12d535bced9f26b65c0a450e6f40aff8)和[移除](https://docs.ros2.org/latest/api/rclcpp/classrclcpp_1_1Node.html#a15d4f7fa0ef760941b6a78f42cccb7e0)参数回调事件。
 
+- [rclcpp: rclcpp: ROS Client Library for C++ (ros2.org)](https://docs.ros2.org/latest/api/rclcpp/)
+
+## 3.使用参数控制节点日志级别
+
+```cpp
+#include <chrono>
 #include "rclcpp/rclcpp.hpp"
 /*
-    # 声明
     # declare_parameter	        声明和初始化一个参数
-    # declare_parameters	    声明和初始化一堆参数
-    # 获取
     # describe_parameter(name)  通过参数名字获取参数的描述
     # get_parameter	            通过参数名字获取一个参数
-    # get_parameters	        通过多个参数名字获取多个参数
-    # 设置
-    # set_parameters	        设置一组参数的值
-    #
-    # has_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);
-
-    RCLCPP_INFO(this->get_logger(), "设置%s节点日志级别 %d .", name.c_str(),
-                log_level);
+    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);
-    RCLCPP_INFO(this->get_logger(), "设置%s节点日志级别完成 %d .", name.c_str(),
-                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) {
@@ -80,12 +119,73 @@ int main(int argc, char** argv) {
 }
 ```
 
-2.RCLCPP参数API
+代码解析
+
+这里我们使用了三个参数相关的函数和一个设置节点日志级别的函数
+
+- declare_parameter,参数有两个参数名和参数值。
+- get_parameter,参数有两个,参数名和放入结果的变量。
+
+设置日志级别
 
+- set_level,设置日志级别,ROS2的日志级别定义在文件`/opt/ros/humble/include/rcutils/rcutils/logging.h`的167-175行。
 
+  ```cpp
+  /// 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.编译测试
+
+```shell
+colcon build --packages-select example_parameters_rclcpp
+source install/setup.bash
+ros2 run example_parameters_rclcpp parameters_basic
+```
 
-3.使用参数控制节点日志级别
+运行后你会发现DEBUG级别的日志并没有被打印出来,原因在于我们将节点的日志级别设置为了0,0对应的日志级别为`RCUTILS_LOG_SEVERITY_UNSET`即未设置使用默认级别,**节点默认的日志级别就是INFO级别**的,所以只能打印INFO以上的日志信息。
 
+![image-20220614013509655](2.参数之RCLCPP实现/imgs/image-20220614013509655.png)
+
+运行节点的时候可以指定参数的值,我们尝试将`log_level`的值改成`10`即`DEBUG`级别。
+
+```shell
+ros2 run example_parameters_rclcpp parameters_basic --ros-args -p rcl_log_level:=10
+```
+
+![image-20220614020525157](2.参数之RCLCPP实现/imgs/image-20220614020525157.png)
+
+再试试其他级别-FATAL
+
+![image-20220614020607314](2.参数之RCLCPP实现/imgs/image-20220614020607314.png)
+
+除了在节点运行前通过CLI传递参数,在运动的过程中也可以动态的修改参数
+
+```shell
+#查看参数列表
+ros2 param list 
+#设置参数级别
+ros2 param set /parameters_basic rcl_log_level 10
+```
+
+![image-20220614020835167](2.参数之RCLCPP实现/imgs/image-20220614020835167.png)
+
+## 5.总结
+
+上面我们通过参数实现了动态控制节点日志级别的功能,其实像这样的功能ROS2早已为我们准备好了,在运行任意节点时候可以通过CLI传递日志级别配置。
+
+```shell
+ros2 run package-name node-name --ros-args --log-level debug
+```
 
+除了命令行设置参数和查看日志,通过rqt也可以可视化设置和查看
 
-4.总结
+![image-20220614022058258](2.参数之RCLCPP实现/imgs/image-20220614022058258.png)

BIN
docs/humble/chapt4/get_started/2.参数之RCLCPP实现/imgs/image-20220613210513693.png


BIN
docs/humble/chapt4/get_started/2.参数之RCLCPP实现/imgs/image-20220614013509655.png


BIN
docs/humble/chapt4/get_started/2.参数之RCLCPP实现/imgs/image-20220614020525157.png


BIN
docs/humble/chapt4/get_started/2.参数之RCLCPP实现/imgs/image-20220614020607314.png


BIN
docs/humble/chapt4/get_started/2.参数之RCLCPP实现/imgs/image-20220614020835167.png


BIN
docs/humble/chapt4/get_started/2.参数之RCLCPP实现/imgs/image-20220614022058258.png