ros2(jazzy)多节点运行在同一个进程范例(对标ros1的nodelet)

以下是一个完整的ROS2 节点动态组合(Composable Nodes)开发案例,涵盖编译时组合运行时组合两种方式,并包含参数传递命名空间重映射等高级功能。


案例目标

  • 实现一个Talker(发布者)Listener(订阅者)节点,并动态组合到单个进程中。
  • 支持编译时组合(硬编码)和运行时组合(通过component_container动态加载)。
  • 演示参数传递命名空间重映射

1. 创建 ROS2 包

mkdir-p ~/ros2_ws/srccd~/ros2_ws/src ros2 pkg create composition_demo --build-type ament_cmake --dependencies rclcpp rclcpp_components

2. 编写 Talker 和 Listener 组件

(1) Talker 组件 (talker_component.cpp)

#include"rclcpp/rclcpp.hpp"#include"rclcpp_components/register_node_macro.hpp"#include"std_msgs/msg/string.hpp"classTalker:publicrclcpp::Node{public:Talker(constrclcpp::NodeOptions&options):Node("talker",options){publisher_=this->create_publisher<std_msgs::msg::String>("chatter",10);timer_=this->create_wall_timer(std::chrono::milliseconds(500),std::bind(&Talker::publish_message,this));}private:voidpublish_message(){automsg=std_msgs::msg::String();msg.data="Hello, ROS2 Composition!";publisher_->publish(msg);RCLCPP_INFO(this->get_logger(),"Published: '%s'",msg.data.c_str());}rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_;rclcpp::TimerBase::SharedPtr timer_;};RCLCPP_COMPONENTS_REGISTER_NODE(Talker)// 注册为组件

(2) Listener 组件 (listener_component.cpp)

#include"rclcpp/rclcpp.hpp"#include"rclcpp_components/register_node_macro.hpp"#include"std_msgs/msg/string.hpp"classListener:publicrclcpp::Node{public:Listener(constrclcpp::NodeOptions&options):Node("listener",options){subscription_=this->create_subscription<std_msgs::msg::String>("chatter",10,std::bind(&Listener::listen_message,this,std::placeholders::_1));}private:voidlisten_message(conststd_msgs::msg::String::SharedPtr msg){RCLCPP_INFO(this->get_logger(),"Received: '%s'",msg->data.c_str());}rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscription_;};RCLCPP_COMPONENTS_REGISTER_NODE(Listener)// 注册为组件

3. 编译时组合(Hardcoded Composition)

(1) 创建manual_composition.cpp

#include"rclcpp/rclcpp.hpp"#include"talker_component.hpp"#include"listener_component.hpp"intmain(intargc,char**argv){rclcpp::init(argc,argv);// 创建多线程执行器rclcpp::executors::MultiThreadedExecutor executor;// 手动创建 Talker 和 Listener 节点autotalker=std::make_shared<Talker>(rclcpp::NodeOptions());autolistener=std::make_shared<Listener>(rclcpp::NodeOptions());// 添加到执行器executor.add_node(talker);executor.add_node(listener);// 运行执行器executor.spin();rclcpp::shutdown();return0;}

(2) 修改CMakeLists.txt

cmake_minimum_required(VERSION 3.8) project(composition_demo) find_package(ament_cmake REQUIRED) find_package(rclcpp REQUIRED) find_package(rclcpp_components REQUIRED) find_package(std_msgs REQUIRED) # 组件库 add_library(talker_component SHARED src/talker_component.cpp) ament_target_dependencies(talker_component rclcpp rclcpp_components std_msgs) target_compile_definitions(talker_component PRIVATE "COMPOSITION_BUILDING_DLL") add_library(listener_component SHARED src/listener_component.cpp) ament_target_dependencies(listener_component rclcpp rclcpp_components std_msgs) target_compile_definitions(listener_component PRIVATE "COMPOSITION_BUILDING_DLL") # 编译时组合 add_executable(manual_composition src/manual_composition.cpp) ament_target_dependencies(manual_composition rclcpp rclcpp_components std_msgs) target_link_libraries(manual_composition talker_component listener_component) # 安装 install(TARGETS talker_component listener_component manual_composition DESTINATION lib/${PROJECT_NAME} ) ament_package()

(3) 编译并运行

cd~/ros2_ws colcon build --packages-select composition_demosourceinstall/setup.bash ros2 run composition_demo manual_composition

输出

[INFO] [talker]: Published: 'Hello, ROS2 Composition!' [INFO] [listener]: Received: 'Hello, ROS2 Composition!'

4. 运行时组合(Dynamic Composition)

(1) 启动component_container

ros2 run rclcpp_components component_container

(2) 动态加载 Talker 和 Listener

# 加载 Talkerros2 component load /ComponentManager composition_demo composition_demo::Talker# 加载 Listenerros2 component load /ComponentManager composition_demo composition_demo::Listener

输出

[INFO] [talker]: Published: 'Hello, ROS2 Composition!' [INFO] [listener]: Received: 'Hello, ROS2 Composition!'

