30 KiB
Identification of the disturbances
- Introduction
- Identification
- Sensitivity to Disturbances
- Power Spectral Density of the effect of the disturbances
- Compute the Power Spectral Density of the disturbance force
- Noise Budget
- Approximation
- Save
- Function that initialize the disturbances
- Display Obtained Disturbances
Introduction ignore
The goal here is to extract the Power Spectral Density of the sources of perturbation.
The sources of perturbations are (schematically shown in figure fig:uniaxial-model-micro-station):
- $D_w$: Ground Motion
- Parasitic forces applied in the system when scanning with the Translation Stage and the Spindle ($F_{rz}$ and $F_{ty}$). These forces can be due to imperfect guiding for instance.
Because we cannot measure directly the perturbation forces, we have the measure the effect of those perturbations on the system (in terms of velocity for instance using geophones, $D$ on figure fig:uniaxial-model-micro-station) and then, using a model, compute the forces that induced such velocity.
This file is divided in the following sections:
- Section sec:identification: transfer functions from the disturbance forces to the relative velocity of the hexapod with respect to the granite are computed using the Simscape Model representing the experimental setup
- Section sec:sensitivity_disturbances: the bode plot of those transfer functions are shown
- Section sec:psd_dist: the measured PSD of the effect of the disturbances are shown
- Section sec:psd_force_dist: from the model and the measured PSD, the PSD of the disturbance forces are computed
- Section sec:noise_budget: with the computed PSD, the noise budget of the system is done
Identification
<<sec:identification>>
The transfer functions from the disturbance forces to the relative velocity of the hexapod with respect to the granite are computed using the Simscape Model representing the experimental setup with the code below.
%% Options for Linearized
options = linearizeOptions;
options.SampleTime = 0;
%% Name of the Simulink File
mdl = 'sim_micro_station_disturbances';
%% Micro-Hexapod
% Input/Output definition
io(1) = linio([mdl, '/Dw'], 1, 'input'); % Ground Motion
io(2) = linio([mdl, '/Fty'], 1, 'input'); % Parasitic force Ty
io(3) = linio([mdl, '/Frz'], 1, 'input'); % Parasitic force Rz
io(4) = linio([mdl, '/Dgm'], 1, 'output'); % Absolute motion - Granite
io(5) = linio([mdl, '/Dhm'], 1, 'output'); % Absolute Motion - Hexapod
io(6) = linio([mdl, '/Vm'], 1, 'output'); % Relative Velocity hexapod/granite
% Run the linearization
G = linearize(mdl, io, 0);
% Input/Output names
G.InputName = {'Dw', 'Fty', 'Frz'};
G.OutputName = {'Dgm', 'Dhm', 'Vm'};
Sensitivity to Disturbances
<<sec:sensitivity_disturbances>>
<<plt-matlab>>
<<plt-matlab>>
<<plt-matlab>>
Power Spectral Density of the effect of the disturbances
<<sec:psd_dist>> The PSD of the relative velocity between the hexapod and the marble in $[(m/s)^2/Hz]$ are loaded for the following sources of disturbance:
- Slip Ring Rotation
- Scan of the translation stage (effect in the vertical direction and in the horizontal direction)
Also, the Ground Motion is measured.
gm = load('./disturbances/mat/psd_gm.mat', 'f', 'psd_gm', 'psd_gv');
rz = load('./disturbances/mat/pxsp_r.mat', 'f', 'pxsp_r');
tyz = load('./disturbances/mat/pxz_ty_r.mat', 'f', 'pxz_ty_r');
tyx = load('./disturbances/mat/pxe_ty_r.mat', 'f', 'pxe_ty_r');
We now compute the relative velocity between the hexapod and the granite due to ground motion.
gm.psd_rv = gm.psd_gm.*abs(squeeze(freqresp(G('Vm', 'Dw'), gm.f, 'Hz'))).^2;
The Power Spectral Density of the relative motion/velocity of the hexapod with respect to the granite are shown in figures fig:dist_effect_relative_velocity and fig:dist_effect_relative_motion.
The Cumulative Amplitude Spectrum of the relative motion is shown in figure fig:dist_effect_relative_motion_cas.
<<plt-matlab>>
<<plt-matlab>>
<<plt-matlab>>
Compute the Power Spectral Density of the disturbance force
<<sec:psd_force_dist>>
Now, from the extracted transfer functions from the disturbance force to the relative motion of the hexapod with respect to the granite (section sec:sensitivity_disturbances) and from the measured PSD of the relative motion (section sec:psd_dist), we can compute the PSD of the disturbance force.
rz.psd_f = rz.pxsp_r./abs(squeeze(freqresp(G('Vm', 'Frz'), rz.f, 'Hz'))).^2;
tyz.psd_f = tyz.pxz_ty_r./abs(squeeze(freqresp(G('Vm', 'Fty'), tyz.f, 'Hz'))).^2;
<<plt-matlab>>
Noise Budget
<<sec:noise_budget>>
Now, from the compute spectral density of the disturbance sources, we can compute the resulting relative motion of the Hexapod with respect to the granite using the model. We should verify that this is coherent with the measurements.
<<plt-matlab>>
<<plt-matlab>>
Approximation
We approximate the PSD of the disturbance with the following transfer functions.
G_ty = 0.1*(s+634.3)*(s+283.7)/((s+2*pi)*(s+2*pi));
G_rz = 0.5*(s+418.8)*(s+36.51)*(s^2 + 110.9*s + 3.375e04)/((s+0.7324)*(s+0.546)*(s^2 + 0.6462*s + 2.391e04));
G_gm = 0.002*(s^2 + 3.169*s + 27.74)/(s*(s+32.73)*(s+8.829)*(s+7.983)^2);
We compute the effect of these approximate disturbances on $D$.
<<plt-matlab>>
<<plt-matlab>>
Save
The PSD of the disturbance force are now saved for further noise budgeting when control is applied (the mat file is accessible here).
dist_f = struct();
dist_f.f = gm.f; % Frequency Vector [Hz]
dist_f.psd_gm = gm.psd_gm; % Power Spectral Density of the Ground Motion [m^2/Hz]
dist_f.psd_ty = tyz.psd_f; % Power Spectral Density of the force induced by the Ty stage in the Z direction [N^2/Hz]
dist_f.psd_rz = rz.psd_f; % Power Spectral Density of the force induced by the Rz stage in the Z direction [N^2/Hz]
dist_f.G_gm = G_ty;
dist_f.G_ty = G_rz;
dist_f.G_rz = G_gm;
save('./disturbances/mat/dist_psd.mat', 'dist_f');
Function that initialize the disturbances
<<sec:initDisturbances>>
This Matlab function is accessible here.
function [] = initDisturbances(opts_param)
% initDisturbances - Initialize the disturbances
%
% Syntax: [] = initDisturbances(opts_param)
%
% Inputs:
% - opts_param -
Default values for the Options
%% Default values for opts
opts = struct();
%% Populate opts with input parameters
if exist('opts_param','var')
for opt = fieldnames(opts_param)'
opts.(opt{1}) = opts_param.(opt{1});
end
end
Load Data
load('./disturbances/mat/dist_psd.mat', 'dist_f');
We remove the first frequency point that usually is very large.
Parameters
We define some parameters that will be used in the algorithm.
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))
t = linspace(0, T0, N+1)'; % Time Vector [s]
Ts = 1/Fs; % Sampling Time [s]
Ground Motion
phi = dist_f.psd_gm;
C = zeros(N/2,1);
for i = 1:N/2
C(i) = sqrt(phi(i)*df);
end
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)))];;
u = N/sqrt(2)*ifft(Cx); % Ground Motion - x direction [m]
% Dwx = struct('time', t, 'signals', struct('values', u));
Dwx = u;
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)))];;
u = N/sqrt(2)*ifft(Cx); % Ground Motion - y direction [m]
Dwy = u;
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)))];;
u = N/sqrt(2)*ifft(Cx); % Ground Motion - z direction [m]
Dwz = u;
Translation Stage - X direction
phi = dist_f.psd_ty; % TODO - we take here the vertical direction which is wrong but approximate
C = zeros(N/2,1);
for i = 1:N/2
C(i) = sqrt(phi(i)*df);
end
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)))];;
u = N/sqrt(2)*ifft(Cx); % Disturbance Force Ty x [N]
Fty_x = u;
Translation Stage - Z direction
phi = dist_f.psd_ty;
C = zeros(N/2,1);
for i = 1:N/2
C(i) = sqrt(phi(i)*df);
end
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)))];;
u = N/sqrt(2)*ifft(Cx); % Disturbance Force Ty z [N]
Fty_z = u;
Spindle - Z direction
phi = dist_f.psd_rz;
C = zeros(N/2,1);
for i = 1:N/2
C(i) = sqrt(phi(i)*df);
end
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)))];;
u = N/sqrt(2)*ifft(Cx); % Disturbance Force Rz z [N]
Frz_z = u;
Direct Forces
u = zeros(length(t), 6);
Fd = u;
Set initial value to zero
Dwx = Dwx - Dwx(1);
Dwy = Dwy - Dwy(1);
Dwz = Dwz - Dwz(1);
Fty_x = Fty_x - Fty_x(1);
Fty_z = Fty_z - Fty_z(1);
Frz_z = Frz_z - Frz_z(1);
Save
save('./mat/nass_disturbances.mat', 'Dwx', 'Dwy', 'Dwz', 'Fty_x', 'Fty_z', 'Frz_z', 'Fd', 'Ts', 't');
Display Obtained Disturbances
initDisturbances();
load('./mat/nass_disturbances.mat', 'Dwx', 'Dwy', 'Dwz', 'Fty_x', 'Fty_z', 'Frz_z', 'Fd', 'Ts', 't');
figure;
hold on;
plot(t, Dwx, 'DisplayName', 'Dw x');
plot(t, Dwy, 'DisplayName', 'Dw y');
plot(t, Dwz, 'DisplayName', 'Dw z');
hold off;
xlabel('Time [s]'); ylabel('Amplitude [m]');
legend('location', 'north east');
figure;
hold on;
plot(t, Fty_x, 'DisplayName', 'Ty x');
plot(t, Fty_z, 'DisplayName', 'Ty z');
plot(t, Frz_z, 'DisplayName', 'Rz z');
hold off;
xlabel('Time [s]'); ylabel('Force [N]');
legend('location', 'north east');