4 ROS2节点参数基础

news2024/11/24 9:25:07

4 ROS2节点参数基础

  • 4.1 ROS2节点参数介绍
  • 4.2 使用C/C++实现对节点参数的增删改查
    • 4.2.1 创建C/C++节点参数的服务端
    • 4.2.2 创建C/C++节点参数客户端
  • 4.3 使用Python实现对节点参数的增删改查
    • 4.3.1 创建Python节点参数的服务端
    • 4.3.2 创建Python节点参数客户端
  • 4.4 ROS2节点参数小结

  • 其他ROS2学习笔记: ROS2学习笔记
  • 代码仓库:Github连接地址
  • 欢迎各位互相学习交流

4.1 ROS2节点参数介绍

参考内容

Understanding parameters

在ROS2的通讯过程中,有一种信息记录某个节点的特征,例如turtlesim仿真时候的乌龟类型,背景的颜色等等,这一类节点设置的数据,通常采用节点参数(parameters)进行设置和操作,可以把节点参数认为是对节点的设置,可以对参数进行增删改查的操作

4.2 使用C/C++实现对节点参数的增删改查

示例创建一个节点参数的服务端,和一个节点参数的客户端,服务端用于实现后续客户端对它的参数进行增删改查操作

参考内容

Using parameters in a class (C++)

2.5.3_参数服务_C++实现_03客户端_01代码框架

4.2.1 创建C/C++节点参数的服务端

  1. 创建功能包,包名为cpp_para_ser,节点名为cppParaSerNode,依赖rclcppros2 pkg create cpp_para_server --build-type ament_cmake --node-name cppParaSerNode --dependencies rclcpp

  2. 配置Vscode环境,在工作空间创建.vscode文件夹,并加入settings.json文件,添加ROS2include环境:

{
    "C_Cpp.default.includePath": [
        "/opt/ros/humble/include/**",
    ],
}
  1. 创建节点参数服务:注意删除节点的参数,只能删除未被声明的内容:
// 1. 生成节点的头文件
#include "rclcpp/rclcpp.hpp"

// 2. 定义节点参数服务端
class CppParamServer : public rclcpp::Node
{
public:
  // 2.1 构造函数,设置节点名,以及允许被删除的内容
  CppParamServer() : Node("cppParamSerNode",rclcpp::NodeOptions().allow_undeclared_parameters(true)) {}

  // 2.2 创建默认的参数表
  void declare_param()
  {
    // 2.2.1 声明参数并设置默认值
    this->declare_parameter("name", "zhangsan");
    this->declare_parameter("height", "1.8");

    // 2.2.2 未声明的参数,该参数可以被删除
    this->set_parameter(rclcpp::Parameter("age", "20"));
  }

  // 3 获取到现在的所有参数
  void get_AllValue()
  {
    RCLCPP_INFO(this->get_logger(), "------------------ Get the params ----------------");
    auto params = this->get_parameters({"name", "height", "age"});
    for (auto &param : params)
    {
      // 3.1 get_name函数获取参数名,value_to_string获取到参数的字符串值
      RCLCPP_INFO(this->get_logger(), "parameter is %s,  the value is %s", param.get_name().c_str(), param.value_to_string().c_str());
    }
  }

  // 4 修改参数
  void update_param()
  {
    RCLCPP_INFO(this->get_logger(), "------------------ Change the value  ----------------");
    this->set_parameter(rclcpp::Parameter("name", "lisi"));
    this->get_AllValue();
  }

  // 5. 删除参数
  void del_param()
  {
    RCLCPP_INFO(this->get_logger(), "------------------ Delete ----------------");
    // 5.1 删除只能删除未声明的参数,不能删除声明过的参数
    this->undeclare_parameter("age");
    auto params = this->get_parameters({"name", "height"});
    for (auto &param : params)
    {
      // 5.1 get_name函数获取参数名,value_to_string获取到参数的字符串值
      RCLCPP_INFO(this->get_logger(), "parameter is %s,  the value is %s", param.get_name().c_str(), param.value_to_string().c_str());
    }
  }
};

