ROS2组件component自定义实现

news2025/1/15 22:02:51

ROS2系列文章目录

ROS2中nav_msgs/msg/Path 数据含义及使用

ROS2中std_msgs/msg/Header 数据含义及使用

ROS中TF变换详解

ROS2中launch编写及参数含义(launch.xml、python)


提示:阅读并实践本文档后,将掌握并理解ros1中nodelet用法,掌握并理解ros2中component用法

文章目录

  • ROS2系列文章目录
  • ROS中nodelet与component的作用
  • 一、创建功能包并添加依赖
  • 二、新建组件函数文件及修改CMakeLists.txt
    • 1.新建component实现函数
    • 2.修改CMakeLists.txt添加组件信息
      • 2.1 使用cmake添加依赖生成库文件
      • 2.2 构建组件实现
    • 3. 使用指令查看是否加载成功自定义组件
      • 3.1查询插件是否生成
      • 3.2 加载运行自定义插件
  • 总结


ROS中nodelet与component的作用

Nodelet/component旨在提供一种方法,在一台机器上、在一个进程中运行多个算法,在进程内传递消息时不会产生拷贝成本。ros1与ros2中的节点发布与订阅话题数据,本质是将数据打包后通过TCP或者UDP将数据发送、接收、解包后进行数据处理。当存在大量数据如点云、图像等会导致消息传送滞后,因此在同一台机器中,使用nodelet/component会很好的避免数据传输问题,使用该方法只需要发送一个指向该数据的指针,而不是通过TCP/UDP发送数据本身,消息传输会更快。

ROS2中Component官方资料:http://docs.ros.org/en/humble/Tutorials/Intermediate/Writing-a-Composable-Node.html


提示:以下是本篇文章正文内容,下面案例可供参考

本教程的主要目标为:生成一个自定义的组件信息test_component::Test1,功能包为test_component,该组件的主要功能为发布话题“/talker”,发送的数据类型为std_msg/msg/string。

一、创建功能包并添加依赖

创建test_component功能包,添加依赖rclcpp、std_msgs、rcl_components等,实现如下:

ros2 pkg create test_component --build-type ament_cmake --dependencies  rclcpp std_msgs rclcpp_components

在这里插入图片描述

二、新建组件函数文件及修改CMakeLists.txt

1.新建component实现函数

test_component/src目录下新建C++实现源文件,文件名为:my_component.cpp
在这里插入图片描述

2.修改CMakeLists.txt添加组件信息

2.1 使用cmake添加依赖生成库文件

在cmake中包含实现功能必要的头文件:

include_directories(${rclcpp_INCLUDE_DIRS} ${std_msgs_INCLUDE_DIRS} ${rclcpp_components_INCLUDE_DIRS})

使用add_library添加要生成的库,具体使用方法如下:

 add_library(<name> [STATIC | SHARED | MODULE]
             [EXCLUDE_FROM_ALL]
             [<source>...])

将src/my_component.cpp文件添加生产Test1库

add_library(Test1 src/my_component.cpp )

给Test1库链接ros2相关的lib

ament_target_dependencies(Test1 rclcpp std_msgs rcl_components)

添加声明新构建的组件: test_component::Test1

rclcpp_components_register_node(Test1 "test_component::Test1")

声明添加一个新的的组件test_component::Test1到ros2系统中去

rclcpp_components_register_nodes(Test1 "test_component::Test1")

最后,将生成的库安装在指定的目录

install(TARGETS Test1
        ARCHIVE DESTINATION lib
        LIBRARY DESTINATION lib
        RUNTIME DESTINATION bin
)

上述操作对应的CMakeLists.txt文件如下:

cmake_minimum_required(VERSION 3.8)
project(test_component)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
find_package(rclcpp_components REQUIRED)

