ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

两轮车隧道与地下车库导航:GPS丢失下的组合导航与地图匹配

两轮车隧道与地下车库导航:GPS丢失下的组合导航与地图匹配 跑两轮车导航这块有几年了被问得最多的一个场景就是从隧道口钻出来那一瞬间导航箭头先卡住不动然后猛地弹到两三百米开外路线重新规划语音提示乱报一遍。地下车库更夸张进场时还在正常导航出场时箭头干脆停在入口那一格不动得等十几秒才慢慢爬回来。这类问题的根源都指向同一件事——GPS信号丢失期间导航系统没有能力自己接着往下算。这篇文章就围绕两轮车这个特殊载体把隧道、地下车库、高架桥下、密集楼宇夹缝这些遮挡场景下的导航连续性问题拆开讲清楚大致要配哪些传感器、传感器怎么选怎么装、融合算法怎么写、GPS数据怎么清洗和展示以及我实际调试过程中踩过的那些坑。内容偏向工程落地看得懂Python和基本嵌入式概念就能上手做两轮车车机、骑行记录仪、共享单车锁车定位、电动车仪表的同学都可以直接参考。1. 先把问题拆开看GPS信号丢失到底丢的是什么1.1 遮挡场景下接收机内部发生了什么很多人把GPS信号丢失理解成一个开关有信号就算没信号就不算。实际不是这样。接收机输出的是定位解这个解是由若干颗卫星的伪距观测值算出来的解算过程本身还有一个质量评估指标比如水平精度因子、参与解算的卫星数、载噪比。进隧道的过程其实是这样的先是卫星数从十几颗掉到五六颗定位解开始漂再掉到四颗以下接收机丢失定位解输出的是一串无效值或者干脆不再更新出隧道后接收机需要重新捕获卫星、同步星历这个重捕获时间冷启动可能几十秒热启动一般一到五秒这也正是你看到箭头愣一下再跳的原因。更麻烦的是多径效应。地下车库入口、玻璃幕墙、高架桥下这些地方并不是完全没信号而是信号经过一次或多次反射才到天线。反射路径比直射路径长伪距偏大算出来的位置会整体偏移。这种偏移往往不是随机的而是有方向性地被推向某一边所以在商场地下车库入口经常能看到箭头稳定地偏在隔壁那条路上看着还挺真。理解这一层之后思路就清楚了要解决的不是没信号怎么办而是信号质量从好到坏、从坏到无、再从无到有整个过程怎么平滑过渡。1.2 两轮车比四轮车多出来的三个坑汽车上的组合导航方案其实已经很成熟惯性测量单元加轮速加方向盘转角再配合地图匹配进隧道几百米基本能做到车道级不飘。把这套东西直接搬到两轮车上会立刻撞上三个差异点。第一是姿态耦合。汽车过弯时车身基本水平陀螺仪测到的横滚角变化很小两轮车压弯时车身倾角可以到二三十度而且这个倾角是驾驶意图的一部分不是干扰。如果直接把车身坐标系下的加速度积分成位移转弯时会把重力分量误当成横向加速度几十米之后位置就歪到另一条街了。所以两轮车必须做姿态解算和倾角补偿把车身姿态从运动估计里剥出去。第二是轮速信号的可信度差异。汽车有四个轮速传感器可以互相校验还能通过差速算出转向角速度。两轮车通常只有后轮一个霍尔传感器前轮悬空、后轮打滑、推车、倒车这些状态下轮速和实际位移完全对不上。而且两轮车的轮胎周长会随胎压、载重、磨损变化标称值和实际值差百分之二很常见一公里就累积二十米误差。第三是振动与安装空间。两轮车的振动频谱比汽车恶劣得多尤其是过减速带和坑洼路面时加速度计会瞬间饱和。同时车把、车架、尾箱这些位置留给传感器的空间和走线余地都很小天线布局往往要迁就外观和防水这就直接影响到信号质量。2. 方案选型为什么走惯性轮速地图匹配这条路2.1 三条可选路线的取舍面对遮挡场景行业里大致有三条路线我把它们的适用性和代价摆在一起看会更清楚。方案核心手段优点局限适合谁纯航位推算加速度计陀螺仪积分不依赖外部信号短时可用误差随时间平方增长10秒后基本不可用记录仪轨迹补点惯性轮速融合加里程计约束速度速度约束住了误差线性增长需要轮速信号打滑时失效车机导航、电动车仪表融合地图匹配再叠加路网约束长隧道也能锁在道路上依赖路网数据质量越界场景会强行纠正完整导航产品我的结论很直接只做前两条隧道超过三百米就没法看。因为航位推算的误差是累积的横向漂移一旦超过路宽的一半你就没法判断车到底在哪条道上。地图匹配的作用是把这条漂移的轨迹重新吸附到路网上等于给了一个持续的绝对约束。所以真正可用的方案是第三条前面的惯性融合负责在信号丢失期间维持一个可用的相对轨迹地图匹配负责把它拉回正确的位置。这里要强调一个顺序问题先融合再匹配不要反过来。有些实现是先把原始定位点丢给地图接口做纠偏再做融合。这样在信号丢失期间没有新点进来匹配无从谈起而且地图接口对漂移点经常会给出错误的匹配结果反而把融合的观测值污染了。正确的做法是融合模块先输出一个自洽的位置和速度估计匹配模块在这个估计的基础上做约束。2.2 传感器清单与成本区间我把实际用过的配置列一下从低成本到高精度都有。六轴惯性测量单元加速度计陀螺仪这是最核心的一颗选型时重点看零偏稳定性和噪声密度不要只看量程。消费级器件零偏稳定性通常在每小时几度到几十度工业级能做到每小时一度以内。价格从十几块到几百块都有。三轴磁力计用来给航向提供绝对参考抑制陀螺仪的航向漂移。但在两轮车上电机、喇叭、车架钢材都会产生硬铁和软铁干扰必须做椭球拟合标定否则比不用还糟。轮速传感器霍尔式或磁电式都行关键是能输出稳定的脉冲。如果原车仪表已经有速度信号直接并一路进去最省事。气压计隧道和地下车库的多层结构里气压计能帮你判断是在上坡匝道还是下坡匝道对垂直方向的位置推断很有用。成本很低建议加。GNSS接收模块要选支持多星座的同时能输出原始观测数据伪距、载噪比这样才能做质量评估和后续的完好性监测。只输出定位结果的模块在遮挡场景下基本没法做二次判断。一套下来如果目标是精度做到十米以内、隧道内不飘出道路硬件成本大致在两百到五百元区间追求车道级的话要上到千元级通常还要差分服务配合。2.3 数据流与系统架构把整个链路串起来看从传感器到最终地图上那个箭头中间经过这么几层第一层是传感器采集与预处理主要工作是时间同步和坐标系统一。惯性测量单元、轮速、GNSS的时间戳必须对齐到同一个时钟基准上误差控制在十毫秒以内。我见过不少项目在这里出问题惯性测量单元跑在一百赫兹GNSS只有一赫兹融合时不做插值直接把最近一帧拼在一起结果就是每次GNSS更新都产生一次位置跳变。第二层是姿态解算输出车身的横滚、俯仰、航向。两轮车建议用四元数做姿态更新再通过互补滤波或者扩展卡尔曼滤波融合加速度计和磁力计避免欧拉角在特定姿态下的奇异问题。第三层是组合导航滤波把姿态、速度、位置作为状态量把GNSS定位结果和轮速当作观测量做扩展卡尔曼滤波。这一层的输出就是连续的位姿估计。第四层是地图匹配把位姿估计投影到路网上输出最终展示用的位置。第五层是平滑与展示对输出位置做滑动窗口平滑避免箭头抖动同时控制延迟不要太大。3. 硬件落地GPS模块和陶瓷天线的选型与摆放3.1 GPS模块参数怎么看挑模块的时候参数表上那一堆数字里真正影响遮挡场景表现的是这几项。冷启动时间和热启动时间要分开看。热启动时间反映的是重捕获能力这个指标比冷启动重要得多因为隧道场景下星历还在属于热启动范畴。好的模块热启动能到一秒以内。灵敏度分追踪灵敏度和捕获灵敏度通常写成分贝毫瓦的负值。追踪灵敏度高意味着在弱信号环境下还能维持解算这个值每差三个分贝实际可用场景就差一档。通道数现在普遍是几十个通道差异不大但要注意是否支持多频。双频模块能利用两个频段的观测值组合消除电离层延迟在城市峡谷环境下的固定率明显更好代价是功耗和成本上升。数据输出率也就是定位更新频率。默认一赫兹对于高速场景是不够的两轮车时速六十公里时一秒就是十六米多隧道口的过渡会非常生硬。能开到五赫兹甚至十赫兹最好配合惯性融合就能平滑很多。是否支持原始观测数据输出这条前面提过但要再强调一次。只有拿到每颗卫星的载噪比和伪距残差你才能判断当前定位解是不是被多径污染了才能做后续的失效保护逻辑。3.2 GPS陶瓷片设计注意事项陶瓷天线是被低估的一环。同样的模块换一根天线地下车库出口的表现能差出一倍。首先是尺寸和增益的取舍。陶瓷片的电性能和它的物理尺寸强相关常见的25×25毫米、18×18毫米、15×15毫米这几档尺寸越大增益越高、带宽越宽但占用的安装空间也越大。两轮车车把位置空间紧张时别为了美观硬塞小尺寸天线宁可挪到车头灯罩内侧或者尾箱顶部。其次是接地平面。这一条是最容易翻车的。陶瓷天线需要一个足够大的金属接地平面才能正常工作通常要求接地平面尺寸不小于天线尺寸的四分之一波长。在自由空间里一五七五兆赫对应的波长约十九厘米接地平面最好不小于四七毫米见方越大越好。很多人把天线贴在一块小电路板上周围全是塑料和空气结果增益掉了一大截还以为是模块的问题。第三是周围金属和介质的影响。天线正上方三厘米内不要有任何金属侧方也要留出净空区。车架钢管、后视镜支架、金属尾箱都会让天线的方向图变形表现为某些方向卫星收得到、某些方向收不到。这个现象在转弯时特别明显往左转信号好、往右转信号差基本就是天线被挡住了。第四是馈线。从天线到模块的馈线要走五十欧姆阻抗长度尽量短超过十厘米就要考虑加低噪声放大器和相应的供电偏置。馈线走线要远离电机线束和DC-DC转换器这两者是两轮车上最大的电磁干扰源。第五是防水与温漂。陶瓷片本身怕潮长期湿度环境下介质损耗会上升表现为用了一两年后定位变慢。封装时做好灌封或者三防处理同时注意低温下陶瓷材料的频率漂移北方冬天可能会出现冷启动困难。3.3 两轮车安装的几个硬约束实际装车时有几条经验文档上一般不会写。天线的极化方向要和卫星信号匹配GPS信号是右旋圆极化天线平放、陶瓷面朝天是最理想的。但两轮车车头是有倾角的如果贴在前脸天线实际上有个二三十度的倾斜增益会损失几分贝。折中的做法是找一个接近水平的安装面或者选一款带倾角补偿设计的天线。远离干扰源这条要具体化。电机控制器的开关频率通常在十几千赫到几十千赫谐波可能落到一五七五兆赫附近DC-DC的开关频率在几百千赫到几兆赫多次谐波更容易命中。装车后一定要做一次实际路测用模块输出的载噪比做判断正常开阔环境下大部分卫星的载噪比应该在三十五到四十五分贝赫兹之间如果普遍低于三十八成是被干扰了。惯性测量单元要尽量靠近车辆重心减少转弯时的离心加速度对测量的影响。同时要做减振处理用软性硅胶垫而不是硬性固定避免高频振动直接传到传感器上。4. 算法部分姿态解算、卡尔曼滤波和丢失检测4.1 姿态解算与航向保持两轮车的姿态解算有两个目标一是给出准确的航向二是把重力分量从加速度里分离出来。姿态更新用四元数做加速度计和磁力计作为观测量做修正。这里有个细节两轮车在压弯时横向加速度很大如果直接用加速度计去修正横滚角会把离心加速度误判成重力方向导致姿态估计在弯道里出错。解决办法是用轮速算出的向心加速度做一个前馈补偿把离心分量从加速度测量里减掉再拿剩下的部分去修正姿态。航向方面磁力计是主要参考但两轮车的磁干扰太强。我的做法是只在直线行驶且速度稳定的时候用磁力计做慢速修正弯道和加速阶段完全靠陀螺仪积分。这样既享受了磁力计的绝对参考又避开了干扰最严重的时段。判断直线的方法很简单陀螺仪横摆角速度接近零、横向加速度接近零、轮速波动小三个条件同时满足持续两秒以上就认为是稳定直线段。4.2 卡尔曼滤波的工程细节组合导航用的扩展卡尔曼滤波状态量一般包括位置、速度、姿态误差、陀螺仪零偏、加速度计零偏十五到十八维比较常见。工程上有几个细节决定了实际效果好坏。观测更新要分场景。GNSS定位结果的噪声方差不能设成常数。具体做法是用载噪比、卫星数、水平精度因子这几个量算一个实时噪声模型卫星数少于六颗、水平精度因子大于三的时候把观测噪声方差放大到正常值的十倍以上让滤波器基本忽略这次观测。这一步能有效抑制出隧道瞬间那个猛地一跳因为那一帧的定位解质量其实很差只是数值上看着正常。零速修正要可靠。车停着的时候速度应该严格为零。这个约束非常强能有效抑制零偏累积。判断零速可以用轮速脉冲数、加速度计方差、陀螺仪方差三个条件组合。两轮车在等红灯时经常有轻微晃动单纯用加速度方差会误判加上轮速脉冲为零就稳了。过程噪声要按运动状态调节。直行时航向的过程噪声可以设小转弯时要设大。用一个基于横摆角速度的简单调度就能有效改善弯道跟踪。代码上来示意一下核心逻辑用的是最简化的两维位置速度模型主要展示噪声调度和观测门限的思路import numpy as np class TightCoupler: def __init__(self, dt0.02): self.dt dt # 状态: [x, y, vx, vy] self.x np.zeros(4) self.P np.eye(4) * 10.0 # 轮速尺度因子, 需要在线估计 self.scale 1.0 def predict(self, ax, ay, yaw_rate): dt self.dt F np.array([ [1, 0, dt, 0], [0, 1, 0, dt], [0, 0, 1, 0], [0, 0, 0, 1], ]) B np.array([0.5*dt*dt, 0.5*dt*dt, dt, dt]) self.x F self.x B * np.array([ax, ay]) # 过程噪声: 转弯时放大航向相关项 q 0.05 abs(yaw_rate) * 1.5 Q np.diag([q*dt, q*dt, q, q]) self.P F self.P F.T Q return self.x def update_gnss(self, z, cn0_mean, sv_count, hdop): # 观测噪声随信号质量动态膨胀 base_r 4.0 penalty 1.0 if sv_count 6: penalty * 4.0 if hdop 3.0: penalty * 3.0 if cn0_mean 30: penalty * 3.0 R np.eye(2) * (base_r ** 2) * penalty H np.array([[1, 0, 0, 0], [0, 1, 0, 0]]) y z - H self.x # 新息门限: 距离超过一定值直接丢弃 if np.linalg.norm(y) 60.0: return self.x S H self.P H.T R K self.P H.T np.linalg.inv(S) self.x self.x K y self.P (np.eye(4) - K H) self.P return self.x def update_wheel(self, speed): # 轮速提供速度幅值约束 v self.x[2:4] v_norm np.linalg.norm(v) if v_norm 1e-3: return self.x z speed * self.scale r z / (v_norm 1e-6) self.x[2:4] v * r return self.x这段代码不是完整实现但里面三个点值得抄观测噪声的膨胀系数、新息门限的直接丢弃、轮速只约束速度幅值不约束方向。第三个点很重要很多人直接把轮速当作速度矢量去更新结果航向误差被强行带进位置越跑越偏。4.3 丢失检测、重捕获与失效保护丢失检测不能只看有没有定位解要综合判断。我用的判据是连续若干帧没有有效解或者虽然有解但水平精度因子持续超标或者新息连续超门限三者满足其一就进入航位推算模式。进入时要记下当前位姿和不确定度这决定了后面能撑多久。纯航位推算的持续时间要设一个上限。根据我的实测消费级惯性测量单元配合轮速在国内城市道路条件下把位置误差控制在十五米以内大约能维持三十到六十秒。超过这个时间就应该让界面明确提示定位信号弱而不是继续画一条越来越假的轨迹。这是产品诚实度的问题比技术本身还重要。重捕获策略要做两件事一是确认新的定位解确实可靠不能刚恢复就信二是把恢复后的位置平滑接到航位推算的轨迹上。第二件事的常用做法是在重捕获后的一段时间内把GNSS观测的权重从零逐渐升到正常值同时观察新息是否持续变小。如果新息一直很大说明之前的推算已经偏了这时候应该以GNSS为准做一次重置并在界面上做一次平滑过渡动画。失效保护这块值得单独说。定位数据在车载场景里已经不只是导航用还涉及计费、调度、轨迹留证。如果接收机受到信号欺骗输出一个被人为构造的位置而系统毫无察觉后果可能很严重。防护思路主要有三条一是接收机自主完好性监测用冗余卫星观测值做一致性检验残差超过门限就判定异常二是多源交叉验证把GNSS位置和轮速推算的位移做比对短时间内差异超过物理极限就报警三是加装保护级计算给定位结果输出一个不确定度包络上层逻辑根据包络决定是否采信。生成式欺骗的特征是信号功率异常、到达角异常、伪距变化率不合理多做几层校验能显著提高发现概率。这部分内容展开能写一整篇这里先点到为止知道有这么个方向就行。5. 数据加工清洗、坐标转换和轨迹可视化5.1 GPS数据清洗与误差评估采集回来的原始GPS数据不能直接用尤其是需要做离线分析和算法调参的时候。第一步是剔除无效解。原始数据里通常用特定数值表示无效比如经纬度为零或者纬度大于九十这些要先过滤掉。同时注意时间戳回退的数据那是接收机复位造成的。第二步是静态漂移评估。把设备放在开阔地静止采集一小时看坐标的分布半径。这个值反映的是接收机在理想条件下的噪声水平也是后面判断动态数据好坏的基准。正常情况下消费级模块的静态散布在开阔地应该是两到三米半径超过五米就说明要么天线有问题要么环境有多径。第三步是速度合理性检验。根据相邻两点的距离和时间差算瞬时速度超过车辆物理极限两轮车就算一百公里每小时吧的点判为跳点。同时注意低速段的处理静止时由于坐标抖动算出来的速度可能有好几米每秒这时候要用一个最小位移门限来过滤。第四步是载噪比筛选。如果模块输出每颗卫星的载噪比可以把低于门限的卫星对应的解算结果标记出来。这一步在离线分析里特别有用能帮你定位到具体是哪一段路的哪个方向被遮挡了。5.2 Python 把 GPS 经纬度转换为高德经纬度这里有个新手必踩的坑从接收机直接读出来的经纬度直接打到高德或腾讯地图上整体会偏移几百米。原因是接收机输出的是WGS84坐标而国内地图服务普遍使用经过加密偏移的GCJ-02坐标。这两个坐标系之间的差值是随位置变化的不是简单的固定偏移必须用算法转换。WGS84转GCJ-02有公开的算法本质是先用一套经验公式算出偏移量再叠加到原坐标上。下面是可直接用的实现import math PI 3.1415926535897932384626 A 6378245.0 EE 0.00669342162296594323 def _out_of_china(lng, lat): 粗略判断是否在转换算法适用范围内 return not (73.66 lng 135.05 and 3.86 lat 53.55) def _transform_lat(lng, lat): ret -100.0 2.0 * lng 3.0 * lat 0.2 * lat * lat ret 0.1 * lng * lat 0.2 * math.sqrt(abs(lng)) ret (20.0 * math.sin(6.0 * lng * PI) 20.0 * math.sin(2.0 * lng * PI)) * 2.0 / 3.0 ret (20.0 * math.sin(lat * PI) 40.0 * math.sin(lat / 3.0 * PI)) * 2.0 / 3.0 ret (160.0 * math.sin(lat / 12.0 * PI) 320 * math.sin(lat * PI / 30.0)) * 2.0 / 3.0 return ret def _transform_lng(lng, lat): ret 300.0 lng 2.0 * lat 0.1 * lng * lng ret 0.1 * lng * lat 0.1 * math.sqrt(abs(lng)) ret (20.0 * math.sin(6.0 * lng * PI) 20.0 * math.sin(2.0 * lng * PI)) * 2.0 / 3.0 ret (20.0 * math.sin(lng * PI) 40.0 * math.sin(lng / 3.0 * PI)) * 2.0 / 3.0 ret (150.0 * math.sin(lng / 12.0 * PI) 300.0 * math.sin(lng / 30.0 * PI)) * 2.0 / 3.0 return ret def wgs84_to_gcj02(lng, lat): WGS84 转 GCJ-02 if _out_of_china(lng, lat): return lng, lat dlat _transform_lat(lng - 105.0, lat - 35.0) dlng _transform_lng(lng - 105.0, lat - 35.0) radlat lat / 180.0 * PI magic math.sin(radlat) magic 1 - EE * magic * magic sqrtmagic math.sqrt(magic) dlat (dlat * 180.0) / ((A * (1 - EE)) / (magic * sqrtmagic) * PI) dlng (dlng * 180.0) / (A / sqrtmagic * math.cos(radlat) * PI) return lng dlng, lat dlat if __name__ __main__: # 示例: 北京附近一组坐标 lng, lat 116.397428, 39.909230 glng, glat wgs84_to_gcj02(lng, lat) print(WGS84: %.6f, %.6f % (lng, lat)) print(GCJ02: %.6f, %.6f % (glng, glat))实际用的时候记住两点。一是转换方向不要搞反如果数据源已经是国内地图SDK回传的坐标那是GCJ-02再转一次就偏了。二是批量转换要做边界判断这套公式只适用于国内范围境外的坐标直接原样返回。反过来的GCJ-02转WGS84工程上一般用迭代逼近因为正向公式没有解析逆。做法是先用一次粗偏移然后迭代修正几次误差就能收敛到厘米级。如果只是做轨迹展示正向转换足够了。5.3 GPS数据导出地图做复盘调算法的时候把轨迹打到地图上看是最直观的手段。我一般用两种方式。一种是生成GeoJSON或者KML文件直接拖到通用地图工具里看。KML适合快速查看GeoJSON适合程序化处理。生成的时候可以把不同数据源分成不同图层比如原始GNSS点一层、融合后轨迹一层、地图匹配结果一层颜色区分开一眼就能看出哪一段对不上。另一种是做成带时间轴的动画用来看隧道出入口的过渡过程。把融合前后的轨迹叠在同一张图上用不同颜色表示置信度高低进出隧道的几秒钟里发生了什么就非常清楚了。导出的时候有个细节要注意时间戳要用带时区的格式否则跨设备对比时会出错。同时建议把原始载噪比、卫星数、水平精度因子这些质量指标作为属性一起写进文件后面用地图工具做属性着色的时候非常方便能直接看出哪一段路是信号被遮挡的重灾区。6. 常见问题与排查6.1 典型故障速查表调试过程中遇到过的、频率最高的问题整理成了一张表方便照着排查。现象可能原因排查方法处理方式开阔地定位就慢冷启动超过一分钟天线接地平面不足、馈线过长换一块足够大的金属板做接地缩短馈线重做天线安装结构载噪比普遍偏低十到二十分贝赫兹电磁干扰或天线被金属遮挡断开电机控制器电源再测一次对比载噪比调整天线位置线束远离干扰源静止时坐标一直缓慢画圈多径、星历精度不足换开阔位置复测观察是否消失增加静止漂移评估融合里降低静态观测权重出隧道后箭头猛跳几十米融合模块无条件采信首个恢复解打印新息门限的日志看恢复帧是否被接受加重捕获渐入逻辑前若干帧观测权重逐步提升弯道里位置越走越偏离心加速度被当成重力姿态解算出错对比陀螺仪积分航向和磁力计航向的差值加轮速前馈补偿弯道禁用磁力计修正长隧道内轨迹提前漂出道路纯航位推算超时未接入地图匹配检查地图匹配模块是否在丢失期间持续输出把路网约束接到融合输出上而不是只做展示同一路线每次偏移方向不一致天线方向图被车架结构畸变记录不同方位的载噪比分布调整安装角度必要时换带倾角设计的天线冬季定位变慢、夏季正常陶瓷天线介质温漂、封装吸潮高低温箱复现对比冷启动时间优化灌封工艺选用温度特性更好的天线6.2 几个只有踩过才知道的坑第一个坑时间同步看起来简单实际最难。惯性测量单元、轮速、GNSS三路数据的时间戳来源不同如果各自用的是本地晶振跑几个小时就会漂出几百毫秒。解决办法是要么统一由一个时钟源打时间戳要么在离线处理时用GNSS的秒脉冲做基准做重采样。我一开始忽略了这件事融合结果在起步阶段还行跑二十分钟就开始出现规律性的位置抖动找了很久才发现是时间对齐的问题。第二个坑轮胎周长标定要经常做。前面提过轮速尺度会漂但很多人只在出厂时标一次。实际用下来胎压变化、载重变化、轮胎磨损都会影响这个值一两个月之后误差累积起来就很明显了。简单做法是每次在直路上跑一段已知距离用GNSS的总位移和轮速总脉冲数算比例做一次在线校准。更省事的办法是在融合里把轮速尺度作为一个状态量在线估计只是收敛需要一点时间。第三个坑不要用磁力计判断航向的绝对值。磁偏角在不同地区差别很大而且车架的铁磁材料会让罗盘读数整体偏移几十度。磁力计的正确用法是提供航向的相对变化不是绝对值。也就是说用它来约束陀螺仪的漂移趋势而不是直接用它的读数当航向。第四个坑压弯时的车身倾角会影响高度估计。如果用了气压计做垂直方向约束两轮车过弯时车身倾斜会不会影响气压读数会但影响很小可以忽略。真正需要注意的是倾角本身会让加速度计的垂直分量发生变化如果不做姿态补偿高度估计会跟着倾角一起摆。这个在多层地下车库里尤其明显容易把上坡道判成下坡道。第五个坑地图匹配不要设太强的约束。路网数据和实际道路总有偏差如果匹配算法过于激进会把正常的行驶轨迹硬拉到一个错误的路段上尤其是在匝道、辅路、园区内部道路这些地方。我的经验是匹配约束只在航位推算模式下加强在GNSS正常的时候放松让原始定位说了算。第六个坑把不确定性告诉用户比假装一切正常更有价值。隧道里那条越来越猜的轨迹与其画成一条实线不如画成带虚化或者用不同透明度表示置信度。用户看到虚线就知道这段不可靠出了隧道重新定位也不会觉得突兀。这个设计决策在体验上带来的提升比单纯把算法误差从十米压到八米要大得多。我个人在实际调试中的体会是这类问题的难点从来不在某一条公式上而在各个模块之间的衔接时间怎么对齐、坐标系怎么统一、噪声参数怎么调、模式怎么切换。算法本身都有成熟的公开方案真正拉开差距的是对这些边角细节的处理。我习惯的做法是先把整条链路跑通哪怕精度很差然后拿着实车数据一段一段地回放把每个环节的日志打出来对着看。等你能准确说出某一次偏移是哪一帧、哪一个观测造成的这套方案基本也就调稳了。至于隧道长度超过一公里、多出入口的地下车库这种极端场景单靠车载传感器终究有极限接入路侧辅助定位或者更密的差分服务是下一步值得尝试的方向。
返回列表