ROS 是什么、为什么需要它:从零理解机器人操作系统(一)

ROS并非传统操作系统,而是运行于Linux之上的机器人软件中间件,提供硬件抽象、进程间通信(Topic/Service/Action)、工具链与包管理。本文厘清其非OS本质、解决的协作复用问题、ROS 1与ROS 2架构差异(Master vs DDS)、计算图核心概念及适用边界,强调ROS 2 LTS为新项目首选,ROS 1已终止支持,并指出其在数据采集平台中作为标准接口与rosbag数据源的关键作用。

ROS 是什么、为什么需要它:从零理解机器人操作系统(一)

通用基础优先 · 第一篇|ROS 通识系列|事实基线:2026-10-24

一图读懂本文:五节要点 + 数采平台衔接 + 新手/老手双视角。先看图建立框架,再逐节展开。

做数采平台这段时间,我发现一个绕不开的事实:机器人本体的控制与数据采集,天然是建立在 ROS 之上的。乐聚 KUAVO 的 SDK 是 ROS 1,主流采集链路 rosbag → parquet → LeRobot 也以 ROS 话题为基本数据单元。所以这套系列,先从"ROS 到底是什么"讲起——不急着敲命令,先把心智模型立住。

一、一句话理解:ROS 不是操作系统

名字里带"OS",但它不是像 Windows、Linux 那样的操作系统。准确地说,ROS(Robot Operating System)是一套运行在 Linux 之上的"机器人中间件 / 元操作系统":

  • 它提供硬件抽象(不用关心"这款相机/那款电机的驱动细节");
  • 提供进程间通信框架(节点之间怎么传数据);
  • 提供一套工具链(可视化、调试、录制回放、包管理)。

你可以把它类比成"机器人界的 Spring + RPC + 一堆运维工具"——它管的是怎么把一堆零散的传感器、控制器、算法模块,组织成一个能协同工作的系统。

记牢这一点:ROS 跑在 Linux(几乎都是 Ubuntu)上,它解决的是"机器人软件怎么分工、怎么通信、怎么复用",而不是"怎么调度 CPU/内存"。
新手视角 · 用一栋楼记住它的位置:把机器人软件想成一栋楼——Linux 是地基(管 CPU、内存、驱动),ROS 是水电管网 + 楼层指示牌(让各楼层之间通水通电、互相找得到人),你的算法是各个房间里的住户。ROS 不替你算账(识别、规划都是你的算法),它保证的是"谁都能找到谁、数据送得到、工具都现成"。

二、为什么需要 ROS:没有它会发生什么

假设没有 ROS,你想让一台机械臂"看到零件→算坐标→抓取",得自己从头写:

  • 相机驱动 → 自己解析 USB/网络协议;
  • 图像处理模块 → 和主控怎么传图?(共享内存?socket?)
  • 运动规划 → 和底层控制器怎么通信?
  • 多个模块之间的启动顺序、命名、错误处理全得手写。

结果就是每个团队、每台机器人都重复造轮子,而且造出来的"轮子"彼此不兼容。ROS 的价值正在于此:

痛点ROS 给的解法
硬件驱动各自为政统一的消息接口(camera_info、Image、JointState…)
模块间通信无标准Topic / Service / Action 三种标准通信原语
没有现成工具rviz 可视化、rqt 调试、rosbag 录制、rosnode 探查
算法难复用以"包(package)"为单位的生态,官方索引几万个包

对我们数采平台来说,ROS 意味着:只要本体暴露了标准的 ROS 接口,我们的采集、转换、适配层就能跨品牌复用——这正是项目"统一动作空间 / retargeting"思路的底层支撑。

老手温故 · ROS 凭什么成为事实标准:不是单项技术最强,而是"开放 + 生态"——开源协议宽松、以包(package)为单位共享、学术圈习惯把论文代码做成 ROS 包发布(MoveIt、Nav2、各类传感器驱动)。工程选型的可执行顺序:先查生态里有没有现成包 → 再看包的维护活跃度 → 最后才考虑自研。反过来,凡是生态没覆盖的部分(比如 1kHz 硬实时电流环),就别指望 ROS 兜底——这条边界越早认清,架构越稳。

三、发展简史与发行版:为什么今天要分 ROS 1 和 ROS 2

ROS 始于 2007 年 Willow Garage,2010 年开源。早期版本(Indigo、Kinetic、Melodic…)统称 ROS 1。它的通信依赖一个中心节点 roscore(ROS Master),用自研的 TCPROS/UDPROS,实时性和嵌入式支持较弱。

2017 年起推出 ROS 2,底层换成工业级 DDS(Data Distribution Service)中间件,解决了 ROS 1 的多机器人、实时性、嵌入式三大短板。关键时间线(来源 docs.ros.org / endoflife.date):

发行版类型发布支持截止备注
ROS 1 Noetic最后 ROS12020-052025-05 EOL整个 ROS 1 线已终结
ROS 2 HumbleLTS2022-05-232027-05-31Ubuntu 22.04
ROS 2 JazzyLTS(推荐)2024-05-232029-05-31Ubuntu 24.04
ROS 2 Kilted短期版2025-05-23~2026 年底非 LTS,迁移不选它
ROS 2 LyricalLTS(最新)2026-05-222031-05-31偶数年 LTS

注:ROS 2 每年 5-23 发版,偶数年 LTS(支持 5 年)、奇数年普通版(1.5 年)。KUAVO 当前仍是 ROS 1,所以本系列对两者都会覆盖。

