当前位置: 首页 > news >正文

【ROS2】ROS2节点Node机制与常用命令行

在这里插入图片描述

ROS 系列学习教程(总目录)
ROS2 系列学习教程(总目录)

目录

  • 一、节点介绍
  • 二、创建自定义节点
  • 三、Node 常用命令行
    • 3.1 运行节点
    • 3.2 节点列表
    • 3.3 节点信息

一、节点介绍

ROS 中的每个节点都应负责单一、模块化的功能,例如控制车轮电机或发布激光测距仪的传感器数据。每个节点都可以通过Topic、Service、Action或Params与其他节点发送和接收数据。

在这里插入图片描述

完整的机器人系统由许多协同工作的节点组成。

在 ROS2 中,节点有如下特点(这里特点与ROS1相同):

  • 单个可执行文件可以包含一个或多个节点。
  • 每个节点可以使用不同的编程语言实现(C++ 程序、Python 程序等)。
  • 每个节点独占一个进程。
  • 处于不同可执行文件的节点,可以分布式的运行在不同主机。
  • 节点名字全局唯一。

二、创建自定义节点

与ROS1相比,ROS2创建节点的方式有稍微改变:

ROS1:

#include "ros/ros.h"int main(int argc, char **argv) 
{ros::init(argc, argv, "my_node");ros::NodeHandle nh;// 节点逻辑ros::spin();return 0;
}

ROS2:

#include "rclcpp/rclcpp.hpp"int main(int argc, char **argv) 
{rclcpp::init(argc, argv);auto node = rclcpp::Node::make_shared("my_node");// 节点逻辑rclcpp::spin(node);rclcpp::shutdown();return 0;
}

ROS2 去掉了 ROS1 中 NodeHandle 的概念,取而代之的是节点指针,ROS1中的节点名字在 init 中初始化,NodeHandle 是匿名的,ROS2 中没有了这一概念,并把节点名字放到节点构造函数中初始化,这样就保证了同一节点内操作句柄是唯一的,即该节点的指针。

这样即简化了节点管理又增强了节点唯一性。在ROS1中,NodeHandle 用于操作节点资源,如创建Publisher和Subscriber。然而,开发者需要额外管理NodeHandle的实例,从而增加了节点的复杂性;在ROS2中,使用节点指针和构造函数初始化节点,简化了节点的管理。开发者无需显式创建和管理NodeHandle,因为节点本身已经包含了所有必要的操作句柄。在ROS1中,虽然可以通过NodeHandle操作多个节点资源,但NodeHandle通常是匿名的,这可能导致节点之间的混淆;ROS2通过将节点名字直接放入节点构造函数中初始化,确保了同一节点内操作句柄的唯一性。这样做有助于避免节点之间的命名冲突和混淆。

上述代码中 auto node = rclcpp::Node::make_shared("my_node"); 创建了一个 rclcpp::Node 类的对象指针,但实际应用中,一般会实现自定义类并继承于 rclcpp::Node 以使用ROS2的接口。

#include <chrono>#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"using namespace std::chrono_literals;// 继承于rclcpp::Node的自定义节点HelloWorldPublisher
class HelloWorldPublisher : public rclcpp::Node
{
public:HelloWorldPublisher(): Node("publisher") // 构造时指定节点的名字, m_count(0){m_publisher = this->create_publisher<std_msgs::msg::String>("/hello_world", 10);m_timer = this->create_wall_timer(500ms, std::bind(&HelloWorldPublisher::timercallback, this));}private:void timercallback(){auto message = std_msgs::msg::String();message.data = "Hello, world! " + std::to_string(this->m_count++);RCLCPP_INFO(this->get_logger(), "Publishing: '%s'", message.data.c_str());this->m_publisher->publish(message);}private:rclcpp::TimerBase::SharedPtr m_timer;rclcpp::Publisher<std_msgs::msg::String>::SharedPtr m_publisher;size_t m_count;
};int main(int argc, char *argv[])
{rclcpp::init(argc, argv);auto node = std::make_shared<HelloWorldPublisher>();rclcpp::spin(node);rclcpp::shutdown();return 0;
}

如前文的hello world示例,自定义了 HelloWorldPublisher 类,继承于 rclcpp::Node,在 HelloWorldPublisher 类中实现自己的业务逻辑。

简单理解就是,ROS2的 rclcpp 库给我们提供了一个父类 Node,我们使用时需要继承这个类,这样就可以在自己的类里调用 rclcpp::Node 的接口。

三、Node 常用命令行

3.1 运行节点

ros2 run <package_name> <executable_name>

比如 ros2 run turtlesim turtlesim_node 会打开一个ROS自带的乌龟测试窗口,前文的hello world示例中 ros2 run hello_world_cpp talker 会运行发布者节点。

注意:package_name 是包名称,executable_name 是可执行文件的名称,不是节点名称。

3.2 节点列表

ros2 node list

该命令会列出所有正在运行的节点的名称。

3.3 节点信息

ros2 node info <node_name>

该命令会列出节点的详细信息。

在这里插入图片描述

其中会包括节点的名字、Topic的发布者和订阅者、Service的服务端和客户端、Action的服务端和客户端。


欢迎大家加QQ群,一起讨论学习:894013891

http://www.xdnf.cn/news/1233559.html

相关文章:

  • 快速了解决策树
  • 一个物理引擎仿真器(mujoco这种)的计算流程
  • 面经——电子电路技术知识详解
  • 关于鸦片战争的历史
  • python匿名函数lambda
  • 题单【模拟与高精度】
  • leetcode热题——组合
  • Java 中的 HashMap.merge() 方法详解
  • 【AI学习】RadioDiff:代码学习
  • 西门子 G120 变频器全解析:从认知到参数设置
  • SpringBoot 02 AOP
  • 「iOS」————weak底层原理
  • 「iOS」————SideTable
  • OpenVLA复现
  • 数据集-目标检测系列- 地球仪 数据集 globe>> DataBall
  • XGBoost三部曲:XGBoost参数详解
  • 数据结构(12)二叉树
  • 【数据结构】栈的顺序存储(整型栈、字符栈)
  • 在linux(ubuntu)服务器上安装NTQQ并使用
  • VS2019安装HoloLens 没有设备选项
  • rag学习-以项目为基础快速启动掌握rag
  • 1. 两数之和
  • uniapp 数组的用法
  • Removing Digits(Dynamic Programming)
  • 入门MicroPython+ESP32:安装逗脑IDE及驱动
  • JJWT 核心工具类 Jwts 源码解析
  • 高效离线转换方案:支持多任务并行处理
  • 通俗易懂解释Java8 HashMap
  • 使用 BERT 的 NSP 实现语义感知切片 —— 提升 RAG 系统的检索质量
  • 一种基于入侵杂草优化算法(IWO)的聚类算法,并与K-Means、高斯混合模型(GMM)进行对比,Matlab