资讯动态

升沉测量中高通滤波器相位滞后描述错误与补偿方法

发布时间:2026/10/27 18:12:54 来源:尧图企业网站定制
1. 从一次海试数据异常说起升沉测量中的相位滞后问题如果你做过船舶或海洋平台的升沉测量大概率遇到过这样一种情况加速度计积分出来的升沉位移在长周期涌浪下看着还行可一旦海况变得复杂、波浪周期变短测量结果就开始对不上——不是幅值偏小就是相位明显超前或滞后于真实运动。更让人头疼的是当你回头去查算法文档发现里面关于高通滤波器相位滞后的描述和实际跑出来的数据根本对不上号。这不是个例。升沉测量本质上是从加速度信号出发经过两次积分得到位移而积分过程会引入低频漂移必须用高通滤波器把低频分量滤掉。问题就出在这个高通滤波器上它确实能抑制漂移但同时也会在通带边缘引入相位滞后。很多技术资料在描述这个滞后时要么一笔带过要么给出的公式和实际离散实现不一致导致工程人员在补偿相位时用错了模型最终测量精度上不去。这篇内容就是围绕升沉测量中高通滤波器相位滞后描述错误这个具体问题展开的。我会把相位滞后到底怎么产生的、常见描述错在哪里、怎么用正确的方式去建模和补偿以及实际工程中怎么验证一层层拆开讲清楚。适合做船舶运动测量、惯性导航、海洋工程信号处理的同行参考也适合刚接触升沉算法、想搞明白为什么我的相位总是对不上的朋友。先说结论相位滞后描述错误通常不是滤波器本身设计错了而是描述模型和实际实现不匹配。模拟域的相位公式直接套到离散域或者忽略了滤波器阶数、采样率、截止频率之间的耦合关系都会让补偿量算错。下面我从原理到实操把这件事讲透。2. 高通滤波器在升沉测量里到底扮演什么角色2.1 为什么升沉测量非要用高通滤波器升沉测量的一般流程是加速度计测到垂向加速度第一次积分得到垂向速度第二次积分得到垂向位移。理想情况下如果加速度信号是纯正弦且没有零偏两次积分就能还原位移。但现实里加速度计有零偏、有噪声积分会把零偏变成随时间线性增长的速度漂移再积分就变成二次增长的位移漂移。几分钟下来位移可能漂到几百米完全不可用。所以必须在积分链路里加高通滤波器把低频和直流分量压掉。高通滤波器的截止频率通常选在波浪主频以下比如0.02Hz到0.05Hz这个量级具体取决于你关心的最低波浪周期。这样一来长周期的漂移被抑制而真正关心的波浪运动频段能通过。但高通滤波器不是理想砖墙它在截止频率附近有一个过渡带过渡带内既有幅值衰减也有相位变化。这个相位变化就是相位滞后的来源。对于升沉测量来说相位误差直接对应时间上的延迟如果滞后0.5秒在周期8秒的波浪里就是22.5度的相位差换算成位移误差可能达到幅值的百分之几到十几高精度场景下这是不能接受的。2.2 相位滞后不是错误描述错误才是问题这里要澄清一个概念高通滤波器有相位滞后这是物理规律不是bug。一阶高通滤波器在截止频率处的相位是45度注意符号取决于定义在远高于截止频率处趋近于0度在远低于截止频率处趋近于90度。二阶高通滤波器相位变化更陡截止频率处可能达到90度甚至更多。真正的问题是很多文档在描述这个相位特性时用的是模拟域的连续传递函数比如一阶高通写成H(s) s / (s ωc)然后直接给出相位公式φ(ω) 90° - arctan(ω / ωc)这个公式本身没错但它描述的是模拟滤波器。实际工程里滤波器是在数字域实现的用的是双线性变换或者冲激响应不变法离散出来的差分方程。离散化之后相位特性会发生畸变尤其是在截止频率附近和高频段。如果你拿模拟域的相位公式去算补偿量就会引入系统性误差。更隐蔽的一种错误是有些资料把相位滞后的符号写反了或者把高通滤波器的相位说成超前。这会导致补偿方向搞错越补越差。我在实际项目里就见过有人把补偿量加反了结果升沉测量的相位误差从原来的10度变成了20度。2.3 相位滞后对升沉测量的实际影响有多大为了让大家有个直观感受我列一个简单的对照表。假设波浪周期为8秒对应频率0.125Hz高通滤波器截止频率设为0.03Hz采用二阶巴特沃斯高通。滤波器类型截止频率在0.125Hz处的相位滞后对应时间延迟对升沉幅值的影响一阶高通0.03Hz约13.5度约0.3秒幅值衰减约1%二阶高通0.03Hz约26度约0.58秒幅值衰减约2%四阶高通0.03Hz约50度约1.1秒幅值衰减约5%从表里能看出来阶数越高相位滞后越明显。四阶高通在8秒周期处已经滞后50度时间延迟超过1秒。对于动力定位、直升机甲板运动补偿这类应用1秒的延迟是致命的。所以升沉测量里通常不会用太高阶的高通二阶已经算比较激进一阶更常见但一阶的滚降太慢抑制漂移能力有限需要配合其他手段。这里的关键点是你必须知道自己用的滤波器在关心频段上的真实相位而不是想当然地套公式。描述错误往往就发生在这一步。3. 相位滞后描述错误的几种典型表现与根因3.1 模拟域公式直接套用到离散域这是最常见的一类错误。很多教材和论文在推导升沉算法时为了简洁直接用模拟域的传递函数分析相位然后给出补偿公式。但实际代码里跑的是离散滤波器比如用双线性变换得到的二阶节。双线性变换有一个特性它会把模拟频率轴非线性地映射到数字频率轴也就是所谓的频率翘曲。在低频段这种翘曲很小可以忽略但在截止频率附近翘曲会变得明显。举个例子采样率50Hz截止频率0.03Hz归一化频率是0.0006翘曲几乎为零这时候模拟公式和离散结果差别不大。但如果采样率降到5Hz归一化截止频率变成0.006翘曲开始显现相位误差可能有几度。更麻烦的是有些实现用的是预畸变双线性变换也就是在离散化之前先把截止频率预畸变一下让离散后的截止频率正好落在设计值上。这种实现下相位特性又和普通双线性变换不同。如果你不知道代码里用的是哪种直接套模拟公式就会错。我个人的经验是只要采样率不是特别高或者截止频率不是特别低就不要偷懒用模拟公式老老实实从离散传递函数算相位。离散传递函数可以写成H(z) (b0 b1*z^-1 b2*z^-2) / (a0 a1*z^-1 a2*z^-2)令z e^(jωT)其中T是采样周期ω是角频率然后求H(e^(jωT))的相角就是真实相位。这个计算在MATLAB或Python里几行代码就能搞定没必要省这个事。3.2 忽略滤波器阶数和级联带来的相位叠加另一个常见错误是只考虑单个二阶节的相位忽略了级联。比如四阶高通通常是两个二阶节级联总相位是两个节相位之和。如果你只算了一个节的相位补偿量就少了一半。还有一种情况是升沉算法里除了高通滤波器还有低通滤波器、积分器、甚至陷波器。这些环节都会贡献相位必须全部算进去。我见过一个项目工程师只补偿了高通滤波器的相位结果发现总相位还是对不上后来一查积分器本身在低频段有-90度相位虽然在高频段趋近于-90度但和频率有关加上低通滤波器的相位总误差就出来了。所以正确的做法是把整个信号链的传递函数写出来从加速度输入到位移输出逐环节相乘然后求总相位。不要只盯着高通滤波器看。3.3 相位符号和补偿方向搞反这个错误听起来很低级但实际中真不少见。高通滤波器的相位在不同定义下符号可能不同。如果你看的是H(s) s/(sωc)当ω远大于ωc时H(jω) ≈ 1相位趋近0当ω远小于ωc时H(jω) ≈ jω/ωc相位趋近90度。所以高通滤波器的相位是正的意味着输出超前输入。但注意这是超前。而在升沉测量里我们通常说相位滞后是因为从加速度到位移的整个链路里积分器贡献了-90度每级的相位高通滤波器的正相位只能部分抵消积分器的负相位净效果仍然是滞后。如果你把高通滤波器的相位当成滞后去补偿方向就反了。更绕的是有些文献定义高通滤波器为H(s) ωc/(sωc)那是低通不是高通。如果看错了传递函数相位符号自然就错了。我建议在代码里统一用输出相对输入的相位差来描述并且用实际数据验证符号不要靠记忆。3.4 用群延迟代替相位滞后群延迟的定义是相位对频率的负导数它描述的是信号包络的延迟而不是单一频率正弦波的相位延迟。对于窄带信号群延迟和相位延迟近似相等但对于宽带信号比如包含多个波浪频率的升沉信号群延迟和相位延迟差别很大。有些资料为了简化直接用群延迟来近似相位滞后然后在全频段用同一个延迟值去补偿。这在窄带情况下勉强能用但升沉信号通常是宽带的涌浪、风浪、涌浪叠加频率成分丰富用单一群延迟补偿会导致某些频率补偿过度某些频率补偿不足。正确的做法是在频域逐频率计算相位然后设计一个全通滤波器或者分数延迟滤波器来补偿。如果精度要求不高至少也要在主要能量频段内做分段补偿而不是全频段一个值。4. 如何正确建模和补偿高通滤波器的相位滞后4.1 从离散传递函数出发计算真实相位第一步拿到你实际使用的滤波器系数。假设你用Python的scipy设计了一个二阶巴特沃斯高通截止频率0.03Hz采样率50Hzfrom scipy import signal import numpy as np fs 50.0 fc 0.03 b, a signal.butter(2, fc/(fs/2), btypehigh)拿到b和a之后计算幅频和相频响应w, h signal.freqz(b, a, worN4096, fsfs) phase_deg np.angle(h, degTrue)这样得到的phase_deg就是离散滤波器在0到fs/2频率范围内的真实相位。注意freqz默认返回的相位是包裹在[-180, 180]度之间的对于高通滤波器低频段相位接近90度高频段接近0度一般不会出现包裹问题但如果你级联了多个环节总相位可能超过180度需要unwrap。我通常会把关心的频段单独拿出来看比如0.01Hz到0.5Hz这是升沉测量的典型频段。然后在这个频段内把相位拟合成一条曲线方便后续补偿。4.2 全通滤波器补偿的设计思路知道了真实相位之后补偿的思路是设计一个全通滤波器它的相位特性正好是滤波器相位的相反数。全通滤波器的幅频响应恒为1只改变相位非常适合做相位补偿。设计全通滤波器的方法有几种一阶全通只有一个极点和一个零点相位从0度变化到-180度或180度适合补偿简单的相位曲线。二阶全通相位变化范围更大可以拟合更复杂的相位曲线。级联多个一阶或二阶全通通过优化算法调整零极点位置拟合目标相位。在升沉测量里如果只是补偿高通滤波器的相位通常一个二阶全通就够了。但如果整个信号链的相位比较复杂可能需要三到四个二阶节级联。设计的时候我习惯用最小二乘拟合先设定全通滤波器的结构然后把系数作为优化变量目标函数是补偿后总相位在关心频段内尽可能接近0。用scipy.optimize.minimize就能做初始值可以根据经验给。这里有个坑全通滤波器在补偿相位的同时会引入自己的群延迟如果群延迟太大实时性会受影响。所以设计完之后要检查一下群延迟确保在可接受范围内。4.3 实时实现中的注意事项离线处理的时候你可以用filtfilt做零相位滤波也就是正向滤一遍再反向滤一遍相位正好抵消。但升沉测量通常是实时的不能用filtfilt只能用单向滤波所以相位滞后必然存在必须补偿。实时补偿全通滤波器的时候要注意状态变量的初始化。如果滤波器刚启动状态变量是0输出会有暂态相位补偿也会不准。我通常的做法是在正式输出之前先让滤波器跑一段预热数据或者用前几个采样点做状态初始化。预热时间至少要是滤波器时间常数的5到10倍。另外如果采样率不是固定的比如有些系统会根据负载动态调整采样率那滤波器的相位特性也会变补偿系数需要跟着变。这种情况我建议要么固定采样率要么把补偿系数做成采样率的函数实时查表。还有一个实际问题是定点运算。如果升沉算法跑在嵌入式DSP上用的是定点数滤波器系数的量化误差会影响相位。特别是全通滤波器零极点位置对系数很敏感量化误差可能导致相位补偿偏差几度。所以定点实现时系数要用足够的位宽并且做仿真验证。5. 实测验证怎么确认相位补偿真的对了5.1 用仿真信号做闭环验证最直接的方法是用仿真信号验证。构造一个已知频率和相位的正弦加速度信号比如t np.arange(0, 100, 1/fs) f_wave 0.125 # 8秒周期 acc np.sin(2*np.pi*f_wave*t)然后把这个加速度信号通过你的升沉算法积分高通相位补偿得到位移输出。理论上位移应该是加速度的二次积分即disp_true -1/(2*pi*f_wave)^2 * np.sin(2*np.pi*f_wave*t)比较算法输出和理论位移的相位差如果补偿正确相位差应该接近0。如果还有明显偏差说明补偿量不对。我一般会扫频验证从0.02Hz到0.5Hz每个频率点都测一下相位误差画成曲线。如果全频段误差都在正负2度以内说明补偿合格。如果某些频段误差大就要回去检查滤波器模型。5.2 用实际海试数据做交叉验证仿真验证通过之后还要用实际数据验证。实际数据的好处是包含真实的噪声、多频率成分和非线性因素。验证方法可以是用高精度参考传感器比如光学测量或者GNSS升沉同步采集和算法输出对比。如果没有参考传感器可以用两个不同原理的算法交叉验证比如一个用高通补偿一个用自适应滤波看两者输出是否一致。还可以做一致性检验把算法输出再微分两次看能不能还原加速度信号如果相位补偿错了微分后的信号和原始加速度会有相位差。我在实际项目里发现仿真验证通过但海试数据对不上的情况多半是因为实际信号的频率成分比仿真复杂或者滤波器在实际实现中有额外的延迟比如通信延迟、计算延迟。这些延迟也要算进总相位里。5.3 常见问题排查清单如果你发现相位补偿后还是不对可以按下面这个清单逐项排查排查项可能问题检查方法滤波器系数系数和设计不符打印实际使用的b、a和设计值对比采样率采样率设置错误确认代码里的fs和实际硬件一致相位符号补偿方向反了用单频正弦测试看补偿后误差是变大还是变小级联环节漏算了某个环节的相位列出完整信号链逐环节算相位状态初始化暂态未消除检查预热时间是否足够定点量化系数精度不够用浮点仿真对比定点结果额外延迟通信或计算延迟测量从采样到输出的总时间这个清单我用了很多次基本上能覆盖90%以上的相位问题。剩下的10%可能是多径效应、传感器安装偏差等那就要具体问题具体分析了。6. 几个容易踩的坑和我的实操心得6.1 不要迷信零相位滤波这个词很多资料说filtfilt可以实现零相位滤波这话没错但filtfilt只适合离线处理。实时系统里用不了因为你需要未来的数据。有些工程师为了追求零相位在实时系统里用filtfilt结果引入更大的延迟得不偿失。实时系统里正确的思路是单向滤波相位补偿而不是追求零相位。补偿做得好残余相位误差可以控制在1度以内完全够用。6.2 截止频率不是越低越好有人觉得截止频率越低抑制漂移越彻底升沉测量越准。但实际上截止频率越低滤波器在波浪频段的相位滞后越大补偿难度越高。而且截止频率太低滤波器的时间常数变大启动暂态变长实时性变差。我的经验是截止频率选在主要波浪频率的1/5到1/10之间比较合适。比如主要波浪周期8秒频率0.125Hz截止频率选0.015Hz到0.025Hz。这样既能抑制漂移又不会在波浪频段引入太大相位滞后。6.3 相位补偿要留余量实际系统里除了滤波器相位还有传感器延迟、AD转换延迟、计算延迟等。这些延迟加起来可能有几十毫秒。如果你只补偿滤波器相位总相位还是会有偏差。所以补偿的时候要留一定余量或者把已知的额外延迟也建模进去。我通常会在补偿后留2到3度的余量然后通过实测微调。微调的方法很简单给系统一个已知频率的激励看输出相位然后调整补偿系数直到误差最小。6.4 文档和代码要同步更新相位滞后描述错误很多时候是因为文档写的是旧版本代码已经改了。比如滤波器阶数从二阶改成四阶但文档里的相位公式还是二阶的。这种不同步会导致后续维护的人用错模型。我的做法是把滤波器系数和相位补偿系数都写在配置文件里代码和文档都从配置文件读取这样就不会出现描述和实现不一致的问题。另外每次修改滤波器参数都要重新跑一遍相位验证确保补偿系数跟着更新。7. 写在最后一点个人体会升沉测量里的相位问题说到底是一个模型和现实匹配的问题。高通滤波器的相位滞后本身不复杂复杂的是整个信号链的相位叠加以及离散实现带来的偏差。我做了这么多年最大的体会是不要相信任何没有经过实测验证的相位公式包括我自己写的。每次换滤波器、换采样率、换硬件平台都要重新验证一遍相位。另外相位补偿不是越精确越好而是要和控制系统的需求匹配。有些应用对相位不敏感补偿到5度以内就够了有些应用要求1度以内那就得用更复杂的补偿结构。关键是搞清楚你的应用到底需要多高的相位精度然后把精力花在刀刃上。如果你正在被升沉测量的相位问题困扰建议先从仿真入手把信号链的每个环节都单独测一遍相位找到误差最大的那个环节重点突破。大部分情况下问题都出在离散滤波器的相位描述上把这块搞对了整体精度会有明显提升。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