if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # comment the line when a copyright and license is added to all source files
  set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # comment the line when this package is in a git repo and when
  # a copyright and license is added to all source files
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()
include_directories(${rclcpp_INCLUDE_DIRS} ${std_msgs_INCLUDE_DIRS} ${rclcpp_components_INCLUDE_DIRS})
add_library(Test1 SHARED src/my_component.cpp )
ament_target_dependencies(Test1 rclcpp std_msgs rclcpp_components)
rclcpp_components_register_nodes(Test1 "test_component::Test1")
install(TARGETS Test1
        ARCHIVE DESTINATION lib
        LIBRARY DESTINATION lib
        RUNTIME DESTINATION bin
)
ament_package()

2.2 构建组件实现

初始化节点, 从Node继承的类开始,并定义了Test1构造函数,确保类的构造函数采用NodeOptions参数。

  explicit Test1(const rclcpp::NodeOptions & options):Node("test_node",options){
        // 创建话题发布者
        pub_ptr = this->create_publisher<std_msgs::msg::String>("/talker",10);
        // 创建定时器,定时1s后进入回调函数
        time_ptr = this->create_wall_timer(std::chrono::seconds(1),std::bind(&Test1::time_callback,this));
    }

使用RSO2中的pluginlib类似的宏调用声明

#include <rclcpp_components/register_node_macro.hpp>
// 给ROS系统调用提供宏定义接口
RCLCPP_COMPONENTS_REGISTER_NODE(test_component::Test1);

生成一个自定义的组件信息test_component::Test1的实现文件test_component.cpp如下:

#include <rclcpp/rclcpp.hpp>
#include <std_msgs/msg/string.hpp>
#include <chrono>
#include <string>
#include <rclcpp_components/register_node_macro.hpp>

namespace test_component{
    //继承rclcpp中的node节点,注意构建组件的构造函数有区别
    class Test1:public rclcpp::Node
    {

    public:
    // 构造函数中加入rclcpp::NodeOptions,并初始化
    explicit Test1(const rclcpp::NodeOptions & options):Node("test_node",options){
        // 创建话题发布者
        pub_ptr = this->create_publisher<std_msgs::msg::String>("/talker",10);
        // 创建定时器,定时1s后进入回调函数
        time_ptr = this->create_wall_timer(std::chrono::seconds(1),std::bind(&Test1::time_callback,this));
    }
    private:
    // 定时器指针
    rclcpp::TimerBase::ConstSharedPtr time_ptr;
    // 发布者话题指针
    rclcpp::Publisher<std_msgs::msg::String>::SharedPtr pub_ptr;
    // 话题发布数据
    std_msgs::msg::String data;
    // 定时器回调函数
    void time_callback(){
        static unsigned int i = 0;
        i++;
        data.data = std::to_string(i);
        pub_ptr->publish(data);
        RCLCPP_INFO(this->get_logger(),"进入定时器回调:%d",i);
    }
    };
};
// 给ROS系统调用提供宏定义接口
RCLCPP_COMPONENTS_REGISTER_NODE(test_component::Test1);

3. 使用指令查看是否加载成功自定义组件

3.1查询插件是否生成

使用ROS2推荐的colcon编译工具编译上述功能包后,执行一下指令:

source install/setup.bash
ros2 component types 

执行后输出结果中可以查看到是否已经加载自定义的组件信息
在这里插入图片描述

3.2 加载运行自定义插件

执行组件容器运行指令

ros2 run rclcpp_components component_container

执行完成后,可以通过查询ROS2中的节点指令确认是否启动成功

在这里插入图片描述

使用指令加载命令对生产的自定义插件加载

#ros2 component load /组件管理器名称  功能包  注册的组件名称
ros2 component load /ComponentManager test_component test_component::Test1 

执行上述指令后,在组件管理终端即可看到打印输出的日志信息

在这里插入图片描述使用节点管理工具以及话题打印工具查看是否正常显示节点以及话题内容

请添加图片描述


总结

本教程主要实现一个自定义的组件信息test_component::Test1,功能包为test_component,组件管理器启动加载该组件后,能够正常发布话题“/talker”,据类型为std_msg/msg/string。

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

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

相关文章

Python面向对象析构函数你学会了吗?

