9.2 KiB
9.2 KiB
Tomography Experiment
Initialize Experiment
initializeGround();
initializeGranite();
initializeTy();
initializeRy();
initializeRz();
initializeMicroHexapod();
initializeAxisc();
initializeMirror();
initializeNanoHexapod(struct('actuator', 'piezo'));
initializeSample(struct('mass', 1));
t = 0:Ts:Tsim;
Generate perturbations
win = hanning(ceil(1/Ts));
[pxx, f] = pwelch(sqrt(1/(2*Ts))*randn(length(t), 1), win, [], [], 1/Ts);
figure;
hold on;
plot(f, sqrt(pxx));
hold off;
set(gca, 'xscale', 'log');
set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD of the measured velocity $\left[\frac{m/s}{\sqrt{Hz}}\right]$')
ylim([0.01, 100]);
load('./disturbances/mat/dist_psd.mat', 'dist_f');
Dwx = lsim(dist_f.G_gm, sqrt(1/(2*Ts))*randn(length(t), 1), t);
Dwy = lsim(dist_f.G_gm, sqrt(1/(2*Ts))*randn(length(t), 1), t);
Dwz = lsim(dist_f.G_gm, sqrt(1/(2*Ts))*randn(length(t), 1), t);
Dw = [Dwx, Dwy, Dwz];
figure;
hold on;
plot(t, Dwx);
plot(t, Dwy);
plot(t, Dwz);
hold off;
xlabel('Time [s]'); ylabel('Displacement [m]');
Fty_z = lsim(dist_f.G_ty, sqrt(1/(2*Ts))*randn(length(t), 1), t);
Frz_z = lsim(dist_f.G_rz, sqrt(1/(2*Ts))*randn(length(t), 1), t);
figure;
hold on;
plot(t, Fty_z);
plot(t, Frz_z);
hold off;
xlabel('Time [s]'); ylabel('Force [N]');
% Spindle
Rz = 2*pi*t;
% Axisc
Rm = zeros(length(t), 2);
Rm(:, 2) = pi*ones(length(t), 1);
inputs = struct( ...
'Ts', Ts, ...
'Dw', timeseries(Dw, t), ...
'Dy', timeseries(zeros(length(t), 1), t), ...
'Ry', timeseries(zeros(length(t), 1), t), ...
'Rz', timeseries(Rz, t), ...
'Dh', timeseries(zeros(length(t), 6), t), ...
'Rm', timeseries(Rm, t), ...
'Dn', timeseries(zeros(length(t), 6), t), ...
'Ds', timeseries(zeros(length(t), 6), t), ...
'Fg', timeseries(zeros(length(t), 3), t), ...
'Fn', timeseries(zeros(length(t), 6), t), ...
'Fnl', timeseries(zeros(length(t), 6), t), ...
'Fty_x', timeseries(zeros(length(t), 1), t), ...
'Fty_z', timeseries(Fty_z, t), ...
'Frz_z', timeseries(Frz_z, t), ...
'Fs', timeseries(zeros(length(t), 6), t) ...
);
Test
cd ..
We define some parameters:
T0
is the duration in secondsN
is the number of samples
T0 = 10; % Signal Duration [s]
N = 10000; % Number of Samples (should be even)
Then, we have:
- $f_s = N/T_0$ is the sampling frequency in Hz
- $f_c = \frac{1}{2} N/T_0$ is the cut-off frequency in Hz
- $f_0 = 1/T_0$ is the frequency resolution of the DFT in Hz
Fs = N/T0; % Sampling frequency [Hz]
Fc = (1/2)*N/T0; % Sampling frequency [Hz]
df = 1/T0; % Frequency resolution of the DFT [Hz]
We then specify the wanted PSD.
phi = ones(N/2, 1);
% phi = logspace(3, 0, N/2);
phi(df:df:Fs/2>10) = 0;
We create $C_x(k)$ such that: \[ C_x(k) = \sqrt{\Phi_{xx}(k\omega_0)\omega_0} \quad k = 1 \dots N/2 \] where $\Phi_{xx}$ is the wanted PSD.
C = zeros(N/2, 1);
for i = 1:N/2
C(i) = sqrt(phi(i))*2*Fs; % TODO - Why this normalization?
end
We generate some random phase that will be added to C
.
theta = 2*pi*rand(N/2, 1); % Generate random phase [rad]
In order to have \[ C_x(N/2+i) = C_x^*(N/2-i) \quad i = 1 \dots N/2 \] We do the following
Cx = [0 ; C.*complex(cos(theta),sin(theta))];
Cx = [Cx; flipud(conj(Cx(2:end)))];;
The time domain data is generated by an inverse FFT.
u = ifft(Cx);
A = fft(u);
figure; plot(2*A.*conj(A))
t = linspace(0, T0, N+1); % Time Vector [s]
figure;
plot(t, u)
xlabel('Time [s]');
ylabel('Amplitude');
nx = length(u);
na = 16;
win = hanning(floor(nx/na));
[pxx, f] = pwelch(u, win, 0, [], Fs);
figure;
hold on;
plot(f,pxx)
plot(df:df:Fc,phi)
hold off;
xlabel('Frequency [Hz]');
ylabel('Power Spectral Density');
set(gca, 'xscale', 'log');
set(gca, 'yscale', 'log');
Test
cd ..
load('./disturbances/mat/dist_psd.mat', 'dist_f');
We remove the first value with very high PSD.
dist_f.f = dist_f.f(3:end);
dist_f.psd_gm = dist_f.psd_gm(3:end);
We define some parameters.
Fs = 2*dist_f.f(end); % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz]
N = 2*length(dist_f.f); % Number of Samples match the one of the wanted PSD
T0 = N/Fs; % Signal Duration [s]
df = 1/T0; % Frequency resolution of the DFT [Hz]
% Also equal to (dist_f.f(2)-dist_f.f(1))
We then specify the wanted PSD.
phi = dist_f.psd_gm;
Create amplitudes corresponding to wanted PSD.
C = zeros(N/2,1);
for i = 1:N/2
C(i) = sqrt(phi(i)*df);
end
Add random phase to C
.
theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
Cx = [0 ; C.*complex(cos(theta),sin(theta))];
Cx = [Cx; flipud(conj(Cx(2:end)))];;
The time domain data is generated by an inverse FFT.
We normalize the ifft
Matlab command.
u = 1/(sqrt(2)*df*1/Fs)*ifft(Cx); % Normalisation of the IFFT
t = linspace(0, T0, N+1); % Time Vector [s]
figure;
plot(t, u)
xlabel('Time [s]');
ylabel('Amplitude');
u_rep = [u;u;u;u;u;u;u;u;u;u;u;u;u;u;u;u;u;u;u;u;u;u;u;u;u];
nx = length(u_rep);
na = 16;
win = hanning(floor(nx/na));
[pxx, f] = pwelch(u_rep, win, 0, [], Fs);
figure;
hold on;
plot(dist_f.f, dist_f.psd_gm, 'DisplayName', 'Original PSD')
plot(f, pxx, 'DisplayName', 'Computed')
% plot(f, pxx./dist_f.psd_gm, 'k-')
hold off;
xlabel('Frequency [Hz]');
ylabel('Power Spectral Density');
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
legend('location', 'northeast');