☰
BOC调制下DLL跟踪环收敛曲线仿真:副峰锁定与参数调试
2026/10/27 8:55:19 网站建设 项目流程

简介:面向BOC调制解调与卫星导航信号跟踪研究者的MATLAB仿真分析资源,聚焦跟踪环锁定跟踪性能的收敛曲线,并引入卡尔曼滤波实现稳定跟踪输出,同时对比Unambiguous与KFPELTA两类方法的跟踪效果。资源基于MATLAB 2021a,包含完整可运行的仿真脚本、用于结果保存的MAT数据文件、收敛曲线截图以及操作录像,录像可指导使用者正确设置当前文件夹路径并复现实验,适合通信或导航专业学生、算法工程师用于环路跟踪算法验证与参数分析。压缩包共31个文件,以.m脚本、.mat数据、.jpg图片和.avi录像为主要类型,整体大小约3.79MB,目录内按sinBOC10_5_40、sinBOC10_5_60、sinBOC10_5_80等不同调制参数组织,便于对照不同BOC阶数下的收敛表现。已有183人学习下载,对理解BOC信号跟踪环路的锁定过程及卡尔曼滤波的优化作用有直接参考价值。

1. BOC 跟踪环收敛曲线先立住概念:副峰模糊才是要防的主问题

把 BOC 调制解调系统的跟踪环锁进主峰,比把 BPSK 锁进主峰难一个量级。不是环路本身复杂,而是 BOC 的自相关函数在主峰两边硬挤出几个副峰,鉴别器 S 曲线跟着多出几个稳态过零点,传统延迟锁定环(DLL)一旦初始码相位误差超过牵引区,就可能朝副峰收敛,测距偏差按米甚至按数十米计。matlab 仿真里真正要盯的,不是曲线能不能收敛,而是收敛曲线最终停在哪个码相位上。这篇笔记按我搭仿真的一贯顺序讲:先从 BOC 相关函数与鉴别器失真讲清楚副峰为什么能骗过环路,再给出一套最小可复现的 matlab DLL 代码和参数表,接着讨论收敛曲线判读、五个高频踩坑点,以及不依赖运气的结果验证技巧。适合正在做 GNSS 基带算法仿真、BOC 兼容性评估或扩频测距毕业设计的人。

2. 副峰锁定为什么防不住:先从 BOC 自相关和 S 曲线看透

2.1 BOC 自相关的多峰结构是“伪相关峰”的源头

BOC 调制把扩频码再乘以一个方波副载波,常见写法是 BOC(m, n),m 代表副载波频率是 1.023 MHz 的 m 倍,n 代表码速率是 1.023 MHz 的 n 倍。以最常用的 BOC(1, 1) 为例,副载波频率和码速率都是 1.023 MHz,每个码片内副载波翻转一次。这个翻转让自相关函数从 BPSK 的宽三角峰变成了尖主峰加两边负副峰的形状,主峰底部宽度压缩到约 1 个码片,而副峰出现在主峰两侧约 ±1 码片处,电平大约为主峰的一半。

副峰电平达到主峰的 50%,这就是问题的根源。延迟锁定环靠超前减滞后相关值的差形成 S 曲线,S 曲线的斜率方向决定环路是否稳定。主峰附近有一个斜率正常的稳定过零点,而副峰位置同样存在斜率相反的假稳定过零点。初始码相位误差如果落在副峰的牵引范围内,环路会把假过零点当作“已锁定”处理,输出一个看着很平、实际错位的收敛曲线。

这里常被忽略的是相干积分时间的选择。积分时间越长,相关峰幅度越高,但不能改变主峰副峰的相对位置,也不能消除副峰。真正能把副峰风险压下去的手段只有两个:一是靠捕获阶段的码相位搜索把初值误差压到主峰牵引区内,二是把早迟间距 d 和环路带宽调到一个不会让 S 曲线副峰参与判定的组合。

2.2 用一个对比表看清 BOC 与 BPSK 的跟踪差异

我习惯把 BPSK-R 和 BOC(1, 1) 的差异浓缩成一张表,仿真参数换挡时对着它检查,能少很多弯路。

