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

ROS核心概念解析:从Node到Master,再到roslaunch的全面指南

Node

在ROS中,最小的进程单元就是节点(node)。一个软件包里可以有多个可执行文件,可执行文件在运行之后就成了一个进程(process),这个进程在ROS中就叫做节点。 从程序角度来说,node就是一个可执行文件(通常为C++编译生成的可执行文件、Python脚本)被执行,加载到了内存之中;从功能角度来说,通常一个node负责者机器人的某一个单独的功能。由于机器人的功能模块非常复杂,我们往往不会把所有功能都集中到一个node上,而会采用分布式的方式,把鸡蛋放到不同的篮子里。

Master

由于机器人的元器件很多,功能庞大,因此实际运行时往往会运行众多的node,负责感知世界、控制运动、决策和计算等功能。那么如何合理的进行调配、管理这些node?这就要利用ROS提供给我们的节点管理器master, master在整个网络通信架构里相当于管理中心,管理着各个node。node首先在master处进行注册,之后master会将该node纳入整个ROS程序中。node之间的通信也是先由master进行“牵线”,才能两两的进行点对点通信。当ROS程序启动时,第一步首先启动master,由节点管理器处理依次启动node。

启动master和node

当我们要启动ROS时,首先输入命令:

$ roscore

此时ROS master启动,同时启动的还有rosoutparameter server,其中rosout是负责日志输出的一个节点,其作用是告知用户当前系统的状态,包括输出系统的error、warning等等,并且将log记录于日志文件中,parameter server即是参数服务器,它并不是一个node,而是存储参数配置的一个服务器。每一次我们运行ROS的节点前,都需要把master启动起来,这样才能够让节点启动和注册。

master之后,节点管理器就开始按照系统的安排协调进行启动具体的节点。节点就是一个进程,只不过在ROS中它被赋予了专用的名字—node。我们知道一个package中存放着可执行文件,可执行文件是静态的,当系统执行这些可执行文件,将这些文件加载到内存中,它就成为了动态的node。

具体启动node的语句是:

$ rosrun pkg_name node_name

通常我们运行ROS,就是按照这样的顺序启动,有时候节点太多,我们会选择用launch文件来启动。 Master、Node之间以及Node之间的关系如下图所示:

rosrun和rosnode命令

rosrun命令的详细用法如下

$ rosrun [--prefix cmd] [--debug] pkg_name node_name [ARGS]

rosrun将会寻找PACKAGE下的名为EXECUTABLE的可执行程序,将可选参数ARGS传入。

例如在GDB下运行ros程序:

$ rosrun --prefix 'gdb -ex run --args' pkg_name node_name

rosnode命令的详细作用列表如下

以上命令中常用的为前三个,在开发调试时经常会需要查看当前node以及node信息,所以请记住这些常用命令。如果想不起来,也可以通过rosnode help来查看rosnode命令的用法。

机器人是一个系统工程,通常一个机器人运行操作时要开启多个node,对于一个复杂的机器人的启动操作应该怎么做呢?当然,我们并不需要每个节点依次进行rosrun,ROS为我们提供了一个命令能一次性启动master和多个node。该命令是:

$ roslaunch pkg_name file_name.launch

roslaunch命令首先会自动进行检测系统的roscore有没有运行,也即是确认节点管理器是否在运行状态中,如果master没有启动,那么roslaunch就会首先启动master,然后再按照launch的规则执行。launch文件里已经配置好了启动的规则。 所以roslaunch就像是一个启动工具,能够一次性把多个节点按照我们预先的配置启动起来,减少我们在终端中一条条输入指令的麻烦。

launch文件同样也遵循着xml格式规范,是一种标签文本,它的格式包括以下标签:

<launch>    <!--根标签-->
<node>    <!--需要启动的node及其参数-->
<include>    <!--包含其他launch-->
<machine>    <!--指定运行的机器-->
<env-loader>    <!--设置环境变量-->
<param>    <!--定义参数到参数服务器-->
<rosparam>    <!--启动yaml文件参数到参数服务器-->
<arg>    <!--定义变量-->
<remap>    <!--设定参数映射-->
<group>    <!--设定命名空间-->
</launch>    <!--根标签-->

launch文件的写法和格式看起来内容比较复杂,我们先来介绍一个最简单的例子如下:

<launch>
<node name="talker" pkg="rospy_tutorials" type="talker" />
</launch>

文本中的信息是,它启动了一个单独的节点talker,该节点是包rospy_tutorials软件包中的节点。

然而实际中的launch文件要复杂很多,我们以Ros-Academy-for-Beginners中的robot_sim_demo为例:

