UWB自动跟随避障系统:从硬件选型到算法调试全解析
发布时间:2026/10/4 9:36:17 作者:尧图编辑部 阅读量:1,286

从很早起我就对“会自己跟着人走”的设备特别感兴趣。不管是机场里那种能跟着旅客走的智能行李箱还是仓库里自动跟着拣货员跑的物料小车背后都绕不开两个核心问题一是怎么精确知道目标在哪儿二是怎么在跟着走的时候不撞上障碍物。这两年UWB技术逐渐从门禁、室内定位这类场景下沉到机器人控制领域让“自动跟随避障”这件事的落地门槛降低了不少。我断断续续研究这个方向半年多基于UWB技术搭了一套自动跟随避障系统从硬件选型到算法调试踩了不少坑这篇就把整套设计研究过程完整拆开讲一讲。这套系统解决的核心痛点很直接传统的跟随方案要么依赖视觉识别容易受光线和遮挡影响要么用蓝牙RSSI做距离估算精度飘得离谱经常跟丢。UWB超宽带测距走的是飞行时间法误差能控制在厘米级而且对非视距场景的容忍度明显好于蓝牙这就让“稳定跟随”成为可能。整个项目适合正在做机器人、智能硬件、嵌入式毕设或者产品预研的开发者参考内容涵盖了原理选型、硬件搭建、算法设计到实车调试的全链路不需要你已经有很深的基础跟着思路走就能复现。1. 整体方案怎么定下来的为什么偏偏选UWB1.1 几种主流跟随方案对比UWB赢在哪自动跟随领域不是什么新技术但市面上成熟的方案无外乎那么几类。我在项目启动前先把主流路线盘了一遍这步真的省了很多后期返工的麻烦。第一类是纯视觉方案。典型做法是用摄像头配合目标检测模型框出目标人物然后用像素偏移量推算相对方位。这套方案的优势是能拿到丰富的外观信息但短板同样明显光照一变化识别就抖动目标转身或者被遮挡时容易丢框而且对算力平台有要求——我用过树莓派跑轻量模型帧率上去了功耗也上去了续航堪忧。如果只是做固定场景的实验室demo倒可以真要跟着人走出户外或者绕来绕去会特别痛苦。第二类是蓝牙RSSI方案。原理是通过接收信号强度反推距离成本极低但精度真不敢恭维。我实测过在普通房间里蓝牙RSSI的波动有时候能到两三米这个精度做跟随基本等于盲走经常出现小车突然往前冲又突然刹停的抽搐动作体验非常差。第三类就是UWB方案。UWB测距用的是双向飞行时间法两个模块之间通过发送纳秒级脉冲并计算飞行时间再乘上光速得到距离理论精度能做到厘米级。相比RSSI靠强度估距离飞行时间法不依赖信号衰减模型所以受环境干扰的影响小得多。实际测试下来在普通室内走廊里我那块DWM1000模块的静态测距波动基本能稳定在正负10厘米以内这个精度做跟随控制才有“值得调算法”的价值。当然UWB也不是完美的它只能给出距离信息不能像雷达一样直接给你角度。所以大多数工程落地都做成“双基站三角定位”或者“单标签多锚点”的组合我也是这么处理的后面会详细讲。1.2 系统架构分层让每个模块各司其职整套系统的设计我按照工业界惯用的“感知-决策-执行”三层来拆这么做的好处是调试时可以单独定位问题到底出在哪个环节不用每次抱着一坨代码和一堆线从头捋。感知层负责两类信息一是UWB基站读取到的目标距离数据我用了两个接收端放在小车左右两侧利用距离差换算出目标相对车体的角度二是避障传感器群我在车头装了三个超声波模块覆盖左、中、右三个方向保证低速前进时能及时发现障碍物。决策层跑在单片机上核心是两个逻辑优先避障其次跟随。也就是说避障的优先级永远高于跟随指令一旦超声波检测到近距离障碍物无论目标往哪走小车必须先减速或转向这个策略后面在算法部分会细说。执行层就是电机驱动加两个直流减速电机通过差速转向实现前进、后退、左右转。整个链路看起来不复杂但真正让系统稳定跑起来关键在每层之间数据怎么同步、怎么处理延迟这恰恰是很多教程不谈的东西。2. 硬件选型与关键参数计算2.1 主控、UWB模块、避障传感器怎么搭配主控我选了STM32F103C8T6也就是俗称的“蓝丸”核心板。选它不是因为性能多强而是因为生态太成熟了网上资料铺天盖地遇到问题搜一下基本都有答案。UWB模块用的DWM1000这是Decawave的经典方案我买的是集成了天线的成品模块省去了自己画射频电路的麻烦。通信距离空旷环境下大概能到三四十米室内隔一堵墙也能稳住足够跟随小车用了。避障部分我同时用了超声波和激光ToF两种传感器做对比测试。超声波用的是HC-SR04便宜、触发简单但有个很要命的特性它对斜面障碍物特别不敏感如果障碍物是个倾斜的板子声波反射到别处去了它就可能完全测不到。所以后来我增加了VL53L0X激光测距模块这是一颗很成熟的ToF传感器测距范围虽短两米左右但胜在波束窄、不受颜色和表面材质影响。最终方案是超声波为主、激光ToF为辅两个数据做交叉验证有效降低了漏检率。电机驱动用的TB6612FNG比老掉牙的L298N效率高不少。供电方面我给电机单独用了一块7.4V锂电池主控和传感器则通过降压模块稳定在5V这样电机启动时的大电流不会直接拉垮单片机的供电电压。2.2 跟随角度解算双基站距离差怎么用这是整个系统里最值得琢磨的部分。单靠一个UWB基站你只能知道目标离你多远但不知道它在左边还是右边所以我在车体左右两侧固定了两个接收基站间距设为30厘米。目标身上带一个UWB标签持续向外广播测距帧。当目标正对着小车时两个基站测出来的距离基本一样当目标偏左时左侧基站距离更近。利用这个距离差加上两个基站之间的固定间距就可以用几何关系估算出目标相对车体的偏转角度。这里直接套一个近似公式就行。设两个基站间距为d左右测距值分别是L1和L2角度θ近似等于arcsin((L2-L1)/d)。实际使用中我不会让程序去跑完整的反正弦函数而是做了一个查表加线性插值既省了单片机算力响应速度也更快。角度出来之后跟随控制的误差量就有了。我设定理想跟随距离为1.2米角度误差控制在正负15度以内就算“跟得正”超出这个范围就加强转向力度。2.3 测距频率和移动速度的匹配关系UWB模块的测距频率不能无脑调高。DWM1000支持的最大测距频率可以做到几十赫兹但频率越高功耗越大而且模块的响应也可能不稳定。我在项目里把标签的广播频率设在了10Hz也就是每100毫秒刷新一次距离值。10Hz看起来不高但配合小车的实际移动速度我限制最大前进速度0.5米/秒是够用的。简单算一下每100毫秒小车最多前进5厘米而UWB测距的静态误差就有正负10厘米也就是说单次测距的误差已经大于两次测距间隔内的实际位移再提高频率对控制精度的提升也不明显反而徒增功耗。真正影响跟随稳定性的不是测距频率而是控制算法的平滑处理这部分我在后面会讲。3. 跟随与避障的算法实现核心逻辑从头捋3.1 简单实用的位置闭环控制PID怎么调很多做UWB跟随的教程一上来就搬出复杂的卡尔曼滤波、粒子滤波说实话在单片机资源有限的情况下这些算法不仅难调还可能因为模型不准适得其反。我第一版就用了最经典的PID控制实际效果已经足够稳。具体做法是把角度偏差作为P项的主要输入偏差大就加大转弯速度距离偏差作为另一个独立的P项控制前进速度。比如目标距离大于1.2米就前进小于1米就减速甚至后退在1到1.2米之间基本维持匀速。D项我加了一个较小的微分系数用来抑制角度抖振。因为UWB测距即使静态也会有小幅波动如果只靠P项电机响应会跟着测距噪声一起抖小车会表现得神经质。D项相当于给“速度变化”加了阻尼实测下来能把车身的来回晃动抑制掉一大半。I项在跟随场景里我直接设为零。原因很简单这个系统没有长期的稳态误差需要消除目标位置一直在变积分项反而容易造成超调。如果以后做“定点停靠”类功能那时候再考虑I项不迟。3.2 避障优先级如何压过跟随指令避障逻辑的优先级是我在设计时特别强调的一点。我的处理方法是加了一个“仲裁层”每一控制周期先读超声波和激光传感器的数据只要有一个传感器测到障碍物距离小于30厘米就立即跳过跟随控制逻辑进入避障逻辑。避障逻辑本身不复杂左侧障碍物近就往右转右侧障碍物近就往左转三个方向都近就原地停下。真正要注意的是避障和跟随之间的切换不能太生硬不然小车会在脱离障碍物之后突然猛加速追目标。我的做法是在避障动作结束之后加了一个“恢复计时器”。避障结束后至少300毫秒内前进速度只允许恢复到原来速度的50%然后慢慢爬升回正常值。这个小技巧让整个跟随过程平滑了很多不会出现避障后突然窜出去撞到下一个障碍物的情况。3.3 核心控制代码思路伪代码级别的实现逻辑我没有贴完整工程代码太长但把主循环的逻辑写成伪代码级别的流程照着搭就行主循环每50ms执行一次 读取UWB左右基站距离 L1, L2 计算目标角度 theta 查表角度(L1, L2) 计算目标距离 dist (L1 L2) / 2 读取超声波避障距离 obs_left, obs_mid, obs_right 判断是否有障碍物触发距离 30cm 如果有障碍物 执行避障转向动作左转/右转/停车 设置恢复计时器 300ms 否则 如果恢复计时器 0: 限制最大前进速度为正常值的50% 递减恢复计时器 否则 正常执行跟随控制 跟随控制 角度误差 e_theta theta - 目标角度(0度) 距离误差 e_dist dist - 目标距离(1.2m) 转向速度 Kp_theta * e_theta Kd_theta * (e_theta - 上次e_theta) 前进速度 Kp_dist * e_dist带限幅 0 ~ 0.5m/s 输出到电机驱动左轮 前进速度 转向速度 右轮 前进速度 - 转向速度这套逻辑实现起来大概四五百行代码就能跑通关键在参数标定和不同场景下的调试。我调参是按“先调转向、再调速度、最后调平滑”的顺序来的每次只动一个变量这样可以避免参数之间互相干扰出了问题也知道是哪个环节的锅。4. 实车调试过程与踩坑实录4.1 UWB天线位置和朝向比想象中影响更大我最开始把两个UWB接收基站直接平放在车体底盘上天线朝上结果测距数据一个劲儿地乱跳。后来翻模块的数据手册才意识到DWM1000的板载天线辐射方向图并不是全向均匀的天线面朝上时水平方向正好处于辐射图的凹陷区域信号质量和测距稳定性都差。后来我把两个基站竖起来安装天线面垂直于地面并且尽量让两个天线之间的间距保持在同一水平线上测距数据立刻稳定了不少。这个细节在项目后期排查问题时帮了大忙——如果你的UWB数据抖动得厉害先检查天线朝向比去调什么滤波器都管用。还有一个经验是两个接收基站不要挨得太近。我最初间距只留了10厘米结果角度解算的分辨率特别低目标稍微动一下角度就跳好几度。拉到30厘米之后角度分辨率明显改善跟随时的转向动作也细腻了很多。我按公式简单算过基站间距太小的情况下同样的距离测量误差换算出来的角度误差会被放大所以30厘米大概是这个车型的一个经验底线。4.2 常见问题速查表这几类坑基本必踩我在调试过程中整理了一份问题速查表基本覆盖了常见翻车现场直接照着排查能省下大量时间症状可能原因处理方法测距数据周期性跳变天线朝向不对或周围有金属遮挡调整天线朝向让天线面垂直地面并避开金属物体小车跟着跟着突然原地打转角度解算噪声大微分项过于敏感降低Kd_theta系数或者对角度数据做滑动平均滤波跟随时走走停停、顿挫感强距离控制P项太激进调低Kp_dist限制前进速度变化率避障功能偶尔失效超声波对斜面物体不敏感增加激光ToF做交叉验证或者调整探头安装角度电机启动瞬间单片机重启供电不足电机启动电流拉低电压电机独立供电或者加大主控供电电容这里重点说一下滑动平均滤波。我最初用的是一个长度为5的滑动窗口对角度数据做平均效果很好但响应延迟也随之增加。后来改成“加权滑动平均”最新的数据权重最高老数据权重递减这样既压住了噪声延迟也只多了一个周期左右算是性价比很高的方案。4.3 室内、室外、金属环境下的参数微调心得不同的环境对UWB测距的影响差异很大我在项目里做了几次对比测试。空旷室外环境下多径干扰很小测距数据最干净跟随效果也最好前提是天线朝向正确。普通室内环境下墙面反射会带来一定的多径干扰尤其是靠近墙角时测距偶尔会突然跳变一二十厘米。这种情况靠滤波基本能扛住但要注意如果周围环境变化频繁比如有人走动还是需要预留一点“容错空间”也就是关联性判断如果某次测距值和上一帧差了超过30厘米就直接忽略这一帧防止控制量突变。金属环境是最头疼的。UWB信号碰到大面积金属平面会产生反射测距结果容易出现“飞点”。我在一个金属货架旁边测试过测距值偶尔会突然变大几十厘米这时候光靠滤波已经不够了。临时补救方案是把避障传感器的触发距离适当调大靠避障来兜底长期方案还是要做多基站冗余或者加数据融合但这已经超出这个项目的范围了算是我留给下一步的拓展方向。4.4 跟随标签的信号丢失与找回策略还有一类问题必须在设计阶段就想清楚UWB信号偶尔会丢。标签电量低、目标走到墙角、或者模块正好处于天线辐射盲区都会导致测距数据长时间不更新。我是这样处理的程序里维护一个“最后有效数据时间戳”如果连续500毫秒没有收到新的距离数据就判定为信号丢失。这时候小车不会傻乎乎地继续往前冲而是先减速停车原地等待1秒如果还没恢复信号就原地缓慢旋转搜索目标直到重新锁定距离数据才恢复跟随。这个策略实测下来很稳。有一次我带着标签从走廊拐进办公室信号被墙体阻断小车在走廊里停了半秒然后自动转了90度继续跟进来整个过程没有撞墙体验还是不错的。需要注意的是旋转搜索的速度不能太快否则即使收到数据也容易因为过冲而再次丢失我最后把转速限制在每秒30度左右。5. 项目效果复盘与后续可扩展方向整套系统最终跑下来的效果我已经比较满意了在普通室内环境下跟随响应距离误差能控制在正负20厘米以内转弯跟随时不会把目标跟丢遇到突然出现的纸箱、椅子也能及时减速避让。对于一套用成品模块加单片机搭起来的低成本方案来说这个表现完全够用。真要说还有什么不足我觉得有两个点比较值得后续优化。第一是UWB测距偶尔出现的飞点问题哪怕是加了关联性判断在复杂金属环境里还是有漏网之鱼。后续可以考虑把IMU惯性测量单元的数据融合进来用加速度和角速度做短时预测对UWB的跳变做校验能做掉很大一部分飞点。第二是动态目标的跟踪模型。我现在用的是目标保持静止的测距假设但实际跟随的人一直在走动测距值本身就包含了目标运动的信息。如果后续引入简单的运动状态估计比如卡尔曼滤波或者更轻量的平滑算法那么目标突然加速、急停、拐弯这些场景都能处理得更细腻小车动作也不会有明显的“反应慢半拍”的感觉。从成本角度看整套系统的物料成本控制在一千元以内核心部件就是UWB模块和单片机剩下的传感器和车体都是常见件。这个性价比对于产品原型验证、课程设计、甚至小批量定制设备来说都是很有吸引力的。我自己的体会是UWB作为一个“测量距离的传感器”配合合理的控制策略能做出很多体验远超蓝牙方案的交互产品。但它不是万能的必须搭配避障传感器、合理的系统架构和充分的场景测试才能真正变成一个可靠的产品。这个项目做完之后我对硬件系统的“模块化思维”有了更深的理解——每一个部件都像积木一样各司其职但真正让它们协同工作的永远是连接处的那一层设计思考。