项目BPSK-R(1)BOC(1,1)
主峰形状底宽约 2 码片的三角峰底宽约 1 码片的尖峰
副峰无±1 码片处各一个负副峰,约主峰一半
S 曲线线性区较宽,约 ±0.5 码片较窄,约 ±0.25 码片
额外过零点无主峰两侧各有一个伪稳定过零
初始误差容忍度初值误差 0.5 码片也能拉回初值误差超过 0.3~0.4 码片时可能误锁

这张表直接解释了为什么同一个跟踪环,跑 BPSK 没问题,一换到 BOC 就总在某个码相位上“锁死”。也解释了为什么仿真录像里演示者总强调先把捕获初值做好:BOC 的跟踪环不是拿来兜底的,它只在初始误差不离谱时才能给你一条漂亮的主峰收敛曲线。

2.3 副峰锁定的数学直觉:鉴别器过零点不等于稳定点

很多初学者看到收敛曲线平了就觉得万事大吉,这是最大的误判。判定一个过零点稳不稳定,要看 S 曲线在该点的斜率。主峰锁定点的斜率是负反馈方向,误差往正方向偏,鉴别器输出就往负方向推,环路能把误差压回来。副峰伪锁定点斜率相反,它看起来也能让误差停在某个值,但这个值偏离真实码相位约 1 个码片,在测距上等价于约 293 米的偏差,对 BOC(1, 1) 而言。

仿真时还有一种情况更隐蔽:副峰锁定与主峰锁定的收敛曲线最终都是平的,只在收敛过程的中间段有区别。我在 2.4 节会专门讲怎么读区别。这里先记住结论:BOC 跟踪环的收敛曲线不能只看“平不平”,还要看终值在哪,以及鉴别器输出在终值附近是否还残留一个不等于零的偏置。

2.4 从捕获到跟踪的误差迁移过程

跟踪环仿真里,初始误差通常由捕获阶段给出。捕获的码相位搜索步长如果等于 0.5 码片,那么跟踪环起步就有 0.25 码片甚至更大误差,刚好落在 BOC 主峰牵引区边缘,误锁概率开始上升。这就是为什么正规接收机里 BOC 捕获往往用更细的搜索步进,或者用副峰消除技术把本地码改造成单主峰形式。

在 matlab 仿真里复现这个过程,不需要把捕获也建模进去,直接把初始码相位误差写成变量就行。我会在下一章给出代码,把初值设为 0.6 码片,跑到 3 秒,让环路的收敛过程完整地画出来。你能清楚看到误差从大慢慢变小、鉴别器输出从饱和区进入线性区、环路滤波器输出逐渐逼近真实码速率的过程。

3. 在 Matlab 里搭最小码跟踪环:参数、环路滤波器与收敛曲线代码

3.1 最小可复现代码:BOC(1,1) 本地码生成

这里只做码跟踪环(DLL),不把载波环耦合进来,避免 PLL 和 DLL 两个环路的交互把收敛曲线分析搅浑。接收信号直接用基带 BOC 码加上高斯噪声,本地码分成超前、即时、滞后三路,做积分清零后进鉴别器。整体仿真时间 3 秒,每个积分块 1 毫秒,共 3000 个块,普通电脑几秒就能跑完。

fs = 20e6; % 采样率 20 MHz,每码片约 19 个样点 fc = 1.023e6; % 扩频码速率 1.023 Mchip/s fsc = 1.023e6; % BOC(1,1) 副载波频率 Nchip = 1023; % 一个码周期的码片数 spc = round(fs / fc); % 每码片采样点数 Ns = Nchip * spc; % 一个码周期的总样点数 % 简化 PRN 为全 1,只保留 BOC 相关峰结构 boc = sign(sin(2 * pi * fsc * (0:Ns-1) / fs));

这段代码把 BOC(1,1) 本地码先做出来。采样率选 20 MHz,是为了让每个码片大约有 19 个采样点,副载波翻转沿能被完整采样到。如果采样率降到 8 MHz 以下,相关峰局部会变形,后面误导锁分析,所以这个参数不建议改小。

3.2 跟踪环主体:相关器、鉴别器、环路滤波器

环路部分我按“积分清零 → 鉴别器 → 二阶环路滤波器 → 码相位累加器”的顺序写。鉴别器用相干超前减滞后,并除以即时幅值做归一化,这样噪声变化不会直接影响鉴别器增益。环路滤波器用比例加积分形式,比例系数和积分系数由环路带宽 BL 和阻尼比 zeta 推导。