<launch>
<!--arg是launch标签中的变量声明,arg的name为变量名,default或者value为值-->
<arg name="robot" default="xbot2"/>
<arg name="debug" default="false"/>
<arg name="gui" default="true"/>
<arg name="headless" default="false"/><!-- Start Gazebo with a blank world -->
<include file="$(find gazebo_ros)/launch/empty_world.launch"> <!--include用来嵌套仿真场景的launch文件-->
<arg name="world_name" value="$(find robot_sim_demo)/worlds/ROS-Academy.world"/>
<arg name="debug" value="$(arg debug)" />
<arg name="gui" value="$(arg gui)" />
<arg name="paused" value="false"/>
<arg name="use_sim_time" value="true"/>
<arg name="headless" value="$(arg headless)"/>
</include><!-- Oh, you wanted a robot? --> <!--嵌套了机器人的launch文件-->
<include file="$(find robot_sim_demo)/launch/include/$(arg robot).launch.xml" /><!--如果你想连同RViz一起启动,可以按照以下方式加入RViz这个node-->
<!--node name="rviz" pkg="rviz" type="rviz" args="-d $(find robot_sim_demo)/urdf_gazebo.rviz" /-->
</launch>

这个launch文件相比上一个简单的例子来说,内容稍微有些复杂,它的作用是:启动gazebo模拟器,导入参数内容,加入机器人模型。

对于初学者,我们不要求掌握每一个标签是什么作用,但至少应该有一个印象。如果我们要进行自己写launch文件,可以先从改launch文件的模板入手,基本可以满足普通项目的要求。

相关文章:

ROS核心概念解析:从Node到Master,再到roslaunch的全面指南

Node 在ROS中&#xff0c;最小的进程单元就是节点&#xff08;node&#xff09;。一个软件包里可以有多个可执行文件&#xff0c;可执行文件在运行之后就成了一个进程(process)&#xff0c;这个进程在ROS中就叫做节点。 从程序角度来说&#xff0c;node就是一个可执行文件&…...

2025广州国际汽车内外饰技术展览会:引领汽车内外饰发展新潮流-Automotive Interiors

随着科技的不断进步和消费者对汽车品质的要求日益提高&#xff0c;汽车内外饰的设计和制造也在不断创新和发展。AUTO TECH China 2025广州国际汽车内外饰技术展览会作为行业内的重要盛会&#xff0c;将于2025年11月20日至22日在广州保利世贸博览馆盛大举办。本次展览会将汇集全…...

ElasticSearch内存占用率过高怎么办?

文章目录 1&#xff0c;先用top看看各个进程的内存占用情况2&#xff0c;不能简单的杀死进程&#xff0c;然后再重启。3&#xff0c;查看一下ElasticSearch进程的具体启动情况4&#xff0c;修改Elasticsearch 的Java堆内存 1&#xff0c;先用top看看各个进程的内存占用情况 先…...

基于Qt的OFD阅读器开发原理与实践

摘要 本文详细探讨了基于Qt开发OFD阅读器的原理与实践。通过解析OFD文件格式、构建文档结构、实现页面渲染、处理用户交互以及进行性能优化&#xff0c;本文展示了如何使用Qt框架开发一个功能强大、性能优异的OFD阅读器。文章还提供了示例代码和未来发展方向&#xff0c;为开发…...

用 HTML5 Canvas 和 JavaScript 实现流星雨特效

最近在研究前端动画效果时,实现了一个超酷的流星雨特效,今天来和大家分享下具体实现过程。 1,整体实现思路 这个流星雨特效主要由 HTML、CSS 和 JavaScript 协同完成。HTML 搭建基础结构,CSS 负责页面样式设计,JavaScript 实现星星和流星的动态效果。 效果展示: 用 HTM…...

Apifox=Postman+Swagger+Jmeter+Mock

A. 开发人员接口管理使用(Swagger 工具管理接口) B. 后端开发人员通过Postman 工具&#xff0c;一边开发一边测试 C. 前端开发人员需要Mock 工具提供前端调用 D. 测试人员通过(Postman、Jmeter)等工具进行接口测试 为了后台开发、前端开发、测试工程师等不同角色更加便捷管理…...

SpringBoot多数据源架构实现

文章目录 1. 环境准备2. 创建Spring Boot项目3. 添加依赖4. 配置多数据源5. 配置MyBatis-Plus6. 使用多数据源7. 创建Mapper接口8. 实体类定义9. 测试多数据源10. 注意事项10.1 事务导致多数据源失效问题解决方案&#xff1a; 10.2 ClickHouse的事务支持10.3 数据源切换的性能开…...

HarmonyOS开发:传参方式

一、父子组件传参 1、父传子&#xff08;Prop方式&#xff09; 父组件代码 Entry Component struct ParentComponent {State parentMessage: string Hello from Parent;build() {Column() {ChildComponent({ message: this.parentMessage });}} } 子组件代码 Component s…...

OpenCV计算机视觉 07 图像的模块匹配