int main(int argc, char **argv)
{
  rclcpp::init(argc, argv);
  auto paramServer = std::make_shared<CppParamServer>();
  // 执行对应的函数
  paramServer->declare_param();
  paramServer->get_AllValue();
  paramServer->update_param();
  paramServer->del_param();

  rclcpp::spin(paramServer);
  rclcpp::shutdown();
  return 0;
}
  1. 由于在创建包的过程中已经指明了所有依赖项,不需要进行额外的配置,直接编译运行即可:colcon build --packages-select cpp_para_server

  2. 激活环境并运行节点:. install/setup.bashros2 run cpp_para_server cppParaSerNode

在这里插入图片描述

4.2.2 创建C/C++节点参数客户端

  1. 创建功能包,包名为cpp_para_client,节点名为cppParaCliNode,依赖rclcppros2 pkg create cpp_para_client --build-type ament_cmake --node-name cppParaCliNode --dependencies rclcpp

  2. 配置Vscode环境,在工作空间创建.vscode文件夹,并加入settings.json文件,添加ROS2include环境:

{
    "C_Cpp.default.includePath": [
        "/opt/ros/humble/include/**",
    ],
}
  1. 创建节点参数客户端,值得注意的是需要连接到服务端节点,然后进行参数的增删改查操作:
// 1.包含头文件;
#include "rclcpp/rclcpp.hpp"

using namespace std::chrono_literals;

// 2.定义节点类;
class CppParaClient : public rclcpp::Node
{
public:
  CppParaClient() : Node("cppParaCliNode")
  {
    // 2.1 连接到节点参数的服务节点,注意此时的第二个参数是连接的服务端节点名
    paramClient = std::make_shared<rclcpp::SyncParametersClient>(this, "cppParamSerNode");
  }

  // 3. 连接服务函数
  bool connect_server()
  {
    // 3.1 等待服务连接
    while (!paramClient->wait_for_service(1s))
    {
      if (!rclcpp::ok())
      {
        return false;
      }
      RCLCPP_INFO(this->get_logger(), "The server connect failed! ");
    }

    return true;
  }

  // 4. 查询参数
  void get_values()
  {
    RCLCPP_INFO(this->get_logger(), "----------- Get the values -----------");
    auto params = paramClient->get_parameters({"name", "height"});
    for (auto &param : params)
    {
      RCLCPP_INFO(this->get_logger(), "%s = %s", param.get_name().c_str(), param.value_to_string().c_str());
    }
  }

  // 5. 修改参数
  void update_param()
  {
    RCLCPP_INFO(this->get_logger(), "----------- Change the values -----------");
    paramClient->set_parameters({rclcpp::Parameter("name", "lisi"),
                                 // 这是服务端不存在的参数,只有服务端设置了rclcpp::NodeOptions().allow_undeclared_parameters(true)时,
                                 //  这个参数才会被成功设置。
                                 rclcpp::Parameter("sex", "man")});
  }

private:
  rclcpp::SyncParametersClient::SharedPtr paramClient;
};

int main(int argc, char const *argv[])
{
  rclcpp::init(argc, argv);

  // 4.创建节点对象指针,调用参数操作函数;
  auto paramClient = std::make_shared<CppParaClient>();
  bool flag = paramClient->connect_server();
  if (!flag)
  {
    return 0;
  }
  paramClient->get_values();
  paramClient->update_param();
  paramClient->get_values();

  // 5.释放资源。
  rclcpp::shutdown();
  return 0;
}
  1. 由于在创建包的过程中已经指明了所有依赖项,不需要进行额外的配置,直接编译运行即可:colcon build --packages-select cpp_para_client

  2. 激活环境并运行节点:. install/setup.bash,先运行服务端节点ros2 run cpp_para_server cppParaSerNode,然后运行客户端节点ros2 run cpp_para_client cppParaCliNode

在这里插入图片描述

4.3 使用Python实现对节点参数的增删改查

参考内容

Using parameters in a class (Python)