选型结论(给团队):新项目优先 ROS 2 Jazzy(推荐 LTS) 或 Lyrical(最新 LTS);已有的 ROS 1 设备(如 KUAVO)用 ros1_bridge 桥接,逐步迁移,不要一次性重写。
老手温故 · "LTS 到底意味着什么":ROS 2 发行节奏固定为每年 5 月 23 日发版,偶数年 LTS(支持 5 年)、奇数年普通版(约 1.5 年)。LTS 对生产环境的意义是持续的安全补丁 + 官方二进制包(apt 可装)。可执行规则三条:生产环境只绑 LTS;实验验证追 Rolling;短期版(如 Kilted)永远不写进交付文档。另外注意:ROS 2 不同发行版绑定的 Ubuntu 版本是锁死的(如 Jazzy→24.04),选发行版 = 连操作系统一起选。

四、核心架构全景:ROS 计算图(Computation Graph)

ROS 系统运行时,是一张由"计算图"组成的网络。无论 ROS 1 还是 ROS 2,下面这几样是必须建立的底层概念:

相机节点
识别节点
规划节点
控制节点
↓ 全部连到 ↓
Master / DDS Domain(通信中枢)
① Node(节点)
一个独立进程,干一件事(如"读相机""跑识别")。系统由很多松耦合的 Node 组成——这就是"分工"。
② Master / Domain(通信中枢)
ROS 1 靠中心化的 roscore(ROS Master)做名字登记;ROS 2 靠 DDS 的 Domain 做去中心化发现。这是 ROS 1 与 ROS 2 最本质的架构差异。
③ Topic(话题)—— 异步发布/订阅
流式数据走这里:相机图像、关节角度、力传感器读数,都是"持续广播、谁想听谁订阅"。一对多、多对多。
④ Service(服务)—— 请求/响应
一次性问答:"现在关节角多少?""把夹爪张开到 50%"。同步、双向。
⑤ Action(动作)—— 长任务 + 反馈
耗时任务专用:"抓取这个零件",过程中持续回报进度,结束才给最终结果。比 Service 更适合机器人动作。
⑥ Message(消息)—— 数据的"类型定义"
Topic/Service/Action 里传的不是裸字节,而是有结构的 .msg / .srv / .action 接口。跨品牌统一,先统一接口。
⑦ Parameter(参数)—— 运行时配置
频率、标定系数、开关等"配置项"集中管理,不用改代码重编译。
⑧ Bag(数据包)—— rosbag
把 Topic 流录下来,事后回放。这是数采平台的数据来源:录 → 转 parquet → 进 LeRobot。
新手视角 · 用"一家餐厅"记住计算图八要素:Node=厨师/服务员(各干各的);Topic=传菜口(菜好了放上去,谁需要谁端走);Service=点单(问一句"有没有鱼",后厨立刻答);Action=等一道大菜(下单后能看到"正在炖"的进度,还能取消);Parameter=菜单规格(辣度、份量,不改菜谱就能调);Bag=监控录像(把传菜口全天录下来,事后回放)。一家餐厅这样运转,一台机器人也这样运转。

图:ROS 计算图最小全景。下一篇会逐个拆开,并用命令行 `rosnode` / `rostopic` 实际探查一张图。

五、适用边界与常见误区

ROS 很强,但不是银弹,提前认清边界能少踩很多坑:

  • 误区 1:ROS 能跑实时控制。→ ROS 1 不行;ROS 2 借助 DDS + 底层实时内核接近实时,但 1kHz 电流环这类硬实时仍需底层控制器兜底(和我们之前分析"小脑不会消失"一致)。
  • 误区 2:用了 ROS 就自动跨平台。→ 接口语义要自己统一,ROS 只提供"通信管道",不保证"两边说的同一种话"。
  • 误区 3:ROS 1 还能长期用。→ Noetic 已于 2025-05 EOL,新设备不应再选 ROS 1。
老手温故 · 实时性的三层拆法(架构设计第一题):①硬实时(1kHz 电流环)——RTOS/实时内核 + EtherCAT 总线,ROS 不碰这条线;②软实时(100Hz 关节指令、30-50Hz 视觉伺服)——ROS 2 + DDS + RT_PREEMPT 内核可以稳定做到;③非实时(任务规划、VLA 推理、日志上云)——普通 Linux 即可。拿到任何一条链路,先判断它属于哪一层、该放在哪个进程/哪台机器上,这是机器人软件架构的第一个设计决策。

六、本系列后续与数采平台的衔接

接下来我们会按这条线推进:

  1. 02 核心概念与计算图:把上面的 8 个概念拆细,用命令行实跑;
  2. 03–04 通信机制:Topic / Service / Action 逐个讲透,配最小 demo;
  3. 10 rosbag:直接落到 rosbag → parquet → LeRobot 的数采实战;
  4. 13–14 ROS2 与落地:评估 KUAVO 链路是否迁 ROS 2,给出 adapter 层设计。

读者只要跟着把 01、02 读透,再配合每篇的小 demo,就能在数采平台上"看得懂、改得动、采得来"。

七、小结

  • ROS 是中间件,不是操作系统,跑在 Linux 上;
  • 它用节点 + 三种通信原语(Topic/Service/Action)+ 统一消息接口,解决机器人软件的分工与复用;
  • ROS 1 已 EOL(2025-05),新项目上 ROS 2(Jazzy / Lyrical LTS),老设备用 ros1_bridge 过渡;
  • 对我们有什么用:rosbag 是数采数据的源头,统一 ROS 接口是跨品牌适配层的地基。
参考资料:ROS 官方文档 docs.ros.org(Distributions);endoflife.date/ros2;endoflife.ai "ROS Noetic Is EOL"。版本事实截至 2026-10-24。下一篇:《ROS 核心概念与计算图(二)》。
深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值