2024-11-06 18:36:01 +01:00
% Matlab Init : noexport : ignore :
% % ustation_3 _disturbances . m
% % Clear Workspace and Close figures
clear ; close all ; clc ;
% % Intialize Laplace variable
s = zpk ( ' s ' ) ;
% % Path for functions , data and scripts
addpath ( ' . / mat / ' ) ; % Path for Data
addpath ( ' . / src / ' ) ; % Path for functions
addpath ( ' . / STEPS / ' ) ; % Path for STEPS
addpath ( ' . / subsystems / ' ) ; % Path for Subsystems Simulink files
% Simulink Model name
mdl = ' ustation_simscape ' ;
load ( ' nass_model _conf _simulink . mat ' ) ;
% % Colors for the figures
colors = colororder ;
% % Frequency Vector
freqs = logspace ( log10 ( 10 ) , log10 ( 2 e3 ) , 1000 ) ;
% Ground Motion
% The ground motion was measured by using a sensitive 3 - axis geophone [ fn : 11 ] placed on the ground .
% The generated voltages were recorded with a high resolution DAC , and converted to displacement using the Geophone sensitivity transfer function .
% The obtained ground motion displacement is shown in Figure ref : fig : ustation_ground _disturbance .
% % Compute Floor Motion Spectral Density
% Load floor motion data
% velocity in [ m / s ] is measured in X , Y and Z directions
load ( ' ustation_ground _motion . mat ' , ' Ts ' , ' Fs ' , ' vel_x ' , ' vel_y ' , ' vel_z ' , ' t ' ) ;
% Estimate ground displacement from measured velocity
% This is done by integrating the motion
gm_x = lsim ( 1 / ( s + 0.1 * 2 * pi ) , vel_x , t ) ;
gm_y = lsim ( 1 / ( s + 0.1 * 2 * pi ) , vel_y , t ) ;
gm_z = lsim ( 1 / ( s + 0.1 * 2 * pi ) , vel_z , t ) ;
Nfft = floor ( 2 / Ts ) ;
win = hanning ( Nfft ) ;
Noverlap = floor ( Nfft / 2 ) ;
[ pxx_gm _vx , f_gm ] = pwelch ( vel_x , win , Noverlap , Nfft , 1 / Ts ) ;
[ pxx_gm _vy , ~ ] = pwelch ( vel_y , win , Noverlap , Nfft , 1 / Ts ) ;
[ pxx_gm _vz , ~ ] = pwelch ( vel_z , win , Noverlap , Nfft , 1 / Ts ) ;
% Convert PSD in velocity to PSD in displacement
pxx_gm _x = pxx_gm _vx . / ( ( 2 * pi * f_gm ) . ^ 2 ) ;
pxx_gm _y = pxx_gm _vy . / ( ( 2 * pi * f_gm ) . ^ 2 ) ;
pxx_gm _z = pxx_gm _vz . / ( ( 2 * pi * f_gm ) . ^ 2 ) ;
% % Measured ground motion
figure ;
hold on ;
plot ( t , 1 e6 * gm_x , ' DisplayName ' , ' $ D_ { xf } $ ' )
plot ( t , 1 e6 * gm_y , ' DisplayName ' , ' $ D_ { yf } $ ' )
plot ( t , 1 e6 * gm_z , ' DisplayName ' , ' $ D_ { zf } $ ' )
hold off ;
xlabel ( ' Time [ s ] ' ) ;
ylabel ( ' Ground motion [ $ \ mu $ m ] ' )
xlim ( [ 0 , 5 ] ) ; ylim ( [ -2 , 2 ] )
leg = legend ( ' location ' , ' northeast ' , ' FontSize ' , 8 , ' NumColumns ' , 1 ) ;
leg . ItemTokenSize ( 1 ) = 15 ;
% Ty Stage
% To measure the positioning errors of the translation stage , the setup shown in Figure ref : fig : ustation_errors _ty _setup is used .
% A special optical element ( called a "straightness interferometer" [ fn : 9 ] ) is fixed on top of the micro - station , while a laser source [ fn : 10 ] and a straightness reflector are fixed on the ground .
% A similar setup was used to measure the horizontal deviation ( i . e . in the $ x $ direction ) , as well as the pitch and yaw errors of the translation stage .
% # + name : fig : ustation_errors _ty _setup
% # + caption : Experimental setup to measure the flatness ( vertical deviation ) of the translation stage
% [ [ file : figs / ustation_errors _ty _setup . png ] ]
% Six scans were performed between $ -4.5 \ , mm $ and $ 4.5 \ , mm $ .
% The results for each individual scan are shown in Figure ref : fig : ustation_errors _dy _vertical .
% The measurement axis may not be perfectly aligned with the translation stage axis ; this , a linear fit is removed from the measurement .
% The remaining vertical displacement is shown in Figure ref : fig : ustation_errors _dy _vertical _remove _mean .
% A vertical error of $ \ pm300 \ , nm $ induced by the translation stage is expected .
% Similar result is obtained for the $ x $ lateral direction .
% % Ty errors
% Setpoint is in [ mm ]
% Vertical error is in [ um ]
ty_errors = load ( ' ustation_errors _ty . mat ' ) ;
% Compute best straight line to remove it from data
average_error = mean ( ty_errors . ty_z ' ) ' ;
straight_line = average_error - detrend ( average_error , 1 ) ;
% % Measurement of the linear ( vertical ) deviation of the Translation stage
figure ;
hold on ;
plot ( ty_errors . setpoint , ty_errors . ty_z ( : , 1 ) , ' - ' , ' color ' , colors ( 1 , : ) , ' DisplayName ' , ' Raw data ' )
plot ( ty_errors . setpoint , ty_errors . ty_z ( : , 2 : end ) , ' - ' , ' color ' , colors ( 1 , : ) , ' HandleVisibility ' , ' off ' )
plot ( ty_errors . setpoint , straight_line , ' - - ' , ' color ' , colors ( 2 , : ) , ' DisplayName ' , ' Linear fit ' )
hold off ;
xlabel ( ' $ D_y $ position [ mm ] ' ) ; ylabel ( ' Vertical error [ $ \ mu $ m ] ' ) ;
xlim ( [ -5 , 5 ] ) ; ylim ( [ -8 , 8 ] ) ;
legend ( ' location ' , ' southwest ' , ' FontSize ' , 8 , ' NumColumns ' , 1 ) ;
% % Measurement of the linear ( vertical ) deviation of the Translation stage - Remove best linear fit
figure ;
plot ( ty_errors . setpoint , ty_errors . ty_z - straight_line , ' k - ' )
xlabel ( ' $ D_y $ position [ mm ] ' ) ; ylabel ( ' Vertical error [ $ \ mu $ m ] ' ) ;
xlim ( [ -5 , 5 ] ) ; ylim ( [ -0.4 , 0.4 ] ) ;
% # + name : fig : ustation_errors _dy
% # + caption : Measurement of the linear ( vertical ) deviation of the Translation stage ( \ subref { fig : ustation_errors _dy _vertical } ) . A linear fit is then removed from the data ( \ subref { fig : ustation_errors _dy _vertical _remove _mean } ) .
% # + attr_latex : : options [ htbp ]
% # + begin_figure
% # + attr_latex : : caption \ subcaption { \ label { fig : ustation_errors _dy _vertical } Measured vertical error }
% # + attr_latex : : options { 0.49 \ textwidth }
% # + begin_subfigure
% # + attr_latex : : width 0.95 \ linewidth
% [ [ file : figs / ustation_errors _dy _vertical . png ] ]
% # + end_subfigure
% # + attr_latex : : caption \ subcaption { \ label { fig : ustation_errors _dy _vertical _remove _mean } Error after removing linear fit }
% # + attr_latex : : options { 0.49 \ textwidth }
% # + begin_subfigure
% # + attr_latex : : width 0.95 \ linewidth
% [ [ file : figs / ustation_errors _dy _vertical _remove _mean . png ] ]
% # + end_subfigure
% # + end_figure
% % Convert the data to frequency domain
% Suppose a certain constant velocity scan
delta_ty = ( ty_errors . setpoint ( end ) - ty_errors . setpoint ( 1 ) ) / ( length ( ty_errors . setpoint ) - 1 ) ; % [ mm ]
ty_vel = 8 * 1.125 ; % [ mm / s ]
Ts = delta_ty / ty_vel ;
2024-11-06 18:55:05 +01:00
Fs = 1 / Ts ;
2024-11-06 18:36:01 +01:00
% Frequency Analysis
Nfft = floor ( length ( ty_errors . setpoint ) ) ; % Number of frequency points
win = hanning ( Nfft ) ; % Windowing
Noverlap = floor ( Nfft / 2 ) ; % Overlap for frequency analysis
% Comnpute the power spectral density
[ pxx_dy _dz , f_dy ] = pwelch ( 1 e -6 * detrend ( ty_errors . ty_z , 1 ) , win , Noverlap , Nfft , Fs ) ;
pxx_dy _dz = mean ( pxx_dy _dz ' ) ' ;
% Having the PSD of the lateral error equal to the PSD of the vertical error
% is a reasonable assumption ( and verified in practice )
pxx_dy _dx = pxx_dy _dz ;
% Spindle
% To measure the positioning errors induced by the Spindle , a "Spindle error analyzer" [ fn : 7 ] is used as shown in Figure ref : fig : ustation_rz _meas _lion _setup .
% A specific target is fixed on top of the micro - station , which consists of two sphere with 1 inch diameter precisely aligned with the spindle rotation axis .
% Five capacitive sensors [ fn : 8 ] are pointing at the two spheres , as shown in Figure ref : fig : ustation_rz _meas _lion _zoom .
% From the 5 measured displacements $ [ d_1 , \ , d_2 , \ , d_3 , \ , d_4 , \ , d_5 ] $ , the translations and rotations $ [ D_x , \ , D_y , \ , D_z , \ , R_x , \ , R_y ] $ of the target can be estimated .
% # + name : fig : ustation_rz _meas _lion _setup
% # + caption : Experimental setup used to estimate the errors induced by the Spindle rotation ( \ subref { fig : ustation_rz _meas _lion } ) . The motion of the two reference spheres is measured using 5 capacitive sensors ( \ subref { fig : ustation_rz _meas _lion _zoom } )
% # + attr_latex : : options [ htbp ]
% # + begin_figure
% # + attr_latex : : caption \ subcaption { \ label { fig : ustation_rz _meas _lion } Micro - station and 5 - DoF metrology }
% # + attr_latex : : options { 0.49 \ textwidth }
% # + begin_subfigure
% # + attr_latex : : width 0.9 \ linewidth
% [ [ file : figs / ustation_rz _meas _lion . jpg ] ]
% # + end_subfigure
% # + attr_latex : : caption \ subcaption { \ label { fig : ustation_rz _meas _lion _zoom } Zoom on the metrology system }
% # + attr_latex : : options { 0.49 \ textwidth }
% # + begin_subfigure
% # + attr_latex : : width 0.9 \ linewidth
% [ [ file : figs / ustation_rz _meas _lion _zoom . jpg ] ]
% # + end_subfigure
% # + end_figure
% A measurement was performed during a constant rotational velocity of the spindle of 60 rpm and during 10 turns .
% The obtained results are shown in Figure ref : fig : ustation_errors _spindle .
% A large fraction of the radial ( Figure ref : fig : ustation_errors _spindle _radial ) and tilt ( Figure ref : fig : ustation_errors _spindle _tilt ) errors is linked to the fact that the two spheres are not perfectly aligned with the rotation axis of the Spindle .
% This is displayed by the dashed circle .
% After removing the best circular fit from the data , the vibrations induced by the Spindle may be viewed as stochastic disturbances .
% However , some misalignment between the "point-of-interest" of the sample and the rotation axis will be considered because the alignment is not perfect in practice .
% The vertical motion induced by scanning the spindle is in the order of $ \ pm 30 \ , nm $ ( Figure ref : fig : ustation_errors _spindle _axial ) .
% % Spindle Errors
% Errors are already converted to x , y , z , Rx , Ry
% Units are in [ m ] and [ rad ]
spindle_errors = load ( ' ustation_errors _spindle . mat ' ) ;
% % Measured radial errors of the Spindle
figure ;
hold on ;
plot ( 1 e6 * spindle_errors . Dx ( 1 : 100 : end ) , 1 e6 * spindle_errors . Dy ( 1 : 100 : end ) , ' DisplayName ' , ' Raw data ' )
% Compute best fitting circle
[ x0 , y0 , R ] = circlefit ( spindle_errors . Dx , spindle_errors . Dy ) ;
theta = linspace ( 0 , 2 * pi , 500 ) ; % Angle to plot the circle [ rad ]
plot ( 1 e6 * ( x0 + R * cos ( theta ) ) , 1 e6 * ( y0 + R * sin ( theta ) ) , ' - - ' , ' DisplayName ' , ' Best Fit ' )
hold off ;
xlabel ( ' X displacement [ $ \ mu $ m ] ' ) ; ylabel ( ' Y displacement [ $ \ mu $ m ] ' ) ;
axis equal
xlim ( [ -1 , 1 ] ) ; ylim ( [ -1 , 1 ] ) ;
xticks ( [ -1 , -0.5 , 0 , 0.5 , 1 ] ) ;
yticks ( [ -1 , -0.5 , 0 , 0.5 , 1 ] ) ;
leg = legend ( ' location ' , ' none ' , ' FontSize ' , 8 , ' NumColumns ' , 1 ) ;
leg . ItemTokenSize ( 1 ) = 15 ;
% % Measured axial errors of the Spindle
figure ;
plot ( spindle_errors . deg ( 1 : 100 : end ) / 360 , 1 e9 * spindle_errors . Dz ( 1 : 100 : end ) )
xlabel ( ' Rotation [ turn ] ' ) ; ylabel ( ' Z displacement [ nm ] ' ) ;
axis square
xlim ( [ 0 , 2 ] ) ; ylim ( [ -40 , 40 ] ) ;
% % Measured tilt errors of the Spindle
figure ;
plot ( 1 e6 * spindle_errors . Rx ( 1 : 100 : end ) , 1 e6 * spindle_errors . Ry ( 1 : 100 : end ) )
xlabel ( ' X angle [ $ \ mu $ rad ] ' ) ; ylabel ( ' Y angle [ $ \ mu $ rad ] ' ) ;
axis equal
xlim ( [ -35 , 35 ] ) ; ylim ( [ -35 , 35 ] ) ;
xticks ( [ -30 , -15 , 0 , 15 , 30 ] ) ;
yticks ( [ -30 , -15 , 0 , 15 , 30 ] ) ;
% # + name : fig : ustation_errors _spindle
% # + caption : Measurement of the radial ( \ subref { fig : ustation_errors _spindle _radial } ) , axial ( \ subref { fig : ustation_errors _spindle _axial } ) and tilt ( \ subref { fig : ustation_errors _spindle _tilt } ) Spindle errors during a 60 rpm spindle rotation . The circular best fit is shown by the dashed circle . It represents the misalignment of the spheres with the rotation axis .
% # + attr_latex : : options [ htbp ]
% # + begin_figure
% # + attr_latex : : caption \ subcaption { \ label { fig : ustation_errors _spindle _radial } Radial errors }
% # + attr_latex : : options { 0.33 \ textwidth }
% # + begin_subfigure
% # + attr_latex : : width 0.9 \ linewidth
% [ [ file : figs / ustation_errors _spindle _radial . png ] ]
% # + end_subfigure
% # + attr_latex : : caption \ subcaption { \ label { fig : ustation_errors _spindle _axial } Axial error }
% # + attr_latex : : options { 0.33 \ textwidth }
% # + begin_subfigure
% # + attr_latex : : width 0.9 \ linewidth
% [ [ file : figs / ustation_errors _spindle _axial . png ] ]
% # + end_subfigure
% # + attr_latex : : caption \ subcaption { \ label { fig : ustation_errors _spindle _tilt } Tilt errors }
% # + attr_latex : : options { 0.33 \ textwidth }
% # + begin_subfigure
% # + attr_latex : : width 0.9 \ linewidth
% [ [ file : figs / ustation_errors _spindle _tilt . png ] ]
% # + end_subfigure
% # + end_figure
% % Remove the circular fit from the data
[ x0 , y0 , R ] = circlefit ( spindle_errors . Dx , spindle_errors . Dy ) ;
% Search the best angular match
fun = @ ( theta ) rms ( ( spindle_errors . Dx - ( x0 + R * cos ( pi / 180 * spindle_errors . deg + theta ( 1 ) ) ) ) . ^ 2 + ( spindle_errors . Dy - ( y0 - R * sin ( pi / 180 * spindle_errors . deg + theta ( 1 ) ) ) ) . ^ 2 ) ;
x0 = [ 0 ] ;
2024-11-06 18:55:05 +01:00
delta_theta = fminsearch ( fun , 0 ) ;
2024-11-06 18:36:01 +01:00
% Compute the remaining error after removing the best circular fit
spindle_errors . Dx_err = spindle_errors . Dx - ( x0 + R * cos ( pi / 180 * spindle_errors . deg + delta_theta ) ) ;
spindle_errors . Dy_err = spindle_errors . Dy - ( y0 - R * sin ( pi / 180 * spindle_errors . deg + delta_theta ) ) ;
% % Convert the data to frequency domain
Ts = ( spindle_errors . t ( end ) - spindle_errors . t ( 1 ) ) / ( length ( spindle_errors . t ) -1 ) ; % [ s ]
Fs = 1 / Ts ; % [ Hz ]
% Frequency Analysis
Nfft = floor ( 2.0 * Fs ) ; % Number of frequency points
win = hanning ( Nfft ) ; % Windowing
Noverlap = floor ( Nfft / 2 ) ; % Overlap for frequency analysis
% Comnpute the power spectral density
[ pxx_rz _dz , f_rz ] = pwelch ( spindle_errors . Dz , win , Noverlap , Nfft , Fs ) ;
[ pxx_rz _dx , ~ ] = pwelch ( spindle_errors . Dx_err , win , Noverlap , Nfft , Fs ) ;
[ pxx_rz _dy , ~ ] = pwelch ( spindle_errors . Dy_err , win , Noverlap , Nfft , Fs ) ;
% Sensitivity to disturbances
% < < ssec : ustation_disturbances _sensitivity > >
% To compute the disturbance source ( i . e . forces ) that induced the measured vibrations in Section ref : ssec : ustation_disturbances _meas , the transfer function from the disturbance sources to the stage vibration ( i . e . the "sensitivity to disturbances" ) needs to be estimated .
% This is achieved using the multi - body model presented in Section ref : sec : ustation_modeling .
% The obtained transfer functions are shown in Figure ref : fig : ustation_model _sensitivity .
% % Extract sensitivity to disturbances from the Simscape model
% Initialize stages
initializeGround ( ) ;
initializeGranite ( ) ;
initializeTy ( ) ;
initializeRy ( ) ;
initializeRz ( ) ;
initializeMicroHexapod ( ) ;
initializeDisturbances ( ' enable ' , false ) ;
initializeSimscapeConfiguration ( ' gravity ' , false ) ;
initializeLoggingConfiguration ( ) ;
% Configure inputs and outputs
clear io ; io_i = 1 ;
io ( io_i ) = linio ( [ mdl , ' / Disturbances / Dwx ' ] , 1 , ' openinput ' ) ; io_i = io_i + 1 ; % Vertical Ground Motion
io ( io_i ) = linio ( [ mdl , ' / Disturbances / Dwy ' ] , 1 , ' openinput ' ) ; io_i = io_i + 1 ; % Vertical Ground Motion
io ( io_i ) = linio ( [ mdl , ' / Disturbances / Dwz ' ] , 1 , ' openinput ' ) ; io_i = io_i + 1 ; % Vertical Ground Motion
io ( io_i ) = linio ( [ mdl , ' / Disturbances / Fdy_x ' ] , 1 , ' openinput ' ) ; io_i = io_i + 1 ; % Parasitic force Ty
io ( io_i ) = linio ( [ mdl , ' / Disturbances / Fdy_z ' ] , 1 , ' openinput ' ) ; io_i = io_i + 1 ; % Parasitic force Ty
io ( io_i ) = linio ( [ mdl , ' / Disturbances / Frz_x ' ] , 1 , ' openinput ' ) ; io_i = io_i + 1 ; % Parasitic force Rz
io ( io_i ) = linio ( [ mdl , ' / Disturbances / Frz_y ' ] , 1 , ' openinput ' ) ; io_i = io_i + 1 ; % Parasitic force Rz
io ( io_i ) = linio ( [ mdl , ' / Disturbances / Frz_z ' ] , 1 , ' openinput ' ) ; io_i = io_i + 1 ; % Parasitic force Rz
io ( io_i ) = linio ( [ mdl , ' / Micro - Station / metrology_6dof / x ' ] , 1 , ' openoutput ' ) ; io_i = io_i + 1 ; % Relative motion - Hexapod / Granite
io ( io_i ) = linio ( [ mdl , ' / Micro - Station / metrology_6dof / y ' ] , 1 , ' openoutput ' ) ; io_i = io_i + 1 ; % Relative motion - Hexapod / Granite
io ( io_i ) = linio ( [ mdl , ' / Micro - Station / metrology_6dof / z ' ] , 1 , ' openoutput ' ) ; io_i = io_i + 1 ; % Relative motion - Hexapod / Granite
% Run the linearization
Gd = linearize ( mdl , io , 0 ) ;
Gd . InputName = { ' Dwx ' , ' Dwy ' , ' Dwz ' , ' Fdy_x ' , ' Fdy_z ' , ' Frz_x ' , ' Frz_y ' , ' Frz_z ' } ;
Gd . OutputName = { ' Dx ' , ' Dy ' , ' Dz ' } ;
% The identified dynamics are then saved for further use .
save ( ' . / mat / ustation_disturbance _sensitivity . mat ' , ' Gd ' )
% % Sensitivity to Ground motion
freqs = logspace ( log10 ( 10 ) , log10 ( 2 e2 ) , 1000 ) ;
figure ;
hold on ;
plot ( freqs , abs ( squeeze ( freqresp ( Gd ( ' Dx ' , ' Dwx ' ) , freqs , ' Hz ' ) ) ) , ' DisplayName ' , ' $ D_x / D_ { xf } $ ' ) ;
plot ( freqs , abs ( squeeze ( freqresp ( Gd ( ' Dy ' , ' Dwy ' ) , freqs , ' Hz ' ) ) ) , ' DisplayName ' , ' $ D_y / D_ { yf } $ ' ) ;
plot ( freqs , abs ( squeeze ( freqresp ( Gd ( ' Dz ' , ' Dwz ' ) , freqs , ' Hz ' ) ) ) , ' DisplayName ' , ' $ D_z / D_ { zf } $ ' ) ;
hold off ;
set ( gca , ' XScale ' , ' log ' ) ; set ( gca , ' YScale ' , ' log ' ) ;
ylabel ( ' Amplitude [ m / m ] ' ) ; xlabel ( ' Frequency [ Hz ] ' ) ;
leg = legend ( ' location ' , ' southeast ' , ' FontSize ' , 8 , ' NumColumns ' , 1 ) ;
leg . ItemTokenSize ( 1 ) = 15 ;
% % Sensitivity to Translation stage disturbance forces
figure ;
hold on ;
plot ( freqs , abs ( squeeze ( freqresp ( Gd ( ' Dx ' , ' Fdy_x ' ) , freqs , ' Hz ' ) ) ) , ' color ' , colors ( 1 , : ) , ' DisplayName ' , ' $ D_x / F_ { xD_y } $ ' ) ;
plot ( freqs , abs ( squeeze ( freqresp ( Gd ( ' Dz ' , ' Fdy_z ' ) , freqs , ' Hz ' ) ) ) , ' color ' , colors ( 3 , : ) , ' DisplayName ' , ' $ D_z / F_ { zD_y } $ ' ) ;
hold off ;
set ( gca , ' XScale ' , ' log ' ) ; set ( gca , ' YScale ' , ' log ' ) ;
ylabel ( ' Amplitude [ m / N ] ' ) ; xlabel ( ' Frequency [ Hz ] ' ) ;
ylim ( [ 1 e -10 , 1 e -7 ] ) ;
leg = legend ( ' location ' , ' southeast ' , ' FontSize ' , 8 , ' NumColumns ' , 1 ) ;
leg . ItemTokenSize ( 1 ) = 15 ;
% % Sensitivity to Spindle disturbance forces
figure ;
hold on ;
plot ( freqs , abs ( squeeze ( freqresp ( Gd ( ' Dx ' , ' Frz_x ' ) , freqs , ' Hz ' ) ) ) , ' DisplayName ' , ' $ D_x / F_ { xR_z } $ ' ) ;
plot ( freqs , abs ( squeeze ( freqresp ( Gd ( ' Dy ' , ' Frz_y ' ) , freqs , ' Hz ' ) ) ) , ' DisplayName ' , ' $ D_y / F_ { yR_z } $ ' ) ;
plot ( freqs , abs ( squeeze ( freqresp ( Gd ( ' Dz ' , ' Frz_z ' ) , freqs , ' Hz ' ) ) ) , ' DisplayName ' , ' $ D_z / F_ { zR_z } $ ' ) ;
hold off ;
set ( gca , ' XScale ' , ' log ' ) ; set ( gca , ' YScale ' , ' log ' ) ;
ylabel ( ' Amplitude [ m / N ] ' ) ; xlabel ( ' Frequency [ Hz ] ' ) ;
ylim ( [ 1 e -10 , 1 e -7 ] ) ;
leg = legend ( ' location ' , ' northwest ' , ' FontSize ' , 8 , ' NumColumns ' , 1 ) ;
leg . ItemTokenSize ( 1 ) = 15 ;
% Obtained disturbance sources
% < < ssec : ustation_disturbances _results > >
% From the measured effect of disturbances in Section ref : ssec : ustation_disturbances _meas and the sensitivity to disturbances extracted from the Simscape model in Section ref : ssec : ustation_disturbances _sensitivity , the power spectral density of the disturbance sources ( i . e . forces applied in the stage ' s joint ) can be estimated .
% The obtained power spectral density of the disturbances are shown in Figure ref : fig : ustation_dist _sources .
% % Compute the PSD of the equivalent disturbance sources
pxx_rz _fx = pxx_rz _dx . / abs ( squeeze ( freqresp ( Gd ( ' Dx ' , ' Frz_x ' ) , f_rz , ' Hz ' ) ) ) . ^ 2 ;
pxx_rz _fy = pxx_rz _dy . / abs ( squeeze ( freqresp ( Gd ( ' Dy ' , ' Frz_y ' ) , f_rz , ' Hz ' ) ) ) . ^ 2 ;
pxx_rz _fz = pxx_rz _dz . / abs ( squeeze ( freqresp ( Gd ( ' Dz ' , ' Frz_z ' ) , f_rz , ' Hz ' ) ) ) . ^ 2 ;
pxx_dy _fx = pxx_dy _dx . / abs ( squeeze ( freqresp ( Gd ( ' Dx ' , ' Fdy_x ' ) , f_dy , ' Hz ' ) ) ) . ^ 2 ;
pxx_dy _fz = pxx_dy _dz . / abs ( squeeze ( freqresp ( Gd ( ' Dz ' , ' Fdy_z ' ) , f_dy , ' Hz ' ) ) ) . ^ 2 ;
% % Save the PSD of the disturbance sources for further used
% in the Simscape model
% Ground motion
min_f = 1 ; max_f = 100 ;
gm_dist . f = f_gm ( f_gm < max_f & f_gm > min_f ) ;
gm_dist . pxx_x = pxx_gm _x ( f_gm < max_f & f_gm > min_f ) ;
gm_dist . pxx_y = pxx_gm _y ( f_gm < max_f & f_gm > min_f ) ;
gm_dist . pxx_z = pxx_gm _z ( f_gm < max_f & f_gm > min_f ) ;
% Translation stage
min_f = 0.5 ; max_f = 500 ;
dy_dist . f = f_dy ( f_dy < max_f & f_dy > min_f ) ;
dy_dist . pxx_fx = pxx_dy _fx ( f_dy < max_f & f_dy > min_f ) ;
dy_dist . pxx_fz = pxx_dy _fz ( f_dy < max_f & f_dy > min_f ) ;
% Spindle
min_f = 1 ; max_f = 500 ;
rz_dist . f = f_rz ( f_rz < max_f & f_rz > min_f ) ;
rz_dist . pxx_fx = pxx_rz _fx ( f_rz < max_f & f_rz > min_f ) ;
rz_dist . pxx_fy = pxx_rz _fy ( f_rz < max_f & f_rz > min_f ) ;
rz_dist . pxx_fz = pxx_rz _fz ( f_rz < max_f & f_rz > min_f ) ;
% The identified dynamics are then saved for further use .
save ( ' . / mat / ustation_disturbance _psd . mat ' , ' rz_dist ' , ' dy_dist ' , ' gm_dist ' )
% % Ground Motion
figure ;
hold on ;
plot ( f_gm , sqrt ( pxx_gm _x ) , ' DisplayName ' , ' $ D_ { wx } $ ' ) ;
plot ( f_gm , sqrt ( pxx_gm _y ) , ' DisplayName ' , ' $ D_ { wy } $ ' ) ;
plot ( f_gm , sqrt ( pxx_gm _z ) , ' DisplayName ' , ' $ D_ { wz } $ ' ) ;
set ( gca , ' xscale ' , ' log ' ) ; set ( gca , ' yscale ' , ' log ' ) ;
xlabel ( ' Frequency [ Hz ] ' ) ; ylabel ( ' Spectral Density $ \ left [ \ frac { m } { \ sqrt { Hz } } \ right ] $ ' )
xlim ( [ 1 , 200 ] ) ;
leg = legend ( ' location ' , ' northeast ' , ' FontSize ' , 8 , ' NumColumns ' , 1 ) ;
leg . ItemTokenSize ( 1 ) = 15 ;
figure ;
hold on ;
plot ( f_dy , sqrt ( pxx_dy _fx ) , ' DisplayName ' , ' $ F_ { xD_y } $ ' ) ;
plot ( f_dy , sqrt ( pxx_dy _fz ) , ' DisplayName ' , ' $ F_ { zD_y } $ ' ) ;
set ( gca , ' xscale ' , ' log ' ) ; set ( gca , ' yscale ' , ' log ' ) ;
xlabel ( ' Frequency [ Hz ] ' ) ; ylabel ( ' Spectral Density $ \ left [ \ frac { N } { \ sqrt { Hz } } \ right ] $ ' )
xlim ( [ 1 , 200 ] ) ; ylim ( [ 1 e -3 , 1 e3 ] ) ;
leg = legend ( ' location ' , ' northeast ' , ' FontSize ' , 8 , ' NumColumns ' , 1 ) ;
leg . ItemTokenSize ( 1 ) = 15 ;
figure ;
hold on ;
plot ( f_rz , sqrt ( pxx_rz _fx ) , ' DisplayName ' , ' $ F_ { xR_z } $ ' ) ;
plot ( f_rz , sqrt ( pxx_rz _fy ) , ' DisplayName ' , ' $ F_ { yR_z } $ ' ) ;
plot ( f_rz , sqrt ( pxx_rz _fz ) , ' DisplayName ' , ' $ F_ { zR_z } $ ' ) ;
set ( gca , ' xscale ' , ' log ' ) ; set ( gca , ' yscale ' , ' log ' ) ;
xlabel ( ' Frequency [ Hz ] ' ) ; ylabel ( ' Spectral Density $ \ left [ \ frac { N } { \ sqrt { Hz } } \ right ] $ ' )
xlim ( [ 1 , 200 ] ) ; ylim ( [ 1 e -3 , 1 e3 ] ) ;
leg = legend ( ' location ' , ' northeast ' , ' FontSize ' , 8 , ' NumColumns ' , 1 ) ;
leg . ItemTokenSize ( 1 ) = 15 ;
% # + name : fig : ustation_dist _sources
% # + caption : Measured spectral density of the micro - station disturbance sources . Ground motion ( \ subref { fig : ustation_dist _source _ground _motion } ) , translation stage ( \ subref { fig : ustation_dist _source _translation _stage } ) and spindle ( \ subref { fig : ustation_dist _source _spindle } ) .
% # + attr_latex : : options [ htbp ]
% # + begin_figure
% # + attr_latex : : caption \ subcaption { \ label { fig : ustation_dist _source _ground _motion } Ground Motion }
% # + attr_latex : : options { 0.33 \ textwidth }
% # + begin_subfigure
% # + attr_latex : : width 0.9 \ linewidth
% [ [ file : figs / ustation_dist _source _ground _motion . png ] ]
% # + end_subfigure
% # + attr_latex : : caption \ subcaption { \ label { fig : ustation_dist _source _translation _stage } Translation Stage }
% # + attr_latex : : options { 0.33 \ textwidth }
% # + begin_subfigure
% # + attr_latex : : width 0.9 \ linewidth
% [ [ file : figs / ustation_dist _source _translation _stage . png ] ]
% # + end_subfigure
% # + attr_latex : : caption \ subcaption { \ label { fig : ustation_dist _source _spindle } Spindle }
% # + attr_latex : : options { 0.33 \ textwidth }
% # + begin_subfigure
% # + attr_latex : : width 0.9 \ linewidth
% [ [ file : figs / ustation_dist _source _spindle . png ] ]
% # + end_subfigure
% # + end_figure
% The disturbances are characterized by their power spectral densities , as shown in Figure ref : fig : ustation_dist _sources .
% However , to perform time domain simulations , disturbances must be represented by a time domain signal .
% To generate stochastic time - domain signals with a specific power spectral densities , the discrete inverse Fourier transform is used , as explained in [ [ cite : & preumont94_random _vibrat _spect _analy chap . 12.11 ] ] .
% Examples of the obtained time - domain disturbance signals are shown in Figure ref : fig : ustation_dist _sources _time .
% % Compute time domain disturbance signals
initializeDisturbances ( ) ;
load ( ' nass_model _disturbances . mat ' ) ;
figure ;
hold on ;
plot ( Rz . t , Rz . x , ' DisplayName ' , ' $ F_ { xR_z } $ ' ) ;
plot ( Rz . t , Rz . y , ' DisplayName ' , ' $ F_ { yR_z } $ ' ) ;
plot ( Rz . t , Rz . z , ' DisplayName ' , ' $ F_ { zR_z } $ ' ) ;
xlabel ( ' Time [ s ] ' ) ; ylabel ( ' Amplitude [ N ] ' )
xlim ( [ 0 , 1 ] ) ; ylim ( [ -100 , 100 ] ) ;
leg = legend ( ' location ' , ' northwest ' , ' FontSize ' , 8 , ' NumColumns ' , 1 ) ;
leg . ItemTokenSize ( 1 ) = 15 ;
figure ;
hold on ;
plot ( Dy . t , Dy . x , ' DisplayName ' , ' $ F_ { xD_y } $ ' ) ;
plot ( Dy . t , Dy . z , ' DisplayName ' , ' $ F_ { zD_y } $ ' ) ;
xlabel ( ' Time [ s ] ' ) ; ylabel ( ' Amplitude [ N ] ' )
xlim ( [ 0 , 1 ] ) ; ylim ( [ -60 , 60 ] )
leg = legend ( ' location ' , ' southwest ' , ' FontSize ' , 8 , ' NumColumns ' , 1 ) ;
leg . ItemTokenSize ( 1 ) = 15 ;
figure ;
hold on ;
plot ( Dw . t , 1 e6 * Dw . x , ' DisplayName ' , ' $ D_ { xf } $ ' ) ;
plot ( Dw . t , 1 e6 * Dw . y , ' DisplayName ' , ' $ D_ { yf } $ ' ) ;
plot ( Dw . t , 1 e6 * Dw . z , ' DisplayName ' , ' $ D_ { zf } $ ' ) ;
xlabel ( ' Time [ s ] ' ) ; ylabel ( ' Amplitude [ $ \ mu $ m ] ' )
2024-11-06 18:55:05 +01:00
xlim ( [ 0 , 1 ] ) ; ylim ( [ -0.6 , 0.6 ] )
2024-11-06 18:36:01 +01:00
leg = legend ( ' location ' , ' southeast ' , ' FontSize ' , 8 , ' NumColumns ' , 1 ) ;
leg . ItemTokenSize ( 1 ) = 15 ;