2.5.4_参数服务_Python实现_01框架搭建

4.3.1 创建Python节点参数的服务端

  1. 创建功能包,包名为python_para_ser,节点名为pythonParaSerNode,依赖rclpyros2 pkg create python_para_ser --build-type ament_python --node-name pythonParaSerNode --dependencies rclpy

  2. 配置Vscode环境,在工作空间创建.vscode文件夹,并加入settings.json文件,添加ROS2include环境:

{
    "C_Cpp.default.includePath": [
        "/opt/ros/humble/include/**"
    ],
    "python.analysis.include": [
        "/opt/ros/humble/local/lib/python3.10/dist-packages/**"
    ]
}
  1. 创建节点参数服务:注意删除节点的参数,只能删除未被声明的内容:
# 1. 导入包
import rclpy
from rclpy.node import Node

# 2. 创建节点参数服务节点
class PythonParaServer(Node):
    def __init__(self):
        # 2.1 构造函数
        super().__init__("pythonParaSerNode",allow_undeclared_parameters=True)

    # 3 声明节点参数
    def declare_param(self):
        self.declare_parameter("name","zhangsan")
        self.declare_parameter("height",1.88)
        # 3.1 声明未声明的参数,可以被删除
        self.age = rclpy.Parameter("age",value = "20")
        self.set_parameters([self.age])

    # 4 查询参数
    def get_param(self):
        self.get_logger().info("---- Get ----")
        params = self.get_parameters(["name","height","age"])
        for param in params:
            self.get_logger().info("%s ---> %s" % (param.name, param.value))

    # 5 修改参数
    def update_param(self):
        self.get_logger().info("---- Change ---")
        self.set_parameters([rclpy.Parameter("name",value = "lisi")])
        self.get_param()

    # 6 删除参数
    def del_param(self):
        self.get_logger().info("---- Delete ---")
        self.undeclare_parameter("age")
        params = self.get_parameters(["name","height"])
        for param in params:
            self.get_logger().info("%s ---> %s" % (param.name, param.value))


def main():
    rclpy.init()
    param_server = PythonParaServer()

    param_server.declare_param()
    param_server.get_param()
    param_server.update_param()
    param_server.del_param()

    rclpy.spin(param_server)
    rclpy.shutdown()


if __name__ == "__main__":
    main()
  1. 编译:colcon build --packages-select python_para_ser

  2. 激活环境:. install/setup.bash

  3. 运行节点:ros2 run python_para_ser pythonParaSerNode

pldz@pldz-pc:/mnt/hgfs/VMware/ROS2_DEMO/4_Chapter/code$ ros2 run python_para_ser pythonParaSerNode 
[INFO] [1683212289.084496335] [pythonParaSerNode]: ---- Get ----
[INFO] [1683212289.084918579] [pythonParaSerNode]: name ---> zhangsan
[INFO] [1683212289.085258809] [pythonParaSerNode]: height ---> 1.88
[INFO] [1683212289.085559614] [pythonParaSerNode]: age ---> 20
[INFO] [1683212289.085874466] [pythonParaSerNode]: ---- Change ---
[INFO] [1683212289.086474845] [pythonParaSerNode]: ---- Get ----
[INFO] [1683212289.086867362] [pythonParaSerNode]: name ---> lisi
[INFO] [1683212289.087193515] [pythonParaSerNode]: height ---> 1.88
[INFO] [1683212289.087519418] [pythonParaSerNode]: age ---> 20
[INFO] [1683212289.087884144] [pythonParaSerNode]: ---- Delete ---
[INFO] [1683212289.088266933] [pythonParaSerNode]: name ---> lisi
[INFO] [1683212289.088594118] [pythonParaSerNode]: height ---> 1.88