Tcoh = 1e-3; % 相干积分时间 1 ms Nblk = round(fs * Tcoh); % 每块 20000 个采样点 nBlocks = 3000; % 3 秒仿真 sigma = 0.05; % 基带噪声幅度,先设小一点 d = 0.2; % 早迟间距,单位 chip dSamp = round(d * spc); % 转换为采样点 BL = 1.0; % 环路带宽 1 Hz zeta = 0.707; % 阻尼比,临界阻尼 wn = BL / (zeta + 0.25 / zeta); % 二阶环自然角频率 Kp = 2 * zeta * wn; % 比例系数 Ki = wn^2; % 积分系数 trueChip = 0; % 真实码相位,单位 chip locChip = 0.6; % 本地码相位,故意初始偏差 0.6 chip intState = 0; % 环路积分状态 errHist = zeros(nBlocks, 1); discHist = zeros(nBlocks, 1); fltHist = zeros(nBlocks, 1); for k = 1:nBlocks blkIdx = (k-1) * Nblk : k * Nblk - 1; % 接收码:真实码相位偏移随时间累积 rIdx = mod(round(blkIdx + trueChip * spc), Ns) + 1; rx = boc(rIdx) + sigma * randn(1, Nblk); % 本地即时、超前、滞后三路 lIdx = mod(round(blkIdx + locChip * spc), Ns) + 1; locP = boc(lIdx); locE = boc(mod(lIdx - dSamp - 1, Ns) + 1); locL = boc(mod(lIdx + dSamp - 1, Ns) + 1); % 相关积分 Ip = sum(rx .* locP); Ie = sum(rx .* locE); Il = sum(rx .* locL); % 归一化超前减滞后鉴别器 disc = (Ie - Il) / abs(Ip + eps); discHist(k) = disc; % 二阶环路滤波器:比例 + 积分 intState = intState + Ki * disc * Tcoh; filtOut = Kp * disc + intState; fltHist(k) = filtOut; % 本地码相位更新 locChip = locChip + (fc + filtOut) * Tcoh; trueChip = trueChip + fc * Tcoh; errHist(k) = trueChip - locChip; end

这段代码里有几个关键点需要说明。第一,鉴别器用 abs(Ip) 做归一化,可以在噪声变化时保持环路的等效增益稳定,否则不同信噪比下收敛曲线形状会差很远。第二,环路滤波器的 intState 每步都累加 Ki * disc * Tcoh,相当于对鉴别器输出做积分,让环路在稳态时输出正好等于输入码速率,误差趋近于零。第三,locChip 和 trueChip 在每步都加 fc * Tcoh,相当于一个理想码 NCO,filtOut 只是叠加上去的修正量。

如果你跑出来发现曲线朝发散的符号方向走,不用怀疑算法结构,这是初始偏差方向定义的差异。解决办法是把鉴别器输出乘以 -1,或者把 locChip 初值改成 -0.6,二选一即可。仿真里这种符号问题很常见,属于定义层面的坑。

3.3 收敛曲线绘图脚本

环路跑完,把误差、鉴别器输出、滤波器输出三路数据画在同一个 figure 里,这就是标题里说的收敛曲线图。我通常把横轴统一成毫秒,便于和示波器或录像里的时间轴对拍。

t_ms = (1:nBlocks) * Tcoh * 1000; figure; subplot(3,1,1); plot(t_ms, errHist, 'LineWidth', 1.2); ylabel('码相位误差 / chip'); grid on; title('BOC(1,1) DLL 收敛曲线'); subplot(3,1,2); plot(t_ms, discHist, 'LineWidth', 1.2); ylabel('鉴别器输出'); grid on; subplot(3,1,3); plot(t_ms, fltHist, 'LineWidth', 1.2); ylabel('环路滤波器输出'); xlabel('时间 / ms'); grid on;

主图上三条曲线各有用途:误差曲线看收敛终值和收敛时间,鉴别器输出看工作点是否进入线性区,滤波器输出看环路的频率修正过程。三张图放在一起,能直接判断环路是否健康。只画误差一条线的录像,建议你在复现时补上下面两条,排查问题会快很多。

