ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

多源传感器空间配准:ECEF坐标变换与偏差补偿算法选型

多源传感器空间配准:ECEF坐标变换与偏差补偿算法选型

简介:这份课件面向目标跟踪、多传感器融合与自动驾驶感知方向的学习者和工程人员,围绕多源传感器空间配准展开,重点解决不同传感器坐标系不统一、安装间距与量测偏差带来的融合误差问题。内容从定义和误差来源讲起,梳理平台级与系统级配准、合作目标与非合作目标两类思路,并延伸到球极投影二维偏差估计、ECEF三维配准及KF/EKF在线实时估计等主流方法,配有算法仿真对比,便于建立从模型到实现的整体认识。资源包仅含1个pptx文件,大小1.82MB,结构紧凑,适合按目录复习或用于组内分享。已有500人学习,可作为空间配准入门梳理与算法选型参考。

1. 两路航迹对不上,先别急着调滤波器

两路雷达对同一架无人机报出的航迹,在同一张态势图上错开了十几米,而且越远错得越多——这类现场问题十有八九不是跟踪滤波器的锅,而是多源传感器空间配准没做干净。这份《目标跟踪系列-融合》的第二篇,讲的就是把不同传感器的量测统一到公共坐标系、并把安装与标定带来的系统偏差补偿掉的那套流程:从误差来源的三类平台形态、平台级与系统级配准的区别,到 RTQC、LS、GLS、EML 与 KF/EKF/UKF 这几类算法的适用边界,再到二维球极投影与 ECEF 三维模型的取舍。它面向的是已经在做多传感器融合、但被「航迹对不齐」卡住的工程师,也适合刚接手自动驾驶或机器人导航项目、需要把雷达、相机、激光雷达拉到同一坐标系下的人。

2. 两步走完坐标与偏差:从传感器极坐标到 ECEF 公共系的转换链

2.1 为什么必须先统一坐标系,再谈偏差补偿

空间配准的定义只有两句:一是把各传感器量测变换到同一个坐标系,二是对传感器在空间中相对位置造成的量测偏差做补偿。听上去像两个可以并行的动作,实际工程里顺序卡得很死,顺序错了后面的算法再精细也是白搭。

原因在于偏差本身是不是常向量,取决于你把它定义在哪个坐标系里。传感器的原始量测是极坐标形式(斜距、方位角、俯仰角),在这个空间里,一个 0.2° 的方位偏差对应的横向位移随距离线性增长:5 km 处约 17.5 m,10 km 处就是 35 m。它不是常数,跟目标在哪、离多远强相关,你没法用一个固定向量去减。只有把所有量测都搬到 ECEF 这类直角公共系之后,安装位置差、标定残差才表现为近似常值的加性偏差,才具备「估一次、长期用」的前提。

所以正确的链路是先变换、再在公共系里估偏差、最后在公共系里补偿。反过来先补再变换,等于假设偏差在极坐标里是常数,遇到远距离目标会直接翻车。

2.2 四级转换链与可抄的 Python 实现

一条完整的变换链通常是四级:传感器极坐标 → 传感器直角系 → 载体系 → 地理系(ENU 或 NED)→ ECEF。每一级都有人往里灌误差,这也是后面误差建模要分场景的原因。

层级输入变换内容主要误差注入点
极坐标→传感器系斜距、方位、俯仰三角展开传感器自身标定误差、角度量化
传感器系→载体系安装矩阵安装角旋转安装角误差、杆臂长度
载体系→地理系姿态角航向/俯仰/横滚旋转惯导姿态误差、正北对准精度
地理系→ECEF载体经纬高椭球参数换算卫导定位误差、高程误差

先落最底层的一级,椭球参数和 ECEF 转换是所有后续步骤的地基:

import numpy as np # WGS84 椭球参数 A = 6378137.0 # 长半轴,米 F = 1 / 298.257223563 # 扁率 E2 = F * (2 - F) # 第一偏心率平方 def geodetic_to_ecef(lat, lon, h): """经纬高(度/度/米) -> ECEF 直角坐标(米)""" lat, lon = np.radians(lat), np.radians(lon) n = A / np.sqrt(1 - E2 * np.sin(lat) ** 2) # 卯酉圈曲率半径 x = (n + h) * np.cos(lat) * np.cos(lon) y = (n + h) * np.cos(lat) * np.sin(lon) z = (n * (1 - E2) + h) * np.sin(lat) return np.array([x, y, z]) def enu_to_ecef_matrix(lat, lon): """ENU 局部坐标 -> ECEF 的旋转矩阵""" lat, lon = np.radians(lat), np.radians(lon) sl, cl = np.sin(lat), np.cos(lat) so, co = np.sin(lon), np.cos(lon) return np.array([ [-so, -sl * co, cl * co], [ co, -sl * so, cl * so], [0.0, cl, sl], ])