4.3.2 创建Python节点参数客户端

  1. 创建功能包,包名为python_para_cli,节点名为pythonParaCliNode,依赖rclpyros2 pkg create python_para_cli --build-type ament_python --node-name pythonParaCliNode --dependencies rclpy

  2. 创建节点参数客户端,值得注意的是需要连接到服务端节点,然后进行参数的增删改查操作,值得注意的是节点参数的客户端在Python中没有被明确封装,但是节点参数底层是通过服务和话题实现的,因此调用原始的服务和话题实现(原来教程连接:https://www.bilibili.com/video/BV1LG411E7qT):

# 1. 导入包
import rclpy
from rclpy.node import Node
from rcl_interfaces.srv import ListParameters
from rcl_interfaces.srv import GetParameters
from rcl_interfaces.srv import SetParameters
from rcl_interfaces.msg import ParameterType
from rcl_interfaces.msg import Parameter
from rcl_interfaces.msg import ParameterValue
from ros2param.api import get_parameter_value

# 2 创建客户节点
class PythonParaClient(Node):
    # 2.1 构造函数
    def __init__(self):
        super().__init__('pythonParaCliNode')

    # 3 连接服务节点
    def list_params(self):
        # 3.1 创建客户端;
        cli_list = self.create_client(ListParameters, '/pythonParaSerNode/list_parameters')
        # 3.2 等待服务连接;
        while not cli_list.wait_for_service(timeout_sec=1.0):
            self.get_logger().info('Waiting for connect ...')
        req = ListParameters.Request()
        future = cli_list.call_async(req)
        rclpy.spin_until_future_complete(self,future)
        return future.result()

    # 4 获得所有参数
    def get_params(self,names):
        # 4.1 创建客户端
        cli_get = self.create_client(GetParameters, '/pythonParaSerNode/get_parameters')
        # 4.2 等待服务连接
        while not cli_get.wait_for_service(timeout_sec=1.0):
            self.get_logger().info('Waiting for connect ...')
        req = GetParameters.Request()
        req.names = names
        future = cli_get.call_async(req)
        rclpy.spin_until_future_complete(self,future)
        return future.result()

    # 5 更新参数服务值
    def set_params(self):
        # 5.1 创建客户端
        cli_set = self.create_client(SetParameters, '/pythonParaSerNode/set_parameters')
        # 5.2 等待服务连接
        while not cli_set.wait_for_service(timeout_sec=1.0):
            self.get_logger().info('Waiting for connect ...')

        req = SetParameters.Request()

        p1 = Parameter()
        p1.name = "name"
        p1.value = get_parameter_value(string_value="zhangsan")

        req.parameters = [p1]
        future = cli_set.call_async(req)
        rclpy.spin_until_future_complete(self,future)
        return future.result()

def main():
    rclpy.init()
    client = PythonParaClient()

    # 获取参数列表
    client.get_logger().info("--------- List all parameters node ---------")
    response = client.list_params()
    for name in response.result.names:
        client.get_logger().info(name)

    client.get_logger().info("--------- Get ---------")
    names = ["name","height"]
    response = client.get_params(names)
    print(response.values)

    client.get_logger().info("--------- Set ---------")
    response = client.set_params()
    results = response.results
    response = client.get_params(names)
    print(response.values)
    rclpy.shutdown()

if __name__ == "__main__":
    main()
  1. 编译:colcon build --packages-select python_para_cli

  2. 激活环境:. install/setup.bash

  3. 先运行服务端节点ros2 run python_para_ser pythonParaSerNode,然后运行客户端节点ros2 run python_para_cli pythonParaCliNode

在这里插入图片描述

4.4 ROS2节点参数小结

    1. 节点参数可删除的内容必须是未被声明的
    1. 客户端节点想修改服务节点的需要进行连接,连接成功之后才能进行增删改查

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/490795.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2008-2020年上市公司能源消耗数据

2008-2020年上市公司能耗数据/上市公司能源消耗数据 1、时间&#xff1a;2008-2020年 2、指标包括&#xff1a;上市公司ID、证券代码、证券简称、资源名称、消耗量、单位 EndDate [统计截止日期] - YYYY-12-31 InstitutionID [上市公司ID] - null Symbol [证券代码] - 交易所…

[架构之路-187]-《软考-系统分析师》-5-数据库系统 - 操作型数据库OLTP与分析型数据库OLAP比较

OLAP与OLTP的区别&#xff1f; OLTP(Online transaction processing) 在线/联机事务处理。典型的OLTP类操作都比较简单&#xff0c;主要是对数据库中的数据进行增删改查&#xff0c;操作主体一般是产品的用户。 OLAP(Online analytical processing): 指联机分析处理。通过分…

Linux网络编程:三次握手 四次挥手

1. 三次握手 建立TCP可靠连接&#xff0c;只能是客户端先发起。 &#xff08;1&#xff09;SYN标志位为1&#xff0c;表示请求建立连接&#xff1b;ACK标志位为1&#xff0c;表示确认收到对方报文。 &#xff08;2&#xff09;seq为数据包序列号&#xff0c;ack为确认序列号。…

计算机视觉的应用4-目标检测任务:利用Faster R-cnn+Resnet50+FPN模型对目标进行预测

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下计算机视觉的应用4-目标检测任务&#xff0c;利用Faster RcnnResnet50FPN模型对目标进行预测&#xff0c;目标检测是计算机视觉三大任务中应用较为广泛的&#xff0c;Faster R-CNN 是一个著名的目标检测网络&#x…

or-tools 应用案例分析:复杂作业车间调度问题

作业调度问题是常见的线性规划(整数规划)问题&#xff0c;其中多个作业在多台机器上处理。每个作业由一系列任务组成&#xff0c;这些任务必须按给定的顺序执行&#xff0c;并且每个任务都必须在特定的机器上处理。如何有效的利用所有的机器在最短的时间内完成所有的作业任务&a…

神经形态处理和自搜索存储如何降低联邦机构的网络风险

组织在边缘处理的信息量呈爆炸式增长。对于联邦机构和军队来说尤其如此&#xff0c;它们从设备、建筑物、船舶、飞机等中的移动设备和传感器生成大量数据。 寻找有效的方法来管理、使用和保护这些数据具有挑战性。但是有一个有效且具有成本效益的解决方案。神经形态处理和自搜…

c#笔记-数组

数组 声明数组 数组是一种可以声明多个同类型变量的数据结构&#xff0c;能替你声明多个变量。 并且其中的值可以通过索引动态访问&#xff0c;可以搭配循环批量处理这些值。 数组类型的写法是&#xff0c;在目标类型后加上一对中括号。 数组值没有字面量&#xff0c;需要构…

海天注塑机KEBA系统数据采集

本文章只针对海天注塑机的KEBA系统&#xff0c;因为其他注塑机厂家也用KEBA系统&#xff0c;他们的采集方式可能不太一样&#xff0c;所以后续有时间我将写其他文章来解释&#xff08;默认你已经向海天采购了OPC组件&#xff09;。 一、采集原理 采集软件&#xff08;OPC cli…

electron+vue3全家桶+vite项目搭建【18】electron新建窗口时传递参数【url版】

文章目录 引入实现效果展示实现思路实现步骤1.调整主进程新建窗口的handle2.调整新建窗口函数3.封装url获取请求参数的工具 测试代码 引入 electronvue的项目中&#xff0c;我们通过传入页面路由来展开新的页面&#xff0c;就像vue-router的路由传参一样&#xff0c;我们可以利…

排序算法 — 桶排序

文章目录 桶排序介绍桶排序实现桶排序复杂度和稳定性桶排序复杂度桶排序稳定性 代码实现核心&总结 桶排序介绍 假设待排序的数组a中共有N个整数&#xff0c;并且已知数组a中数据的范围[0, MAX)。在桶排序时&#xff0c;创建容量为MAX的桶数组r&#xff0c;并将桶数组元素都…

【AUTOSAR】【通信安全】E2E

目录 一、概述 二、约束和假设 三、依赖模块 四、功能描述 4.1 开发错误 4.1.1 运行时错误 五、API接口 5.1 E2E Profile 接口 5.2 E2E其他接口 一、概述 该文档制定了PRS E2E协议的平台特定实现要求。这包括所使用的接口和数据类型。 E2E保护的概念假设在运行时应对…

探讨Redis缓存问题及解决方案:缓存穿透、缓存击穿、缓存雪崩与缓存预热(如何解决Redis缓存中的常见问题并提高应用性能)

Redis是一种非常流行的开源缓存系统&#xff0c;用于缓存数据以提高应用程序性能。但是&#xff0c;如果我们不注意一些缓存问题&#xff0c;Redis也可能会导致一些性能问题。在本文中&#xff0c;我们将探讨Redis中的一些常见缓存问题&#xff0c;并提供解决方案。 一、缓存穿…

云计算中的边缘计算技术及其应用

章节一&#xff1a;云计算和边缘计算的简介 随着互联网的发展&#xff0c;数据中心的规模不断扩大&#xff0c;云计算也成为了越来越受欢迎的计算模式。但是&#xff0c;云计算存在着一些问题&#xff0c;比如延迟较高&#xff0c;网络瓶颈&#xff0c;数据隐私和安全性等等。…

Canny边缘检测算法

文章目录 前言1、Canny边缘检测算法2、代码1函数 3、代码24、基于tensor数据的代码 前言 最近在向卷积神经网络里的数据预处理和数据增强部分加这个函数&#xff0c;记录一下。 1、Canny边缘检测算法 Canny边缘检测算法是一种经典的边缘检测算法&#xff0c;其基本原理如下&a…

榜单!直接式TPMS前装搭载率突破60%,哪些厂商在领跑

2016年&#xff0c;《乘用车轮胎气压监测系统的性能要求和试验方法》通过强制性国家标准技术审查&#xff1b;根据规定&#xff0c;自2020年1月1日起&#xff0c;所有中国市场在产乘用车将开始实施强制安装TPMS&#xff08;胎压监测系统&#xff09;的要求。 目前&#xff0c;…

vue项目前端解决跨域问题

在前后端分离项目中&#xff0c;跨域是一定会出现的问题&#xff0c;本文主要介绍跨域问题的解决思路&#xff0c;以及在vue项目中如何使用代理的方式在前端解决跨域问题&#xff0c;同时提供一个后段解决的方案。 1、产生原因 跨域问题产生的原因是浏览器的同源策略。浏览器同…

哪款蓝牙耳机便宜又好用?2023公认质量最好的蓝牙耳机推荐

哪款蓝牙耳机便宜又好用&#xff1f;现如今&#xff0c;市面上的蓝牙耳机越来越多&#xff0c;在选择增多的同时也有着不小的困惑&#xff0c;不知道哪款好用。针对这个问题&#xff0c;我来给大家推荐几款质量最好的蓝牙耳机&#xff0c;一起来看看吧。 一、南卡小音舱Lite2蓝…

安装kali虚拟机

1&#xff1a;kali是什么? kali 是由 Offensive Security 公司开发和维护的。它在安全领域是一家知名的、值得信赖的公司它甚至还有一些受人尊敬的认证&#xff0c;来对安全从业人员做资格认证。Kali 也是一个简便的安全解决方案。Kali 并不要求你自己去维护一个 Linux 系统&…

u盘中病毒文件被隐藏怎么恢复?看看这三种方法

U盘是我们日常生活中常用的存储设备&#xff0c;但是如果U盘被病毒感染&#xff0c;可能会导致文件被隐藏或丢失。被病毒隐藏的U盘文件给我们的生活、工作带来了很大的麻烦&#xff0c;因此必须马上采取行动来恢复这些文件。 而解决“u盘文件被病毒隐藏如何恢复正常”的问题原来…

SpringBoot【运维实用篇】---- 日志

SpringBoot【运维实用篇】---- 日志 1. 代码中使用日志工具记录日志教你一招&#xff1a;优化日志对象创建代码 2. 日志输出格式控制3. 日志文件 运维篇最后一部分我们来聊聊日志&#xff0c;日志大家不陌生&#xff0c;简单介绍一下。日志其实就是记录程序日常运行的信息&…