简介:面向Matlab信号处理学习者的实用代码包,聚焦位移、速度、加速度三类物理量之间的微分与积分转换,适用于机械振动分析、运动控制、传感器数据处理等场景。压缩包共4个文件,包含三个m脚本与一个mat数据文件,整体仅23KB,轻量易学。其中角速度与角位移互转、正弦波模拟、加速度与速度换算等脚本分别对应不同转换需求,配套的mat文件则提供实测样本数据供练习。已有6115人学习,适合需要快速理解物理量转换原理或编写Matlab信号处理程序的读者。通过运行这些脚本,可直观掌握diff、cumsum等核心函数在实际数据上的应用,并熟悉从数据导入、滤波预处理到结果可视化的完整流程,为后续振动分析、控制算法开发等科研实验提供可复用的代码基础。
1. 互转这件事,到底难在哪
干过振动测试、运动控制或状态监测的朋友,应该都遇到过这种场景:手里只有一个加速度传感器,但客户要的是振动速度有效值;或者装了个激光位移计,结果分析冲击响应时又需要加速度。物理课上早就学过,速度是位移的一阶导,加速度是速度的一阶导,反过来就是积分。公式三行能写完,可一放到实测数据里,情况就完全变了。
实测信号不是理想光滑曲线,它带着传感器噪声、采集系统的零点漂移、环境干扰,说不定还混着工频干扰。对这样的信号直接做微分,高频噪声被放大好几个数量级,出来的曲线毛刺能扎死人;直接做积分,直流偏置和趋势项累积漂移,几分钟就能漂到天上去。所以“位移、速度、加速度信号互转”看着是数学问题,实际上是个信号处理工程问题。
这篇博文我会把自己在振动测试、伺服运动控制和频谱分析里用过的互转方法完整写一遍,包含时域积分/微分、频域积分/微分、去趋势项、滤波器设计、相位问题,以及各种“理论上对但实战翻车”的坑。适合做振动测试的工程师、机器人控制方向的研究生,以及任何和加速度计、位移传感器打交道的人。
2. 先搞清楚互转的数学本质
2.1 三者的微分/积分链条
位移量记为 x(t),速度 v(t)=dx/dt,加速度 a(t)=d²x/dt²。正向链条是位移→速度→加速度,对应两次微分;反向链条是加速度→速度→位移,对应两次积分。频域里更简洁:微分一次就是乘以 jω,积分一次就是除以 jω。
这里有个关键认知:微分是高频增强的过程,信号高频成分的幅值随频率线性增加;积分是高频抑制、低频增强的过程,信号低频成分的幅值随频率倒数增加。这就是为什么微分放大噪声、积分漂移严重的根源——它们本质上在放大信号的不同频段。明白这一点,后面所有的预处理手段都是有据可循的。
2.2 为什么不能用理想化公式硬算
如果你把传感器采集到的离散序列直接按数值微分公式去算,例如用 (x[i+1]-x[i])/Δt 求速度,会立刻发现:输出曲线毛刺严重,完全没法用。因为采集数据里的高频噪声被微分算子放大后,信噪比急剧恶化。
反过来,用 cumsum 或梯形法直接积分加速度信号,你会发现速度曲线和位移曲线会以一个几乎恒定的斜率往上飘或往下飘,像一条缓慢爬升的斜坡——这就是漂移。实际工程中,加速度传感器的零点偏移即使只有几十毫伏,积分之后也会产生一个随时间线性增长的速度项和随时间二次增长的位移项,几秒钟就能占据整个量程。
3. 频率域互转:工程上最稳的一条路
3.1 频域法核心步骤
实测互转,我绝大多数情况都在频率域做。步骤是先对原始信号做去均值和去趋势预处理,再做 FFT 得到频谱,对频谱做算子运算,最后 IFFT 回到时域。核心算子:
- 微分一次:Y(k) = X(k) · j·2π·f(k)
- 积分一次:Y(k) = X(k) / (j·2π·f(k)),注意 f=0 那一点直接置零
你在代码里实现时,频率轴 f 要生成从 0 到 fs/2 再镜像到负频率,或者用 np.fft.fftfreq 来生成。用 Python 写的话,核心就十几行。
3.2 频域积分时零频为什么必须置零
频域积分时,若直接用 1/(jω) 去乘,0 Hz 处的 1/(jω) 是无穷大,实际计算中会出现 NaN 或极大值。物理含义也很清楚:0 Hz 对应信号的直流分量,对直流做积分,在时间域就是无限累积的斜坡,不存在有限的积分结果。所以工程上统一做法是直接把零频分量清零。
但清零会带来一个新问题:如果原始信号本身包含真实物理直流分量(比如加速度计有重力分量),清零后这部分会被丢掉,积分结果和真实值会有恒定偏差。所以对带直流分量的信号,要区分“真实物理直流”和“传感器偏置”——前者保留后处理,后者必须去掉。我的习惯是先在时域做去均值,再频域积分,最后根据物理约束修正常数项。
4. 实操:Python 里完成加速度→速度→位移的完整互转
4.1 基础版本:频域积分实现
下面这段代码是我在振动数据分析里最常用的模板,完整跑过一次后,换数据改一下路径就能复用。
import numpy as np from scipy.signal import detrend import matplotlib.pyplot as plt def freq_integrate(signal, fs): """ 频域积分,返回积分后的时域信号 signal: 输入信号,一维数组 fs: 采样率,Hz """ n = len(signal) # 去均值,消除直流偏置 x = signal - np.mean(signal) # 去线性趋势,进一步消除低频漂移 x = detrend(x, type='linear') # 做 FFT X = np.fft.fft(x) # 生成频率轴 freqs = np.fft.fftfreq(n, d=1.0/fs) # 积分算子:除以 j*2*pi*f,零频置零 with np.errstate(divide='ignore', invalid='ignore'): H = 1.0 / (2j * np.pi * freqs) H[freqs == 0] = 0 Y = X * H y = np.real(np.fft.ifft(Y)) return y # 使用示例 fs = 1280 # 采样率,常见振动测试采样率 t = np.arange(0, 10, 1/fs) # 模拟一个 10Hz 正弦加速度信号(含少量噪声) a = 2.0 * np.sin(2 * np.pi * 10 * t) + 0.05 * np.random.randn(len(t)) v = freq_integrate(a, fs) # 加速度 -> 速度 d = freq_integrate(v, fs) # 速度 -> 位移 # 理论上速度和位移的幅值 # 速度幅值 = 2 / (2*pi*10) # 位移幅值 = 2 / (2*pi*10)**2 print(f"速度幅值理论: {2/(2*np.pi*10):.4f}, 实测约: {np.max(np.abs(v)):.4f}") print(f"位移幅值理论: {2/(2*np.pi*10)**2:.4f}, 实测约: {np.max(np.abs(d)):.4f}")4.2 频域微分的实现与噪声放大控制
频域微分算子的代码和积分几乎对称,只是把 1/(jω) 换成 jω。比如位移传感器输出的是位移序列,想换算成速度序列:
def freq_differentiate(signal, fs): n = len(signal) x = signal - np.mean(signal) X = np.fft.fft(x) freqs = np.fft.fftfreq(n, d=1.0/fs) H = 2j * np.pi * freqs # 微分算子 Y = X * H y = np.real(np.fft.ifft(Y)) return y但实际执行时,千万别直接用这个裸算子去处理带噪信号。下面第 5 节会详细说怎么处理。这里先记住一个结论:微分算子对高频噪声特别敏感,1000Hz 处 1mV 的噪声,微分后已经被放大成 6.28V 的等效输出,信号直接被埋了。
5. 时域积分/微分:另一种常用路线
5.1 数值积分:梯形法、Simpson 法与滤波结合
频域法虽稳,但有时手里数据在时域处理更直觉,比如实时嵌入式系统里没法做整段 FFT,只能边采边积。这时候必须用数值积分。
最常用的是累计梯形法,即 cumtrapz,在 Python 里就是 scipy.integrate.cumulative_trapezoid。相比矩形法,梯形法对线性变化量更准确;要更高精度可以用 Simpson 法,但实时性稍差。累加过程的零点偏移会导致漂移,所以时域积分要配合高通滤波或实时去趋势。
我的嵌入式习惯做法:加速度信号先经过一个模拟或数字高通滤波器(截止频率远低于关注频段,如 0.5Hz 或 1Hz),滤掉直流偏置和极低频漂移,再做梯形积分。每积一次后,再做一次滑动窗口去均值,防止积分器输出累积偏置。工程上这叫“实时积分+周期清零”,能保证几分钟内不漂出范围。
5.2 数值微分:差分法与平滑的先决关系
数值微分比积分更敏感。一阶前向差分误差为 O(Δt),中心差分误差为 O(Δt²),精度更好。但无论哪种差分都会放大噪声。所以在做微分前,必须先做低通滤波,把高频噪声压下去;不然微分会把噪声放得极大。
比如位移信号是 100Hz 采样,关注 0~10Hz,那先做一个 20Hz 截止的低通滤波,再做中心差分,得到的速度曲线比较平滑。如果硬要用裸差分,速度曲线全是毛刺,根本没法用。
6. 滤波、去趋势与其他预处理细节
6.1 去均值、去线性趋势的适用场景
做积分前,去均值和去线性趋势几乎是必须的。去均值就是减掉直流分量;去线性趋势通常用最小二乘拟合一条直线,把信号里那个整体上升或下降的斜坡去掉。这两个操作能大幅度减轻后续积分漂移。
但过度去趋势也会剥夺真实低频信号。比如结构低频振动本身可能就包含一个缓慢变化的趋势项,如果强行用线性去趋势把斜坡完全拿掉,真实位移的幅值相位就歪了。我的经验是:先做频谱分析,看看低频段是否有明确峰,再决定去趋势的阶数和截止频率。如果低频段是一片平缓抬升,没有明显峰,那大概率是漂移,放心去;如果有峰且不同工况下稳定,那就是真实信号,去趋势要小心。
6.2 高通/低通滤波器选择的思路
滤波器在互转流程里是配角,却决定了成败。
- 做积分:用高通滤波器,截止频率约低于关注最低频段的 1/3。例如要分析的振动最低频率是 5Hz,高通截止可设在 1Hz 左右。
- 做微分:用低通滤波器,截止频率约高于关注最高频段的 3 倍。例如关注 0~30Hz,低通截止可设在 100Hz 左右。
滤波器阶数我一般选二阶 Butterworth,再用零相位滤波(scipy.signal.sosfiltfilt)消除相位偏移。注意,零相位滤波会引入“未来数据”的依赖,不适合严格实时系统;嵌入式里只能用普通因果滤波,要接受相位滞后,然后做相位补偿。
6.3 为什么实测积分后曲线仍然缓慢漂移
即使做了预处理,积分出来的位移曲线长时间后仍会缓慢漂移。原因是传感器低频噪声(如温度漂移、电荷放大器衰减)并非完全线性,去趋势只能去掉一阶趋势,二阶以上的缓慢变化无法去除。这时要加一个更高截止频率的高通滤波,或使用滑动窗口去均值,或接受“短时积分有效、长时积分不可靠”的现实。这个限制没法根除,能缓解就不错了。
7. 相位 vs 幅值:互转中最容易被忽视的坑
7.1 真实相位偏移来源
时域微分和积分,对理想正弦信号有精确的 ±90° 相位变化。但实测处理中,滤波会引入额外相移。因果低通/高通滤波器在使用时会使信号整体延迟,产生相位滞后;零相位滤波虽能解决相位畸变,但会改变因果性。
另一处易忽略的是离散差分法:前向差分 y[n]=(x[n+1]-x[n])/Δt 的相位中心是 n+0.5,输出的时间点相对原始时间偏移了半个采样周期。如果后续要对比速度环和位移环同步性,这个偏移会直接影响相位差判断。
7.2 零相位滤波与因果滤波的选择
离线分析用 sosfiltfilt 做零相位滤波,相位不畸变;在线控制用普通 filter,但要知道它带有滞后,可以通过补偿粗略校正。如果你做的是事后分析数据对比,建议直接零相位滤波,省心很多。但如果做闭环控制,滤波器的相位滞后会影响稳定性,那必须用最小相位滤波器并做滞后补偿,这已经超出“信号互转”的范畴,属于控制系统的设计了。
8. 边界效应、采样率和数据长度的取舍
8.1 FFT 互转时的端点振荡
频域积分时做 FFT,信号两端如果差异很大(不满足周期性假设),IFFT 回来的时域信号首尾会明显振荡,这就是频谱泄漏和 Gibbs 现象。解决思路:数据加窗后再处理,或两端做衰减(如用前 5% 和后 5% 的 fade in/out 斜坡),或对信号做镜像延拓。我的习惯是加 Hann 窗做预处理,然后平缓恢复端点,防止首尾失真。
8.2 低采样率对微分/积分的影响
采样率过低,高频细节丢失,微分结果精度差;采样率过高,数据量增大,FFT 和滤波的实时性变差,且普遍存在的量化噪声在高频范围内平均分配,微分后噪声放大更剧。一般建议采样率至少是被分析最高频率的 10 倍。比如关心 0~100Hz,采样率至少 1000Hz 起步,工程上常用 1280 或 2560 Hz,和滑动平均滤波器配合效果更好。
8.3 数据长度对频域频率分辨率的影响
频率分辨率 = fs / N。N 太少,分辨率低,区分不了两个近邻峰。做互转前先算一下,如果两个峰相距 0.5Hz 而分辨率只有 1Hz,就分辨不出来。振动分析里为了保证分辨率和足够长的积分窗口,我一般会采集至少 10~20 个振动周期。比如 1Hz 振动,采集 10~20 秒。
9. 常见问题与处理速查
| 现象 | 可能原因 | 解决方式 |
|---|---|---|
| 积分后曲线线性上飘/下飘 | 信号含直流偏置 | 先去均值,再积分 |
| 积分后曲线二次抛物线 | 含线性趋势项 | 去线性趋势 |
| 微分后噪声毛刺巨大 | 高频噪声被放大 | 先低通滤波再做微分 |
| 频域积分首尾振荡 | FFT 边缘效应 | 两端 fade in/out 或加窗处理 |
| 信号越积越低频漂荡 | 低频噪声累积 | 高通滤波截止频率调高 |
| 相位差对不上 | 滤波相移或差分偏移 | 零相位滤波或中心差分 |
| 频域积分出现极大值 | 零频未置零 | f=0处置零 |
| 实时积分持续漂移 | 传感器低频漂移 | 定期清零,或接受短时有效 |
10. 实测三次之后我最想强调的三件事
第一,别迷信某一个高阶方法。频域积分看整体效果确实好,但在嵌入式实时环境里,你没法对数据做整段 FFT,时域梯形法加滤波器的组合仍然是最务实的路。选型取决于你的场景,而不是哪个“看起来更牛”。
第二,所有互转结果都需要物理校验。比如你用加速度积分算出来的速度,和激光测速仪实测速度对一下幅值和相位;算出来的位移,和静态位移传感器对比。如果对不上,回头查你的预处理环节,大概率是滤波截止频率或去趋势参数没选对。纯靠软件算出个漂亮曲线,不代表真实物理量的准确性。
第三,不要忽略传感器本身的频响范围。加速度传感器有低频截止和高频上限,超出范围的数据本身就没有置信度,后面的互转全是“垃圾进垃圾出”。做互转前先确认传感器的有效带宽,比调任何滤波器参数都重要。这一点我在早期做振动测试时踩过好几次,传感器标称 0.5Hz 低频截止,结果我拿 0.2Hz 的数据去做积分,得到的位置偏移曲线完全失实,折腾了整整一天才发现问题出在传感器端而不是算法端。
本文还有配套的精品资源,点击获取