01.% 测试积分对正弦信号的作用
02.clc
03.clear
04.close all
05.%% 原始正弦信号
06.ts = 0.001;
07.fs = 1/ts;
08.t = 0:ts:1000*ts;
09.f = 50;
10.dis = sin(2*pi*f*t); % 位移
11.vel = 2*pi*f.*cos(2*pi*f*t); % 速度
12.acc = -(2*pi*f).^2.*sin(2*pi*f*t); % 加速度
13.% 多个正弦波的测试
14.% f1 = 400;
15.% dis1 = sin(2*pi*f1*t); % 位移
16.% vel1 = 2*pi*f1.*cos(2*pi*f1*t); % 速度
17.% acc1 = -(2*pi*f1).^2.*sin(2*pi*f1*t); % 加速度
18.% dis = dis + dis1;
19.% vel = vel + vel1;
20.% acc = acc + acc1;
21.% 结:频域积分正常恢复信号,时域积分恢复加入的高频信息有误差
22.% 加噪声测试
23.acc = acc + (2*pi*f).^2*0.2*randn(size(acc));
24.% 结:噪声会使积分结果产生大的趋势项
25.figure
26.ax(1) = subplot(311);
27.plot(t, dis), title('位移')
28.ax(2) = subplot(312);
29.plot(t, vel), title('速度')
30.ax(3) = subplot(313);
31.plot(t, acc), title('加速度')
32.linkaxes(ax, 'x');
33.% 由加速度信号积分算位移
34.[disint, velint] = IntFcn(acc, t, ts, 2);
35.axes(ax(2)); hold on
36.plot(t, velint, 'r'), legend({'原始信号', '恢复信号'})
37.axes(ax(1)); hold on
38.plot(t, disint, 'r'), legend({'原始信号', '恢复信号'})
39.%% 测试积分算子的频率特性
40.n = 30;
41.amp = zeros(n, 1);
42.f = [5:30 40:10:480];
43.figure
44.for i = 1:length(f)
45. fi = f(i);
46. acc = -(2*pi*fi).^2.*sin(2*pi*fi*t); % 加速度
47. [disint, velint] = IntFcn(acc, t, ts, 2); % 积分算位移
48. amp(i) = sqrt(sum(disint.^2))/sqrt(sum(dis.^2));
49. plot(t, disint)
50. drawnow
51.% pause
52.end
53.close
54.figure
55.plot(f, amp)
56.title('位移积分的频率特性曲线')
57.xlabel('f')
58.ylabel('单位正弦波的积分位移幅值')
——————————————————————————————————————————————
01.% 积分操作由加速度求位移,可选时域积分和频域积分
02.function [disint, velint] = IntFcn(acc, t, ts, flag)
03.if flag == 1
04. % 时域积分
05. [disint, velint] = IntFcn_Time(t, acc);
06. velenergy = sqrt(sum(velint.^2));
07. velint = detrend(velint);
08. velreenergy = sqrt(sum(velint.^2));
09. velint = velint/velreenergy*velenergy;
10. disenergy = sqrt(sum(disint.^2));
11. disint = detrend(disint);
12. disreenergy = sqrt(sum(disint.^2));
13. disint = disint/disreenergy*disenergy; % 此操作是为了弥补去趋势时能量的损失
14. % 去除位移中的二次项
15. p = polyfit(t, disint, 2);
16. disint = disint - polyval(p, t);
17.else
18. % 频域积分
19. velint = iomega(acc, ts, 3, 2);
20. velint = detrend(velint);
21. disint = iomega(acc, ts, 3, 1);
22. % 去除位移中的二次项
23. p = polyfit(t, disint, 2);
24. disint = disint - polyval(p, t);
25.end
26.end
——————————————————————————————————————————————
01.% 时域内梯形积分
02.function [xn, vn] = IntFcn_Time(t, an)
03.vn = cumtrapz(t, an);
04.vn = vn - repmat(mean(vn), size(vn,1), 1);
05.xn = cumtrapz(t, vn);
06.xn = xn - repmat(mean(xn), size(xn,1), 1);
07.end
——————————————————————————————————————————————
01.function dataout = iomega(datain, dt, datain_type, dataout_type)
02.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
03.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
04.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
05.%
06.% IOMEGA is a MATLAB script for converting displacement, velocity, or
07.% acceleration time-series to either displacement, velocity, or
08.% acceleration times-series. The script takes an array of waveform data
09.% (datain), transforms into the frequency-domain in order to more easily
10.% convert into desired output form, and then converts back into the time
11.% domain resulting in output (dataout) that is converted into the desired
12.% form.
13.%
14.% Variables:
15.% ----------
16.%
17.% datain = input waveform data of type datain_type
18.%
19.% dataout = output waveform data of type dataout_type
20.%
21.% dt = time increment (units of seconds per sample)
22.%
23.% 1 - Displacement
24.% datain_type = 2 - Velocity
25.% 3 - Acceleration
26.%
27.% 1 - Displacement
28.% dataout_type = 2 - Velocity
29.% 3 - Acceleration
30.%
31.%
32.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35.% Make sure that datain_type and dataout_type are either 1, 2 or 3
36.if (datain_type < 1 || datain_type > 3)
37. error('Value for datain_type must be a 1, 2 or 3');
38.elseif (dataout_type < 1 || dataout_type > 3)
39. error('Value for dataout_type must be a 1, 2 or 3');
40.end
41.% Determine Number of points (next power of 2), frequency increment
42.% and Nyquist frequency
43.N = 2^nextpow2(max(size(datain)));
44.df = 1/(N*dt);
45.Nyq = 1/(2*dt);
46.% Save frequency array
47.iomega_array = 1i*2*pi*(-Nyq : df : Nyq-df);
48.iomega_exp = dataout_type - datain_type;
49.% Pad datain array with zeros (if needed)
50.size1 = size(datain,1);
51.size2 = size(datain,2);
52.if (N-size1 ~= 0 && N-size2 ~= 0)
53. if size1 > size2
54. datain = vertcat(datain,zeros(N-size1,1));
55. else
56. datain = horzcat(datain,zeros(1,N-size2));
57. end
58.end
59.% Transform datain into frequency domain via FFT and shift output (A)
60.% so that zero-frequency amplitude is in the middle of the array
61.% (instead of the beginning)
62.A = fft(datain);
63.A = fftshift(A);
64.% Convert datain of type datain_type to type dataout_type
65.for j = 1 : N
66. if iomega_array(j) ~= 0
67. A(j) = A(j) * (iomega_array(j) ^ iomega_exp);
68. else
69. A(j) = complex(0.0,0.0);
70. end
71.end
72.% Shift new frequency-amplitude array back to MATLAB format and
73.% transform back into the time domain via the inverse FFT.
74.A = ifftshift(A);
75.datain = ifft(A);
76.% Remove zeros that were added to datain in order to pad to next
77.% biggerst power of 2 and return dataout.
78.if size1 > size2
79. dataout = real(datain(1:size1,size2));
80.else
81. dataout = real(datain(size1,1:size2));
82.end
83.return |