当前位置: 首页 > 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.dtcms.com/a/311946.html

相关文章:

  • Autosar Nm-网管报文PNC停发后无法休眠问题排查
  • 决策树算法:三大核心流程解析
  • Agents-SDK智能体开发[4]之集成MCP入门
  • Qt 槽函数被执行多次,并且使用Qt::UniqueConnection无效【已解决】
  • Python编程基础与实践:Python文件处理入门
  • 智能手表:MPU6050和水平仪,动态表情包
  • 第14届蓝桥杯Python青少组中/高级组选拔赛(STEMA)2023年1月15日真题
  • Qemu-NUC980(二):时钟clock代码添加
  • 驾驶场景玩手机识别:陌讯行为特征融合算法误检率↓76% 实战解析
  • 如何修复非json数据
  • 兰空图床部署教程
  • 从C++0基础到C++入门(第十五节:switch语句)
  • 工具包:位图格式一键生成可无限放大的矢量图SVG/EPS及CAD文件DXF
  • 我的世界模组开发教程——物品item(1)
  • 建筑施工场景安全帽识别误报率↓79%:陌讯动态融合算法实战解析
  • 深入 Vue v-model
  • SpringBoot启动项目详解
  • MC0351区间询问和
  • MybatisPlus-自动生成代码
  • 【走遍美国精讲笔记】第 1 课:林登大街 46 号
  • 深入 Go 底层原理(四):GMP 模型深度解析
  • 编译器与解释器:核心原理与工程实践
  • Linux I/O 系统调用完整对比分析
  • linux source命令使用详细介绍
  • [qt]QTreeWidget使用
  • JAVA国际版同城服务同城信息同城任务发布平台APP源码Android + IOS
  • 【设计模式】 原则
  • AI驱动SEO关键词智能进化
  • 具身智能VLA困于“数据泥潭”,人类活动视频数据是否是“破局之钥”?
  • 【Python修仙编程】(二) Python3灵源初探(10)