(3) 查看已加载组件

ros2 component list

输出

/ComponentManager 1 /talker 2 /listener

(4) 卸载组件

ros2 component unload /ComponentManager12

输出

Unloaded component 1 from '/ComponentManager' container Unloaded component 2 from '/ComponentManager' container

5. 高级功能

(1) 参数传递

ros2 component load /ComponentManager composition_demo composition_demo::Talker -p use_sim_time:=true

(2) 命名空间重映射

ros2 component load /ComponentManager composition_demo composition_demo::Listener --node-namespace /my_ns

(3) 使用dlopen动态加载

ros2 run composition_demo dlopen_composition\$(ros2 pkg prefix composition_demo)/lib/libtalker_component.so\$(ros2 pkg prefix composition_demo)/lib/liblistener_component.so

6. 总结

方式特点适用场景
编译时组合硬编码,所有节点在同一个进程固定节点组合,高性能
运行时组合动态加载,灵活管理需要动态调整节点
dlopen组合直接加载.so文件无 ROS 接口依赖
Launch 文件组合自动化启动复杂系统部署

完整代码:GitHub - ROS2 Composition Demo


通过这个案例,你可以:

  1. 理解 ROS2 组件化开发(Composable Nodes)。
  2. 掌握编译时和运行时组合的方式。
  3. 学会参数传递和命名空间重映射
  4. 应用于多传感器融合、自主导航等复杂系统

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

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

相关文章

【C++】2.7 哈希表及其实现

二次探测&#xff1a;由于直接这么探测&#xff0c;要是数据堆积那么效率较低 因此&#xff0c;可以将i改成-i方&#xff0c;让数据更加分散 其它都一样&#xff0c;将hash0 i改为hashi*i即可(2) 双重散列法 由于二次探测在冲突时-的值时一样的&#xff0c;依旧不能解决堆积问…

PDF-Extract-Kit错误排查:解决‘上传文件无反应‘问题

PDF-Extract-Kit错误排查&#xff1a;解决上传文件无反应问题 1. 引言 在使用PDF-Extract-Kit这一由科哥二次开发构建的PDF智能提取工具箱时&#xff0c;用户可能会遇到“上传文件后无反应”的典型问题。该问题表现为&#xff1a;用户成功启动WebUI服务并访问页面后&#xff…

HY-MT1.5部署实战:5分钟搭建企业级翻译系统

HY-MT1.5部署实战&#xff1a;5分钟搭建企业级翻译系统 在AI驱动的全球化浪潮中&#xff0c;高质量、低延迟的机器翻译能力已成为企业出海、跨语言协作的核心基础设施。腾讯近期开源的混元翻译大模型HY-MT1.5系列&#xff0c;凭借其卓越的翻译质量与灵活的部署能力&#xff0c…

操作指南:Proteus8.16下载安装教程配合Keil联合仿真

手把手搭建嵌入式虚拟实验室&#xff1a;Proteus 8.16 Keil 联合仿真实战指南 你有没有过这样的经历&#xff1f; 写好一段51单片机代码&#xff0c;烧进芯片却发现LED不闪&#xff1b;反复检查电路&#xff0c;换了几块板子才意识到是定时器配置错了。等改完再烧录&#xf…

Spring+Quartz实现定时任务的配置方法

<?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xmlns:context"http://www.springframework.org/schema/c…

腾讯HY-MT1.5-1.8B性能测试:小模型大作为实战分析

腾讯HY-MT1.5-1.8B性能测试&#xff1a;小模型大作为实战分析 1. 引言&#xff1a;小参数&#xff0c;大能力——腾讯混元翻译模型的轻量化突破 随着多语言交流需求的爆发式增长&#xff0c;高质量、低延迟的机器翻译系统成为智能应用的核心组件。然而&#xff0c;传统大模型虽…

Spring 过滤器:OncePerRequestFilter 应用详解

在Web应用中&#xff0c;过滤器&#xff08;Filter&#xff09;是一个强大的工具&#xff0c;它可以在请求到达目标资源之前或响应返回客户端之前对请求或响应进行拦截和处理。然而&#xff0c;在某些情况下&#xff0c;我们可能希望确保过滤器逻辑在一次完整的HTTP请求中仅执行…

PDF-Extract-Kit部署教程:跨平台部署解决方案

PDF-Extract-Kit部署教程&#xff1a;跨平台部署解决方案 1. 引言 1.1 技术背景与学习目标 PDF-Extract-Kit 是一款由开发者“科哥”二次开发构建的PDF智能提取工具箱&#xff0c;集成了布局检测、公式识别、OCR文字提取、表格解析等核心功能&#xff0c;广泛适用于学术论文…

HY-MT1.5术语干预SDK开发:自定义术语库集成

HY-MT1.5术语干预SDK开发&#xff1a;自定义术语库集成 1. 引言 随着全球化进程的加速&#xff0c;高质量、可定制化的机器翻译需求日益增长。尤其是在专业领域&#xff08;如法律、医疗、金融&#xff09;和多语言混合场景中&#xff0c;通用翻译模型往往难以满足对术语一致…