3.4 参数设置表与调节方向

仿真做熟了以后,参数怎么调基本可以背下来。下面这张表是我每次新建仿真时的默认起点。

参数默认值调节方向与影响
fs20 MHz每码片约 19 个采样点;低于 8 MHz 相关峰失真
Tcoh1 ms加大抗噪好,但动态响应变慢;高动态时改 0.5 ms
BL1 Hz调大收敛快但稳态抖动大,调小反之
zeta0.707小于 0.5 会明显过冲
d0.2 chip调小理论精度高,但牵引区变窄,副峰风险增大
sigma0.05基带噪声幅度,蒙特卡洛时按 SNR 折算

这组参数里,最容易让新手翻车的是 BL 和 d 的联调。BL 决定收敛速度,d 决定 S 曲线形状,两者互相独立,但都对误锁概率有影响。想看到标准二阶收敛曲线,先把 BL 固定到 1 Hz,d 固定到 0.2 chip,不要一上来就两个一起扫。

4. 把收敛曲线读成诊断报告:锁定时间、稳态抖动与副峰误锁的判读

4.1 一条完整的收敛曲线要读四个量

很多人拿到 matlab 画的收敛曲线,只看误差曲线有没有拉平。这个不够。我至少读四个量:码相位误差的终值、误差进入 ±0.1 码片后再没出去的时间点、鉴别器输出在稳态附近是否过零、以及环路滤波器输出是否收敛到某个固定值。

误差终值接近 0 是主峰锁定的必要条件,但不是充分条件。鉴别器输出在稳态时必须在零附近小幅摆动,如果稳态时它还维持一个明显偏置,说明本地码波形和接收码波形之间有系统性差异,常见原因是采样率不足或 d 太大。环路滤波器输出则应该收敛到输入信号的码多普勒和码钟漂移之和,如果它一直在单调爬升,那说明真实信号里存在一个未被完全补偿的加速度项,用户可能误把二阶环当三阶环用。

还有一个判读工具是即时相关幅值 Ip。主峰锁定时 Ip 明显大于副峰锁定时,因为 BOC 主峰自相关值大于副峰。仿真的时候把 Ip 也存下来,画在第四个子图里,有没有锁上主峰一眼就能分辨。这就是为什么我建议即使标题只要收敛曲线,也顺手把 Ip 画出来。

4.2 锁定时间与稳态抖动的权衡

收敛曲线里最直观的指标是锁定时间,我把它定义为误差第一次进入 ±0.1 码片并持续保持 500 ms 以上的时间点。BL 越大锁定越快,但稳态抖动也会变大。抖动幅度大致正比于环路带宽的平方根,带宽从 1 Hz 提到 4 Hz,抖动大约翻一倍,而锁定时间可能只缩短三四倍。这个交换比不划算,所以我不建议把 BL 调得过高。

d 的影响更微妙。d 从 0.2 降到 0.1,S 曲线的线性区变窄,理论上稳态精度提高,但鉴别器输出在小误差下的斜率变陡,环路的等效增益变大,实际抖动可能反而上升。d 同时影响牵引区宽度,d 越大,主峰附近的线性区越宽,副峰离线性区边缘的距离越短。结果就是 d 太大容易让副峰进入可牵引范围,d 太小容易让主峰线性区覆盖不了初始误差。仿真里出现“换了一个 d 就从主峰锁定变成副峰锁定”时,多半是 d 已经到 0.3 以上了。

4.3 副峰误锁在曲线上的三个特征

副峰误锁不是随机的,它在收敛曲线上有比较固定的表现。第一,误差终值不会到零,而是停在约 ±1 码片附近,对应 BOC(1,1) 副峰位置。第二,收敛过程看起来也很快,甚至可能比主峰锁定还快,因为副峰牵引区的斜率也很大。第三,环路滤波器输出和主峰锁定时几乎相同,因为副峰和主峰只差码相位,频率修正量在稳态都一样。前两条能区分大部分误锁,第三条解释了为什么只看前两个图也会被骗。

