第4章 信号处理基础:常用信号源、采样与重构、滤波器与频谱分析
各位同学,欢迎来到信号处理这一章。说实话,很多做运动控制的工程师,一开始都觉得信号处理是通信专业的事。我以前也这么想,直到有一次调试伺服系统,电机在某个速度区间一直抖,怎么调PID都没用。后来一查,是编码器信号里有高频噪声,被我当成真实位置去控制了。嗯,从那以后,我再也不敢小看信号处理了。
这一章,我带你打好信号处理的地基。内容不多,但都是我在项目里反复用到的。
4.1 常用信号源:阶跃、斜坡、正弦
做仿真,第一步就是要有信号。就像炒菜要先有食材。MATLAB里最常用的三种信号,我一个个说。
4.1.1 阶跃信号
阶跃信号,说白了就是“啪”一下从0跳到1。它用来测试系统的响应速度。比如你给电机一个阶跃速度指令,看它多久能跟上。
% 生成阶跃信号
t = 0:0.01:10;
u = zeros(size(t));
u(t >= 1) = 1; % 在t=1秒时跳变
plot(t, u);
title('阶跃信号');
xlabel('时间 (s)'); ylabel('幅值');
我个人习惯用heaviside函数,但直接逻辑判断更直观,新手不容易错。
4.1.2 斜坡信号
斜坡信号就是一条斜线。它用来模拟缓慢变化的指令,比如机器人关节的平滑启动。
% 生成斜坡信号
t = 0:0.01:10;
u = 0.5 * t; % 斜率为0.5
plot(t, u);
title('斜坡信号');
我在项目中遇到过一个问题:斜坡信号如果斜率太大,电机实际位置会滞后很多。这时候就要考虑加速度限制了。
4.1.3 正弦信号
正弦信号是频率分析的基础。你想想看,任何复杂的振动,都可以分解成不同频率的正弦波叠加。
% 生成正弦信号
f = 2; % 频率2Hz
A = 1; % 幅值1
t = 0:0.001:1;
u = A * sin(2*pi*f * t);
plot(t, u);
title('正弦信号 (2Hz)');
这里有个坑:采样频率必须大于信号最高频率的2倍,否则会混叠。我后面会细讲。
核心要点:阶跃测响应速度,斜坡测跟踪能力,正弦测频率特性。三种信号配合使用,基本能摸清一个系统的脾气。
4.2 信号采样与重构
计算机只能处理离散的点,但真实世界是连续的。采样就是把连续信号变成离散点。重构则是反过来。
4.2.1 采样定理(Nyquist定理)
采样频率必须大于信号最高频率的2倍。这是铁律。我见过有人用100Hz采样去分析60Hz的信号,结果频谱全乱了。
% 演示采样
fs = 100; % 采样频率100Hz
t_cont = 0:0.0001:1; % 连续时间
t_sample = 0:1/fs:1; % 采样点
f_signal = 10; % 信号频率10Hz
x_cont = sin(2*pi*f_signal * t_cont);
x_sample = sin(2*pi*f_signal * t_sample);
% 画图对比
plot(t_cont, x_cont, 'b-', 'LineWidth', 1); hold on;
stem(t_sample, x_sample, 'r', 'LineWidth', 2);
legend('连续信号', '采样点');
title('采样过程演示 (fs=100Hz, f=10Hz)');
注意:如果采样频率不够,高频信号会伪装成低频信号出现。这叫“混叠”。我曾经在振动分析中吃过这个亏,测出来的频率比实际低了一半,差点误判了故障原因。
4.2.2 信号重构
重构就是从离散点恢复连续信号。理想情况下用sinc函数插值,但实际中常用零阶保持或线性插值。
% 零阶保持重构
t_recon = 0:0.001:1;
x_recon = zeros(size(t_recon));
for i = 1:length(t_sample)-1
idx = (t_recon >= t_sample(i)) & (t_recon < t_sample(i+1));
x_recon(idx) = x_sample(i);
end
plot(t_recon, x_recon);
title('零阶保持重构');
说白了,零阶保持就是“台阶状”的恢复。虽然粗糙,但硬件实现简单,很多DAC就是这么干的。
4.3 滤波器基础
滤波器就是用来“挑信号”的。让有用的频率通过,把没用的滤掉。运动控制里最常用的是低通滤波器。
4.3.1 低通滤波器
低通滤波器让低频通过,衰减高频。比如编码器信号里的毛刺,用低通一滤就干净了。
% 设计一个简单的一阶低通滤波器
fc = 10; % 截止频率10Hz
RC = 1/(2*pi*fc);
dt = 0.001;
alpha = dt/(RC + dt); % 滤波系数
% 对信号滤波
x = sin(2*pi*2*t) + 0.5*sin(2*pi*50*t); % 2Hz信号+50Hz噪声
y = zeros(size(x));
y(1) = x(1);
for i = 2:length(x)
y(i) = (1-alpha)*y(i-1) + alpha*x(i);
end
plot(t, x, 'b-', t, y, 'r-');
legend('原始信号(含噪声)', '滤波后');
title('一阶低通滤波效果');
我建议新手先掌握一阶滤波器。它简单、计算量小,很多场合够用了。高阶滤波器虽然更陡峭,但相位延迟也更大,运动控制里有时候反而坏事。
4.3.2 高通与带通滤波器
高通滤掉低频,保留高频。带通只让某个频段通过。比如检测振动时,用带通锁定共振频率。
| 滤波器类型 | 作用 | 运动控制应用 |
|---|---|---|
| 低通 | 滤除高频噪声 | 编码器信号平滑 |
| 高通 | 滤除低频漂移 | 加速度信号去直流 |
| 带通 | 提取特定频段 | 共振频率检测 |
小技巧:在MATLAB里可以用filter函数或者designfilt来设计滤波器。但我个人建议,刚开始先用一阶差分方程手写,这样你能真正理解滤波器的原理。
4.4 频谱分析入门
频谱分析就是把时域信号变成频域信号。你看时间波形可能看不出问题,但一看频谱,哪个频率有异常一目了然。
4.4.1 傅里叶变换与FFT
FFT是快速傅里叶变换的缩写。它是频谱分析的核心工具。MATLAB里直接用fft函数。
% FFT频谱分析示例
fs = 1000; % 采样频率
t = 0:1/fs:1-1/fs;
x = sin(2*pi*50*t) + 0.5*sin(2*pi*120*t); % 50Hz和120Hz混合
Y = fft(x);
f = (0:length(Y)-1)*fs/length(Y); % 频率轴
% 只画单边频谱
plot(f(1:length(f)/2), abs(Y(1:length(Y)/2)));
title('单边幅值频谱');
xlabel('频率 (Hz)'); ylabel('幅值');
你想想看,如果电机振动,时域波形可能乱糟糟的。但频谱上一看,如果某个频率特别突出,那就是振源。
4.4.2 频谱分析注意事项
- 频率分辨率:等于采样频率除以采样点数。采样时间越长,分辨率越高。
- 频谱泄漏:信号不是整周期采样时,频谱会“糊掉”。加窗函数可以缓解。
- 幅值校正:FFT出来的幅值需要乘以2/N才能得到真实幅值(单边谱)。
避坑指南:我曾经用FFT分析一个振动信号,发现有个频率一直在变。后来才发现是采样频率不稳定导致的。记住,FFT的前提是等间隔采样。如果采样时间不均匀,结果就是错的。
知识体系总览
下面这张图,我画了本章的核心逻辑。你看一遍就能串起来。
好了,这一章的内容就这些。信号源、采样重构、滤波器、频谱分析,这四个东西是运动控制仿真的基本功。你把这章吃透了,后面讲系统辨识、控制器设计的时候,你会觉得轻松很多。