ROS2- 参数的实现cpp+py-14
参数的cpp实现
如何接收到参数并将其应用的?
ROS2的RCLCPP中参数相关的API实现对ROS2打印的日志级别控制。
ROS2将日志分为五个级别:
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);
mkdir -p chapt4/chapt4_ws/
ros2 pkg create example_parameters_rclcpp --build-type ament_cmake --dependencies rclcpp --destination-directory src --node-name parameters_basic
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
参数操作的命令:https://docs.ros2.org/latest/api/rclcpp/
参数控制节点日志级别
#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,设置日志级别
再次编译运行
colcon build --packages-select example_parameters_rclcpp
source install/setup.bash
ros2 run example_parameters_rclcpp parameters_basic
root@ubuntu-16:~/stephen/chapt4/chapt4_ws# ros2 run example_parameters_rclcpp parameters_basic
[INFO] [1749550317.944786325] [parameters_basic]: 节点已启动:parameters_basic.
======================================================
[INFO] [1749550318.445165350] [parameters_basic]: 我是INFO级别的日志,我被打印出来了!
[WARN] [1749550318.445244268] [parameters_basic]: 我是WARN级别的日志,我被打印出来了!
[ERROR] [1749550318.445269097] [parameters_basic]: 我是ERROR级别的日志,我被打印出来了!
[FATAL] [1749550318.445289960] [parameters_basic]: 我是FATAL级别的日志,我被打印出来了!
运行看效果
root@ubuntu-16:~/stephen/chapt4/chapt4_ws# ros2 run example_parameters_rclcpp parameters_basic --ros-args -p rcl_log_level:=50
root@ubuntu-16:~/stephen/chapt4/chapt4_ws# ros2 run example_parameters_rclcpp parameters_basic --ros-args -p rcl_log_level:=10
root@ubuntu-16:~/stephen/chapt4/chapt4_ws# ros2 run example_parameters_rclcpp parameters_basic
运行过程中 修改
查看参数列表
ros2 param list
设置参数级别
ros2 param set /parameters_basic rcl_log_level 10
ros2 param set /parameters_basic rcl_log_level 50
上面通过参数设置实现了动态控制节点日志级别的功能,
这样的功能ROS2早已为我们准备好了,在运行任意节点时候可以通过CLI传递日志级别配置。
ros2 run package-name node-name --ros-args --log-level debug
python版
上一节使用RCLCPP的API实现了参数相关的基础操作
cd chapt4/chapt4_ws/
ros2 pkg create example_parameters_rclpy --build-type ament_python --dependencies rclpy --destination-directory src --node-name parameters_basic
parameters_basic.py
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
class ParametersBasicNode(Node):
"""
创建一个ParametersBasicNode节点,并在初始化时输出一个话
"""
def __init__(self,name):
super().__init__(name)
self.get_logger().info(f"节点已启动:{name}!")
def main(args=None):
rclpy.init(args=args) # 初始化rclpy
node = ParametersBasicNode("parameters_basic") # 新建一个节点
rclpy.spin(node) # 保持节点运行,检测是否收到退出指令(Ctrl+C)
rclpy.shutdown() # 关闭rclpy
RCLPY的参数API文档:https://docs.ros2.org/latest/api/rclpy/api/node.html
运行
vi src/example_parameters_rclpy/
example_parameters_rclpy/ package.xml resource/ setup.cfg setup.py test/
root@ubuntu-16:~/stephen/chapt4/chapt4_ws# vi src/example_parameters_rclpy/example_parameters_rclpy/
__init__.py parameters_basic.py
root@ubuntu-16:~/stephen/chapt4/chapt4_ws# vi src/example_parameters_rclpy/example_parameters_rclpy/parameters_basic.py
root@ubuntu-16:~/stephen/chapt4/chapt4_ws# colcon build --packages-select example_parameters_rclpy
source install/setup.bash
Starting >>> example_parameters_rclpy
Finished <<< example_parameters_rclpy [1.29s]
Summary: 1 package finished [1.59s]
root@ubuntu-16:~/stephen/chapt4/chapt4_ws# ros2 run example_parameters_rclpy parameters_basic
vi src/example_parameters_rclpy/example_parameters_rclpy/
class ParametersBasicNode(Node):
"""
创建一个ParametersBasicNode节点,并在初始化时输出一个话
"""
def __init__(self, name):
super().__init__(name)
self.get_logger().info(f"节点已启动:{name}!")
# 声明参数
self.declare_parameter('rcl_log_level', 0)
# 获取参数
log_level = self.get_parameter("rcl_log_level").value
# 设置参数
self.get_logger().set_level(log_level)
# 定时修改
self.timer = self.create_timer(0.5, self.timer_callback)
def timer_callback(self):
"""定时器回调函数"""
# 获取参数
log_level = self.get_parameter("rcl_log_level").value
# 设置参数
self.get_logger().set_level(log_level)
print(
f"========================{log_level}=============================")
self.get_logger().debug("我是DEBUG级别的日志,我被打印出来了!")
self.get_logger().info("我是INFO级别的日志,我被打印出来了!")
self.get_logger().warn("我是WARN级别的日志,我被打印出来了!")
self.get_logger().error("我是ERROR级别的日志,我被打印出来了!")
self.get_logger().fatal("我是FATAL级别的日志,我被打印出来了!")
colcon build --packages-select example_parameters_rclpy
source install/setup.bash
ros2 run example_parameters_rclpy parameters_basic
ros2 run example_parameters_rclpy parameters_basic --ros-args -p rcl_log_level:=10
ros2 param list
ros2 param set /parameters_basic rcl_log_level 40