​ 当我第一次接触Python面向对象编程时&#xff0c;我完全被析构函数的概念给搞懵了。但是&#xff0c;随着我深入研究&#xff0c;我发现它其实并没有那么复杂。 1.析构函数是什么 析构函数是Python面向对象编程中的一个重要概念&#xff0c;它是在对象生命周期结束时自动调…

网工内推 | 浪潮原厂售前、方案经理,上市公司大平台,最高20K

01 浪潮集团 招聘岗位&#xff1a;售前经理 职责描述&#xff1a; 1、负责数字生态、数字教育、工业互联网、数字乡村、智慧城市、智慧交通等数字经济领域解决方案的售前工作&#xff0c;包括但不限于融合方案编制、项目调研、订制文档输出及客户咨询支持。 2、负责与公司各产…

数据完整性

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 数据完整性 数据完整性是关系数据库的一个重要特征&#xff0c;一般包含实体完整性、参照完整性和用户自定义完整性 3 种 实体完整性 实体完整性&#xff1a;规定表中的每…

VXLAN学习笔记

声明&#xff1a;该博客内容大部分参考参考链接整理 什么是VXLAN&#xff1f; VXLAN(Virtual Extensible LAN)即虚拟扩展局域网&#xff0c;是大二层网络中广泛使用的网络虚拟化技术。在源网络设备与目的网络设备之间建立一条逻辑VXLAN隧道&#xff0c;采用MAC in UDP的封装方…

Python的asyncio 多线程

-- 多线程、进程、协程是什么就不讲了&#xff0c;&#xff08;就是你理解的一边呼吸&#xff0c;一边看文章&#xff09; 仅解决问题的话&#xff0c;下边两篇不用看&#xff0c; Python 中的 async await 概念-CSDN博客 再深一点的看这个 Python中的多线程、进程、协程、…

Vue.js+SpringBoot开发个人健康管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 健康档案模块2.2 体检档案模块2.3 健康咨询模块 三、系统展示四、核心代码4.1 查询健康档案4.2 新增健康档案4.3 查询体检档案4.4 新增体检档案4.5 新增健康咨询 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpri…

【项目设计】基于Httplib和Mysql的视频播放

项目源码&#xff08;绝对可以直接运行&#xff09; 一、项目介绍 1. 对视频播放系统的认识 搭建视频共享播放服务器&#xff0c;可以让所有人通过浏览器访问服务器&#xff0c;实现视频的上传查看&#xff0c;以及管理并播放的功能。主要是完成服务器端的程序业务功能的实现…

腾讯云轻量4核8G12M服务器性能如何?价格感人

腾讯云轻量4核8G12M服务器配置446元一年&#xff0c;646元12个月&#xff0c;腾讯云轻量应用服务器具有100%CPU性能&#xff0c;系统盘为180GB SSD盘&#xff0c;12M带宽下载速度1536KB/秒&#xff0c;月流量2000GB&#xff0c;折合每天66.6GB流量&#xff0c;超出月流量包的流…

springboot276基于JS的个人云盘管理系统的设计与实现

个人云盘管理系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装个人云盘管理系统软件来发挥其…

开发反应式API

开发反应式API 开发反应式API1 使用SpringWebFlux1.1 Spring WebFlux 简介1.2 编写反应式控制器 2 定义函数式请求处理器3 测试反应式控制器3.1 测试 GET 请求3.2 测试 POST 请求3.3 使用实时服务器进行测试 4 反应式消费RESTAPI4.1 获取资源4.2 发送资源4.3 删除资源4.4 处理错…

大话设计模式——7.抽象工厂模式(Abstract Factory Pattern)

1.介绍 抽象工厂模式是工厂模式的进一步优化&#xff0c;提供一个创建一系列相关或相互依赖对象的接口&#xff0c;而无需指定它们具体的类。属于创建型模式。 UML图&#xff1a; 2.示例 车辆制造工厂&#xff0c;不仅可以制造轿车也可以用来生产自行车。 1&#xff09;Abs…