Spring 的三种注入方式?

1. 实例的注入方式 首先来看看 Spring 中的实例该如何注入&#xff0c;总结起来&#xff0c;无非三种&#xff1a;属性注入set 方法注入构造方法注入我们分别来看下。 1.1 属性注入 属性注入是大家最为常见也是使用最多的一种注入方式了&#xff0c;代码如下&#xff1a; Servi…

深度剖析ST7789初始化序列:适合初学的理解方式

点亮第一帧&#xff1a;拆解ST7789初始化背后的工程逻辑你有没有遇到过这样的场景&#xff1f;硬件接好了&#xff0c;代码烧进去了&#xff0c;LVGL界面也写得漂漂亮亮——结果屏幕一动不动&#xff0c;黑屏、白屏、花屏轮番上演。反复检查接线无误&#xff0c;SPI通信也有波形…

PDF-Extract-Kit实战案例:智能文档检索系统

PDF-Extract-Kit实战案例&#xff1a;智能文档检索系统 1. 引言 在科研、教育和企业办公场景中&#xff0c;PDF 文档作为知识传递的核心载体&#xff0c;往往包含大量结构化信息——如文字、表格、数学公式和图像。然而&#xff0c;传统方式难以高效提取这些内容并进行二次利…

BRAM在图像处理缓存中的实现:完整示例解析

BRAM在图像处理缓存中的实战设计&#xff1a;从原理到可综合代码你有没有遇到过这样的问题——明明FPGA的逻辑资源还很充裕&#xff0c;但图像处理流水线却频频卡顿&#xff1f;像素流断了、卷积核等数据、边缘检测结果延迟飙升……最终发现&#xff0c;瓶颈不在算法&#xff0…

HY-MT1.5性能对比:与Google翻译API实测数据

HY-MT1.5性能对比&#xff1a;与Google翻译API实测数据 在多语言交流日益频繁的今天&#xff0c;高质量、低延迟的机器翻译模型成为跨语言沟通的核心基础设施。近年来&#xff0c;随着大模型技术的快速发展&#xff0c;开源翻译模型逐渐具备了与商业API相媲美的能力。腾讯近期…

PDF智能提取工具箱实战:手写公式转LaTeX完整步骤

PDF智能提取工具箱实战&#xff1a;手写公式转LaTeX完整步骤 1. 引言&#xff1a;从扫描文档到结构化数据的智能化跃迁 在科研、教学和工程实践中&#xff0c;PDF文档中常包含大量手写或印刷体数学公式、表格和文本内容。传统方式下&#xff0c;将这些非结构化信息转化为可编…

基于深度学习 YOLOv8➕pyqt5的西红柿成熟度检测系统

基于深度学习 YOLOv8➕pyqt5的西红柿成熟度检测系统&#xff0c; 完整源码源文件已标注的数据集训练好的模型环境配置教程程序运行说明文档 可以替换自己训练的模型&#xff0c;实现检测目标自定义 blog.csdnimg.cn/direct/31c61653310648458126c961a01fd682.png) 以下文章及示…

PDF-Extract-Kit快速上手:10分钟完成第一个PDF解析项目

PDF-Extract-Kit快速上手&#xff1a;10分钟完成第一个PDF解析项目 1. 引言 在科研、教育和办公场景中&#xff0c;PDF文档常包含大量结构化信息——如公式、表格、图文混排内容。然而&#xff0c;传统方式难以高效提取这些元素&#xff0c;尤其是数学公式和复杂表格的数字化…

STM32CubeMX工业电机控制配置:完整指南

用STM32CubeMX打造工业级电机控制系统&#xff1a;从配置到实战的深度实践你有没有遇到过这样的场景&#xff1f;刚接手一个三相PMSM电机控制项目&#xff0c;硬件板子已经打好了&#xff0c;但PWM波形不对、电流采样总在噪声区、编码器读数跳变……调试几天都没找出问题。最后…

无人机培训PPT课件 多旋翼无人飞行培训无人机精灵培训PPT

无人机培训PPT课件 多旋翼无人飞行培训无人机精灵培训PPT 素材 一、课程内容概述 基础理论&#xff1a; 详细讲解无人机的定义、分类以及多旋翼无人机在整个无人机体系中的独特地位和特点。 让学员清晰了解无人机的基本概念&#xff0c;包括按照用途&#xff08;如航拍、物流、…

HY-MT1.5边缘计算方案:离线环境翻译应用部署

HY-MT1.5边缘计算方案&#xff1a;离线环境翻译应用部署 在多语言交流日益频繁的今天&#xff0c;高质量、低延迟的翻译服务成为智能设备、跨境沟通和本地化应用的核心需求。然而&#xff0c;依赖云端API的传统翻译方案面临网络延迟、数据隐私和离线不可用等挑战。为此&#x…