geodetic_to_ecef里那个n是卯酉圈曲率半径,纬度越高它越小,忽略它直接用球模型在纬度 45° 以上会引入十几米的系统性偏差,这一点在平原地区做测试基本发现不了,换个高纬度试验场就暴露。enu_to_ecef_matrix返回的是正交阵,用它做旋转不会改变距离,所以误差不会被放大,可以放心当作无损环节。

接着往上补传感器到载体的两级。传感器极坐标转直角时要注意方位角的起算基准,雷达常用「正北起算、顺时针为正」,而不少开源库默认「东向起算、逆时针为正」,两者差一个 90° 减法和一个符号:

def polar_to_local(rng, az_deg, el_deg): """传感器极坐标 -> 传感器直角系(ENU 对齐) az: 正北起算顺时针为正; el: 水平面起算向上为正""" az, el = np.radians(az_deg), np.radians(el_deg) return np.array([ rng * np.cos(el) * np.sin(az), # 东向 rng * np.cos(el) * np.cos(az), # 北向 rng * np.sin(el), # 天向 ]) def body_to_enu(p, yaw, pitch, roll): """载体系 -> ENU,ZYX 顺序,角度单位为度""" y, p_, r = np.radians(yaw), np.radians(pitch), np.radians(roll) rz = np.array([[np.cos(y), -np.sin(y), 0], [np.sin(y), np.cos(y), 0], [0, 0, 1]]) ry = np.array([[ np.cos(p_), 0, np.sin(p_)], [0, 1, 0], [-np.sin(p_), 0, np.cos(p_)]]) rx = np.array([[1, 0, 0], [0, np.cos(r), -np.sin(r)], [0, np.sin(r), np.cos(r)]]) return rz @ ry @ rx @ p

polar_to_local的输出约定成 ENU 三轴对齐,是为了让body_to_enu只用管姿态旋转、不用再管轴向映射,少一层出错的机会。body_to_enu用的 ZYX 顺序对应「先航向、再俯仰、最后横滚」,跟多数惯导输出的欧拉角定义一致;如果你的惯导给的是 ZXY 或别的顺序,这里必须改,否则横滚一大的时候姿态矩阵整个是错的,而小角度试验时又看不出来,属于典型的玄学 bug。

串起来就是完整一条链:

def sensor_to_ecef(rng, az, el, R_bs, yaw, pitch, roll, lat0, lon0, h0): """单个量测从传感器极坐标一路推到 ECEF R_bs: 传感器系 -> 载体系的安装矩阵(3x3) lat0/lon0/h0: 载体自身的地理位置""" p_s = polar_to_local(rng, az, el) p_b = R_bs @ p_s # 安装矩阵 p_e = body_to_enu(p_b, yaw, pitch, roll) R = enu_to_ecef_matrix(lat0, lon0) return geodetic_to_ecef(lat0, lon0, h0) + R @ p_e

参数上唯一需要留心的是R_bs。它由三个安装角构成,标称值通常来自结构图纸,实际装配完能差到 0.1°~0.5°,在 10 km 上就是 17~87 m 的横移。这也是为什么很多团队明明坐标变换公式写得没错,配准结果还是烂——误差不在公式里,在R_bs那个矩阵里。

2.3 偏差补偿放在哪一步:两种做法不等价

工程上补偿偏差有两条路。一条是在极坐标里先把斜距偏差、方位偏差、俯仰偏差扣掉,再走变换链;另一条是先全部变换到 ECEF,在公共系里减一个三维偏移向量。前者贴合物理,后者贴合算法。

差别有多大?斜距偏差 10 m、方位偏差 0.2°,在 5 km 处合成的位置偏差约 20 m。如果你在公共系里只补了一个固定向量,当目标方位从 0° 转到 90°,原来那个偏移向量的方向就跟实际偏差方向差了 90°,残差还是 20 m 量级,等于没补。所以只要偏差源里有角度成分,就必须在极坐标阶段处理,或者把角度偏差作为待估量放进模型里联合估计,不能粗暴地用一个公共系常向量糊过去。

实际的折中做法是:把可标定的部分(斜距零偏、角度零偏)在极坐标阶段扣掉,把不可标定的残余(安装角残差、杆臂残差)留在公共系里用配准算法估。这个分界点定在哪,直接决定后面待估参数的维数,也决定你有没有足够多的观测把它估出来。

3. 误差来源按平台场景分三档:同载体、静止多载体、运动多载体的偏差模型

3.1 同载体多传感器:先认为原点重合,再抠三项残差

同一架无人机、同一辆车上挂的雷达和相机,彼此间距相对目标距离可以忽略,工程上直接假设原点重合,先把杆臂那一项砍掉。剩下的误差就三项:各传感器自身的校准系统误差,表现为同一目标在距离和方位上的固定偏差;坐标变换公式本身的精度误差,尤其是把极坐标转到直角坐标那一步的非线性;以及自然环境带来的扰动,风雨雷电会让量测出现不确定的漂移。

这三项里前两项是常值或缓变,可以估;第三项是随机扰动,估不了,只能靠滤波压制。所以同载体场景的配准模型通常只挂 3~6 个参数:每个传感器一个斜距零偏、一个方位零偏,有俯仰通道的再加一个。参数少、可观测性好,是最容易做干净的一档。

3.2 静止多载体:位置误差与正北不精确是两头大账

换成地面上分开架设的几部传感器,原点不再重合,杆臂这一项必须显式建模。多出来的误差源有五项:各自的校准误差;各自坐标系下的方位、俯仰、距离偏差,主要来自惯性测量单元的测量误差;传感器本身的定位误差,也就是它在公共坐标系里到底站在哪,这一项由导航系统偏差引起;为减小计算量而采用近似公式带来的坐标转换精度损失;以及环境误差。

这里最容易被低估的是「正北不精确」。地面上架设的设备通常靠指北设备或卫导定向来定北,误差 0.3°~1° 很常见。1° 的定向偏差在 20 km 上就是 349 m 的横移,而且它是整体旋转偏差,不是平移偏差,用平移量去补永远补不平。做静止多平台配准,第一件事是把各站的正北一致性校一遍,这一步省掉,后面估出来的偏差参数全是脏的。

3.3 运动多载体:卫导误差与姿态误差随平台运动放大

平台一动,问题复杂度上一档。误差源变成六项:传感器校准误差;各自坐标系下的方位、俯仰、距离偏差(同样来自惯导);坐标转换公式的近似误差;各载体位置和各传感器位置的不确定性,主要来自卫导;环境误差;以及天线正北方向不够精确。

运动平台的特殊性在于载体位置本身是时变的,而卫导给出的位置有米级噪声,这个噪声会直接进入 ECEF 原点,等效成所有量测共享的一个公共偏移。它有个讨厌的性质:不会因为多测几次就抵消,因为偏移在短时间内是相关的。解决办法通常是用差分或后处理平滑把载体轨迹先修一遍,再拿去做配准;顺序反过来,把卫导噪声当成传感器偏差估进去,估出来的参数就没法复用了。

3.4 把误差清单落成偏差向量:维数怎么定

三档场景梳理完,要落到一个可估的偏差向量上。这一步定错了,后面算法再好也白搭。常见做法是分两级建模:

偏差层级典型参数维数(双传感器)是否可独立估计
传感器级斜距零偏、方位零偏、俯仰零偏6仅相对量可观测
平台级三维位置偏差、三轴姿态偏差12需合作目标或机动
联合上述全部18需长时间多构型观测

关键在「是否可独立估计」那一列。非合作目标场景下,两传感器同时看一个未知真实位置的目标,你能拿到的只有两者量测之差,这个差里只含偏差之差,不含偏差之和。所以严格来说,只有相对偏差可观测,绝对偏差必须靠外部基准(合作目标、已知点、或者干脆把主传感器偏差钉死为零)来定标。这一点在资料里对应的就是「联合估计算法」与「独立估计算法」的分野:偏差成分复杂、耦合严重时,把偏差和状态分开估反而更干净。

顺带说一下均匀分布与非均匀分布的区别。均匀分布假设偏差在整个探测空域内是常数,非均匀分布假设它是缓变曲面(比如二次曲面)。前者参数少但残差大,后者拟合能力强但需要更多观测支撑,观测稀疏时容易过拟合出一个看着漂亮、换个方位就崩的曲面。我一般先用均匀分布跑一版看残差量级,残差如果随方位呈现明显趋势,再升到非均匀模型。

4. 算法选型:从 RTQC、LS、GLS、EML 到 KF/EKF/UKF 的取舍

4.1 二维球极投影在自动驾驶里为什么不够用

二维路线的核心思想是把 ECEF 里的量测用保角映射投到一个公共切平面上,在平面上估偏差,好处是计算量小、实现简单。球极投影是其中代表,它保角,但代价有三个:地球是椭球不是圆球,投影本身引入误差;保角只保证角度不变形,斜距会变形,导致原本是常数的系统偏差在投影后变成与量测相关的变量;平面模型里压根没有俯仰通道,俯仰角偏差估不出来。

对自动驾驶这种场景,第三个缺点基本判死刑。激光雷达和相机的外参里俯仰是必估项,只估方位和径向斜距根本不够。所以二维路线适合作为快速验证和粗标定的第一步,正式上线还是得走 ECEF 三维。

历史算法里,RTQC 是最朴素的一种:把多传感器对同一目标的量测取均值当作真值,各传感器减去均值即为偏差估计。它在噪声小的时候能用,噪声一大估计就散。最小二乘、广义最小二乘、精确极大似然这三种,前三个(RTQC、LS、GLS)在观测模型里都对系统偏差做了线性化处理,对目标的空间分布很敏感,而且忽略了测量噪声对偏差估计的影响;EML 考虑了噪声,但因为仍然是二维算法,数据扭曲的问题绕不过去。

4.2 离线批量估计:LS、GLS、EML 的最小实现

先看最容易抄的一版。假设已经做完目标关联和时间对齐,两传感器在公共系下的量测序列是z1、z2,模型是z_i = x_true + b_i + v_i,两两相减后真实位置被消掉,只剩偏差差和噪声差:

import numpy as np def ls_relative_bias(z1, z2): """最小二乘估计两传感器相对偏差 z1, z2: (K,3) 公共系下的量测序列,已做目标关联与时间对齐 返回: 相对偏差 db, 以及满足 b1 + b2 = 0 约束下的各自偏差""" d = z1 - z2 # 每帧的偏差差观测 db = d.mean(axis=0) # 算术平均即 LS 解 return db, db / 2.0, -db / 2.0 def gls_relative_bias(z1, z2, w_list): """广义最小二乘,w_list[k] 为第 k 帧的权重矩阵,通常取 (R1+R2)^-1""" num = np.zeros(3) den = np.zeros((3, 3)) for k in range(len(z1)): w = w_list[k] num += w @ (z1[k] - z2[k]) den += w return np.linalg.solve(den, num)

ls_relative_bias里那个d.mean(axis=0)之所以就是最小二乘解,是因为模型对偏差是线性的,且噪声零均值,正规方程化简后就是算术平均。返回的db/2和-db/2用了一个隐含约束:两传感器偏差之和为零。这个约束不是物理事实,纯粹是为了让方程有唯一解,等价于把其中一个传感器当作基准。工程上更稳妥的写法是明确指定主传感器,把它的偏差钉死为零,另一个全吃。

gls_relative_bias值得单独说一句:如果每帧的权重矩阵都是同一个常矩阵,它退化成的结果和算术平均一模一样。GLS 真正比 LS 强的地方,是权重随距离和方位变化的时候——量测噪声在极坐标下近似各向同性,转到直角系后会变成椭球,距离越远横向方差越大。这时候给远距离帧小权重、近距离帧大权重,估计方差能明显压下来。所以用 GLS 之前先确认你的噪声协方差是不是真的在变,不变的话直接上 LS,省事。

EML 则是在这两者之上再进一步,把噪声分布显式写进似然函数,用数值优化求解。它的代价是要跑迭代,且对初值敏感,初值给得离谱会收敛到局部极值。我一般拿 LS 的结果当 EML 的初值,两段式跑,收敛稳定很多。

4.3 在线滤波族:KF、EKF、UKF 的适用边界与发散诱因

离线批量估计要求偏差基本恒定,且得攒够一批数据。要实时出结果,就得上滤波。

KF 是最直接的一档,把偏差当状态、把两传感器量测之差当观测,递推着估。它考虑了测量噪声,但只适用于配准偏差和姿态偏差都很小的情形,偏差一大,线性假设就站不住。

def kf_bias_track(z1, z2, q=1e-4, r=1e-2): """用 Kalman 滤波在线递推相对偏差 q: 过程噪声方差(偏差缓变); r: 量测噪声方差""" x = np.zeros(3) P = np.eye(3) * 10.0 H = np.eye(3) Q = np.eye(3) * q Rm = np.eye(3) * r hist = [] for k in range(len(z1)): P = P + Q # 预测 y = (z1[k] - z2[k]) - H @ x # 新息 S = H @ P @ H.T + Rm K = P @ H.T @ np.linalg.inv(S) # 增益 x = x + K @ y P = (np.eye(3) - K @ H) @ P hist.append(x.copy()) return np.array(hist)

q和r的比值决定收敛速度和平稳度的折中。q给太小,滤波器认为偏差万年不变,收敛慢得像蜗牛;q给太大,估计值跟着噪声一起跳,看着就不像常数。经验做法是先用离线 LS 估一个偏差量级,再按「每秒允许偏差漂移千分之一」来反推q。这段代码只做演示,真实系统里H通常不是单位阵,因为量测之差和偏差之间的映射要经过雅可比。

EKF 在 KF 基础上处理非线性,能同时估传感器位置偏差和方位偏差,缺点有三个:要求各传感器时钟完全同步、且假定无测量噪声(实际做不到);把配准和跟踪塞进同一个滤波方程,待估量和状态量没解耦,计算量陡增;以及最要命的一点——它直接假定测量误差服从零均值高斯,而量测从极坐标转到直角坐标后,高斯特性就丢了,这个假设从一开始就是错的。此外 EKF 的线性化误差会降低模型准确性,时间一长估计精度保不住。

KF 和 EKF 还有几个共性毛病:对模型参数不确定性鲁棒性差;系统到稳态时增益趋近极值,丧失对突变状态的跟踪能力;对初值依赖大;存在滤波发散。UKF 换了个思路,不去线性化状态函数,而是用 U 变换选一组确定性的 Sigma 点,让这些点沿时间传播,用它们的统计特性逼近后验。对配准这种强非线性场景,UKF 通常比 EKF 稳,代价是每步要算 2n+1 个点的传播,n 是状态维数,维数一高开销就上来了。

选型的实际判断标准,我一般这么排:偏差恒定、能攒数据,走 LS/EML 离线;偏差缓变、要实时,走 KF;非线性强、角度偏差占主导,走 UKF;EKF 放在最后考虑,除非系统里已经有现成的 EKF 框架不想动。至于强跟踪滤波器、模糊 C 均值聚类这些偏研究向的方法,适合在论文复现里做对比,产品线上慎用,可解释性和调参成本都偏高。

5. 避坑与排查:五次配准翻车的现象、原因和解决

5.1 偏差估出来是常数,远端航迹还是错位

现象:离线跑完 LS,两传感器的偏差估计收敛得很好,残差曲线也漂亮,但把参数灌到线上,近距离目标对得上,十几公里外的航迹还是偏十几米。

原因:只估出了相对偏差,绝对基准没定。方程里那个b1 + b2 = 0的约束是我人为加的,它保证了解唯一,但不保证解正确。真实场景里两个传感器可能同向偏,相对差很小但绝对偏差很大,这时候近距离看不出问题,远距离被几何放大就露馅了。

解决:明确指定一个主传感器,把它的偏差钉死为零(或者用它自己的出厂标定值),只估另一个;或者引入合作目标——某个位置已知的固定目标,让两个传感器同时看它,用已知真值把绝对基准锁住。这一步不能省,省了就是给自己留隐患。

5.2 目标换方位后偏差估计整体漂移

现象:用一批目标全在东北方向的数据估出偏差,换一批西北方向的数据重新估,两组参数差了一大截,看不出哪个是对的。

原因:偏差模型选的是二维球极投影,斜距在投影后变形,导致系统偏差不再是常数、而是跟量测相关。数据里目标方位分布一变,估出来的「常数」自然跟着变。

解决:换 ECEF 三维模型,把偏差定义在直角公共系里。如果非要用二维做快速验证,至少保证标定数据的方位覆盖 360°,并且明确记录标定覆盖的空域范围,超出范围不做外推。

5.3 滤波越跑越偏,估计值单向发散

现象:KF 或 UKF 跑着跑着,偏差估计值一路往一个方向走,最后大到不合理,残差反而在减小——滤波器把自己的错误吸收进状态里了。

原因:可观测性不足。目标一直匀速直线飞,两个传感器的几何构型几乎不变,偏差和真实位置在这组观测下是耦合的,滤波器分不清哪个是偏差哪个是位置,就随便分了一个。加上过程噪声q给得偏大,状态有足够的自由度去乱跑。

解决:加可观测性门限——只在目标有机动、或者载体有转弯、或者观测几何有明显变化时才更新偏差状态,其余时间冻结;同时把q调小,让偏差状态更「懒」。这一条是血泪经验,早期我总想着让滤波器自己学,结果学出来的全是噪声。

5.4 时间戳没对齐,被当成空间偏差吃掉

现象:配准后残余偏差始终有一两米的固定值,怎么调空间模型都消不掉,换个目标速度就变。

原因:两传感器的时间戳不同步。目标以 20 m/s 运动时,50 ms 的延迟就对应 1 m 位移,这个位移在空间配准模型里跟真实偏差长得一模一样,算法分不出来,直接当偏差估进去了。速度一变,这个「偏差」就变,所以永远调不稳。

解决:先做时间对齐,再做空间配准,顺序不能反。常用的做法是用插值把两路量测重采样到同一时基,插值阶数按目标机动性选,匀速段一阶线性插值够用,机动段得上二阶以上。对齐之后再看残余偏差,往往能小一半。

5.5 安装矩阵用标称值,近距离没事远距离翻车

现象:实验室里两传感器对着十米外的靶标,配准精度很高;拉到外场对几公里外的目标,误差线性增长。

原因:R_bs用的是结构图纸上的标称安装角,实际装配的角误差在 0.1°~0.5°。这个角度误差造成的位置偏差与距离成正比,十米处只有几厘米,看不出来;几公里处就是米级甚至十米级。

解决:把安装角作为待估量放进配准模型里联合估计,而不是当常数。如果结构上允许,也可以先用合作目标做一次外参标定,把R_bs修准再上线。判断要不要修,看残差是不是随距离线性增长——是的话八成就是角度误差。

6. 仿真对比怎么搭才有说服力:可观测性、几何构型与残差自检

资料最后一节给了算法仿真对比结果,但光看别人跑出来的曲线意义不大,得自己搭一套能复现的仿真,才知道哪个算法在你的场景下站得住。我一般按三个维度搭网格:噪声水平(量测噪声从 1 m 扫到 50 m)、几何构型(目标方位均匀分布、集中扇区、单点悬停三种)、观测帧数(10、50、200 帧)。每个格子跑 100 次蒙特卡洛,统计偏差估计的 RMSE 和收敛所需帧数,出一张表比看十条曲线管用。

场景推荐算法收敛帧数(量级)主要风险
同载体、噪声小、方位全覆盖LS / GLS20~50噪声大方差大
同载体、噪声大、有角度偏差UKF50~100调参成本高
多载体静止、有合作目标EML10~30初值敏感
多载体运动、非合作KF + 可观测性门限100 以上易发散

仿真里最容易糊弄自己的一步是「真值生成」和「量测生成」用了同一套坐标变换代码。这样跑出来的残差永远漂亮,因为误差源被同一份 bug 抵消了。稳妥做法是量测生成用一套独立实现的变换链(哪怕写得笨一点),估计端用另一套,两边对不上才说明有真误差。

上线前我最常用的自检手段是留一段数据不参与估计,专门算配准后的残差随距离和方位的分布:

def residual_check(z1, z2, b1, b2, rng): """配准后残差自检:残差应无随距离/方位的系统性趋势""" r = (z1 - b1) - (z2 - b2) # 按距离分箱看均值,趋势明显说明模型还缺项 for lo, hi in [(0, 2000), (2000, 5000), (5000, 10000)]: m = (rng >= lo) & (rng < hi) if m.any(): print(f"{lo}-{hi}m 残差均值 {r[m].mean(axis=0).round(2)}")

如果三个距离箱的残差均值符号一致、量级递增,基本可以断定是角度类偏差没估干净;如果符号随机跳,那是噪声,不用管。这个检查只要几分钟,比事后在现场猜省事得多。

从那以后我每次交付配准参数,都强制走一遍「留出集残差按距离分箱」这道工序,不管算法跑出来的收敛曲线多好看。希望帮到你。

本文还有配套的精品资源,点击获取

返回列表