要区分副峰锁定和主峰锁定,最可靠的方法就是把本地码和接收码的相关峰值算出来。副峰锁定时 Ip 只到主峰锁定时的约一半。另一个辅助判据是随机改变初始误差重新跑几十次,统计最终误差落在主峰还是副峰的次数,这个概率就是误锁率。误锁率高过 10% 时,我会先回头调捕获步进,而不是动环路参数。

5. BOC 跟踪环仿真的五个常见翻车点:现象、原因与解决

第一个坑:误差曲线停在 1 码片附近,看着平了但 Ip 只有主峰的一半。原因就是初始误差落入副峰牵引区,环路锁到了副峰上。解决办法是先把初始误差改到 0.1 码片以内确认主峰锁定形态,然后逐步加大初值找出临界牵引范围,再回头把捕获搜索步进调细。

第二个坑:误差曲线在零附近来回振荡,衰减很慢甚至等幅振荡。原因通常是 BL 设到 5 Hz 以上,环路带宽接近甚至超过积分更新率,数字环路滤波器的离散化误差被放大。解决方法是把 BL 先降到 1 Hz 试跑,确认无振荡后再慢慢提升。也有可能是 zeta 设成了 0.2 左右,欠阻尼造成,把 zeta 固定到 0.707 就能消除。

第三个坑:改采样率后收敛曲线形态完全变了,明明同样的初值和环路参数,结果却不同。原因是采样率低于每码片 8 个采样点时,BOC 副载波翻转沿被平均掉,相关峰变钝,S 曲线斜率跟着变。解决方法是采样率不要低于 16 MHz,这不是玄学,是 BOC 测距精度的基本底线。仿真只追求趋势时最低也要 10 MHz。

第四个坑:加噪声后误差曲线完全发散,不加噪声时明明收敛很好。原因一般是 sigma 设得过大,也就是等效载噪比过低,或者噪声功率没有按带宽归一化。解决方法是把 sigma 从 0.01 开始逐步加大,看环路在哪一格开始失锁,而不是一上来就在强噪声下跑。真正的接收机里还有载波环辅助,码环单独扛噪声的能力弱很多。

第五个坑:拿着别人的仿真录像对拍,参数和结构都对,但曲线对不上。原因经常是早迟间距的定义差一个正负号,或者初始误差方向不同,导致收敛过程前半段不一致。解决方法是先录一条无噪声的收敛曲线,对比误差终值和锁定时间是否一致,再考虑噪声。对拍时如果录像只给误差曲线,没有给鉴别器和滤波器输出,建议直接重新自己跑一组完整数据,别拿半张图硬猜。这个习惯能省你半天到一天时间。

6. 收敛曲线的两条验证技巧,以及我自己的每轮必查习惯

最后一件事,是给自己留一条验证后路。我第一次跑 BOC 跟踪环仿真时,把误差曲线调得笔直,以为万事大吉,后来加上真实噪声发现抖动远比我预期大,才意识到收敛曲线好不好看不代表性能达标。之后我固定了一轮验证方案。

第一步,先跑无噪声版本。无噪声时环路应该达到零稳态误差,误差曲线最后贴在零线上,没有任何残留偏置。如果无噪声版本还有固定偏置,先检查 d 是不是太大,或者采样率是不是不足。第二步,再跑有噪声版本,至少重复 30 次,把误差曲线画成均值加标准差带。单次曲线可能因为随机种子不同看上去差异很大,均值带才能反映真实性能。第三步,做一个快速带宽切换实验:先用 BL 等于 5 Hz 让误差快速收敛到零附近,等 1 秒后把 BL 切到 0.5 Hz,观察曲线是否变得平滑而均值不移动。均值不动说明环路没有偏置,带宽减小后抖动变小说明环路设计正常。

这个带宽切换技巧在工程里很实用,它能把“收敛快”和“稳态准”两件事分开验证。一个真正交付的跟踪环,通常是先用宽带拉入、再用窄带跟踪,仿真阶段就把这个流程验证一遍,后面做 FPGA 或者实时处理时心里是有底的。我自己每轮仿真必查三件事:初始误差方向符号对不对、BL 和 d 有没有设反、Ip 曲线有没有保存。这三件小事踩过太多次,属于血泪经验。BOC 跟踪环的收敛曲线本来就不难看懂,难的是确认它真的锁在主峰上,希望我的这套习惯能帮你在复现这类仿真资料时少走弯路。

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询