简介:针对全球卫星导航系统欺骗攻击与惯性测量单元融合定位需求,资料包提供了从原理分析到算法实现的完整参考,面向卫星导航、组合导航方向的研究人员、工程师及高年级学生。压缩包共包含30个文件,以13张示意图片、13个扩展标记文件为主,另含少量关联关系文件和1张图片;图片用于展示欺骗检测流程与融合定位结果,标记文件多用于保存文档结构与配置信息,整包仅1.99兆,下载查看都比较轻量。已有42人完成学习下载。文档从欺骗攻击原理入手,系统梳理了基于信号特征、位置一致性以及统计学习等检测技术,重点说明惯性测量单元与全球卫星导航系统融合时如何利用惯性数据补偿卫星信号中断,并在融合框架下设计欺骗识别与结果分析流程;随附的代码可直接在仿真环境中运行,帮助读者复现检测算法、评估其灵敏度和鲁棒性。资源内容兼具理论深度与工程可操作性,适合作为科研入门、课程设计或系统开发中的实用参考。 把一台普通GNSS接收机摆在楼顶,它根本不知道收到的信号是真是假。去年我在做无人车组合导航测试时,同事随口问了一句:如果这些“卫星信号”是伪造的,车子会往哪儿开?本来是想活跃气氛,结果整个会议室的注意力全被吸过去了。答案很直白:在没有任何额外信息的情况下,接收机会完全相信这些伪信号,并且把定位结果平滑地牵引到攻击者想要的位置。GNSS欺骗检测,就是为了解决这个“信任危机”而做的。这篇文章会把基于IMU+GNSS融合定位的欺骗检测算法完整梳理一遍,包括检测原理、Matlab仿真代码架构、结果分析里最容易踩的坑,适合正在做组合导航、无人系统或安全方向的朋友参考。
1. 欺骗信号是如何“攻破”普通接收机的
1.1 从信号结构看欺骗的三种手段
GNSS欺骗攻击通常可以分成三类,这点在做检测算法之前必须想清楚,因为不同的欺骗方式在观测数据上留下的“指纹”完全不同。
第一类是生成式欺骗。攻击者自己生成一套伪卫星信号,码结构、载波频率、导航电文全部模拟,功率稍微压过真实信号一点,接收机的跟踪环路就会锁定到伪造信号上。生成式欺骗最强的地方在于可以任意指定接收机解算出来的位置、速度和时间,也就是俗称的“把定位结果直接搬走”。但它的实现门槛高,需要精确知道卫星星座、码相位和电文内容。
第二类是转发式欺骗,也叫“弹射攻击”。攻击者接收真实卫星信号,经过延迟和放大后再播发出去。这种方式不用生成任何卫星电文,信号相关性和真实信号完全一样,所以接收机很难通过解调内容判断真假。转发式欺骗主要造成时钟偏移和位置偏移,虽然很难做到任意位置控制,但足以干扰授时设备和依赖GNSS的同步系统。
第三类是数据层欺骗,直接修改接收机输出的NMEA语句或位置结果,属于“走后门”。在纯射频欺骗检测里一般不考虑它,但实际工程项目里很常见,尤其是接收机固件被篡改或者接口被人接了个假源。
1.2 为什么传统接收机对欺骗几乎无感
关键在于接收机本身是一套“开环信任”的定位装置。正常工作时,接收机的码跟踪环路会搜索本地复制码与接收信号的相关峰,只要找到相关峰,就认为锁定了一颗卫星。欺骗信号只要在功率上比真实信号高几个dB,相关峰就会被拖过去,接收机甚至不会察觉到信号发生了切换。
很多人以为接收机可以靠载噪比、导航电文CRC校验、卫星数量一致性来识别欺骗,但这些东西全部能被伪造。欺骗信号本身就是一个完整、合法的信号结构,载噪比可以设计得和真实信号差不多,电文内容也能完全按实际卫星广播复制。所以单靠接收机自身的观测量来做欺骗判别,本质上只能做“特征怀疑”,没法做“真实性判定”,必须引入不受射频信号影响的独立参考源,这就是IMU的价值。
2. IMU与GNSS的互补关系:惯性测量为什么能当“照妖镜”
2.1 惯性导航的短期精度与长期漂移
IMU由加速度计和陀螺仪组成,它测量的是载体自身的比力和角速度,然后通过积分得到速度、位置和姿态。整个过程完全在接收机内部完成,不依赖任何外部射频信号,所以哪怕天上所有卫星信号都是假的,IMU给出的短时运动趋势也依然是真实的。
但惯性导航有一个天然缺点:误差随时间累积。加速度计零偏积分一次变成速度误差,再积分一次变成位置误差;陀螺仪零偏则会让姿态角缓慢漂移,姿态误差又会进一步放大加速度积分误差。所以单独使用IMU,几分钟内位置还可用,跑上十分钟位置可能就飞了。这也正是为什么惯导和卫星导航总是成对出现:GNSS负责修正长期漂移,IMU负责提供短时连续、平滑的运动信息。
用一个生活类比:GNSS像一个识字但容易轻信陌生人的本地向导,IMU像一个记性好但在无人区会慢慢迷路的旅人。两个人配合,向导提供全局坐标,旅人记录每一步怎么走,谁也别想轻易被骗。
2.2 融合定位中IMU带来的“一致性约束”
在组合导航里,惯导解算结果会作为滤波器的预测基准,GNSS量测作为外部修正。正常情况下,GNSS解算出的位置会在IMU预测位置附近小范围波动,这个“波动幅度”由滤波器协方差和GNSS噪声共同决定。如果GNSS信号被欺骗,量测位置会被强行拉到伪造轨迹上,和IMU预测位置之间就会出现一个明显偏离。
这个偏离在算法上表现为“新息”,也就是量测值与预测值的差。正常噪声下,新息服从零均值高斯分布;而一旦出现欺骗,新息的均值会发生偏移。直接拿新息的幅值和某个固定米数阈值比较其实不靠谱,因为IMU本身有噪声和漂移,不同运动状态下滤波器的置信度也不一样。正确做法是把新息除以它的标准差,用归一化统计量来做假设检验,这样无论车辆是静止、匀速还是急转弯,检测判据都能统一。
3. 融合定位架构下的欺骗检测指标设计
3.1 松耦合 vs 紧耦合:我应该怎么选
IMU+GNSS融合有松耦合和紧耦合两种主流架构,二者对欺骗检测的影响差异很大。松耦合把GNSS解算出的位置、速度作为量测输入滤波器,好处是结构简单、计算量小,工程上最容易落地;坏处是GNSS接收机内部已经把原始伪距、载波相位信息压缩成了定位结果,欺骗信号对原始观测量的影响会被平均和滤波,检测的灵敏度相对低。
紧耦合则直接使用伪距、伪距率等原始观测量。单颗卫星的信号被欺骗,伪距残差会表现出异常;多颗卫星联合欺骗,虽然每颗伪距看起来都自洽,但和IMU预测的几何关系会对不上。紧耦合检测能力更强,但需要拿到接收机原始观测量输出,很多商业接收机不开放完整数据,而且滤波器维度和复杂度也要高出一截。
如果只是做算法验证、毕业设计或者想快速跑通一条检测链路,我建议先用松耦合+位置域检测,把整个流程吃透;等需要做真机部署和更细粒度的检测时,再往紧耦合迁移。这个路线最省时间,也能把核心问题理清楚。两种方案对比如下:
| 架构 | 量测输入 | 检测灵敏度 | 工程复杂度 | 适用阶段 |
|---|---|---|---|---|
| 松耦合 | 位置/速度 | 中 | 低 | 算法演示、快速原型 |
| 紧耦合 | 伪距/伪距率 | 高 | 高 | 实机部署、精确检测 |
3.2 检测指标的构造逻辑:新息、残差与一致性检验
检测指标的核心就是构造一个能衡量“GNSS量测和IMU预测是否一致”的统计量。以松耦合位置域检测为例,设状态向量包含位置p和速度v,EKF预测后得到位置预测值x_pred,GNSS量测为z,则新息为:
r_k = z_k - H * x_pred
在实际判别时,会使用马氏距离:
d_k = r_k^T * S_k^{-1} * r_k
其中S_k = H * P_pred * H^T + R,是新息协方差。在无欺骗假设下,d_k近似服从自由度为3的卡方分布,因此给定一个虚警概率Pfa,就能用卡方分布表查出阈值。每次更新后,只要d_k超过阈值,就判定当前GNSS量测可疑。
但这里有一个容易被忽略的细节:当欺骗是“缓慢牵引”而非“瞬间跳变”时,单次新息可能并不大,因为滤波器会慢慢地跟着量测一起移动。应对方法有几种,最常用的是滑动窗口累积新息能量,把最近N个时刻的d_k累加起来再和阈值比较;也可以用CUSUM算法,专门检测均值的小幅偏移。从我的经验看,窗口长度取5~10个GNSS更新周期,对缓慢欺骗的检测延迟和误报率平衡得比较好。
4. Matlab工程实现:从数据生成到欺骗检测全流程
4.1 仿真数据生成:怎样制造“逼真”的欺骗场景
Matlab仿真里很多人第一步就做错了:直接生成一条真实轨迹,然后在轨迹上叠加一个欺骗偏移,最后跑滤波器发现检测不到,就开始怀疑算法。原因很简单,欺骗攻击针对的不是真值,而是GNSS量测。你必须把欺骗作用在“GNSS量测的值”上,而不是“载体的真值”上,滤波器才会产生异常新息。
我习惯这样生成仿真场景:先产生一条载体运动轨迹,比如“匀速直线+转弯”的组合;再根据轨迹生成IMU量测,在真实比力、角速度上叠加零偏和高斯白噪声;接着生成GNSS量测,把高斯噪声叠加到真实位置上。欺骗注入则是在某个时间段内,把GNSS量测整体拉向一个伪造位置。快速跳变场景直接加固定偏移;缓慢牵引场景则让偏移量按斜坡函数逐渐增大。核心代码框架如下:
% 生成真实轨迹 traj(n,3) traj = generateTrajectory(Ts, total_time); % 生成IMU量测:真实值 + 零偏 + 白噪声 imu_meas = traj_imu + bias + randn(n,6) .* sigma_imu; % 生成GNSS量测 gps_norm = traj + randn(n,3) * sigma_gps; % 注入欺骗:从100秒开始向目标位置牵引 spoof_start = 100; target_offset = [100, 200, 0]; % 伪造位置偏移 for k = spoof_start : n alpha = (k - spoof_start) / (spoof_duration / Ts); gps_spoof(k,:) = traj(k,:) + alpha * target_offset; end需要说明的是,这里生成的都是“量测值”,不是真值。欺骗开始后,滤波器看到的GNSS位置会逐渐偏离真实位置,但IMU依然按照真实运动积分,二者之间的矛盾就是检测算法的输入。
4.2 融合滤波器与检测模块的代码化
我习惯在Matlab里使用EKF做融合,状态变量是位置和速度,过程模型用恒速模型近似。量测矩阵H只对位置部分起作用,因此每一轮更新能够同时得到位置估计和一些速度修正。欺骗检测模块放在量测更新这一步:先预测,再计算新息和马氏距离,然后与卡方阈值比较,最后再决定是否执行正常更新。
% EKF预测 x_pred = F * x; P_pred = F * P * F' + Q; % 量测更新 H = [eye(3), zeros(3)]; r = z - H * x_pred; S = H * P_pred * H' + R; d = r' / S * r; % 欺骗检测 if d > chi2inv(1 - Pfa, 3) spoof_flag(k) = 1; else spoof_flag(k) = 0; end % 正常卡尔曼更新 K = P_pred * H' / S; x = x_pred + K * r; P = (eye(6) - K * H) * P_pred;这里有几个实现细节需要强调。R矩阵要根据GNSS接收机的定位噪声来设置,不能拍脑袋决定;d的计算用矩阵除法而不是直接求逆,数值稳定性更好;卡方阈值用chi2inv查表,自由度是3,不要把密度函数和分布函数搞混。检测标志置1后,我不会立刻丢弃GNSS量测,而是把它标记为可疑,再结合后面的多指标融合做最终判决。
4.3 结果可视化与评价指标
仿真跑完,需要从三个维度看结果:检测率、检测延迟和误报率。检测率是欺骗发生后被正确识别的概率,检测延迟是欺骗开始到首次触发告警的时间差,误报率则是无欺骗时段被误判为欺骗的概率。如果只画一条“检测到了”的曲线,很难判断算法好坏。
我会用subplot画出四条曲线:真实轨迹与估计轨迹对比、GNSS量测与IMU预测的位置误差、马氏距离随时间变化曲线、检测标志时间线。在欺骗注入时间段用xline或fill背景标出来,这样一眼就能看出检测延迟和误报位置。马氏距离曲线是最直观的工具,正常段基本在阈值以下小幅波动,欺骗段会明显冲破阈值,缓慢欺骗场景则可能表现为持续贴近阈值徘徊,这时就需要看累积统计量的曲线。
5. 结果分析中的三个关键调优方向
5.1 阈值选取与检测延迟的权衡
阈值直接决定了检测系统的“性格”。把虚警概率Pfa设成0.95对应的卡方阈值是7.81,系统非常灵敏,但正常噪声下也容易误报;设成0.999对应的阈值是16.27,误报明显减少,但小偏移欺骗可能漏检。我在调参时不会直接套理论值,而是先跑一遍正常场景,统计马氏距离的实际分位点,然后取比正常最高值再高20%左右作为阈值,这样能在保证不误报的前提下尽可能缩短检测延迟。
检测延迟和阈值本质上是一对矛盾。阈值放宽,误报率下降,但检测延迟上升;阈值收紧,检测快,但误报变多。工程上我倾向于优先保证正常场景零误报,因为车辆在正常道路上被误判为欺骗并切断GNSS更新,风险远高于检测延迟多出几百毫秒。
5.2 欺骗强度/场景参数对检测率的影响
不同欺骗参数下检测结果差异非常大,实验设计时一定要覆盖。快速跳变欺骗最容易检测,因为新息瞬间突变,马氏距离直接顶到几百上千;缓慢牵引欺骗最具挑战性,偏移增长速度和滤波器跟踪能力相当甚至更慢,单次新息一直处在阈值附近,很容易漏检。
我把常见参数对检测结果的影响整理成一个表,方便对照:
| 参数方向 | 对检测率的影响 | 原因 |
|---|---|---|
| 欺骗偏移量增大 | 检测率上升 | 新息幅度增大 |
| 欺骗牵引速度变慢 | 检测率下降 | 滤波器逐渐跟踪偏移 |
| IMU噪声增大 | 检测率下降 | 新息方差增大,统计量降低 |
| GNSS更新率提高 | 检测率上升 | 异常积累更快 |
| 欺骗持续时间缩短 | 检测率下降 | 可供观测的异常样本不足 |
由此可见,单纯靠位置新息对缓慢欺骗的检测能力有限,这也是为什么实际系统会把多个来源的观测量、多个统计特征放在一起做综合判决。
5.3 误报率控制与多指标融合
单一指标的局限性在实测中会被放大。车辆过弯、过减速带、GNSS信号被高楼遮挡时,载波相位周跳和卫星几何突变都会产生短暂的新息尖峰,单靠马氏距离很容易误报。我在工程上倾向于构造多个检测特征,然后采用“多指标表决”逻辑:位置新息、速度新息、接收机钟差跳变、载噪比突变同时出现异常时,才判定为欺骗告警。
多指标融合会牺牲一点检测灵敏度,但换来的误报率下降非常划算。告警后的处理策略也需要注意:不要检测到欺骗就立刻丢掉GNSS量测并切换纯惯导,因为此时惯导漂移会随时间快速累积。正确做法是先暂停GNSS更新,保存一段量测缓冲,确认欺骗持续存在后再切换模式,同时尝试重新捕获卫星信号。
6. 实操中踩过的坑与可以复用的经验
6.1 惯性器件噪声参数设置不当导致的“假检测”
仿真阶段最容易踩的坑是把IMU过程噪声Q给得太小。Q代表滤波器对运动模型的信任程度,Q设小,P_pred就小,新息协方差S也小,同样的量测噪声会被当成更大的异常,直接导致正常场景疯狂误报。我一度以为检测算法有问题,排查了半天才发现是Q矩阵里的加速度噪声密度少了两个数量级。
解决方法是先用正常仿真数据做一次IMU噪声参数标定,或者用Allan方差法把加速度计、陀螺仪的白噪声和零偏不稳定性估出来,再填入Q矩阵。没有标定数据时,宁可把Q设大一些,让滤波器更“迟钝”,也不要让滤波器“过度自信”。误报率爆炸的调试过程非常浪费时间。
6.2 同步误差对IMU/GNSS一致性检验的影响
IMU和GNSS时间不同步是实机上的经典问题,仿真阶段很难暴露,但一旦发现整个检测指标里总有一个固定偏置,就要开始怀疑时间戳。车辆在高速转弯时,GNSS数据晚到100毫秒,和IMU预测位置之间就可能差出几米,这个差值在静态场景下根本看不出来,但在动态检测里足够触发误报。
处理办法有两个:硬件上做PPS秒脉冲对齐,软件上把GNSS延迟估计成状态量,或者用量测缓存对齐时间戳。在Matlab仿真阶段可以先把时间同步问题忽略,但写博客或者做实验报告时一定要说明这个假设,否则别人拿到代码放在非理想时间戳环境下会得到完全不同的结论。
6.3 从仿真到实车/实机部署的迁移建议
Matlab代码跑通只是第一步,实机部署的坑远比仿真多。真实IMU存在温度漂移和安装偏置,GNSS在城市峡谷里有多路径,卫星变化会引起几何分布突变,这些都会干扰新息统计量。我建议的迁移路线是:先用自己采集的离线数据回放,跑一遍检测算法,把误报率压到零;再上实时平台,加短时间的欺骗测试;最后才做长时间的路测。
调试顺序也很重要。先从快速跳变欺骗开始,确认检测链路通;再切换到缓慢牵引欺骗,全力对付漏报问题;最后在复杂运动场景下做误报率优化。别一上来就追求“完美检测率”,先把正常场景跑一百遍,误报率归零,再谈检测灵敏度,这个顺序能省掉大量无用功。
本文还有配套的精品资源,点击获取