小米 机器人操作系统(ROS)开发工程师 面试题精选:10道高频考题+答案解析
一、ROS核心机制(3题)
第1题:请对比ROS 1和ROS 2的核心差异,重点说说当中Master机制的变化以及为什么要这么改?
考察点: ROS框架底层理解、架构演进认知
答案解析:
面试官问这个问题,是想看你对ROS体系有没有深度认知,不是单纯背概念。
先说最关键的——Master没了。ROS 1依赖一个叫roscore的中央节点来做"通讯录",所有节点启动后先去Master注册,Publisher要发布话题得先问Master"谁订了这个话题?",Master告诉它Subscriber的地址,两边才能建连。这就带来几个致命问题:单点故障(Master挂了整个系统崩)、无法跨网络(Master必须统一发现)、没有安全性(谁都能连)。
ROS 2改用了DDS(Data Distribution Service) 作为底层通信中间件。DDS自带分布式发现机制,每个节点启动后通过DDS的Discovery协议自己去发现其他节点,不需要中央节点。这就彻底解决了单点故障,而且DDS原生支持QoS(服务质量配置,比如可靠传输、超时等),也支持跨网络通信和安全加密。
再补充几个重要差异:
-
实时性: ROS 1走TCPROS/UDPROS,没有实时保证;ROS 2基于DDS可以配置实时策略,满足工业级需求
-
跨平台: ROS 2支持Windows、macOS、RTOS,ROS 1只支持Linux
-
Python版本: ROS 1用Python 2,ROS 2至少Python 3.5+
-
Launch文件: ROS 1的launch是XML,表达能力有限;ROS 2改成Python脚本,可以做条件判断、参数计算等复杂逻辑
说到小米,有个很有意思的背景——小米CyberDog(铁蛋)项目在2020年技术选型时,团队内部对用ROS 1还是ROS 2争论了很久。ROS 1生态更成熟,但当时还是二号员工的徐海望力排众议坚持用ROS 2,因为看好它的设计理念——工业化的开发、部署、维护。为了说服大家,他还帮不同方向的同事解决ROS 2的学习问题和bug。小米是国内最早采用ROS 2路线的团队之一,这在面试中提到会很加分。
第2题:请详细解释ROS 2的三种通信方式——Topic、Service、Action,各自适合什么场景?给个实际例子。
考察点: 通信机制理解、场景判断力
答案解析:
这道题几乎是ROS面试必问,但区别在于你能不能说清楚"为什么要有三种"以及"什么时候选哪个"。
Topic(话题): 发布/订阅模式,单向、异步、一对多。Publisher发数据到某个话题上,所有订阅了这个话题的节点都能收到。适合高频、持续的数据流,比如激光雷达的点云数据、IMU的加速度数据、相机的图像流。为什么不用Service?因为传感器数据一秒可能有10次、20次、甚至100次,如果用Service的请求-响应模式,CPU全浪费在握手上了。Topic的设计理念就是"发送端不管接收端是谁",解耦性最好。
Service(服务): 请求/响应模式,双向、同步。客户端发请求,服务端处理完后返回结果,这个过程中客户端会阻塞等待。适合一次性、需要确认结果的场景,比如"打开相机"、"切换到导航模式"、"查询机器人当前电量"。典型的例子是小车上的"急停服务"——上层发一个Stop请求,底层收到后立刻刹车并返回确认。
Action(动作): 双向、异步、带反馈。Action本质上是Service的升级版。Service有硬伤——如果服务端需要执行很长时间(比如让机器人从A点走到B点),客户端会一直等在那儿,既不知道进度也取消不了。Action在Service的request/response基础上增加了feedback(中间反馈) 和cancel(取消)机制。适合长时间执行且需要进度反馈的任务,比如导航("当前走到了30%的位置")、机械臂抓取("手臂正在下降")。
一句话总结: 传感器流用Topic,查询/触发用Service,长时间任务用Action。
第3题:什么是ROS 2的QoS(Quality of Service)配置?在CyberDog这样的四足机器人上,传感器数据和运动控制指令分别该怎么配QoS?
考察点: ROS 2高阶特性、工程实践
答案解析:
这道题区分度很高,只会用默认QoS的人答不上来。
QoS是ROS 2基于DDS层提供的一套通信质量配置参数,让你可以精细控制消息的传输行为。核心配置项包括:
-
Reliability(可靠性): RELIABLE(保证送达,会重传)vs BEST_EFFORT(尽力送达,丢了不重传)
-
Durability(持久性): TRANSIENT_LOCAL(晚订阅也能收到最后一条消息)vs VOLATILE(只收订阅后的消息)
-
Deadline(截止时间): 要求消息在指定时间内送达
-
Liveliness(活性): 检测节点是否还活着
-
History(历史深度): 保留最近N条消息还是全部
在CyberDog这类四足机器人上的典型配置:
激光雷达/深度相机数据 → BEST_EFFORT + VOLATILE
-
点云数据量极大,一秒几十万点,追求Reliable的话网络会炸
-
丢掉一两帧没关系,下一帧马上来,机器人运动很慢,传感器速度远快于场景变化
-
用BEST_EFFORT保证低延迟
摄像头图像 → BEST_EFFORT + VOLATILE
-
类似理由,图像数据量大,追求实时性不追求局部丢帧
运动控制指令(cmd_vel) → RELIABLE + VOLATILE
-
控制指令绝对不能丢,丢了机器人可能撞墙
-
每条都必须送达,所以必须Reliable
-
但不需要持久性,每次都发最新的就行
地图数据(map) → RELIABLE + TRANSIENT_LOCAL
-
地图数据建好后基本不变,后面启动的节点也需要加载
-
TRANSIENT_LOCAL保证晚订阅的节点也能收到整张地图
面试技巧: 如果能结合CyberDog的实际场景说,比如"四足机器人在奔跑时全身12个关节的关节状态数据用BEST_EFFORT发布,因为频率高且丢一帧不影响控制",就很加分。
二、TF变换与导航栈(3题)
第4题:请解释ROS中TF(坐标变换)树的概念。对于一台装有激光雷达的移动机器人,TF树长什么样?map→odom→base_link这三个坐标系是干什么的?
考察点: TF机制理解、导航基础
答案解析:
TF(Transform)是ROS里管理坐标系变换的核心库(ROS 2里是TF2)。机器人身上有各种"坐标系"——机器人的中心叫base_link,激光雷达有自己的坐标系,相机有自己的坐标系,地图也有坐标系。机器人在移动,这些坐标系之间的相对关系在变化,TF就是维护这棵"坐标系关系树"的。
一个典型的移动机器人TF树:
暂时无法在飞书文档外展示此内容
三个核心坐标系的含义:
map(地图坐标系): 固定坐标系,一般是启动时确定的全局坐标原点。它是"绝对参考系"——机器人在世界上的真实位置用map坐标表示。日常不会变。
odom(里程计坐标系): 也是固定坐标系,由里程计驱动维护。它和map的关系是:map→odom的变换由定位模块(比如AMCL或SLAM)持续修正。为什么需要这个中间层?因为里程计会漂移(轮子打滑、IMU误差),但里程计的短期精度很高。odom是"局部平滑的",map是"全局准确的"。这层"双坐标系结构"让导航系统能同时利用里程计的局部平滑性和地图的全局一致性。
base_link(机器人基坐标系): 跟随机器的坐标系,原点一般在机器人底盘中心。所有传感器都相对于base_link定义位置。
核心机制:
-
map→odom:由定位模块(AMCL/SLAM)发布,慢更新但准确,修正里程计漂移
-
odom→base_link:由里程计系统(轮式编码器+IMU融合)发布,快更新但会漂移
-
base_link→sensor:静态变换,在URDF里定义,表示传感器装在机器人什么位置
面试官还想听到你理解"为什么要有map和odom两层"——这是REP 105标准规定的,目的是解耦全局定位和局部里程计的更新频率差异。
第5题:Nav2导航栈的核心构成模块有哪些?从"接到一个导航目标点到机器人到达"的完整流程是怎样的?
考察点: Navigation Stack架构理解、工程实践
答案解析:
Nav2是ROS 2下官方导航框架,接到目标点到实际到达,大致流程如下:
第一步:全局路径规划(Global Planner)
-
收到目标点后,全局规划器(默认是Navfn或Smac Planner)在全局代价地图上规划一条从当前位置到目标点的路径
-
全局代价地图由静态地图层(事先建好的地图)+ 障碍物层组成
-
输出是一条粗糙的全局路径,用A*或Dijkstra算法
第二步:局部路径规划与跟随(Local Planner)
-
机器人开始沿着全局路径移动,但只走一小段(比如前方3-5米范围内)
-
局部规划器(默认是Regulated Pure Pursuit或DWB)在局部代价地图上实时规划
-
局部代价地图更新频率高,包含激光雷达/深度相机检测到的动态障碍物
-
输出是速度指令(线速度+角速度),发布到cmd_vel话题
第三步:行为树控制(Behavior Tree)
-
Nav2用行为树管理导航生命周期,包括"规划→控制→恢复"的决策逻辑
-
如果局部规划器发现走不通(比如前方突然出现一个人),行为树会触发"恢复行为"——比如先停止、后退、旋转再重新规划
-
如果多次重试失败,返回导航失败状态
第四步:定位持续修正
-
整个过程中,AMCL(自适应蒙特卡罗定位)一直在运行
-
它用粒子滤波器将雷达数据和静态地图做匹配,持续修正map→odom的变换
-
这保证了机器人知道自己"到底在哪儿"
核心模块总结:
| 模块 | 功能 |
|------|------|
| AMCL | 粒子滤波定位,输出map→odom TF |
| Planner | A*/Dijkstra全局路径规划 |
| Controller | DWB/Regulated Pure Pursuit局部控制 |
| Costmap | 代价地图(全局+局部),多层感知障碍物 |
| Behavior Tree | 导航决策逻辑编排 |
| Recoveries | 旋转、后退等恢复行为 |
| Map Server | 加载/提供静态地图 |
第6题:AMCL定位的原理是什么?它在系统中负责什么?粒子收敛后,遇到"机器人绑架问题"(Kidnapped Robot Problem)怎么办?
考察点: 定位算法理解、异常处理
答案解析:
AMCL是"自适应蒙特卡罗定位"的缩写,是Nav2标配的二维定位算法。
原理:
-
在全局地图上"撒"大量粒子,每个粒子代表机器人可能的一个位置和朝向(即一个位姿假设)
-
初始时,粒子均匀散布在整个地图上,或者集中在已知的初始位姿周围
-
机器人移动后,通过运动模型给每个粒子更新位置
-
拿到雷达扫描数据后,计算每个粒子位置的"观测似然"——也就是"如果机器人真在这个位置,雷达看到的环境应该长这样,跟实际扫描像不像?"
-
粒子滤波器的"重采样"步骤:高分粒子(像真的)被保留甚至复制,低分粒子被淘汰
-
经过几轮迭代,粒子在真正的位置附近"收敛",形成一个集中的粒子簇
-
"自适应"体现在:粒子数不是固定的,当定位很确定时可以减少粒子(省算力),不确定时自动增加粒子
AMCL在系统中的职责:
-
输出map→odom的TF变换
-
它接收:雷达扫描数据、地图、里程计数据、初始位姿
-
它堵的是"里程计漂移"的窟窿——轮式里程计短期准但长期飘,AMCL用地图修正这个漂移
机器人绑架问题(Kidnapped Robot Problem):
这是定位算法最难解决的问题之一。场景:机器人正常导航中,突然被人抱起来放到另一个位置。AMCL的粒子还集中在原位置,但实际位置变了,定位就丢了。
AMCL处理绑架的方式:
-
随机注入新粒子: 在每次重采样时,会随机在地图其他地方注入一小部分粒子(默认约0.01-0.05的比例)
-
差分布: 如果连续几帧观测到"所有现有粒子的观测似然都很低,但某个新粒子突然拿高分",说明被绑架了,系统会快速收敛到新位置
-
参数调节: recovery_alpha_slow和recovery_alpha_fast两个参数控制了粒子退化速度的监测——当快速退化远大于慢速退化时,说明定位可能在崩,自动增加随机粒子
面试加分: 可以提一下在CyberDog这样四足机器人上,运动模型比轮式机器人更复杂——四足机器人走路有"弹跳""震动",里程计噪声更大,AMCL的参数需要特殊调校。
三、仿真与URDF(2题)
第7题:请手写一个大致的URDF文件结构,描述一个带有激光雷达的两轮差速机器人,需要包含哪些关键元素?joint的类型如何选择?
考察点: URDF建模能力、对机器人运动学的理解
答案解析:
URDF(Unified Robot Description Format)是用XML描述机器人模型的格式。面试官让你手写URDF,目的是看你知道一个完整机器人描述包含什么,以及你对"刚体"和"关节"两个核心概念的理解。
一个典型的两轮差速小车URDF骨架(重点展示关键部分):
暂时无法在飞书文档外展示此内容
Joint类型选择:
| 类型 | 说明 | 适用场景 |
| fixed | 固定连接,两个link间无相对运动 | 激光雷达、相机等传感器支架 |
| revolute | 旋转关节,有限角度范围 | 机械臂肘关节(-90°~90°) |
| continuous | 连续旋转关节,无角度限制 | 车轮、四足机器人髋关节 |
| prismatic | 滑动关节,沿一个轴直线运动 | 伸缩臂、电梯机构 |
| planar | 平面关节,2D平移+1个旋转 | 很少用 |
| floating | 6自由度浮动关节 | 很少用,一般用TF替代 |
面试Tips:
-
别忘了inertial标签——Gazebo仿真需要质量+惯性矩阵,否则物理引擎报warning
-
collision和visual可以不同,比如用简单形状做碰撞检测,复杂模型做可视化
-
描述四足机器人时,每条腿至少3个关节(hip/ thigh/calf),关节类型分别是continuous(hip旋转轴)、revolute(大腿前后摆)、revolute(小腿前后摆)
第8题:你在做Gazebo仿真的时候遇到过哪些坑?怎么把一台在Gazebo里跑得好好的机器人模型,正确部署到小米CyberDog这种真实机器上?
考察点: 仿真→真实迁移(Sim2Real)经验、工程问题解决能力
答案解析:
这道题面试官想听你踩过的坑,不是背诵知识点。说真话最打动人。
Gazebo常见坑:
1. 物理参数不对导致机器人"飞天"或"钻地"
-
惯性矩阵算错了,机器人一启动就抽风。解决方案:核对SolidWorks/Onshape导出数据和URDF里的inertial值是否一致
-
mu1、mu2摩擦系数设得太小,机器人原地打滑走不动;设得太大,转弯甩不过来
-
悬架刚度(stiffness / damping)不对,车体一直在抖
2. PID参数在仿真和真机上天差地别
-
仿真里的电机模型太理想,PID随便调就稳。上真机后同样的P值会导致振荡甚至电机烧掉
-
解决方案:仿真中故意加入噪声和延迟,或者用"先调D、再调P、最后调I"的顺序
3. 传感器噪声模型设置不当
-
仿真里雷达扫描"完美"无噪声,上真机后完全定位不准
-
应该在Gazebo里给激光雷达配置高斯噪声,模拟真实传感器的测量误差
仿真→真实迁移的关键步骤:
第一步:硬件抽象层替换
-
仿真中机器人通过diff_drive_controller和gazebo_ros_control与物理世界交互
-
上真机后,这部分要换成真实的电机驱动节点,通过CAN总线或串口跟电机通信
-
硬件抽象层(HAL)要设计好接口——控制指令格式、反馈数据解析
第二步:Sensor驱动替换
-
仿真中的雷达数据来自gazebo_ros_laser插件,上真机后换用真实雷达厂商的ROS驱动
-
注意frame_id要一致,如果真机雷达的坐标系和仿真里不同,TF就会错乱
第三步:参数标定
-
里程计参数(编码器线数、轮子直径、轮距)必须和真实硬件严格一致,否则TF和odom全错
-
关节限位(soft_limits)要跟实际电机行程匹配
-
IMU的安装方向、零偏值需要实际标定
第四步:网络和延迟适配
-
仿真里所有节点在同一台机器上,没有网络延迟
-
真机上控制节点在板载计算机、电机驱动在MCU、视觉处理可能在另一台设备,网络延迟变了
-
QoS参数可能需要从BEST_EFFORT改成RELIABLE或者调整Deadline
第五步:逐步替换,分模块验证
-
不要"一把梭"全部替换到真机
-
建议顺序:底盘驱动验证 → 里程计验证 → 雷达驱动验证 → 定位验证 → 导航验证 → 完整功能验证
-
每替换一个模块,都在真机上跑一遍基础测试
说到小米: CyberDog团队当初在仿真→真机迁移中也踩了不少坑,比如ROS 2早期版本在WiFi切换时会崩溃(从WiFi切到手机热点),团队花了一天一夜从底层改DDS源码才解决。这种"踩坑→解决"的故事,在面试中说出来非常加分。
四、系统设计(2题)
第9题:如果要你在CyberDog四足机器人上设计一个"自主跟随"功能(人走到哪狗跟到哪),请画出完整的ROS节点/话题架构并说明数据流。
考察点: 系统设计能力、架构思考、工程落地
答案解析:
这道题是开放题,没有标准答案,但面试官看的是你的"架构感"——能不能把感知、决策、控制串起来。
完整架构设计:
暂时无法在飞书文档外展示此内容
数据流说明:
-
感知阶段: 深度相机数据→YOLOv8检测到人→输出人的2D框→逆投影到3D空间得到人的位置(PointStamped);同时激光雷达数据被用于障碍物级+人的辅助追踪
-
追踪阶段: PersonTrackNode用卡尔曼滤波对目标位置做平滑、预测,消除检测抖动和偶然漏检
-
决策阶段: FollowBehaviorNode维护一个"期望跟随距离"(如1.5米),根据实际距离计算目标点——人在前方1.5米处就是目标点,保持人和机器人的相对方向
-
导航阶段: 调用Nav2的NavigateToPose Action,把/follow_goal传给Nav2。关键点:目标要持续更新,但不能太频繁(否则路径规划一直在重新算),每秒刷新2-3次比较合理
-
恢复机制: 如果跟丢目标(连续5秒没检测到人),启动"原地旋转搜索"模式;如果超过10秒还是找不到,停止并上报状态
需要重点考虑的Edge Cases:
-
人被遮挡时怎么处理 → 结合卡尔曼预测状态保持跟随
-
人突然转向时响应速度 → 通过预测+方向变化检测提前响应
-
前方有障碍物时是否绕行 → Nav2自带避障,但需要调整"与人保持安全距离"的规划参数
-
楼梯/斜坡等复杂地形 → 四足机器人通过性比轮式好,但可能需要切换步态
五、场景应用(1题)
第10题:你在实际ROS开发过程中,遇到过一个印象最深的技术难题,你是怎么一步一步定位并解决的?
考察点: 实际问题排查能力、工程经验、系统性思维
答案解析:
这道题面试官其实不是在问技术细节,而是在考察你的故障排查方法论。建议用"STAR法则"(Situation-Task-Action-Result)来讲。
可以参考的思路(以一个实际难题为例):
问题背景: 一个四足机器人在跑步模式下,每隔几分钟会出现一次"突然跛行"——某条腿动作异常,持续几百毫秒后恢复。传统方法加日志很难捕捉。
排查过程(由易到难):
Step 1:确定是硬件还是软件问题
-
先跑简单的"单腿画圈"测试,确认关节电机和编码器本身没问题
-
用示波器抓电机端的CAN数据,信号正常
-
排除硬件故障
Step 2:定位到ROS 2通信卡顿
-
用ros2 topic hz和ros2 topic delay监控关节控制话题的频率和延迟
-
发现异常时刻:关节控制话题的发布频率从正常的500Hz突然掉到200Hz
-
进一步用ros2 topic bw查看带宽占用
Step 3:追根溯源到QoS堵塞
-
发现原因是某一路传感器数据量暴涨(比如深度相机在强光下输出异常多的点云)
-
这条高速传感器话题吃了大量DDS缓冲区,影响了Control指令的传输
-
传感器和控制话题在同一Network Partition里
解决方案:
-
分离资源: 将传感器数据和控制指令放在不同的DDS分区(Partition),保证控制通道不受影响
-
调整QoS: 传感器话题改用BEST_EFFORT降低带宽占用;控制话题用RELIABLE+设置Depth=1(只保留最新一条)
-
添加保护机制: 在传感器节点中增加"流量整形"——如果传感器数据超过阈值,自动降采样
-
增加监控: 添加/system_status话题,定期发布各节点的CPU占用、内存、话题延迟等健康数据
复盘总结(面试官想听的部分):
-
排查时要"先怀疑自己、再怀疑别人、最后才怀疑硬件"
-
善用ROS 2的调试工具链:rqt_graph看拓扑、ros2 topic hz/delay/bw做定量的通信分析
-
四足机器人对实时性要求极高,500Hz的关节控制频率下,任何通信延迟都会导致"跛行"
-
学到的一点:不要迷信DDS的默认配置,一定要根据实际场景调优QoS
面试注意: 如果没做过四足机器人,可以说一个类似的ROS项目排故经历,关键是要有"定位过程"和"方法论总结",而不是只讲现象不分析。
总结
小米作为国内最早采用ROS 2路线的机器人团队之一,从CyberDog到CyberOne,面试中非常看重:
-
工程实践能力 — 不止于"会调包",要看你能不能独立搭建系统、解决实际问题
-
底层理解 — ROS 2的DDS、QoS、TF、生命周期管理这些如果你只会表层,大概率被淘汰
-
系统思维 — 能不能把感知→决策→控制串起来,能不能识别架构层面的问题
-
踩坑经验 — 面试官更愿意听你"遇到什么困难怎么解决"的故事,而不只是背八股
祝面试顺利!
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)