在做目标检测、图像识别时&#xff0c;我们经常用到模板匹配&#xff0c;以确定模板在输入图像中的可能位置 API函数 cv2.matchTemplate(image, templ, method, resultNone, maskNone) 参数含义&#xff1a; image&#xff1a;待搜索图像 templ&#xff1a;模板图像 method&…...

国产游戏崛起,燕云十六移动端1.9上线,ToDesk云电脑先开玩

游戏爱好者的利好消息出新了&#xff01;网易大型武侠仙游《燕云十六声》正式官宣&#xff0c;移动端要在1月9日正式上线了&#xff01;你期待手游版的燕云吗&#xff1f;不妨评论区留言说说你的看法。小编分别花了几个小时在台式机电脑和手机上都试了下&#xff0c;欣赏画面还…...

企业级PHP异步RabbitMQ协程版客户端 2.0 正式发布

概述 workerman/rabbitmq 是一个异步RabbitMQ客户端&#xff0c;使用AMQP协议。 RabbitMQ是一个基于AMQP&#xff08;高级消息队列协议&#xff09;实现的开源消息组件&#xff0c;它主要用于在分布式系统中存储和转发消息。RabbitMQ由高性能、高可用以及高扩展性出名的Erlan…...

[OPEN SQL] 限定选择行数

本次操作使用的数据库表为SCUSTOM&#xff0c;其字段内容如下所示 航班用户(SCUSTOM) 该数据库表中的部分值如下所示 指定查询多少行数据&#xff0c;我们可以使用语法UP TO n ROWS来实现对数据前n项的查询 语法格式 SELECT * FROM <dbtab> UP TO n ROWS 参数说明 db…...

Vite源码学习分享(一)

!](https://i-blog.csdnimg.cn/direct/971c35b61c57402b95be91d2b4965d85.png) 同一个项目 vite VS webpack启动速度对比...

定位,用最通俗易懂的方法2:TDOA与对应的CRLB

二郎就不设置什么VIP可见啥的了&#xff0c;这样大家都能看到。 如果觉得受益&#xff0c;可以给予一些打赏&#xff0c;也算对原创的一些鼓励&#xff0c;谢谢。 钱的用途&#xff1a;1&#xff09;布施给他人&#xff1b;2&#xff09;二郎会有更多空闲时间写教程 起因&…...

Linux第一课:c语言 学习记录day06

四、数组 冒泡排序 两两比较&#xff0c;第 j 个和 j1 个比较 int a[5] {5, 4, 3, 2, 1}; 第一轮&#xff1a;i 0 n&#xff1a;n个数&#xff0c;比较 n-1-i 次 4 5 3 2 1 // 第一次比较 j 0 4 3 5 2 1 // 第二次比较 j 1 4 3 2 5 1 // 第三次比较 j 2 4 3 2 1 5 // …...

ExplaineR:集成K-means聚类算法的SHAP可解释性分析 | 可视化混淆矩阵、决策曲线、模型评估与各类SHAP图

集成K-means聚类算法的SHAP可解释性分析 加载数据集并训练机器学习模型 SHAP 分析以提取特征对预测的影响 通过混淆矩阵可视化模型性能 决策曲线分析 模型评估&#xff08;多指标和ROC曲线的目视检查&#xff09; 带注释阈值的 ROC 曲线 加载 SHAP 结果以进行下游分析 与…...

2025年第三届“华数杯”国际大学生数学建模竞赛A题题目

问题A&#xff1a;他能游得更快吗&#xff1f; 背景介绍 在2024年巴黎奥运会上&#xff0c;中国游泳运动员潘展乐凭借出色的表现成为全球瞩目的焦点。年仅19岁的他在男子100米自由泳比赛中以46秒40 的成绩夺冠&#xff0c;并创造了自己保持的世界纪录。在男子4100米混合泳接力…...

用c实现C++类(八股)

在 C 语言中&#xff0c;虽然没有内建的面向对象编程&#xff08;OOP&#xff09;特性&#xff08;如封装、继承、多态&#xff09;&#xff0c;但通过一些编程技巧&#xff0c;我们仍然可以模拟实现这些概念。下面将用通俗易懂的方式&#xff0c;逐步介绍如何在 C 中实现封装、…...

【C++多线程编程:六种锁】

目录 普通互斥锁&#xff1a; 轻量级锁 独占锁&#xff1a; std::lock_guard&#xff1a; std::unique_lock: 共享锁&#xff1a; 超时的互斥锁 递归锁 普通互斥锁&#xff1a; std::mutex确保任意时刻只有一个线程可以访问共享资源&#xff0c;在多线程中常用于保…...

【Javascript Day5】for循环及典型案例

for 循环 // 语法&#xff1a; for( 开始 ; 结束 ; 步长 ){ 循环体 } // for( var i 循环初始值 ; i的循环范围 ; i的增加或减少规则 ){ 循环体 } // 死循环 // for(;;){ // console.log("for循环"); // } // 循环打…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...