【技术类-02】python实现docx段落文字的“手动换行符(软回车)”变成“段落标记(硬回车)”

作品展示 背景需求&#xff1a; 制作周计划时&#xff0c;需要将周计划docx内所有的表格里的手动换行符&#xff08;软回车&#xff09;”变成“段落标记&#xff08;硬回车&#xff09;”&#xff0c; 全部改成段落标记&#xff08;硬回车&#xff09; 但是19份docx每份都要打…

人工智能入门学习笔记1:什么是人工智能

一、什么是人工智能 人工智能(Artificial Intelligence)&#xff0c;是一个以计算机科学&#xff08;Computer Science&#xff09;为基础&#xff0c;由计算机、心理学、哲学等多学科交叉融合的交叉学科、新兴学科&#xff0c;研究、开发用于模拟、延伸和扩展人的智能的理论、…

day06、07-MySQL

文章目录 一、MySQL概述1.1 安装1.2 数据模型1.3 SQL简介1.3.1 SQL通用语法1.3.2 分类 二. 数据库设计-DDL2.1 项目开发流程2.2 数据库操作2.2.1 查询数据库2.2.2 创建数据库2.2.3 使用数据库2.2.4 删除数据库 2.3 图形化工具2.3.1 介绍2.3.2 安装2.3.3 使用2.2.3.1 连接数据库…

Docker 容器化技术:构建高效、可移植的开发环境和部署流程|Docker 网络

为了支持网络协议栈的多个实例&#xff0c;Linux 在网络协议栈中引入了网络命名空间。这些独立的协议栈被隔离到不同的命名空间中&#xff0c;处于不同命名空间中的网络协议栈是完全隔离的&#xff0c;彼此无法通信。通过对网络资源的隔离&#xff0c;就能在一台宿主机上虚拟多…

【ACW 服务端】页面操作Java增删改查代码生成

版本: 1.2.2-JDK17-SNAPSHOT 项目地址&#xff1a;wu-smart-acw 演示地址&#xff1a;演示地址 admin/admin Java增删改查代码生成 找到对应菜单 选择你需要的数据实例 选择数据库 选择数据库表 选择客户端&#xff08;如果是本地ACW服务代码启动默认注册上的客户端ID是…

错误:npm ERR! code CERT_HAS_EXPIRED 解决

问题&#xff1a; 在打开项目用npm install安装依赖时报错&#xff1a;npm ERR! code CERT_HAS_EXPIRED如下图&#xff1a; 原因&#xff1a; 说明正在尝试访问的npm registry 淘宝npm镜像源 的SSL证书已经过期&#xff0c;导致无法建立安全连接。 解决&#xff1a; 配置不…

深度学习基础知识之Atrous卷积(空洞卷积)

太久不看代码确实生疏了&#xff0c;盯着一堆不同的dilation&#xff0c;不知道有什么作用&#xff0c;论文中说是Atrous卷积&#xff0c;原来就是空洞卷积的意思。 Dilated/Atrous Convolution 空洞卷积&#xff08;膨胀卷积/扩张卷积&#xff09; 空洞卷积是一种不增加参数量…

2024 Meetup地区组织者招募ing!| 共赴IvorySQL城市行

IvorySQL每一次线下活动&#xff0c;都离不开背后默默付出及用心策划的地区组织者。是他们&#xff0c;让我们的相聚变得更加有意义&#xff0c;让我们的交流更加深入。每次看到大家在活动现场热情洋溢的面孔&#xff0c;听到大家对IvorySQL的喜欢和期待&#xff0c;我们都感到…

CSS:过渡动画 (Transition)与关键帧动画(Keyfram)

一、过渡动画 (Transition) 1.简单介绍 Transition能为样式的变化提供过渡效果&#xff0c;例如在下面的代码中&#xff1a; .main {width: 300px;height: 100px;background-color: #d26f6f;}.main:hover {width: 300px;height: 200px;background-color: #5e3e3e;transition:…