2020-01-15 16:23:40 +01:00
#+TITLE : Active Damping applied on the Simscape Model
2019-07-15 11:07:24 +02:00
:DRAWER:
#+STARTUP : overview
#+LANGUAGE : en
#+EMAIL : dehaeze.thomas@gmail.com
#+AUTHOR : Dehaeze Thomas
#+HTML_LINK_HOME : ../index.html
#+HTML_LINK_UP : ../index.html
#+HTML_HEAD : <link rel="stylesheet" type="text/css" href="../css/htmlize.css"/>
#+HTML_HEAD : <link rel="stylesheet" type="text/css" href="../css/readtheorg.css"/>
#+HTML_HEAD : <link rel="stylesheet" type="text/css" href="../css/zenburn.css"/>
#+HTML_HEAD : <script type="text/javascript" src="../js/jquery.min.js"></script>
#+HTML_HEAD : <script type="text/javascript" src="../js/bootstrap.min.js"></script>
#+HTML_HEAD : <script type="text/javascript" src="../js/jquery.stickytableheaders.min.js"></script>
#+HTML_HEAD : <script type="text/javascript" src="../js/readtheorg.js"></script>
#+HTML_MATHJAX : align: center tagside: right font: TeX
#+PROPERTY : header-args:matlab :session *MATLAB*
#+PROPERTY : header-args:matlab+ :comments org
#+PROPERTY : header-args:matlab+ :results none
#+PROPERTY : header-args:matlab+ :exports both
#+PROPERTY : header-args:matlab+ :eval no-export
#+PROPERTY : header-args:matlab+ :output-dir figs
2019-10-25 16:02:23 +02:00
#+PROPERTY : header-args:matlab+ :tangle no
2019-07-15 11:07:24 +02:00
#+PROPERTY : header-args:matlab+ :mkdirp yes
#+PROPERTY : header-args:shell :eval no-export
2019-10-14 16:42:53 +02:00
#+PROPERTY : header-args:latex :headers '("\\usepackage{tikz}" "\\usepackage{import}" "\\import{$HOME/Cloud/thesis/latex/}{config.tex}")
2019-07-15 11:07:24 +02:00
#+PROPERTY : header-args:latex+ :imagemagick t :fit yes
#+PROPERTY : header-args:latex+ :iminoptions -scale 100% -density 150
#+PROPERTY : header-args:latex+ :imoutoptions -quality 100
#+PROPERTY : header-args:latex+ :results raw replace :buffer no
#+PROPERTY : header-args:latex+ :eval no-export
#+PROPERTY : header-args:latex+ :exports both
#+PROPERTY : header-args:latex+ :mkdirp yes
#+PROPERTY : header-args:latex+ :output-dir figs
:END:
2019-10-18 17:34:45 +02:00
2020-02-25 17:49:08 +01:00
* Introduction :ignore:
2020-02-06 17:07:11 +01:00
The goal of this file is to study the use of active damping for the control of the NASS.
2019-10-18 17:34:45 +02:00
2020-02-06 17:07:11 +01:00
In general, three sensors can be used for Active Damping:
- A force sensor
- A relative motion sensor such as a capacitive sensor
- An inertial sensor such as an accelerometer of geophone
2019-10-18 17:34:45 +02:00
2020-02-06 17:07:11 +01:00
First, in section [[sec:undamped_system ]], we look at the undamped system and we identify the dynamics from the actuators to the three sensor types.
Then, in section [[sec:act_damp_variability_plant ]], we study the change of dynamics for the active damping plants with respect to various experimental conditions such as the sample mass and the spindle rotation speed.
Then, we will apply and compare the results of three active damping techniques:
- In section [[sec:iff ]]: Integral Force Feedback is applied
- In section [[sec:dvf ]]: Direct Velocity Feedback using a relative motion sensor is applied
- In section [[sec:ine ]]: Inertial Control using a geophone is applied
For each of the active damping technique, we:
- Look at the obtain damped plant that will be used for High Authority control
2020-01-15 16:23:40 +01:00
- Simulate tomography experiments
- Compare the sensitivity from disturbances
2019-10-18 17:34:45 +02:00
* Undamped System
2019-10-25 16:02:23 +02:00
:PROPERTIES:
:header-args:matlab+: :tangle matlab/undamped_system.m
2019-12-11 14:46:31 +01:00
:header-args:matlab+: :comments none :mkdirp yes
2019-10-25 16:02:23 +02:00
:END:
<<sec:undamped_system >>
2020-01-15 16:23:40 +01:00
** Introduction :ignore:
2020-02-04 18:36:27 +01:00
In this section, we identify the dynamic of the system from forces applied in the nano-hexapod legs to the various sensors included in the nano-hexapod that could be use for Active Damping, namely:
- A relative motion sensor, measuring the relative displacement of each of the leg
- A force sensor measuring the total force transmitted to the top part of the leg in the direction of the leg
- A absolute velocity sensor measuring the absolute velocity of the top part of the leg in the direction of the leg
After that, a tomography experiment is simulation without any active damping techniques.
2019-10-18 17:34:45 +02:00
2020-01-15 16:23:40 +01:00
** Matlab Init :noexport:ignore:
2019-10-18 17:34:45 +02:00
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir >>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init >>
#+end_src
#+begin_src matlab :tangle no
simulinkproject('../');
#+end_src
2020-01-15 16:23:40 +01:00
#+begin_src matlab
addpath('active_damping/src/ ');
#+end_src
2019-10-18 17:34:45 +02:00
#+begin_src matlab
2020-02-18 11:33:04 +01:00
open('nass_model.slx')
2019-10-18 17:34:45 +02:00
#+end_src
2020-01-15 16:23:40 +01:00
** Identification of the dynamics for Active Damping
2020-02-06 17:07:11 +01:00
*** Identification
2019-10-18 17:34:45 +02:00
We initialize all the stages with the default parameters.
#+begin_src matlab
2020-02-06 17:07:11 +01:00
prepareLinearizeIdentification();
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-06 17:07:11 +01:00
We identify the dynamics of the system using the =linearize= function.
2020-01-13 11:42:31 +01:00
#+begin_src matlab
%% Options for Linearized
options = linearizeOptions;
options.SampleTime = 0;
%% Name of the Simulink File
2020-02-18 11:33:04 +01:00
mdl = 'nass_model';
2020-01-13 11:42:31 +01:00
%% Input/Output definition
clear io; io_i = 1;
2020-02-18 11:33:04 +01:00
io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
2020-02-04 18:36:27 +01:00
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Dnlm'); io_i = io_i + 1; % Relative Motion Outputs
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm'); io_i = io_i + 1; % Force Sensors
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Vlm'); io_i = io_i + 1; % Absolute Velocity Outputs
2020-01-13 11:42:31 +01:00
%% Run the linearization
2020-02-04 10:26:06 +01:00
G = linearize(mdl, io, 0.5, options);
2020-01-15 16:23:40 +01:00
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6', ...
'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6', ...
2020-02-06 17:07:11 +01:00
'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'};
2020-01-13 11:42:31 +01:00
#+end_src
2020-01-15 16:23:40 +01:00
We then create transfer functions corresponding to the active damping plants.
2020-01-13 11:42:31 +01:00
#+begin_src matlab
2020-01-15 16:23:40 +01:00
G_iff = minreal(G({'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}));
G_dvf = minreal(G({'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}));
G_ine = minreal(G({'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}));
2020-01-13 11:42:31 +01:00
#+end_src
2020-01-15 16:23:40 +01:00
And we save them for further analysis.
2020-01-13 11:42:31 +01:00
#+begin_src matlab
2020-01-15 16:23:40 +01:00
save('./active_damping/mat/undamped_plants.mat', 'G_iff', 'G_dvf', 'G_ine');
2020-01-13 11:42:31 +01:00
#+end_src
2020-01-15 16:23:40 +01:00
*** Obtained Plants for Active Damping
2020-01-21 17:28:49 +01:00
#+begin_src matlab
load('./active_damping/mat/undamped_plants.mat', 'G_iff', 'G_dvf', 'G_ine');
#+end_src
2020-01-13 11:42:31 +01:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
2020-01-15 16:23:40 +01:00
for i = 1:6
plot(freqs, abs(squeeze(freqresp(G_iff(['Fnlm', num2str(i)], ['Fnl', num2str(i)]), freqs, 'Hz'))));
end
2020-01-13 11:42:31 +01:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-01-21 17:28:49 +01:00
ylabel('Amplitude [N/N]'); set(gca, 'XTickLabel',[]);
2020-01-13 11:42:31 +01:00
ax2 = subplot(2, 1, 2);
hold on;
2020-01-15 16:23:40 +01:00
for i = 1:6
plot(freqs, 180/pi*angle(squeeze(freqresp(G_iff(['Fnlm', num2str(i)], ['Fnl', num2str(i)]), freqs, 'Hz'))));
end
2020-01-13 11:42:31 +01:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
linkaxes([ax1,ax2],'x');
#+end_src
2020-01-15 16:23:40 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/nass_active_damping_iff_plant.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:nass_active_damping_iff_plant
#+caption : =G_iff=: Transfer functions from forces applied in the actuators to the force sensor in each actuator ([[./figs/nass_active_damping_iff_plant.png][png]], [[./figs/nass_active_damping_iff_plant.pdf][pdf]])
2020-01-15 16:23:40 +01:00
[[file:figs/nass_active_damping_iff_plant.png ]]
2020-01-13 11:42:31 +01:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
2020-01-15 16:23:40 +01:00
for i = 1:6
plot(freqs, abs(squeeze(freqresp(G_dvf(['Dnlm', num2str(i)], ['Fnl', num2str(i)]), freqs, 'Hz'))));
end
2020-01-13 11:42:31 +01:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
hold on;
2020-01-15 16:23:40 +01:00
for i = 1:6
plot(freqs, 180/pi*angle(squeeze(freqresp(G_dvf(['Dnlm', num2str(i)], ['Fnl', num2str(i)]), freqs, 'Hz'))));
end
2020-01-13 11:42:31 +01:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
linkaxes([ax1,ax2],'x');
#+end_src
2020-01-15 16:23:40 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/nass_active_damping_dvf_plant.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2020-01-13 11:42:31 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:nass_active_damping_dvf_plant
#+caption : =G_dvf=: Transfer functions from forces applied in the actuators to the relative motion sensor in each actuator ([[./figs/nass_active_damping_dvf_plant.png][png]], [[./figs/nass_active_damping_dvf_plant.pdf][pdf]])
2020-02-04 18:36:27 +01:00
[[file:figs/nass_active_damping_dvf_plant.png ]]
2020-01-15 16:23:40 +01:00
2020-01-13 11:42:31 +01:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
2020-01-15 16:23:40 +01:00
for i = 1:6
plot(freqs, abs(squeeze(freqresp(G_ine(['Vnlm', num2str(i)], ['Fnl', num2str(i)]), freqs, 'Hz'))));
end
2020-01-13 11:42:31 +01:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-01-20 17:20:50 +01:00
ylabel('Amplitude [$\frac{m/s}{N}$]'); set(gca, 'XTickLabel',[]);
2020-01-13 11:42:31 +01:00
ax2 = subplot(2, 1, 2);
hold on;
2020-01-15 16:23:40 +01:00
for i = 1:6
plot(freqs, 180/pi*angle(squeeze(freqresp(G_ine(['Vnlm', num2str(i)], ['Fnl', num2str(i)]), freqs, 'Hz'))));
end
2020-01-13 11:42:31 +01:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
linkaxes([ax1,ax2],'x');
#+end_src
2020-01-15 16:23:40 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/nass_active_damping_inertial_plant.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-01-13 11:42:31 +01:00
2020-02-06 17:07:11 +01:00
#+name : fig:nass_active_damping_inertial_plant
#+caption : =G_ine=: Transfer functions from forces applied in the actuators to the geophone located in each leg measuring the absolute velocity of the top part of the leg in the direction of the leg ([[./figs/nass_active_damping_inertial_plant.png][png]], [[./figs/nass_active_damping_inertial_plant.pdf][pdf]])
2020-01-15 16:23:40 +01:00
[[file:figs/nass_active_damping_inertial_plant.png ]]
2020-01-13 11:42:31 +01:00
2020-02-06 17:07:11 +01:00
** Identification of the dynamics for High Authority Control
*** Identification
We initialize all the stages with the default parameters.
#+begin_src matlab
prepareLinearizeIdentification();
#+end_src
We identify the dynamics of the system using the =linearize= function.
#+begin_src matlab
%% Options for Linearized
options = linearizeOptions;
options.SampleTime = 0;
%% Name of the Simulink File
2020-02-18 11:33:04 +01:00
mdl = 'nass_model';
2020-02-06 17:07:11 +01:00
%% Input/Output definition
clear io; io_i = 1;
2020-02-25 17:49:08 +01:00
io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
2020-02-18 11:33:04 +01:00
io(io_i) = linio([mdl, '/Tracking Error'], 1, 'openoutput', [], 'En'); io_i = io_i + 1; % Metrology Outputs
2020-02-06 17:07:11 +01:00
#+end_src
#+begin_src matlab
masses = [1, 10, 50]; % [kg]
#+end_src
#+begin_src matlab :exports none
G_cart = {zeros(length(masses))};
load('mat/stages.mat', 'nano_hexapod');
for i = 1:length(masses)
initializeSample('mass', masses(i));
%% Run the linearization
G = linearize(mdl, io, 0.3, options);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G.OutputName = {'Dnx', 'Dny', 'Dnz', 'Rnx', 'Rny', 'Rnz'};
G_cart_i = G*inv(nano_hexapod.J');
G_cart_i.InputName = {'Fnx', 'Fny', 'Fnz', 'Mnx', 'Mny', 'Mnz'};
G_cart(i) = {G_cart_i};
end
#+end_src
And we save them for further analysis.
#+begin_src matlab
save('./active_damping/mat/cart_plants.mat', 'G_cart', 'masses');
#+end_src
*** Obtained Plants
#+begin_src matlab
load('./active_damping/mat/cart_plants.mat', 'G_cart', 'masses');
#+end_src
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
for i = 1:length(masses)
set(gca,'ColorOrderIndex',i);
p1 = plot(freqs, abs(squeeze(freqresp(G_cart{i}('Dnx', 'Fnx'), freqs, 'Hz'))));
set(gca,'ColorOrderIndex',i);
p2 = plot(freqs, abs(squeeze(freqresp(G_cart{i}('Dny', 'Fny'), freqs, 'Hz'))), '--');
set(gca,'ColorOrderIndex',i);
p3 = plot(freqs, abs(squeeze(freqresp(G_cart{i}('Dnz', 'Fnz'), freqs, 'Hz'))), ':');
end
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); xlabel('Frequency [Hz]');
legend([p1,p2,p3], {'Fx/Dx', 'Fy/Dx', 'Fz/Dz'});
ax2 = subplot(2, 1, 2);
hold on;
for i = 1:length(masses)
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart{i}('Dnx', 'Fnx'), freqs, 'Hz')))), ...
'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart{i}('Dny', 'Fny'), freqs, 'Hz')))), '--', 'HandleVisibility', 'off');
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart{i}('Dnz', 'Fnz'), freqs, 'Hz')))), ':', 'HandleVisibility', 'off');
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
yticks([-540:180:540]);
legend('location', 'northeast');
linkaxes([ax1,ax2],'x');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/undamped_hac_plant_translations.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
#+name : fig:undamped_hac_plant_translations
#+caption : Undamped Plant - Translations ([[./figs/undamped_hac_plant_translations.png][png]], [[./figs/undamped_hac_plant_translations.pdf][pdf]])
[[file:figs/undamped_hac_plant_translations.png ]]
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
for i = 1:length(masses)
set(gca,'ColorOrderIndex',i);
p1 = plot(freqs, abs(squeeze(freqresp(G_cart{i}('Rnx', 'Mnx'), freqs, 'Hz'))));
set(gca,'ColorOrderIndex',i);
p2 = plot(freqs, abs(squeeze(freqresp(G_cart{i}('Rny', 'Mny'), freqs, 'Hz'))), '--');
set(gca,'ColorOrderIndex',i);
p3 = plot(freqs, abs(squeeze(freqresp(G_cart{i}('Rnz', 'Mnz'), freqs, 'Hz'))), ':');
end
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); xlabel('Frequency [Hz]');
legend([p1,p2,p3], {'Rx/Mx', 'Ry/Mx', 'Rz/Mz'});
ax2 = subplot(2, 1, 2);
hold on;
for i = 1:length(masses)
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart{i}('Rnx', 'Mnx'), freqs, 'Hz')))), ...
'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart{i}('Rny', 'Mny'), freqs, 'Hz')))), '--', 'HandleVisibility', 'off');
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart{i}('Rnz', 'Mnz'), freqs, 'Hz')))), ':', 'HandleVisibility', 'off');
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
yticks([-540:180:540]);
legend('location', 'northeast');
linkaxes([ax1,ax2],'x');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/undamped_hac_plant_rotations.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
#+name : fig:undamped_hac_plant_rotations
#+caption : Undamped Plant - Rotations ([[./figs/undamped_hac_plant_rotations.png][png]], [[./figs/undamped_hac_plant_rotations.pdf][pdf]])
[[file:figs/undamped_hac_plant_rotations.png ]]
2020-01-15 16:23:40 +01:00
** Tomography Experiment
*** Simulation
We initialize elements for the tomography experiment.
#+begin_src matlab
prepareTomographyExperiment();
#+end_src
We change the simulation stop time.
#+begin_src matlab
2020-02-18 11:33:04 +01:00
load('mat/conf_simulink.mat');
set_param(conf_simulink, 'StopTime', '4.5');
2020-01-15 16:23:40 +01:00
#+end_src
And we simulate the system.
#+begin_src matlab
2020-02-18 13:57:55 +01:00
sim('nass_model');
2020-01-15 16:23:40 +01:00
#+end_src
Finally, we save the simulation results for further analysis
#+begin_src matlab
save('./active_damping/mat/tomo_exp.mat', 'En', 'Eg', '-append');
#+end_src
*** Results
We load the results of tomography experiments.
#+begin_src matlab
load('./active_damping/mat/tomo_exp.mat', 'En');
2020-02-06 17:07:11 +01:00
Fs = 1e3; % Sampling Frequency of the Data
t = (1/Fs)*[0:length(En(:,1))-1];
2020-01-15 16:23:40 +01:00
#+end_src
#+begin_src matlab :exports none
figure;
2020-02-06 17:07:11 +01:00
ax1 = subplot(3, 1, 1);
2020-01-13 11:42:31 +01:00
hold on;
2020-01-15 16:23:40 +01:00
plot(t, En(:,1), 'DisplayName', '$\epsilon_{x}$')
2020-02-06 17:07:11 +01:00
legend('location', 'southwest');
ax2 = subplot(3, 1, 2);
hold on;
2020-01-15 16:23:40 +01:00
plot(t, En(:,2), 'DisplayName', '$\epsilon_{y}$')
2020-02-06 17:07:11 +01:00
legend('location', 'southwest');
ylabel('Position Error [m]');
ax3 = subplot(3, 1, 3);
hold on;
2020-01-15 16:23:40 +01:00
plot(t, En(:,3), 'DisplayName', '$\epsilon_{z}$')
2020-02-06 17:07:11 +01:00
legend('location', 'northwest');
xlabel('Time [s]');
linkaxes([ax1,ax2,ax3],'x');
xlim([0.5,inf]);
2020-01-15 16:23:40 +01:00
#+end_src
2020-01-13 11:42:31 +01:00
2020-01-15 16:23:40 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-06 17:07:11 +01:00
#+begin_src matlab :var filepath="figs/nass_act_damp_undamped_sim_tomo_trans.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
2020-01-15 16:23:40 +01:00
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:nass_act_damp_undamped_sim_tomo_trans
#+caption : Position Error during tomography experiment - Translations ([[./figs/nass_act_damp_undamped_sim_tomo_trans.png][png]], [[./figs/nass_act_damp_undamped_sim_tomo_trans.pdf][pdf]])
2020-01-15 16:23:40 +01:00
[[file:figs/nass_act_damp_undamped_sim_tomo_trans.png ]]
#+begin_src matlab :exports none
figure;
2020-02-06 17:07:11 +01:00
ax1 = subplot(3, 1, 1);
2020-01-13 11:42:31 +01:00
hold on;
2020-01-15 16:23:40 +01:00
plot(t, En(:,4), 'DisplayName', '$\epsilon_{\theta_x}$')
2020-02-06 17:07:11 +01:00
legend('location', 'northwest');
ax2 = subplot(3, 1, 2);
hold on;
2020-01-15 16:23:40 +01:00
plot(t, En(:,5), 'DisplayName', '$\epsilon_{\theta_y}$')
2020-02-06 17:07:11 +01:00
legend('location', 'southwest');
ylabel('Position Error [rad]');
ax3 = subplot(3, 1, 3);
hold on;
2020-01-15 16:23:40 +01:00
plot(t, En(:,6), 'DisplayName', '$\epsilon_{\theta_z}$')
legend();
2020-02-06 17:07:11 +01:00
xlabel('Time [s]');
linkaxes([ax1,ax2,ax3],'x');
xlim([0.5,inf]);
2020-01-15 16:23:40 +01:00
#+end_src
2020-01-13 11:42:31 +01:00
2020-01-15 16:23:40 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-06 17:07:11 +01:00
#+begin_src matlab :var filepath="figs/nass_act_damp_undamped_sim_tomo_rot.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
2020-01-15 16:23:40 +01:00
<<plt-matlab >>
2020-01-13 11:42:31 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:nass_act_damp_undamped_sim_tomo_rot
#+caption : Position Error during tomography experiment - Rotations ([[./figs/nass_act_damp_undamped_sim_tomo_rot.png][png]], [[./figs/nass_act_damp_undamped_sim_tomo_rot.pdf][pdf]])
2020-01-15 16:23:40 +01:00
[[file:figs/nass_act_damp_undamped_sim_tomo_rot.png ]]
2020-01-13 11:42:31 +01:00
2020-02-04 16:13:52 +01:00
* Variability of the system dynamics for Active Damping
2020-01-15 16:23:40 +01:00
:PROPERTIES:
2020-02-04 16:13:52 +01:00
:header-args:matlab+: :tangle matlab/act_damp_variability_plant.m
:header-args:matlab+: :comments org :mkdirp yes
2020-01-15 16:23:40 +01:00
:END:
2020-02-04 16:13:52 +01:00
<<sec:act_damp_variability_plant >>
2020-01-15 16:23:40 +01:00
** Introduction :ignore:
2020-02-04 16:13:52 +01:00
The goal of this section is to study how the dynamics of the Active Damping plants are changing with the experimental conditions.
These experimental conditions are:
- The mass of the sample (section [[sec:variability_sample_mass ]])
- The spindle angle with a null rotating speed (section [[sec:variability_spindle_angle ]])
- The spindle rotation speed (section [[sec:variability_rotation_speed ]])
- The tilt angle (section [[sec:variability_tilt_angle ]])
- The scans of the translation stage (section [[sec:variability_ty_scans ]])
For the identification of the dynamics, the system is simulation for $\approx 0.5s$ before the linearization is performed.
This is done in order for the transient phase to be over.
2020-01-15 16:23:40 +01:00
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir >>
2020-01-13 11:42:31 +01:00
#+end_src
2020-01-15 16:23:40 +01:00
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init >>
#+end_src
2020-01-13 11:42:31 +01:00
2020-01-15 16:23:40 +01:00
#+begin_src matlab :tangle no
simulinkproject('../');
2020-02-04 16:13:52 +01:00
addpath('active_damping/src/ ');
2020-01-15 16:23:40 +01:00
#+end_src
2020-01-13 11:42:31 +01:00
2020-01-15 16:23:40 +01:00
#+begin_src matlab
2020-02-18 11:33:04 +01:00
open('nass_model.slx')
load('mat/conf_simulink.mat');
2020-01-15 16:23:40 +01:00
#+end_src
2020-01-13 11:42:31 +01:00
2020-02-04 16:13:52 +01:00
** Variation of the Sample Mass
<<sec:variability_sample_mass >>
*** Introduction :ignore:
For all the identifications, the disturbances are disabled and no controller are used.
2020-02-06 17:07:11 +01:00
*** Identification :ignore:
2020-02-04 16:13:52 +01:00
We initialize all the stages with the default parameters.
2020-01-15 16:23:40 +01:00
#+begin_src matlab
2020-02-06 17:07:11 +01:00
prepareLinearizeIdentification();
2020-02-04 16:13:52 +01:00
#+end_src
#+begin_src matlab :exports none
%% Options for Linearized
options = linearizeOptions;
options.SampleTime = 0;
%% Name of the Simulink File
2020-02-18 11:33:04 +01:00
mdl = 'nass_model';
2020-02-04 16:13:52 +01:00
%% Input/Output definition
clear io; io_i = 1;
2020-02-18 13:57:55 +01:00
io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
2020-02-04 16:13:52 +01:00
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Dnlm'); io_i = io_i + 1;
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm'); io_i = io_i + 1;
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Vlm'); io_i = io_i + 1;
#+end_src
We identify the dynamics for the following sample mass.
#+begin_src matlab
masses = [1, 10, 50]; % [kg]
#+end_src
#+begin_src matlab :exports none
Gm = {zeros(length(masses))};
Gm_iff = {zeros(length(masses))};
Gm_dvf = {zeros(length(masses))};
Gm_ine = {zeros(length(masses))};
for i = 1:length(masses)
initializeSample('mass', masses(i));
%% Run the linearization
G = linearize(mdl, io, 0.3, options);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6', ...
'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6', ...
'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'};
Gm(i) = {G};
Gm_iff(i) = {minreal(G({'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}))};
Gm_dvf(i) = {minreal(G({'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}))};
Gm_ine(i) = {minreal(G({'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}))};
end
#+end_src
#+begin_src matlab :exports none
save('./active_damping/mat/plants_variable.mat', 'masses', 'Gm_iff', 'Gm_dvf', 'Gm_ine', '-append');
#+end_src
*** Plots :ignore:
#+begin_src matlab :exports none
load('./active_damping/mat/plants_variable.mat', 'masses', 'Gm_iff', 'Gm_dvf', 'Gm_ine');
#+end_src
2020-01-15 16:23:40 +01:00
2020-01-13 11:42:31 +01:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gm_iff)
plot(freqs, abs(squeeze(freqresp(Gm_iff{i}('Fnlm1', 'Fnl1'), freqs, 'Hz'))));
2020-01-15 16:23:40 +01:00
end
2020-01-13 11:42:31 +01:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-01-15 16:23:40 +01:00
ylabel('Amplitude [N/N]'); set(gca, 'XTickLabel',[]);
2020-01-13 11:42:31 +01:00
ax2 = subplot(2, 1, 2);
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gm_iff)
2020-02-04 18:36:27 +01:00
plot(freqs, 180/pi*angle(squeeze(freqresp(Gm_iff{i}('Fnlm1', 'Fnl1'), freqs, 'Hz'))), ...
'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
2020-01-15 16:23:40 +01:00
end
2020-01-13 11:42:31 +01:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
2020-02-04 16:13:52 +01:00
legend('location', 'southwest');
2020-01-13 11:42:31 +01:00
linkaxes([ax1,ax2],'x');
2020-02-04 16:13:52 +01:00
xlim([freqs(1), freqs(end)]);
2020-01-13 11:42:31 +01:00
#+end_src
2020-01-15 16:23:40 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/act_damp_variability_iff_sample_mass.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2020-01-15 16:23:40 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_iff_sample_mass
#+caption : Variability of the dynamics from actuator force to force sensor with the Sample Mass ([[./figs/act_damp_variability_iff_sample_mass.png][png]], [[./figs/act_damp_variability_iff_sample_mass.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_iff_sample_mass.png ]]
2020-01-15 16:23:40 +01:00
2020-01-13 11:42:31 +01:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gm_dvf)
plot(freqs, abs(squeeze(freqresp(Gm_dvf{i}('Dnlm1', 'Fnl1'), freqs, 'Hz'))));
2020-01-15 16:23:40 +01:00
end
hold off;
2020-01-13 11:42:31 +01:00
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-02-04 16:13:52 +01:00
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
2020-01-13 11:42:31 +01:00
ax2 = subplot(2, 1, 2);
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gm_dvf)
plot(freqs, 180/pi*angle(squeeze(freqresp(Gm_dvf{i}('Dnlm1', 'Fnl1'), freqs, 'Hz'))), 'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
2020-01-15 16:23:40 +01:00
end
2020-01-13 11:42:31 +01:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
2020-02-04 16:13:52 +01:00
legend('location', 'southwest');
2020-01-13 11:42:31 +01:00
linkaxes([ax1,ax2],'x');
2020-02-04 16:13:52 +01:00
xlim([freqs(1), freqs(end)]);
2020-01-13 11:42:31 +01:00
#+end_src
2020-01-15 16:23:40 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/act_damp_variability_dvf_sample_mass.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2020-01-15 16:23:40 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_dvf_sample_mass
#+caption : Variability of the dynamics from actuator force to relative motion sensor with the Sample Mass ([[./figs/act_damp_variability_dvf_sample_mass.png][png]], [[./figs/act_damp_variability_dvf_sample_mass.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_dvf_sample_mass.png ]]
2020-01-20 17:20:50 +01:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gm_ine)
plot(freqs, abs(squeeze(freqresp(Gm_ine{i}('Vnlm1', 'Fnl1'), freqs, 'Hz'))));
2020-01-20 17:20:50 +01:00
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-02-04 16:13:52 +01:00
ylabel('Amplitude [$\frac{m/s}{N}$]'); set(gca, 'XTickLabel',[]);
2020-01-20 17:20:50 +01:00
ax2 = subplot(2, 1, 2);
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gm_ine)
plot(freqs, 180/pi*angle(squeeze(freqresp(Gm_ine{i}('Vnlm1', 'Fnl1'), freqs, 'Hz'))), 'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
2020-01-20 17:20:50 +01:00
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
2020-02-04 16:13:52 +01:00
legend('location', 'southwest');
2020-01-20 17:20:50 +01:00
linkaxes([ax1,ax2],'x');
2020-02-04 16:13:52 +01:00
xlim([freqs(1), freqs(end)]);
2020-01-20 17:20:50 +01:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/act_damp_variability_ine_sample_mass.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2020-01-20 17:20:50 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_ine_sample_mass
#+caption : Variability of the dynamics from actuator force to absolute velocity with the Sample Mass ([[./figs/act_damp_variability_ine_sample_mass.png][png]], [[./figs/act_damp_variability_ine_sample_mass.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_ine_sample_mass.png ]]
2020-01-20 17:20:50 +01:00
2020-02-04 16:13:52 +01:00
** Variation of the Spindle Angle
<<sec:variability_spindle_angle >>
*** Introduction :ignore:
2020-02-06 17:07:11 +01:00
*** Identification :ignore:
2020-02-04 16:13:52 +01:00
We initialize all the stages with the default parameters.
2020-01-20 17:20:50 +01:00
#+begin_src matlab
2020-02-06 17:07:11 +01:00
prepareLinearizeIdentification();
2020-01-15 16:23:40 +01:00
#+end_src
2020-02-04 16:13:52 +01:00
#+begin_src matlab :exports none
2020-01-13 11:42:31 +01:00
%% Options for Linearized
options = linearizeOptions;
options.SampleTime = 0;
%% Name of the Simulink File
2020-02-18 11:33:04 +01:00
mdl = 'nass_model';
2020-01-13 11:42:31 +01:00
%% Input/Output definition
clear io; io_i = 1;
2020-02-18 13:57:55 +01:00
io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
2020-01-13 11:42:31 +01:00
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Dnlm'); io_i = io_i + 1;
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm'); io_i = io_i + 1;
2020-02-04 16:13:52 +01:00
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Vlm'); io_i = io_i + 1;
2020-01-13 11:42:31 +01:00
#+end_src
2020-02-04 16:13:52 +01:00
We identify the dynamics for the following Spindle angles.
2020-01-15 16:23:40 +01:00
#+begin_src matlab
2020-02-04 16:13:52 +01:00
Rz_amplitudes = [0, pi/4, pi/2, pi]; % [rad]
2020-01-13 11:42:31 +01:00
#+end_src
2019-10-18 17:34:45 +02:00
#+begin_src matlab :exports none
2020-02-04 16:13:52 +01:00
Ga = {zeros(length(Rz_amplitudes))};
Ga_iff = {zeros(length(Rz_amplitudes))};
Ga_dvf = {zeros(length(Rz_amplitudes))};
Ga_ine = {zeros(length(Rz_amplitudes))};
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
for i = 1:length(Rz_amplitudes)
initializeReferences('Rz_type', 'constant', 'Rz_amplitude', Rz_amplitudes(i))
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
%% Run the linearization
G = linearize(mdl, io, 0.3, options);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6', ...
'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6', ...
'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'};
Ga(i) = {G};
Ga_iff(i) = {minreal(G({'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}))};
Ga_dvf(i) = {minreal(G({'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}))};
Ga_ine(i) = {minreal(G({'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}))};
end
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-04 16:13:52 +01:00
#+begin_src matlab :exports none
save('./active_damping/mat/plants_variable.mat', 'Rz_amplitudes', 'Ga_iff', 'Ga_dvf', 'Ga_ine', '-append');
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-04 16:13:52 +01:00
*** Plots :ignore:
#+begin_src matlab :exports none
load('./active_damping/mat/plants_variable.mat', 'Rz_amplitudes', 'Ga_iff', 'Ga_dvf', 'Ga_ine');
#+end_src
2019-10-18 17:34:45 +02:00
2019-10-25 16:02:23 +02:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
2020-02-04 16:13:52 +01:00
ax1 = subplot(2, 1, 1);
2019-10-25 16:02:23 +02:00
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Ga_iff)
plot(freqs, abs(squeeze(freqresp(Ga_iff{i}('Fnlm1', 'Fnl1'), freqs, 'Hz'))));
end
hold off;
2019-10-25 16:02:23 +02:00
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-02-04 16:13:52 +01:00
ylabel('Amplitude [N/N]'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
hold on;
for i = 1:length(Ga_iff)
plot(freqs, 180/pi*angle(squeeze(freqresp(Ga_iff{i}('Fnlm1', 'Fnl1'), freqs, 'Hz'))), 'DisplayName', sprintf('$Rz = %.0f$ [deg]', Rz_amplitudes(i)*180/pi));
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
legend('location', 'southwest');
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
2019-10-25 16:02:23 +02:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/act_damp_variability_iff_spindle_angle.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2019-10-25 16:02:23 +02:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_iff_spindle_angle
#+caption : Variability of the dynamics from the actuator force to the force sensor with the Spindle Angle ([[./figs/act_damp_variability_iff_spindle_angle.png][png]], [[./figs/act_damp_variability_iff_spindle_angle.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_iff_spindle_angle.png ]]
2019-10-18 17:34:45 +02:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
2020-02-04 16:13:52 +01:00
ax1 = subplot(2, 1, 1);
2019-10-18 17:34:45 +02:00
hold on;
2020-01-15 16:23:40 +01:00
2020-02-04 16:13:52 +01:00
for i = 1:length(Ga_dvf)
plot(freqs, abs(squeeze(freqresp(Ga_dvf{i}('Dnlm1', 'Fnl1'), freqs, 'Hz'))));
end
2019-10-18 17:34:45 +02:00
hold off;
2020-02-04 16:13:52 +01:00
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
ax2 = subplot(2, 1, 2);
2020-01-15 16:23:40 +01:00
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Ga_dvf)
plot(freqs, 180/pi*angle(squeeze(freqresp(Ga_dvf{i}('Dnlm1', 'Fnl1'), freqs, 'Hz'))), 'DisplayName', sprintf('$Rz = %.0f$ [deg]', Rz_amplitudes(i)*180/pi));
end
2020-01-15 16:23:40 +01:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
2020-02-04 16:13:52 +01:00
legend('location', 'southwest');
2020-01-15 16:23:40 +01:00
2020-02-04 16:13:52 +01:00
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
2019-10-18 17:34:45 +02:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/act_damp_variability_dvf_spindle_angle.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_dvf_spindle_angle
#+caption : Variability of the dynamics from actuator force to relative motion sensor with the Spindle Angle ([[./figs/act_damp_variability_dvf_spindle_angle.png][png]], [[./figs/act_damp_variability_dvf_spindle_angle.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_dvf_spindle_angle.png ]]
2019-10-18 17:34:45 +02:00
2020-01-15 16:23:40 +01:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
2019-10-25 16:02:23 +02:00
2020-01-15 16:23:40 +01:00
figure;
2020-02-04 16:13:52 +01:00
ax1 = subplot(2, 1, 1);
hold on;
for i = 1:length(Ga_ine)
plot(freqs, abs(squeeze(freqresp(Ga_ine{i}('Vnlm1', 'Fnl1'), freqs, 'Hz'))));
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [$\frac{m/s}{N}$]'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
hold on;
for i = 1:length(Ga_ine)
plot(freqs, 180/pi*angle(squeeze(freqresp(Ga_ine{i}('Vnlm1', 'Fnl1'), freqs, 'Hz'))), 'DisplayName', sprintf('$Rz = %.0f$ [deg]', Rz_amplitudes(i)*180/pi));
2020-01-15 16:23:40 +01:00
end
2020-02-04 16:13:52 +01:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
legend('location', 'southwest');
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
2019-10-25 16:02:23 +02:00
#+end_src
2020-01-15 16:23:40 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/act_damp_variability_ine_spindle_angle.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2020-01-15 16:23:40 +01:00
#+end_src
2019-10-25 16:02:23 +02:00
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_ine_spindle_angle
#+caption : Variability of the dynamics from actuator force to absolute velocity with the Spindle Angle ([[./figs/act_damp_variability_ine_spindle_angle.png][png]], [[./figs/act_damp_variability_ine_spindle_angle.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_ine_spindle_angle.png ]]
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
** Variation of the Spindle Rotation Speed
<<sec:variability_rotation_speed >>
*** Introduction :ignore:
2020-02-06 17:07:11 +01:00
*** Identification :ignore:
2020-02-04 16:13:52 +01:00
We initialize all the stages with the default parameters.
2020-01-15 16:23:40 +01:00
#+begin_src matlab
2020-02-06 17:07:11 +01:00
prepareLinearizeIdentification();
2020-01-15 16:23:40 +01:00
#+end_src
2020-02-04 16:13:52 +01:00
#+begin_src matlab :exports none
%% Options for Linearized
options = linearizeOptions;
options.SampleTime = 0;
2020-01-15 16:23:40 +01:00
2020-02-04 16:13:52 +01:00
%% Name of the Simulink File
2020-02-18 11:33:04 +01:00
mdl = 'nass_model';
2020-01-20 17:20:50 +01:00
2020-02-04 16:13:52 +01:00
%% Input/Output definition
clear io; io_i = 1;
2020-02-18 13:57:55 +01:00
io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
2020-02-04 16:13:52 +01:00
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Dnlm'); io_i = io_i + 1;
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm'); io_i = io_i + 1;
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Vlm'); io_i = io_i + 1;
2020-01-20 17:20:50 +01:00
#+end_src
2020-02-04 16:13:52 +01:00
We identify the dynamics for the following Spindle rotation periods.
2020-01-20 17:20:50 +01:00
#+begin_src matlab
2020-02-04 16:13:52 +01:00
Rz_periods = [60, 6, 2, 1]; % [s]
2020-01-20 17:20:50 +01:00
#+end_src
2020-02-04 16:13:52 +01:00
The identification of the dynamics is done at the same Spindle angle position.
#+begin_src matlab :exports none
Gw = {zeros(length(Rz_periods))};
Gw_iff = {zeros(length(Rz_periods))};
Gw_dvf = {zeros(length(Rz_periods))};
Gw_ine = {zeros(length(Rz_periods))};
for i = 1:length(Rz_periods)
initializeReferences('Rz_type', 'rotating', ...
'Rz_period', Rz_periods(i), ... % Rotation period [s]
'Rz_amplitude', -0.5*(2*pi/Rz_periods(i))); % Angle offset [rad]
load('mat/nass_references.mat', 'Rz'); % We load the reference for the Spindle
[~, i_end] = min(abs(Rz.signals.values)); % Obtain the indice where the spindle angle is zero
t_sim = Rz.time(i_end) % Simulation time before identification [s]
%% Run the linearization
G = linearize(mdl, io, t_sim, options);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6', ...
'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6', ...
'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'};
Gw(i) = {G};
Gw_iff(i) = {minreal(G({'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}))};
Gw_dvf(i) = {minreal(G({'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}))};
Gw_ine(i) = {minreal(G({'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}))};
end
2020-01-15 16:23:40 +01:00
#+end_src
2020-02-04 16:13:52 +01:00
#+begin_src matlab :exports none
save('./active_damping/mat/plants_variable.mat', 'Rz_periods', 'Gw_iff', 'Gw_dvf', 'Gw_ine', '-append');
2020-01-20 17:20:50 +01:00
#+end_src
2020-02-04 16:13:52 +01:00
*** Dynamics of the Active Damping plants
#+begin_src matlab :exports none
load('./active_damping/mat/plants_variable.mat', 'Rz_periods', 'Gw_iff', 'Gw_dvf', 'Gw_ine');
load('./active_damping/mat/undamped_plants.mat', 'G_iff', 'G_dvf', 'G_ine');
2020-01-15 16:23:40 +01:00
#+end_src
#+begin_src matlab :exports none
2020-02-04 16:13:52 +01:00
freqs = logspace(0, 3, 10000);
2020-01-15 16:23:40 +01:00
figure;
2020-02-04 16:13:52 +01:00
ax1 = subplot(2, 1, 1);
2020-01-15 16:23:40 +01:00
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gw_iff)
plot(freqs, abs(squeeze(freqresp(Gw_iff{i}('Fnlm1', 'Fnl1'), freqs, 'Hz'))));
end
plot(freqs, abs(squeeze(freqresp(G_iff('Fnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [N/N]'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
hold on;
for i = 1:length(Gw_iff)
plot(freqs, 180/pi*angle(squeeze(freqresp(Gw_iff{i}('Fnlm1', 'Fnl1'), freqs, 'Hz'))), 'DisplayName', sprintf('$Rz = %.0f$ [rpm]', 60/Rz_periods(i)));
end
plot(freqs, 180/pi*angle(squeeze(freqresp(G_iff('Fnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--', 'DisplayName', 'No Rotation');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
legend('location', 'southwest');
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
2020-01-20 17:20:50 +01:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/act_damp_variability_iff_spindle_speed.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
2020-01-20 17:20:50 +01:00
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_iff_spindle_speed
#+caption : Variability of the dynamics from the actuator force to the force sensor with the Spindle rotation speed ([[./figs/act_damp_variability_iff_spindle_speed.png][png]], [[./figs/act_damp_variability_iff_spindle_speed.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_iff_spindle_speed.png ]]
2020-01-20 17:20:50 +01:00
#+begin_src matlab :exports none
2020-02-04 16:13:52 +01:00
xlim([20, 30]);
2020-01-15 16:23:40 +01:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/act_damp_variability_iff_spindle_speed_zoom.pdf" :var figsize= "wide-normal" :post pdf2svg(file=*this*, ext= "png")
2020-01-15 16:23:40 +01:00
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_iff_spindle_speed_zoom
#+caption : Variability of the dynamics from the actuator force to the force sensor with the Spindle rotation speed ([[./figs/act_damp_variability_iff_spindle_speed_zoom.png][png]], [[./figs/act_damp_variability_iff_spindle_speed_zoom.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_iff_spindle_speed_zoom.png ]]
2020-01-15 16:23:40 +01:00
#+begin_src matlab :exports none
2020-02-04 16:13:52 +01:00
freqs = logspace(0, 3, 5000);
2020-01-15 16:23:40 +01:00
figure;
2020-01-20 17:20:50 +01:00
2020-02-04 16:13:52 +01:00
ax1 = subplot(2, 1, 1);
2020-01-20 17:20:50 +01:00
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gw_dvf)
plot(freqs, abs(squeeze(freqresp(Gw_dvf{i}('Dnlm1', 'Fnl1'), freqs, 'Hz'))));
end
plot(freqs, abs(squeeze(freqresp(G_dvf('Dnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
2020-01-20 17:20:50 +01:00
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gw_dvf)
plot(freqs, 180/pi*angle(squeeze(freqresp(Gw_dvf{i}('Dnlm1', 'Fnl1'), freqs, 'Hz'))), 'DisplayName', sprintf('$Rz = %.0f$ [rpm]', 60/Rz_periods(i)));
end
plot(freqs, 180/pi*angle(squeeze(freqresp(G_dvf('Dnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--', 'DisplayName', 'No Rotation');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
legend('location', 'southwest');
2020-01-20 17:20:50 +01:00
2020-02-04 16:13:52 +01:00
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
2020-01-15 16:23:40 +01:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/act_damp_variability_dvf_spindle_speed.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
2020-01-15 16:23:40 +01:00
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_dvf_spindle_speed
#+caption : Variability of the dynamics from the actuator force to the relative motion sensor with the Spindle rotation speed ([[./figs/act_damp_variability_dvf_spindle_speed.png][png]], [[./figs/act_damp_variability_dvf_spindle_speed.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_dvf_spindle_speed.png ]]
2020-01-15 16:23:40 +01:00
2020-02-04 16:13:52 +01:00
#+begin_src matlab :exports none
xlim([20, 30]);
#+end_src
2020-01-15 16:23:40 +01:00
2020-02-04 16:13:52 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/act_damp_variability_dvf_spindle_speed_zoom.pdf" :var figsize= "wide-normal" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-01-15 16:23:40 +01:00
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_dvf_spindle_speed_zoom
#+caption : Variability of the dynamics from the actuator force to the relative motion sensor with the Spindle rotation speed ([[./figs/act_damp_variability_dvf_spindle_speed_zoom.png][png]], [[./figs/act_damp_variability_dvf_spindle_speed_zoom.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_dvf_spindle_speed_zoom.png ]]
2019-10-18 17:34:45 +02:00
#+begin_src matlab :exports none
2020-02-04 16:13:52 +01:00
freqs = logspace(0, 3, 5000);
2019-10-18 17:34:45 +02:00
figure;
ax1 = subplot(2, 1, 1);
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gw_ine)
plot(freqs, abs(squeeze(freqresp(Gw_ine{i}('Vnlm1', 'Fnl1'), freqs, 'Hz'))));
2019-10-18 17:34:45 +02:00
end
2020-02-04 16:13:52 +01:00
plot(freqs, abs(squeeze(freqresp(G_ine('Vnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--');
2019-10-18 17:34:45 +02:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-02-04 16:13:52 +01:00
ylabel('Amplitude [$\frac{m/s}{N}$]'); set(gca, 'XTickLabel',[]);
2019-10-18 17:34:45 +02:00
ax2 = subplot(2, 1, 2);
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gw_ine)
plot(freqs, 180/pi*angle(squeeze(freqresp(Gw_ine{i}('Vnlm1', 'Fnl1'), freqs, 'Hz'))), 'DisplayName', sprintf('$Rz = %.0f$ [rpm]', 60/Rz_periods(i)));
2019-10-18 17:34:45 +02:00
end
2020-02-04 16:13:52 +01:00
plot(freqs, 180/pi*angle(squeeze(freqresp(G_ine('Vnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--', 'DisplayName', 'No Rotation');
2019-10-18 17:34:45 +02:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
2020-02-04 16:13:52 +01:00
legend('location', 'southwest');
2019-10-18 17:34:45 +02:00
linkaxes([ax1,ax2],'x');
2020-02-04 16:13:52 +01:00
xlim([freqs(1), freqs(end)]);
2019-10-18 17:34:45 +02:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/act_damp_variability_ine_spindle_speed.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_ine_spindle_speed
#+caption : Variability of the dynamics from the actuator force to the absolute velocity sensor with the Spindle rotation speed ([[./figs/act_damp_variability_ine_spindle_speed.png][png]], [[./figs/act_damp_variability_ine_spindle_speed.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_ine_spindle_speed.png ]]
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
#+begin_src matlab :exports none
xlim([20, 30]);
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-04 16:13:52 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/act_damp_variability_ine_spindle_speed_zoom.pdf" :var figsize= "wide-normal" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_ine_spindle_speed_zoom
#+caption : Variability of the dynamics from the actuator force to the absolute velocity sensor with the Spindle rotation speed ([[./figs/act_damp_variability_ine_spindle_speed_zoom.png][png]], [[./figs/act_damp_variability_ine_spindle_speed_zoom.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_ine_spindle_speed_zoom.png ]]
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
*** Variation of the poles and zeros with the Spindle rotation frequency
2019-10-18 17:34:45 +02:00
#+begin_src matlab :exports none
2020-02-04 16:13:52 +01:00
load('./active_damping/mat/plants_variable.mat', 'Rz_periods', 'Gw_iff', 'Gw_dvf', 'Gw_ine');
load('./active_damping/mat/undamped_plants.mat', 'G_iff', 'G_dvf', 'G_ine');
#+end_src
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
#+begin_src matlab :exports none
2019-10-18 17:34:45 +02:00
figure;
2020-02-04 16:13:52 +01:00
subplot(1,2,1);
2019-10-18 17:34:45 +02:00
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gw_iff)
G_poles = pole(Gw_iff{i}('Fnlm1', 'Fnl1'));
plot(1/Rz_periods(i), real(G_poles(imag(G_poles)<2*pi*30 & imag(G_poles) >2*pi*22)), 'kx');
2019-10-18 17:34:45 +02:00
end
2020-02-04 16:13:52 +01:00
G_poles = pole(G_iff('Fnlm1', 'Fnl1'));
plot(0, real(G_poles(imag(G_poles)<2*pi*30 & imag(G_poles) >2*pi*22)), 'kx');
2019-10-18 17:34:45 +02:00
hold off;
2020-02-04 16:13:52 +01:00
ylim([-inf, 0]);
xlabel('Rotation Speed [Hz]');
ylabel('Real Part');
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
subplot(1,2,2);
2019-10-18 17:34:45 +02:00
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gw_iff)
G_poles = pole(Gw_iff{i}('Fnlm1', 'Fnl1'));
plot(1/Rz_periods(i), imag(G_poles(imag(G_poles)<2*pi*30 & imag(G_poles) >2*pi*22)), 'kx');
2019-10-18 17:34:45 +02:00
end
2020-02-04 16:13:52 +01:00
G_poles = pole(G_iff('Fnlm1', 'Fnl1'));
plot(0, imag(G_poles(imag(G_poles)<2*pi*30 & imag(G_poles) >2*pi*22)), 'kx');
2019-10-18 17:34:45 +02:00
hold off;
2020-02-04 16:13:52 +01:00
ylim([0, inf]);
xlabel('Rotation Speed [Hz]');
ylabel('Imaginary Part');
2019-10-18 17:34:45 +02:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/campbell_diagram_spindle_rotation.pdf" :var figsize= "full-normal" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:campbell_diagram_spindle_rotation
#+caption : Evolution of the pole with respect to the spindle rotation speed ([[./figs/campbell_diagram_spindle_rotation.png][png]], [[./figs/campbell_diagram_spindle_rotation.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/campbell_diagram_spindle_rotation.png ]]
2020-01-15 16:23:40 +01:00
2020-02-04 16:13:52 +01:00
#+begin_src matlab :exports none
figure;
subplot(1,2,1);
hold on;
for i = 1:length(Gw_ine)
set(gca,'ColorOrderIndex',1);
G_zeros = zero(Gw_ine{i}('Vnlm1', 'Fnl1'));
plot(1/Rz_periods(i), real(G_zeros(imag(G_zeros)<2*pi*25 & imag(G_zeros) >2*pi*22)), 'o');
set(gca,'ColorOrderIndex',2);
G_zeros = zero(Gw_iff{i}('Fnlm1', 'Fnl1'));
plot(1/Rz_periods(i), real(G_zeros(imag(G_zeros)<2*pi*25 & imag(G_zeros) >2*pi*22)), 'o');
set(gca,'ColorOrderIndex',3);
G_zeros = zero(Gw_dvf{i}('Dnlm1', 'Fnl1'));
plot(1/Rz_periods(i), real(G_zeros(imag(G_zeros)<2*pi*25 & imag(G_zeros) >2*pi*22)), 'o');
end
hold off;
xlabel('Rotation Speed [Hz]');
ylabel('Real Part');
subplot(1,2,2);
hold on;
for i = 1:length(Gw_ine)
set(gca,'ColorOrderIndex',1);
G_zeros = zero(Gw_ine{i}('Vnlm1', 'Fnl1'));
p_ine = plot(1/Rz_periods(i), imag(G_zeros(imag(G_zeros)<2*pi*25 & imag(G_zeros) >2*pi*22)), 'o');
set(gca,'ColorOrderIndex',2);
G_zeros = zero(Gw_iff{i}('Fnlm1', 'Fnl1'));
p_iff = plot(1/Rz_periods(i), imag(G_zeros(imag(G_zeros)<2*pi*25 & imag(G_zeros) >2*pi*22)), 'o');
set(gca,'ColorOrderIndex',3);
G_zeros = zero(Gw_dvf{i}('Dnlm1', 'Fnl1'));
p_dvf = plot(1/Rz_periods(i), imag(G_zeros(imag(G_zeros)<2*pi*25 & imag(G_zeros) >2*pi*22)), 'o');
end
hold off;
xlabel('Rotation Speed [Hz]');
ylabel('Imaginary Part');
legend([p_ine p_iff p_dvf],{'Inertial Sensor','Force Sensor', 'Relative Motion Sensor'}, 'location', 'southwest');
2020-01-15 16:23:40 +01:00
#+end_src
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/variation_zeros_active_damping_plants.pdf" :var figsize= "full-normal" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2020-01-15 16:23:40 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:variation_zeros_active_damping_plants
#+caption : Evolution of the zero with respect to the spindle rotation speed ([[./figs/variation_zeros_active_damping_plants.png][png]], [[./figs/variation_zeros_active_damping_plants.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/variation_zeros_active_damping_plants.png ]]
** Variation of the Tilt Angle
<<sec:variability_tilt_angle >>
*** Introduction :ignore:
2020-02-06 17:07:11 +01:00
*** Identification :ignore:
2020-02-04 16:13:52 +01:00
We initialize all the stages with the default parameters.
2019-10-18 17:34:45 +02:00
#+begin_src matlab
2020-02-06 17:07:11 +01:00
prepareLinearizeIdentification();
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-04 16:13:52 +01:00
#+begin_src matlab :exports none
2020-01-15 16:23:40 +01:00
%% Options for Linearized
options = linearizeOptions;
options.SampleTime = 0;
%% Name of the Simulink File
2020-02-18 11:33:04 +01:00
mdl = 'nass_model';
2020-01-15 16:23:40 +01:00
%% Input/Output definition
clear io; io_i = 1;
2020-02-18 13:57:55 +01:00
io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
2020-01-15 16:23:40 +01:00
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Dnlm'); io_i = io_i + 1;
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm'); io_i = io_i + 1;
2020-02-04 16:13:52 +01:00
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Vlm'); io_i = io_i + 1;
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-04 16:13:52 +01:00
We identify the dynamics for the following Tilt stage angles.
2019-10-25 16:02:23 +02:00
#+begin_src matlab
2020-02-04 16:13:52 +01:00
Ry_amplitudes = [-3*pi/180, 3*pi/180]; % [rad]
2019-10-25 16:02:23 +02:00
#+end_src
2019-10-18 17:34:45 +02:00
#+begin_src matlab :exports none
2020-02-04 16:13:52 +01:00
Gy = {zeros(length(Ry_amplitudes))};
Gy_iff = {zeros(length(Ry_amplitudes))};
Gy_dvf = {zeros(length(Ry_amplitudes))};
Gy_ine = {zeros(length(Ry_amplitudes))};
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
for i = 1:length(Ry_amplitudes)
initializeReferences('Ry_type', 'constant', 'Ry_amplitude', Ry_amplitudes(i))
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
%% Run the linearization
G = linearize(mdl, io, 0.3, options);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6', ...
'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6', ...
'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'};
Gy(i) = {G};
Gy_iff(i) = {minreal(G({'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}))};
Gy_dvf(i) = {minreal(G({'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}))};
Gy_ine(i) = {minreal(G({'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}))};
end
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-04 16:13:52 +01:00
#+begin_src matlab :exports none
save('./active_damping/mat/plants_variable.mat', 'Ry_amplitudes', 'Gy_iff', 'Gy_dvf', 'Gy_ine', '-append');
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-04 16:13:52 +01:00
*** Plots :ignore:
#+begin_src matlab :exports none
load('./active_damping/mat/plants_variable.mat', 'Ry_amplitudes', 'Gy_iff', 'Gy_dvf', 'Gy_ine');
load('./active_damping/mat/undamped_plants.mat', 'G_iff', 'G_dvf', 'G_ine');
#+end_src
2019-10-18 17:34:45 +02:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
2020-02-04 16:13:52 +01:00
ax1 = subplot(2, 1, 1);
2019-10-18 17:34:45 +02:00
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gy_iff)
plot(freqs, abs(squeeze(freqresp(Gy_iff{i}('Fnlm1', 'Fnl1'), freqs, 'Hz'))));
end
plot(freqs, abs(squeeze(freqresp(G_iff('Fnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [N/N]'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
hold on;
for i = 1:length(Gy_iff)
plot(freqs, 180/pi*angle(squeeze(freqresp(Gy_iff{i}('Fnlm1', 'Fnl1'), freqs, 'Hz'))), 'DisplayName', sprintf('$Ry = %.0f$ [deg]', Ry_amplitudes(i)*180/pi));
end
plot(freqs, 180/pi*angle(squeeze(freqresp(G_iff('Fnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--', 'DisplayName', '$Ry = 0$ [deg]');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
legend('location', 'southwest');
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
2019-10-18 17:34:45 +02:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/act_damp_variability_iff_tilt_angle.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_iff_tilt_angle
#+caption : Variability of the dynamics from the actuator force to the force sensor with the Tilt stage Angle ([[./figs/act_damp_variability_iff_tilt_angle.png][png]], [[./figs/act_damp_variability_iff_tilt_angle.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_iff_tilt_angle.png ]]
2019-10-18 17:34:45 +02:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
2020-02-04 16:13:52 +01:00
ax1 = subplot(2, 1, 1);
2019-10-18 17:34:45 +02:00
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gy_dvf)
plot(freqs, abs(squeeze(freqresp(Gy_dvf{i}('Dnlm1', 'Fnl1'), freqs, 'Hz'))));
end
plot(freqs, abs(squeeze(freqresp(G_dvf('Dnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--');
hold off;
2019-10-18 17:34:45 +02:00
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-02-04 16:13:52 +01:00
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
ax2 = subplot(2, 1, 2);
2019-10-18 17:34:45 +02:00
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gy_dvf)
plot(freqs, 180/pi*angle(squeeze(freqresp(Gy_dvf{i}('Dnlm1', 'Fnl1'), freqs, 'Hz'))), 'DisplayName', sprintf('$Ry = %.0f$ [deg]', Ry_amplitudes(i)*180/pi));
end
plot(freqs, 180/pi*angle(squeeze(freqresp(G_dvf('Dnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--', 'DisplayName', '$Ry = 0$ [deg]');
2019-10-18 17:34:45 +02:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
2020-02-04 16:13:52 +01:00
legend('location', 'southwest');
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/act_damp_variability_dvf_tilt_angle.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_dvf_tilt_angle
#+caption : Variability of the dynamics from the actuator force to the relative motion sensor with the Tilt Angle ([[./figs/act_damp_variability_dvf_tilt_angle.png][png]], [[./figs/act_damp_variability_dvf_tilt_angle.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_dvf_tilt_angle.png ]]
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
2019-10-18 17:34:45 +02:00
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gy_ine)
plot(freqs, abs(squeeze(freqresp(Gy_ine{i}('Vnlm1', 'Fnl1'), freqs, 'Hz'))));
end
plot(freqs, abs(squeeze(freqresp(G_ine('Vnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [$\frac{m/s}{N}$]'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
hold on;
for i = 1:length(Gy_ine)
plot(freqs, 180/pi*angle(squeeze(freqresp(Gy_ine{i}('Vnlm1', 'Fnl1'), freqs, 'Hz'))), 'DisplayName', sprintf('$Ry = %.0f$ [deg]', Ry_amplitudes(i)*180/pi));
end
plot(freqs, 180/pi*angle(squeeze(freqresp(G_ine('Vnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--', 'DisplayName', '$Ry = 0$ [deg]');
2019-10-18 17:34:45 +02:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
2020-02-04 16:13:52 +01:00
legend('location', 'southwest');
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
2019-10-18 17:34:45 +02:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/act_damp_variability_ine_tilt_angle.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_ine_tilt_angle
#+caption : Variability of the dynamics from the actuator force to the absolute velocity sensor with the Tilt Angle ([[./figs/act_damp_variability_ine_tilt_angle.png][png]], [[./figs/act_damp_variability_ine_tilt_angle.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_ine_tilt_angle.png ]]
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
** Scans of the Translation Stage
<<sec:variability_ty_scans >>
*** Introduction :ignore:
We want here to verify if the dynamics used for Active damping is varying when using the translation stage for scans.
2020-02-06 17:07:11 +01:00
*** Identification :ignore:
2020-02-04 16:13:52 +01:00
We initialize all the stages with the default parameters.
2020-01-15 16:23:40 +01:00
#+begin_src matlab
2020-02-06 17:07:11 +01:00
prepareLinearizeIdentification();
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-04 16:13:52 +01:00
#+begin_src matlab :exports none
%% Options for Linearized
options = linearizeOptions;
options.SampleTime = 0;
%% Name of the Simulink File
2020-02-18 11:33:04 +01:00
mdl = 'nass_model';
2020-02-04 16:13:52 +01:00
%% Input/Output definition
clear io; io_i = 1;
2020-02-18 13:57:55 +01:00
io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
2020-02-04 16:13:52 +01:00
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Dnlm'); io_i = io_i + 1;
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm'); io_i = io_i + 1;
io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Vlm'); io_i = io_i + 1;
2020-01-15 16:23:40 +01:00
#+end_src
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
We initialize the translation stage reference to be a sinus with an amplitude of 5mm and a period of 1s (Figure [[fig:ty_scanning_reference_sinus ]]).
2020-01-15 16:23:40 +01:00
#+begin_src matlab
2020-02-04 16:13:52 +01:00
initializeReferences('Dy_type', 'sinusoidal', ...
'Dy_amplitude', 5e-3, ... % [m]
'Dy_period', 1); % [s]
2020-01-15 16:23:40 +01:00
#+end_src
2019-10-18 17:34:45 +02:00
2020-01-15 16:23:40 +01:00
#+begin_src matlab :exports none
2020-02-04 16:13:52 +01:00
load('mat/nass_references.mat', 'Dy');
2020-01-15 16:23:40 +01:00
figure;
2020-02-04 16:13:52 +01:00
plot(Dy.time, Dy.signals.values);
xlabel('Time [s]'); ylabel('Dy - Position [m]');
xlim([0, 2]);
2020-01-20 17:20:50 +01:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/ty_scanning_reference_sinus.pdf" :var figsize= "wide-normal" :post pdf2svg(file=*this*, ext= "png")
2020-01-20 17:20:50 +01:00
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:ty_scanning_reference_sinus
#+caption : Reference path for the translation stage ([[./figs/ty_scanning_reference_sinus.png][png]], [[./figs/ty_scanning_reference_sinus.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/ty_scanning_reference_sinus.png ]]
We identify the dynamics at different positions (times) when scanning with the Translation stage.
#+begin_src matlab
t_lin = [0.5, 0.75, 1, 1.25];
#+end_src
#+begin_src matlab :exports none
Gty = {zeros(length(t_lin))};
Gty_iff = {zeros(length(t_lin))};
Gty_dvf = {zeros(length(t_lin))};
Gty_ine = {zeros(length(t_lin))};
%% Run the linearization
G = linearize(mdl, io, t_lin, options);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6', ...
'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6', ...
'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'};
for i = 1:length(t_lin)
Gty(i) = {G(:,:,i)};
Gty_iff(i) = {minreal(G({'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}, i))};
Gty_dvf(i) = {minreal(G({'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}, i))};
Gty_ine(i) = {minreal(G({'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}, i))};
end
#+end_src
#+begin_src matlab :exports none
Gty_tlin = t_lin;
save('./active_damping/mat/plants_variable.mat', 'Gty_tlin', 'Dy', 'Gty_iff', 'Gty_dvf', 'Gty_ine', '-append');
#+end_src
*** Plots :ignore:
#+begin_src matlab :exports none
load('./active_damping/mat/plants_variable.mat', 'Gty_tlin', 'Dy', 'Gty_iff', 'Gty_dvf', 'Gty_ine');
load('./active_damping/mat/undamped_plants.mat', 'G_iff', 'G_dvf', 'G_ine');
#+end_src
2020-01-20 17:20:50 +01:00
#+begin_src matlab :exports none
2020-02-04 16:13:52 +01:00
freqs = logspace(0, 3, 1000);
2020-01-20 17:20:50 +01:00
figure;
2020-02-04 16:13:52 +01:00
ax1 = subplot(2, 1, 1);
2020-01-20 17:20:50 +01:00
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gty_iff)
plot(freqs, abs(squeeze(freqresp(Gty_iff{i}('Fnlm1', 'Fnl1'), freqs, 'Hz'))));
end
plot(freqs, abs(squeeze(freqresp(G_iff('Fnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [N/N]'); set(gca, 'XTickLabel',[]);
2020-01-20 17:20:50 +01:00
2020-02-04 16:13:52 +01:00
ax2 = subplot(2, 1, 2);
2020-01-20 17:20:50 +01:00
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gty_iff)
[~, i_t] = min(abs(Dy.time - Gty_tlin(i)));
plot(freqs, 180/pi*angle(squeeze(freqresp(Gty_iff{i}('Fnlm1', 'Fnl1'), freqs, 'Hz'))), 'DisplayName', sprintf('$Dy = %.0f$ [mm]', 1e3*Dy.signals.values(i_t)));
end
plot(freqs, 180/pi*angle(squeeze(freqresp(G_iff('Fnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--', 'DisplayName', '$Ry = 0$ [deg]');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
legend('location', 'southwest');
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
2019-10-18 17:34:45 +02:00
#+end_src
2020-01-15 16:23:40 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/act_damp_variability_iff_ty_scans.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
2020-01-15 16:23:40 +01:00
<<plt-matlab >>
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_iff_ty_scans
#+caption : Variability of the dynamics from the actuator force to the absolute velocity sensor plant at different Ty scan positions ([[./figs/act_damp_variability_iff_ty_scans.png][png]], [[./figs/act_damp_variability_iff_ty_scans.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_iff_ty_scans.png ]]
2019-10-18 17:34:45 +02:00
2020-01-15 16:23:40 +01:00
#+begin_src matlab :exports none
2020-02-04 16:13:52 +01:00
freqs = logspace(0, 3, 1000);
2020-01-15 16:23:40 +01:00
figure;
2020-02-04 16:13:52 +01:00
ax1 = subplot(2, 1, 1);
2020-01-15 16:23:40 +01:00
hold on;
2020-01-20 17:20:50 +01:00
2020-02-04 16:13:52 +01:00
for i = 1:length(Gty_dvf)
plot(freqs, abs(squeeze(freqresp(Gty_dvf{i}('Dnlm1', 'Fnl1'), freqs, 'Hz'))));
end
plot(freqs, abs(squeeze(freqresp(G_dvf('Dnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ax2 = subplot(2, 1, 2);
2020-01-20 17:20:50 +01:00
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gty_dvf)
[~, i_t] = min(abs(Dy.time - Gty_tlin(i)));
plot(freqs, 180/pi*angle(squeeze(freqresp(Gty_dvf{i}('Dnlm1', 'Fnl1'), freqs, 'Hz'))), 'DisplayName', sprintf('$Dy = %.0f$ [mm]', 1e3*Dy.signals.values(i_t)));
end
plot(freqs, 180/pi*angle(squeeze(freqresp(G_dvf('Dnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--', 'DisplayName', '$Ry = 0$ [deg]');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
legend('location', 'southwest');
2020-01-20 17:20:50 +01:00
2020-02-04 16:13:52 +01:00
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/act_damp_variability_dvf_ty_scans.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_dvf_ty_scans
#+caption : Variability of the dynamics from actuator force to relative displacement sensor at different Ty scan positions ([[./figs/act_damp_variability_dvf_ty_scans.png][png]], [[./figs/act_damp_variability_dvf_ty_scans.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_dvf_ty_scans.png ]]
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
2020-01-20 17:20:50 +01:00
hold on;
2020-02-04 16:13:52 +01:00
for i = 1:length(Gty_ine)
plot(freqs, abs(squeeze(freqresp(Gty_ine{i}('Vnlm1', 'Fnl1'), freqs, 'Hz'))));
end
plot(freqs, abs(squeeze(freqresp(G_ine('Vnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [$\frac{m/s}{N}$]'); set(gca, 'XTickLabel',[]);
2020-01-20 17:20:50 +01:00
2020-02-04 16:13:52 +01:00
ax2 = subplot(2, 1, 2);
hold on;
for i = 1:length(Gty_ine)
[~, i_t] = min(abs(Dy.time - Gty_tlin(i)));
plot(freqs, 180/pi*angle(squeeze(freqresp(Gty_ine{i}('Vnlm1', 'Fnl1'), freqs, 'Hz'))), 'DisplayName', sprintf('$Dy = %.0f$ [mm]', 1e3*Dy.signals.values(i_t)));
end
plot(freqs, 180/pi*angle(squeeze(freqresp(G_ine('Vnlm1', 'Fnl1'), freqs, 'Hz'))), 'k--', 'DisplayName', '$Ry = 0$ [deg]');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
legend('location', 'southwest');
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
2019-10-18 17:34:45 +02:00
#+end_src
2020-01-15 16:23:40 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/act_damp_variability_ine_ty_scans.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
2020-01-15 16:23:40 +01:00
<<plt-matlab >>
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_variability_ine_ty_scans
#+caption : Variability of the Inertial plant at different Ty scan positions ([[./figs/act_damp_variability_ine_ty_scans.png][png]], [[./figs/act_damp_variability_ine_ty_scans.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/act_damp_variability_ine_ty_scans.png ]]
2019-10-18 17:34:45 +02:00
2020-01-15 16:23:40 +01:00
** Conclusion
2020-02-04 16:13:52 +01:00
#+name : tab:active_damping_plant_variability
#+caption : Conclusion on the variability of the system dynamics for active damping
| <c> | <c> |
| | *Change of Dynamics* |
|---------------------------+--------------------------------------------|
| *Sample Mass* | Large |
| *Spindle Angle* | Small |
| *Spindle Rotation Speed* | First resonance is split in two resonances |
| *Tilt Angle* | Negligible |
| *Translation Stage scans* | Negligible |
Also, for the Inertial Sensor, a RHP zero may appear when the spindle is rotating fast.
2020-01-15 16:23:40 +01:00
#+begin_important
2020-02-04 16:13:52 +01:00
When using either a force sensor or a relative motion sensor for active damping, the only "parameter" that induce a large change for the dynamics to be controlled is the *sample mass* .
Thus, the developed damping techniques should be robust to variations of the sample mass.
2020-01-15 16:23:40 +01:00
#+end_important
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
* Integral Force Feedback
2020-01-15 16:23:40 +01:00
:PROPERTIES:
2020-02-04 16:13:52 +01:00
:header-args:matlab+: :tangle matlab/iff.m
2020-01-15 16:23:40 +01:00
:header-args:matlab+: :comments none :mkdirp yes
:END:
2020-02-04 16:13:52 +01:00
<<sec:iff >>
2019-10-18 17:34:45 +02:00
2020-01-15 16:23:40 +01:00
** ZIP file containing the data and matlab files :ignore:
#+begin_src bash :exports none :results none
2020-02-04 16:13:52 +01:00
if [ matlab/iff.m -nt data/iff.zip ]; then
cp matlab/iff.m iff.m;
zip data/iff \
2020-01-15 16:23:40 +01:00
mat/plant.mat \
2020-02-04 16:13:52 +01:00
iff.m
rm iff.m;
2020-01-15 16:23:40 +01:00
fi
2019-10-18 17:34:45 +02:00
#+end_src
2020-01-15 16:23:40 +01:00
#+begin_note
2020-02-04 16:13:52 +01:00
All the files (data and Matlab scripts) are accessible [[file:data/iff.zip ][here ]].
2020-01-15 16:23:40 +01:00
#+end_note
2019-10-18 17:34:45 +02:00
2020-01-15 16:23:40 +01:00
** Introduction :ignore:
2020-02-04 18:36:27 +01:00
Here, we study the use of *Integral Force Feedback* (IFF) to actively damp the resonances.
The IFF control is applied in a decentralized way: there is on controller for each leg.
The control architecture is represented in figure [[fig:iff_1dof ]] where one of the 6 nano-hexapod legs is represented.
#+name : fig:iff_1dof
#+caption : Integral Force Feedback applied to a 1dof system
#+RESULTS :
[[file:figs/iff_1dof.png ]]
2019-10-18 17:34:45 +02:00
2020-01-15 16:23:40 +01:00
** Matlab Init :noexport:ignore:
2019-10-18 17:34:45 +02:00
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir >>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init >>
#+end_src
#+begin_src matlab :tangle no
simulinkproject('../');
#+end_src
#+begin_src matlab
2020-01-15 16:23:40 +01:00
addpath('active_damping/src/ ');
#+end_src
#+begin_src matlab
2020-02-18 11:33:04 +01:00
open('nass_model.slx')
2019-10-18 17:34:45 +02:00
#+end_src
** Control Design
2020-01-15 16:23:40 +01:00
*** Plant
2020-02-04 18:36:27 +01:00
Let's load the previously identified undamped plant:
2019-10-18 17:34:45 +02:00
#+begin_src matlab
2020-02-04 16:13:52 +01:00
load('./active_damping/mat/undamped_plants.mat', 'G_iff');
2020-02-04 18:36:27 +01:00
load('./active_damping/mat/plants_variable.mat', 'masses', 'Gm_iff');
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-04 16:13:52 +01:00
Let's look at the transfer function from actuator forces in the nano-hexapod to the force sensor in the nano-hexapod legs for all 6 pairs of actuator/sensor (figure [[fig:iff_plant ]]).
2019-10-18 17:34:45 +02:00
#+begin_src matlab :exports none
2020-02-06 17:07:11 +01:00
freqs = logspace(-2, 3, 1000);
2019-10-18 17:34:45 +02:00
figure;
ax1 = subplot(2, 1, 1);
hold on;
2020-02-04 18:36:27 +01:00
for i=1:length(masses)
plot(freqs, abs(squeeze(freqresp(-Gm_iff{i}('Fnlm1', 'Fnl1'), freqs, 'Hz'))));
2019-10-18 17:34:45 +02:00
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-02-04 16:13:52 +01:00
ylabel('Amplitude [N/N]'); set(gca, 'XTickLabel',[]);
2019-10-18 17:34:45 +02:00
ax2 = subplot(2, 1, 2);
hold on;
2020-02-04 18:36:27 +01:00
for i=1:length(masses)
plot(freqs, 180/pi*angle(squeeze(freqresp(-Gm_iff{i}('Fnlm1', 'Fnl1'), freqs, 'Hz'))), ...
'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
2019-10-18 17:34:45 +02:00
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
2020-02-04 18:36:27 +01:00
legend('location', 'southwest');
2019-10-18 17:34:45 +02:00
linkaxes([ax1,ax2],'x');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/iff_plant.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
2019-10-18 17:34:45 +02:00
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:iff_plant
#+caption : Transfer function from forces applied in the legs to force sensor ([[./figs/iff_plant.png][png]], [[./figs/iff_plant.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/iff_plant.png ]]
2020-01-15 16:23:40 +01:00
*** Control Design
2020-02-04 16:13:52 +01:00
The controller for each pair of actuator/sensor is:
2019-10-18 17:34:45 +02:00
#+begin_src matlab
2020-02-04 18:36:27 +01:00
w0 = 2*pi*50;
K_iff = -5000/s * (s/w0)/ (1 + s/w0);
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-04 16:13:52 +01:00
The corresponding loop gains are shown in figure [[fig:iff_open_loop ]].
2019-10-18 17:34:45 +02:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
2020-02-04 18:36:27 +01:00
for i=1:length(masses)
plot(freqs, abs(squeeze(freqresp(K_iff*Gm_iff{i}('Fnlm1', 'Fnl1'), freqs, 'Hz'))));
2019-10-18 17:34:45 +02:00
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-02-04 16:13:52 +01:00
ylabel('Amplitude [N/N]'); set(gca, 'XTickLabel',[]);
2019-10-18 17:34:45 +02:00
ax2 = subplot(2, 1, 2);
hold on;
2020-02-04 18:36:27 +01:00
for i=1:length(masses)
plot(freqs, 180/pi*angle(squeeze(freqresp(K_iff*Gm_iff{i}('Fnlm1', 'Fnl1'), freqs, 'Hz'))), ...
'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
2019-10-18 17:34:45 +02:00
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
2020-02-04 18:36:27 +01:00
legend('location', 'southwest');
2019-10-18 17:34:45 +02:00
linkaxes([ax1,ax2],'x');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/iff_open_loop.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
2019-10-18 17:34:45 +02:00
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:iff_open_loop
#+caption : Loop Gain for the Integral Force Feedback ([[./figs/iff_open_loop.png][png]], [[./figs/iff_open_loop.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/iff_open_loop.png ]]
2020-01-15 16:23:40 +01:00
*** Diagonal Controller
2020-02-04 16:13:52 +01:00
We create the diagonal controller and we add a minus sign as we have a positive
feedback architecture.
2020-01-15 16:23:40 +01:00
#+begin_src matlab
2020-02-04 16:13:52 +01:00
K_iff = -K_iff*eye(6);
2020-01-15 16:23:40 +01:00
#+end_src
We save the controller for further analysis.
#+begin_src matlab
2020-02-04 16:13:52 +01:00
save('./active_damping/mat/K_iff.mat', 'K_iff');
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-06 17:07:11 +01:00
** Identification of the damped plant :noexport:
*** Identification
2020-02-04 16:13:52 +01:00
We initialize all the stages with the default parameters.
#+begin_src matlab
2020-02-06 17:07:11 +01:00
prepareLinearizeIdentification();
2020-02-04 16:13:52 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
We set the IFF controller.
2020-02-04 16:13:52 +01:00
#+begin_src matlab
2020-02-04 18:36:27 +01:00
load('./active_damping/mat/K_iff.mat', 'K_iff');
2020-02-18 11:33:04 +01:00
initializeController('type', 'iff', 'K', K_iff);
2020-02-04 16:13:52 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
We identify the dynamics of the system using the =linearize= function.
2020-02-04 16:13:52 +01:00
#+begin_src matlab
%% Options for Linearized
options = linearizeOptions;
options.SampleTime = 0;
%% Name of the Simulink File
2020-02-18 11:33:04 +01:00
mdl = 'nass_model';
2020-02-04 16:13:52 +01:00
%% Input/Output definition
clear io; io_i = 1;
2020-02-18 13:57:55 +01:00
io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1;
2020-02-04 16:13:52 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
We identify the dynamics for the following sample mass.
2020-02-04 16:13:52 +01:00
#+begin_src matlab
2020-02-06 17:07:11 +01:00
load('./active_damping/mat/cart_plants.mat', 'masses');
2020-02-04 16:13:52 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
#+begin_src matlab :exports none
G_cart_iff = {zeros(length(masses))};
2020-02-04 16:13:52 +01:00
2020-02-06 17:07:11 +01:00
load('mat/stages.mat', 'nano_hexapod');
2020-02-04 16:13:52 +01:00
2020-02-06 17:07:11 +01:00
for i = 1:length(masses)
initializeSample('mass', masses(i));
2020-02-04 16:13:52 +01:00
2020-02-06 17:07:11 +01:00
%% Run the linearization
G = linearize(mdl, io, 0.3, options);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G.OutputName = {'Dnx', 'Dny', 'Dnz', 'Rnx', 'Rny', 'Rnz'};
2020-02-04 16:13:52 +01:00
2020-02-06 17:07:11 +01:00
G_cart = G*inv(nano_hexapod.J');
G_cart.InputName = {'Fnx', 'Fny', 'Fnz', 'Mnx', 'Mny', 'Mnz'};
2020-02-04 16:13:52 +01:00
2020-02-06 17:07:11 +01:00
G_cart_iff(i) = {G_cart};
end
2020-02-04 16:13:52 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
And we save them for further analysis.
#+begin_src matlab
save('./active_damping/mat/cart_plants.mat', 'G_cart_iff', '-append');
2020-02-04 16:13:52 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
*** Damped Plant
Now, look at the new damped plant to control.
#+begin_src matlab
load('./active_damping/mat/cart_plants.mat', 'masses', 'G_cart', 'G_cart_iff');
#+end_src
2020-02-04 16:13:52 +01:00
2020-02-06 17:07:11 +01:00
It damps the plant (resonance of the nano hexapod as well as other resonances) as shown in figure [[fig:plant_iff_damped ]].
2020-02-04 16:13:52 +01:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
2020-02-06 17:07:11 +01:00
ax1 = subplot(2, 1, 1);
2020-02-04 16:13:52 +01:00
hold on;
2020-02-06 17:07:11 +01:00
for i = 1:length(masses)
set(gca,'ColorOrderIndex',i);
p1 = plot(freqs, abs(squeeze(freqresp(G_cart_iff{i}('Dnx', 'Fnx'), freqs, 'Hz'))));
set(gca,'ColorOrderIndex',i);
p2 = plot(freqs, abs(squeeze(freqresp(G_cart_iff{i}('Dny', 'Fny'), freqs, 'Hz'))), '--');
set(gca,'ColorOrderIndex',i);
p3 = plot(freqs, abs(squeeze(freqresp(G_cart_iff{i}('Dnz', 'Fnz'), freqs, 'Hz'))), ':');
end
2020-02-04 16:13:52 +01:00
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); xlabel('Frequency [Hz]');
2020-02-06 17:07:11 +01:00
legend([p1,p2,p3], {'Fx/Dx', 'Fy/Dx', 'Fz/Dz'});
ax2 = subplot(2, 1, 2);
hold on;
for i = 1:length(masses)
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_iff{i}('Dnx', 'Fnx'), freqs, 'Hz')))), ...
'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_iff{i}('Dny', 'Fny'), freqs, 'Hz')))), '--', 'HandleVisibility', 'off');
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_iff{i}('Dnz', 'Fnz'), freqs, 'Hz')))), ':', 'HandleVisibility', 'off');
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
yticks([-540:180:540]);
2020-02-04 16:13:52 +01:00
legend('location', 'northeast');
2020-02-06 17:07:11 +01:00
linkaxes([ax1,ax2],'x');
2020-02-04 16:13:52 +01:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-06 17:07:11 +01:00
#+begin_src matlab :var filepath="figs/plant_iff_damped_translations.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
2020-02-04 16:13:52 +01:00
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:plant_iff_damped_translations
#+caption : Damped Plant for the translations after IFF is applied ([[./figs/plant_iff_damped_translations.png][png]], [[./figs/plant_iff_damped_translations.pdf][pdf]])
[[file:figs/plant_iff_damped_translations.png ]]
2019-10-18 17:34:45 +02:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
2020-02-06 17:07:11 +01:00
ax1 = subplot(2, 1, 1);
2019-10-18 17:34:45 +02:00
hold on;
2020-02-06 17:07:11 +01:00
for i = 1:length(masses)
set(gca,'ColorOrderIndex',i);
p1 = plot(freqs, abs(squeeze(freqresp(G_cart_iff{i}('Rnx', 'Mnx'), freqs, 'Hz'))));
set(gca,'ColorOrderIndex',i);
p2 = plot(freqs, abs(squeeze(freqresp(G_cart_iff{i}('Rny', 'Mny'), freqs, 'Hz'))), '--');
set(gca,'ColorOrderIndex',i);
p3 = plot(freqs, abs(squeeze(freqresp(G_cart_iff{i}('Rnz', 'Mnz'), freqs, 'Hz'))), ':');
end
2019-10-18 17:34:45 +02:00
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); xlabel('Frequency [Hz]');
2020-02-06 17:07:11 +01:00
legend([p1,p2,p3], {'Fx/Dx', 'Fy/Dx', 'Fz/Dz'});
2019-10-18 17:34:45 +02:00
2020-02-06 17:07:11 +01:00
ax2 = subplot(2, 1, 2);
2019-10-18 17:34:45 +02:00
hold on;
2020-02-06 17:07:11 +01:00
for i = 1:length(masses)
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_iff{i}('Rnx', 'Mnx'), freqs, 'Hz')))), ...
'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_iff{i}('Rny', 'Mny'), freqs, 'Hz')))), '--', 'HandleVisibility', 'off');
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_iff{i}('Rnz', 'Mnz'), freqs, 'Hz')))), ':', 'HandleVisibility', 'off');
end
2019-10-18 17:34:45 +02:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
2020-02-04 18:36:27 +01:00
yticks([-540:180:540]);
2020-02-06 17:07:11 +01:00
legend('location', 'northeast');
2019-10-18 17:34:45 +02:00
2020-02-06 17:07:11 +01:00
linkaxes([ax1,ax2],'x');
2019-10-18 17:34:45 +02:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-06 17:07:11 +01:00
#+begin_src matlab :var filepath="figs/plant_iff_damped_rotations.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
2019-10-18 17:34:45 +02:00
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:plant_iff_damped_rotations
#+caption : Damped Plant for the Rotations after IFF is applied ([[./figs/plant_iff_damped_rotations.png][png]], [[./figs/plant_iff_damped_rotations.pdf][pdf]])
[[file:figs/plant_iff_damped_rotations.png ]]
2020-02-04 16:13:52 +01:00
However, it increases coupling at low frequency (figure [[fig:plant_iff_coupling ]]).
#+begin_src matlab :exports none
2020-02-06 17:07:11 +01:00
freqs = logspace(1, 3, 1000);
2020-02-04 16:13:52 +01:00
figure;
for ix = 1:6
for iy = 1:6
subplot(6, 6, (ix-1)*6 + iy);
hold on;
2020-02-06 17:07:11 +01:00
plot(freqs, abs(squeeze(freqresp(G_cart{1}(ix, iy), freqs, 'Hz'))), 'k-');
plot(freqs, abs(squeeze(freqresp(G_cart_iff{1}(ix, iy), freqs, 'Hz'))), 'k--');
2020-02-04 16:13:52 +01:00
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-02-04 18:36:27 +01:00
ylim([1e-13, 1e-4]);
xticks([])
yticks([])
2020-02-04 16:13:52 +01:00
end
end
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/plant_iff_coupling.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:plant_iff_coupling
#+caption : Coupling induced by IFF ([[./figs/plant_iff_coupling.png][png]], [[./figs/plant_iff_coupling.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/plant_iff_coupling.png ]]
2019-10-18 17:34:45 +02:00
2020-01-15 16:23:40 +01:00
** Tomography Experiment
2020-02-04 16:13:52 +01:00
*** Simulation with IFF Controller
2020-01-15 16:23:40 +01:00
We initialize elements for the tomography experiment.
#+begin_src matlab
prepareTomographyExperiment();
#+end_src
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
We set the IFF controller.
2020-01-15 16:23:40 +01:00
#+begin_src matlab
2020-02-04 16:13:52 +01:00
load('./active_damping/mat/K_iff.mat', 'K_iff');
2020-02-18 11:33:04 +01:00
initializeController('type', 'iff', 'K', K_iff);
2020-01-15 16:23:40 +01:00
#+end_src
2019-10-25 16:02:23 +02:00
2020-01-15 16:23:40 +01:00
We change the simulation stop time.
#+begin_src matlab
2020-02-18 11:33:04 +01:00
load('mat/conf_simulink.mat');
set_param(conf_simulink, 'StopTime', '4.5');
2019-10-25 16:02:23 +02:00
#+end_src
2020-01-15 16:23:40 +01:00
And we simulate the system.
#+begin_src matlab
2020-02-18 13:57:55 +01:00
sim('nass_model');
2020-01-15 16:23:40 +01:00
#+end_src
2019-10-25 16:02:23 +02:00
2020-01-15 16:23:40 +01:00
Finally, we save the simulation results for further analysis
#+begin_src matlab
2020-02-04 16:13:52 +01:00
En_iff = En;
Eg_iff = Eg;
save('./active_damping/mat/tomo_exp.mat', 'En_iff', 'Eg_iff', '-append');
2020-01-15 16:23:40 +01:00
#+end_src
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
*** Compare with Undamped system
2020-02-06 17:07:11 +01:00
#+begin_src matlab :exports none
load('./active_damping/mat/tomo_exp.mat', 'En', 'En_iff');
Fs = 1e3; % Sampling Frequency of the Data
t = (1/Fs)*[0:length(En(:,1))-1];
2020-02-04 16:13:52 +01:00
#+end_src
#+begin_src matlab :exports none
figure;
hold on;
plot(En(:,1), En(:,2), 'DisplayName', '$\epsilon_{x,y}$ - OL')
plot(En_iff(:,1), En_iff(:,2), 'DisplayName', '$\epsilon_ {x,y}$ - IFF')
xlabel('X Motion [m]'); ylabel('Y Motion [m]');
legend('location', 'northwest');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/nass_act_damp_iff_sim_tomo_xy.pdf" :var figsize= "small-normal" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:nass_act_damp_iff_sim_tomo_xy
#+caption : Position Error during tomography experiment - XY Motion ([[./figs/nass_act_damp_iff_sim_tomo_xy.png][png]], [[./figs/nass_act_damp_iff_sim_tomo_xy.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/nass_act_damp_iff_sim_tomo_xy.png ]]
2020-01-20 17:20:50 +01:00
#+begin_src matlab :exports none
figure;
ax1 = subplot(3, 1, 1);
hold on;
2020-01-15 16:23:40 +01:00
plot(t, En(:,1), 'DisplayName', '$\epsilon_{x}$')
2020-02-04 16:13:52 +01:00
plot(t, En_iff(:,1), 'DisplayName', '$\epsilon_ {x}$ - IFF')
legend('location', 'southwest');
2020-01-20 17:20:50 +01:00
ax2 = subplot(3, 1, 2);
hold on;
2020-01-15 16:23:40 +01:00
plot(t, En(:,2), 'DisplayName', '$\epsilon_{y}$')
2020-02-04 16:13:52 +01:00
plot(t, En_iff(:,2), 'DisplayName', '$\epsilon_ {y}$ - IFF')
legend('location', 'southwest');
2020-01-20 17:20:50 +01:00
ylabel('Position Error [m]');
ax3 = subplot(3, 1, 3);
hold on;
2020-01-15 16:23:40 +01:00
plot(t, En(:,3), 'DisplayName', '$\epsilon_{z}$')
2020-02-04 16:13:52 +01:00
plot(t, En_iff(:,3), 'DisplayName', '$\epsilon_ {z}$ - IFF')
legend('location', 'northwest');
2020-01-20 17:20:50 +01:00
xlabel('Time [s]');
2020-02-06 17:07:11 +01:00
linkaxes([ax1,ax2,ax3],'x');
xlim([0.5,inf]);
2020-01-15 16:23:40 +01:00
#+end_src
2019-10-18 17:34:45 +02:00
2020-01-15 16:23:40 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/nass_act_damp_iff_sim_tomo_trans.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
2020-01-15 16:23:40 +01:00
<<plt-matlab >>
#+end_src
2019-10-18 17:34:45 +02:00
2020-02-06 17:07:11 +01:00
#+name : fig:nass_act_damp_iff_sim_tomo_trans
#+caption : Position Error during tomography experiment - Translations ([[./figs/nass_act_damp_iff_sim_tomo_trans.png][png]], [[./figs/nass_act_damp_iff_sim_tomo_trans.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/nass_act_damp_iff_sim_tomo_trans.png ]]
2019-10-18 17:34:45 +02:00
2020-01-15 16:23:40 +01:00
#+begin_src matlab :exports none
figure;
2020-01-20 17:20:50 +01:00
ax1 = subplot(3, 1, 1);
2020-01-15 16:23:40 +01:00
hold on;
plot(t, En(:,4), 'DisplayName', '$\epsilon_{\theta_x}$')
2020-02-04 16:13:52 +01:00
plot(t, En_iff(:,4), 'DisplayName', '$\epsilon_ {\theta_x}$ - IFF')
legend('location', 'northwest');
2020-01-20 17:20:50 +01:00
ax2 = subplot(3, 1, 2);
hold on;
2020-01-15 16:23:40 +01:00
plot(t, En(:,5), 'DisplayName', '$\epsilon_{\theta_y}$')
2020-02-04 16:13:52 +01:00
plot(t, En_iff(:,5), 'DisplayName', '$\epsilon_ {\theta_y}$ - IFF')
legend('location', 'southwest');
2020-01-20 17:20:50 +01:00
ylabel('Position Error [rad]');
ax3 = subplot(3, 1, 3);
hold on;
2020-01-15 16:23:40 +01:00
plot(t, En(:,6), 'DisplayName', '$\epsilon_{\theta_z}$')
2020-02-04 16:13:52 +01:00
plot(t, En_iff(:,6), 'DisplayName', '$\epsilon_ {\theta_z}$ - IFF')
2020-01-15 16:23:40 +01:00
legend();
2020-01-20 17:20:50 +01:00
xlabel('Time [s]');
linkaxes([ax1,ax2,ax3],'x');
2020-02-06 17:07:11 +01:00
xlim([0.5,inf]);
2019-10-18 17:34:45 +02:00
#+end_src
2020-01-15 16:23:40 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/nass_act_damp_iff_sim_tomo_rot.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
2020-01-15 16:23:40 +01:00
<<plt-matlab >>
#+end_src
2019-10-18 17:34:45 +02:00
2020-02-06 17:07:11 +01:00
#+name : fig:nass_act_damp_iff_sim_tomo_rot
#+caption : Position Error during tomography experiment - Rotations ([[./figs/nass_act_damp_iff_sim_tomo_rot.png][png]], [[./figs/nass_act_damp_iff_sim_tomo_rot.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/nass_act_damp_iff_sim_tomo_rot.png ]]
2019-10-18 17:34:45 +02:00
2020-01-15 16:23:40 +01:00
** Conclusion
#+begin_important
2020-02-06 17:07:11 +01:00
Integral Force Feedback using a force sensor:
2020-02-04 16:13:52 +01:00
- Robust (guaranteed stability)
- Acceptable Damping
- Increase the sensitivity to disturbances at low frequencies
2020-01-15 16:23:40 +01:00
#+end_important
2019-10-18 17:34:45 +02:00
2020-02-04 16:13:52 +01:00
* Direct Velocity Feedback
2020-01-21 17:28:49 +01:00
:PROPERTIES:
2020-02-04 16:13:52 +01:00
:header-args:matlab+: :tangle matlab/dvf.m
:header-args:matlab+: :comments none :mkdirp yes
2020-01-21 17:28:49 +01:00
:END:
2020-02-04 16:13:52 +01:00
<<sec:dvf >>
2020-01-21 17:28:49 +01:00
** ZIP file containing the data and matlab files :ignore:
#+begin_src bash :exports none :results none
2020-02-04 16:13:52 +01:00
if [ matlab/dvf.m -nt data/dvf.zip ]; then
cp matlab/dvf.m dvf.m;
zip data/dvf \
mat/plant.mat \
dvf.m
rm dvf.m;
fi
2020-01-21 17:28:49 +01:00
#+end_src
#+begin_note
2020-02-04 16:13:52 +01:00
All the files (data and Matlab scripts) are accessible [[file:data/dvf.zip ][here ]].
2020-01-21 17:28:49 +01:00
#+end_note
** Introduction :ignore:
2020-02-04 16:13:52 +01:00
In the Direct Velocity Feedback (DVF), a derivative feedback is applied between the measured actuator displacement to the actuator force input.
The actuator displacement can be measured with a capacitive sensor for instance.
2020-01-21 17:28:49 +01:00
** Matlab Init :noexport:ignore:
2019-10-18 17:34:45 +02:00
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir >>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init >>
#+end_src
2020-01-21 17:28:49 +01:00
#+begin_src matlab :tangle no
simulinkproject('../');
2020-01-15 16:23:40 +01:00
#+end_src
2019-10-18 17:34:45 +02:00
2020-01-21 17:28:49 +01:00
#+begin_src matlab
2020-02-04 16:13:52 +01:00
addpath('active_damping/src/ ');
2020-01-15 16:23:40 +01:00
#+end_src
2019-10-18 17:34:45 +02:00
2020-01-21 17:28:49 +01:00
#+begin_src matlab
2020-02-18 11:33:04 +01:00
open('nass_model.slx')
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-04 16:13:52 +01:00
** Control Design
*** Plant
Let's load the undamped plant:
2020-01-21 17:28:49 +01:00
#+begin_src matlab
2020-02-04 16:13:52 +01:00
load('./active_damping/mat/undamped_plants.mat', 'G_dvf');
2020-02-06 17:07:11 +01:00
load('./active_damping/mat/plants_variable.mat', 'masses', 'Gm_dvf');
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-04 16:13:52 +01:00
Let's look at the transfer function from actuator forces in the nano-hexapod to the measured displacement of the actuator for all 6 pairs of actuator/sensor (figure [[fig:dvf_plant ]]).
2019-10-18 17:34:45 +02:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
2020-02-06 17:07:11 +01:00
for i=1:length(masses)
plot(freqs, abs(squeeze(freqresp(-Gm_dvf{i}('Dnlm1', 'Fnl1'), freqs, 'Hz'))));
2020-01-21 17:28:49 +01:00
end
hold off;
2019-10-18 17:34:45 +02:00
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-02-04 16:13:52 +01:00
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
2019-10-18 17:34:45 +02:00
ax2 = subplot(2, 1, 2);
hold on;
2020-02-06 17:07:11 +01:00
for i=1:length(masses)
plot(freqs, 180/pi*angle(squeeze(freqresp(-Gm_dvf{i}('Dnlm1', 'Fnl1'), freqs, 'Hz'))), ...
'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
2020-01-21 17:28:49 +01:00
end
2019-10-18 17:34:45 +02:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
2020-02-06 17:07:11 +01:00
legend('location', 'southwest');
2019-10-18 17:34:45 +02:00
linkaxes([ax1,ax2],'x');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/dvf_plant.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2019-10-18 17:34:45 +02:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:dvf_plant
#+caption : Transfer function from forces applied in the legs to leg displacement sensor ([[./figs/dvf_plant.png][png]], [[./figs/dvf_plant.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/dvf_plant.png ]]
*** Control Design
The Direct Velocity Feedback is defined below.
A Low pass Filter is added to make the controller transfer function proper.
#+begin_src matlab
2020-02-06 17:07:11 +01:00
K_dvf = s*30000/(1 + s/2/pi/10000);
2020-02-04 16:13:52 +01:00
#+end_src
The obtained loop gains are shown in figure [[fig:dvf_open_loop ]].
2019-10-25 16:02:23 +02:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
ax1 = subplot(2, 1, 1);
hold on;
2020-02-06 17:07:11 +01:00
for i=1:length(masses)
plot(freqs, abs(squeeze(freqresp(K_dvf*Gm_dvf{i}('Dnlm1', 'Fnl1'), freqs, 'Hz'))));
2020-01-21 17:28:49 +01:00
end
hold off;
2020-01-15 16:23:40 +01:00
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-02-06 17:07:11 +01:00
ylabel('Loop Gain'); set(gca, 'XTickLabel',[]);
2020-01-15 16:23:40 +01:00
ax2 = subplot(2, 1, 2);
hold on;
2020-02-06 17:07:11 +01:00
for i=1:length(masses)
plot(freqs, 180/pi*angle(squeeze(freqresp(K_dvf*Gm_dvf{i}('Dnlm1', 'Fnl1'), freqs, 'Hz'))), ...
'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
2020-01-21 17:28:49 +01:00
end
2019-10-25 16:02:23 +02:00
hold off;
2020-01-15 16:23:40 +01:00
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
2020-02-06 17:07:11 +01:00
legend('location', 'southwest');
2020-01-15 16:23:40 +01:00
linkaxes([ax1,ax2],'x');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/dvf_open_loop.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2020-01-15 16:23:40 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:dvf_open_loop
#+caption : Loop Gain for the Integral Force Feedback ([[./figs/dvf_open_loop.png][png]], [[./figs/dvf_open_loop.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/dvf_open_loop.png ]]
2019-10-25 16:02:23 +02:00
2020-02-04 16:13:52 +01:00
*** Diagonal Controller
We create the diagonal controller and we add a minus sign as we have a positive feedback architecture.
#+begin_src matlab
K_dvf = -K_dvf*eye(6);
2019-10-25 16:02:23 +02:00
#+end_src
2020-02-04 16:13:52 +01:00
We save the controller for further analysis.
#+begin_src matlab
save('./active_damping/mat/K_dvf.mat', 'K_dvf');
2019-10-25 16:02:23 +02:00
#+end_src
2020-02-06 17:07:11 +01:00
** Identification of the damped plant :noexport:
*** Identification
We initialize all the stages with the default parameters.
2019-10-25 16:02:23 +02:00
#+begin_src matlab
2020-02-06 17:07:11 +01:00
prepareLinearizeIdentification();
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
We set the DVF controller.
2020-01-21 17:28:49 +01:00
#+begin_src matlab
2020-02-06 17:07:11 +01:00
load('./active_damping/mat/K_dvf.mat', 'K_dvf');
2020-02-18 11:33:04 +01:00
initializeController('type', 'dvf', 'K', K_dvf);
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
We identify the dynamics of the system using the =linearize= function.
2020-02-04 16:13:52 +01:00
#+begin_src matlab
2020-01-21 17:28:49 +01:00
%% Options for Linearized
options = linearizeOptions;
options.SampleTime = 0;
%% Name of the Simulink File
2020-02-18 11:33:04 +01:00
mdl = 'nass_model';
2020-01-21 17:28:49 +01:00
%% Input/Output definition
clear io; io_i = 1;
2020-02-18 13:57:55 +01:00
io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1;
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
We identify the dynamics for the following sample mass.
2020-02-04 16:13:52 +01:00
#+begin_src matlab
2020-02-06 17:07:11 +01:00
load('./active_damping/mat/cart_plants.mat', 'masses');
2020-01-21 17:28:49 +01:00
#+end_src
#+begin_src matlab :exports none
2020-02-06 17:07:11 +01:00
G_cart_dvf = {zeros(length(masses))};
2020-01-21 17:28:49 +01:00
2020-02-06 17:07:11 +01:00
load('mat/stages.mat', 'nano_hexapod');
2020-01-21 17:28:49 +01:00
2020-02-06 17:07:11 +01:00
for i = 1:length(masses)
initializeSample('mass', masses(i));
2020-01-21 17:28:49 +01:00
2020-02-06 17:07:11 +01:00
%% Run the linearization
G = linearize(mdl, io, 0.3, options);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G.OutputName = {'Dnx', 'Dny', 'Dnz', 'Rnx', 'Rny', 'Rnz'};
G_cart = G*inv(nano_hexapod.J');
G_cart.InputName = {'Fnx', 'Fny', 'Fnz', 'Mnx', 'Mny', 'Mnz'};
G_cart_dvf(i) = {G_cart};
end
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
And we save them for further analysis.
#+begin_src matlab
save('./active_damping/mat/cart_plants.mat', 'G_cart_dvf', '-append');
#+end_src
*** Damped Plant
Now, look at the new damped plant to control.
#+begin_src matlab
load('./active_damping/mat/cart_plants.mat', 'masses', 'G_cart', 'G_cart_dvf');
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
It damps the plant (resonance of the nano hexapod as well as other resonances) as shown in figure [[fig:plant_dvf_damped ]].
2020-01-21 17:28:49 +01:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
2020-02-06 17:07:11 +01:00
ax1 = subplot(2, 1, 1);
2020-01-21 17:28:49 +01:00
hold on;
2020-02-06 17:07:11 +01:00
for i = 1:length(masses)
set(gca,'ColorOrderIndex',i);
p1 = plot(freqs, abs(squeeze(freqresp(G_cart_dvf{i}('Dnx', 'Fnx'), freqs, 'Hz'))));
set(gca,'ColorOrderIndex',i);
p2 = plot(freqs, abs(squeeze(freqresp(G_cart_dvf{i}('Dny', 'Fny'), freqs, 'Hz'))), '--');
set(gca,'ColorOrderIndex',i);
p3 = plot(freqs, abs(squeeze(freqresp(G_cart_dvf{i}('Dnz', 'Fnz'), freqs, 'Hz'))), ':');
end
2020-01-21 17:28:49 +01:00
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-02-04 16:13:52 +01:00
ylabel('Amplitude [m/N]'); xlabel('Frequency [Hz]');
2020-02-06 17:07:11 +01:00
legend([p1,p2,p3], {'Fx/Dx', 'Fy/Dx', 'Fz/Dz'});
ax2 = subplot(2, 1, 2);
hold on;
for i = 1:length(masses)
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_dvf{i}('Dnx', 'Fnx'), freqs, 'Hz')))), ...
'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_dvf{i}('Dny', 'Fny'), freqs, 'Hz')))), '--', 'HandleVisibility', 'off');
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_dvf{i}('Dnz', 'Fnz'), freqs, 'Hz')))), ':', 'HandleVisibility', 'off');
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
yticks([-540:180:540]);
2020-02-04 16:13:52 +01:00
legend('location', 'northeast');
2020-02-06 17:07:11 +01:00
linkaxes([ax1,ax2],'x');
2020-01-21 17:28:49 +01:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-06 17:07:11 +01:00
#+begin_src matlab :var filepath="figs/plant_dvf_damped_translations.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
2020-02-04 16:13:52 +01:00
<<plt-matlab >>
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:plant_dvf_damped_translations
#+caption : Damped Plant for the translations after DVF is applied ([[./figs/plant_dvf_damped_translations.png][png]], [[./figs/plant_dvf_damped_translations.pdf][pdf]])
[[file:figs/plant_dvf_damped_translations.png ]]
2020-01-21 17:28:49 +01:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
2020-02-06 17:07:11 +01:00
ax1 = subplot(2, 1, 1);
2020-01-21 17:28:49 +01:00
hold on;
2020-02-06 17:07:11 +01:00
for i = 1:length(masses)
set(gca,'ColorOrderIndex',i);
p1 = plot(freqs, abs(squeeze(freqresp(G_cart_dvf{i}('Rnx', 'Mnx'), freqs, 'Hz'))));
set(gca,'ColorOrderIndex',i);
p2 = plot(freqs, abs(squeeze(freqresp(G_cart_dvf{i}('Rny', 'Mny'), freqs, 'Hz'))), '--');
set(gca,'ColorOrderIndex',i);
p3 = plot(freqs, abs(squeeze(freqresp(G_cart_dvf{i}('Rnz', 'Mnz'), freqs, 'Hz'))), ':');
end
2020-01-21 17:28:49 +01:00
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-02-04 16:13:52 +01:00
ylabel('Amplitude [m/N]'); xlabel('Frequency [Hz]');
2020-02-06 17:07:11 +01:00
legend([p1,p2,p3], {'Fx/Dx', 'Fy/Dx', 'Fz/Dz'});
2020-01-21 17:28:49 +01:00
2020-02-06 17:07:11 +01:00
ax2 = subplot(2, 1, 2);
2020-02-04 16:13:52 +01:00
hold on;
2020-02-06 17:07:11 +01:00
for i = 1:length(masses)
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_dvf{i}('Rnx', 'Mnx'), freqs, 'Hz')))), ...
'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_dvf{i}('Rny', 'Mny'), freqs, 'Hz')))), '--', 'HandleVisibility', 'off');
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_dvf{i}('Rnz', 'Mnz'), freqs, 'Hz')))), ':', 'HandleVisibility', 'off');
end
2020-01-21 17:28:49 +01:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
2020-02-06 17:07:11 +01:00
yticks([-540:180:540]);
legend('location', 'northeast');
2020-01-21 17:28:49 +01:00
2020-02-06 17:07:11 +01:00
linkaxes([ax1,ax2],'x');
#+end_src
2020-02-04 16:13:52 +01:00
2020-02-06 17:07:11 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/plant_dvf_damped_rotations.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
#+name : fig:plant_dvf_damped_rotations
#+caption : Damped Plant for the Rotations after DVF is applied ([[./figs/plant_dvf_damped_rotations.png][png]], [[./figs/plant_dvf_damped_rotations.pdf][pdf]])
[[file:figs/plant_dvf_damped_rotations.png ]]
However, it does not change the 6x6 plant away from the resonances (figure [[fig:plant_dvf_coupling ]]).
#+begin_src matlab :exports none
freqs = logspace(1, 3, 1000);
figure;
for ix = 1:6
for iy = 1:6
subplot(6, 6, (ix-1)*6 + iy);
hold on;
plot(freqs, abs(squeeze(freqresp(G_cart{1}(ix, iy), freqs, 'Hz'))), 'k-');
plot(freqs, abs(squeeze(freqresp(G_cart_dvf{1}(ix, iy), freqs, 'Hz'))), 'k--');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylim([1e-13, 1e-4]);
xticks([])
yticks([])
end
end
2020-01-21 17:28:49 +01:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-06 17:07:11 +01:00
#+begin_src matlab :var filepath="figs/plant_dvf_coupling.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
2020-02-04 16:13:52 +01:00
<<plt-matlab >>
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:plant_dvf_coupling
#+caption : Coupling induced by DVF actuative damping technique ([[./figs/plant_dvf_coupling.png][png]], [[./figs/plant_dvf_coupling.pdf][pdf]])
[[file:figs/plant_dvf_coupling.png ]]
2020-01-21 17:28:49 +01:00
2020-02-04 16:13:52 +01:00
** Tomography Experiment
*** Initialize the Simulation
We initialize elements for the tomography experiment.
2020-01-21 17:28:49 +01:00
#+begin_src matlab
2020-02-04 16:13:52 +01:00
prepareTomographyExperiment();
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-04 16:13:52 +01:00
We set the DVF controller.
2020-01-21 17:28:49 +01:00
#+begin_src matlab
2020-02-04 16:13:52 +01:00
load('./active_damping/mat/K_dvf.mat', 'K_dvf');
2020-02-18 11:33:04 +01:00
initializeController('type', 'dvf', 'K', K_dvf);
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-04 16:13:52 +01:00
We change the simulation stop time.
2020-01-21 17:28:49 +01:00
#+begin_src matlab
2020-02-18 11:33:04 +01:00
load('mat/conf_simulink.mat');
set_param(conf_simulink, 'StopTime', '4.5');
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-04 16:13:52 +01:00
And we simulate the system.
2020-01-21 17:28:49 +01:00
#+begin_src matlab
2020-02-18 13:57:55 +01:00
sim('nass_model');
2020-02-04 16:13:52 +01:00
#+end_src
Finally, we save the simulation results for further analysis
#+begin_src matlab
En_dvf = En;
Eg_dvf = Eg;
save('./active_damping/mat/tomo_exp.mat', 'En_dvf', 'Eg_dvf', '-append');
#+end_src
*** Compare with Undamped system
2020-02-06 17:07:11 +01:00
#+begin_src matlab :exports none
2020-02-04 16:13:52 +01:00
load('./active_damping/mat/tomo_exp.mat', 'En', 'En_dvf');
2020-02-06 17:07:11 +01:00
Fs = 1e3; % Sampling Frequency of the Data
t = (1/Fs)*[0:length(En(:,1))-1];
2020-01-21 17:28:49 +01:00
#+end_src
#+begin_src matlab :exports none
2020-02-04 16:13:52 +01:00
figure;
hold on;
plot(En(:,1), En(:,2), 'DisplayName', '$\epsilon_{x,y}$ - OL')
plot(En_dvf(:,1), En_dvf(:,2), 'DisplayName', '$\epsilon_ {x,y}$ - DVF')
xlabel('X Motion [m]'); ylabel('Y Motion [m]');
legend();
#+end_src
2020-01-21 17:28:49 +01:00
2020-02-04 16:13:52 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/nass_act_damp_dvf_sim_tomo_xy.pdf" :var figsize= "small-normal" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-01-21 17:28:49 +01:00
2020-02-06 17:07:11 +01:00
#+name : fig:nass_act_damp_dvf_sim_tomo_xy
#+caption : Position Error during tomography experiment - XY Motion ([[./figs/nass_act_damp_dvf_sim_tomo_xy.png][png]], [[./figs/nass_act_damp_dvf_sim_tomo_xy.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/nass_act_damp_dvf_sim_tomo_xy.png ]]
#+begin_src matlab :exports none
figure;
ax1 = subplot(3, 1, 1);
hold on;
plot(t, En(:,1), 'DisplayName', '$\epsilon_{x}$')
plot(t, En_dvf(:,1), 'DisplayName', '$\epsilon_ {x}$ - DVF')
legend();
ax2 = subplot(3, 1, 2);
hold on;
plot(t, En(:,2), 'DisplayName', '$\epsilon_{y}$')
plot(t, En_dvf(:,2), 'DisplayName', '$\epsilon_ {y}$ - DVF')
legend();
ylabel('Position Error [m]');
ax3 = subplot(3, 1, 3);
hold on;
plot(t, En(:,3), 'DisplayName', '$\epsilon_{z}$')
plot(t, En_dvf(:,3), 'DisplayName', '$\epsilon_ {z}$ - DVF')
legend();
xlabel('Time [s]');
2020-02-06 17:07:11 +01:00
linkaxes([ax1,ax2,ax3],'x');
xlim([0.5,inf]);
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-04 16:13:52 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/nass_act_damp_dvf_sim_tomo_trans.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:nass_act_damp_dvf_sim_tomo_trans
#+caption : Position Error during tomography experiment - Translations ([[./figs/nass_act_damp_dvf_sim_tomo_trans.png][png]], [[./figs/nass_act_damp_dvf_sim_tomo_trans.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/nass_act_damp_dvf_sim_tomo_trans.png ]]
2020-02-04 10:26:06 +01:00
2020-02-04 16:13:52 +01:00
#+begin_src matlab :exports none
figure;
ax1 = subplot(3, 1, 1);
hold on;
plot(t, En(:,4), 'DisplayName', '$\epsilon_{\theta_x}$')
plot(t, En_dvf(:,4), 'DisplayName', '$\epsilon_ {\theta_x}$ - DVF')
legend();
2020-01-21 17:28:49 +01:00
2020-02-04 16:13:52 +01:00
ax2 = subplot(3, 1, 2);
hold on;
plot(t, En(:,5), 'DisplayName', '$\epsilon_{\theta_y}$')
plot(t, En_dvf(:,5), 'DisplayName', '$\epsilon_ {\theta_y}$ - DVF')
legend();
ylabel('Position Error [rad]');
2020-02-04 10:26:06 +01:00
2020-02-04 16:13:52 +01:00
ax3 = subplot(3, 1, 3);
hold on;
plot(t, En(:,6), 'DisplayName', '$\epsilon_{\theta_z}$')
plot(t, En_dvf(:,6), 'DisplayName', '$\epsilon_ {\theta_z}$ - DVF')
legend();
xlabel('Time [s]');
2020-01-21 17:28:49 +01:00
2020-02-04 16:13:52 +01:00
linkaxes([ax1,ax2,ax3],'x');
2020-02-06 17:07:11 +01:00
xlim([0.5,inf]);
2020-02-04 16:13:52 +01:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/nass_act_damp_dvf_sim_tomo_rot.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:nass_act_damp_dvf_sim_tomo_rot
#+caption : Position Error during tomography experiment - Rotations ([[./figs/nass_act_damp_dvf_sim_tomo_rot.png][png]], [[./figs/nass_act_damp_dvf_sim_tomo_rot.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/nass_act_damp_dvf_sim_tomo_rot.png ]]
** Conclusion
#+begin_important
2020-02-06 17:07:11 +01:00
Direct Velocity Feedback using a relative motion sensor:
- Robust (guaranteed stability)
2020-02-04 16:13:52 +01:00
#+end_important
* Inertial Control
:PROPERTIES:
:header-args:matlab+: :tangle matlab/ine.m
:header-args:matlab+: :comments none :mkdirp yes
:END:
<<sec:ine >>
** ZIP file containing the data and matlab files :ignore:
#+begin_src bash :exports none :results none
if [ matlab/ine.m -nt data/ine.zip ]; then
cp matlab/ine.m ine.m;
zip data/ine \
mat/plant.mat \
ine.m
rm ine.m;
fi
#+end_src
#+begin_note
All the files (data and Matlab scripts) are accessible [[file:data/ine.zip ][here ]].
#+end_note
** Introduction :ignore:
In Inertial Control, a feedback is applied between the measured *absolute* motion (velocity or acceleration) of the platform to the actuator force input.
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir >>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init >>
#+end_src
#+begin_src matlab :tangle no
simulinkproject('../');
#+end_src
2020-02-04 10:26:06 +01:00
2020-02-04 16:13:52 +01:00
#+begin_src matlab
addpath('active_damping/src/ ');
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-04 16:13:52 +01:00
#+begin_src matlab
2020-02-18 11:33:04 +01:00
open('nass_model.slx')
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-04 16:13:52 +01:00
** Control Design
*** Plant
Let's load the undamped plant:
#+begin_src matlab
load('./active_damping/mat/undamped_plants.mat', 'G_ine');
2020-02-06 17:07:11 +01:00
load('./active_damping/mat/plants_variable.mat', 'masses', 'Gm_ine');
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-04 16:13:52 +01:00
Let's look at the transfer function from actuator forces in the nano-hexapod to the measured velocity of the nano-hexapod platform in the direction of the corresponding actuator for all 6 pairs of actuator/sensor (figure [[fig:ine_plant ]]).
2020-01-21 17:28:49 +01:00
#+begin_src matlab :exports none
2020-02-04 16:13:52 +01:00
freqs = logspace(0, 3, 1000);
2020-01-21 17:28:49 +01:00
figure;
ax1 = subplot(2, 1, 1);
hold on;
2020-02-06 17:07:11 +01:00
for i=1:length(masses)
plot(freqs, abs(squeeze(freqresp(Gm_ine{i}('Vnlm1', 'Fnl1'), freqs, 'Hz'))));
2020-01-21 17:28:49 +01:00
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-02-06 17:07:11 +01:00
ylabel('Amplitude [(m/s)/N]'); set(gca, 'XTickLabel',[]);
2020-01-21 17:28:49 +01:00
ax2 = subplot(2, 1, 2);
hold on;
2020-02-06 17:07:11 +01:00
for i=1:length(masses)
plot(freqs, 180/pi*angle(squeeze(freqresp(Gm_ine{i}('Vnlm1', 'Fnl1'), freqs, 'Hz'))), ...
'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
2020-01-21 17:28:49 +01:00
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
2020-02-06 17:07:11 +01:00
legend('location', 'southwest');
2020-01-21 17:28:49 +01:00
linkaxes([ax1,ax2],'x');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/ine_plant.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:ine_plant
#+caption : Transfer function from forces applied in the legs to leg velocity sensor ([[./figs/ine_plant.png][png]], [[./figs/ine_plant.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/ine_plant.png ]]
2020-01-21 17:28:49 +01:00
2020-02-04 16:13:52 +01:00
*** Control Design
The controller is defined below and the obtained loop gain is shown in figure [[fig:ine_open_loop_gain ]].
2020-01-21 17:28:49 +01:00
2020-02-04 16:13:52 +01:00
#+begin_src matlab
2020-02-06 17:07:11 +01:00
K_ine = 2.5e4;
2020-01-21 17:28:49 +01:00
#+end_src
#+begin_src matlab :exports none
2020-02-04 16:13:52 +01:00
freqs = logspace(0, 3, 1000);
2020-01-21 17:28:49 +01:00
figure;
ax1 = subplot(2, 1, 1);
hold on;
2020-02-06 17:07:11 +01:00
for i=1:length(masses)
plot(freqs, abs(squeeze(freqresp(K_ine*Gm_ine{i}('Vnlm1', 'Fnl1'), freqs, 'Hz'))));
2020-01-21 17:28:49 +01:00
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-02-06 17:07:11 +01:00
ylabel('Loop Gain'); set(gca, 'XTickLabel',[]);
2020-01-21 17:28:49 +01:00
ax2 = subplot(2, 1, 2);
hold on;
2020-02-06 17:07:11 +01:00
for i=1:length(masses)
plot(freqs, 180/pi*angle(squeeze(freqresp(K_ine*Gm_ine{i}('Vnlm1', 'Fnl1'), freqs, 'Hz'))), ...
'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
2020-01-21 17:28:49 +01:00
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
2020-02-06 17:07:11 +01:00
legend('location', 'southwest');
2020-01-21 17:28:49 +01:00
linkaxes([ax1,ax2],'x');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-04 16:13:52 +01:00
#+begin_src matlab :var filepath="figs/ine_open_loop_gain.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:ine_open_loop_gain
#+caption : Loop Gain for Inertial Control ([[./figs/ine_open_loop_gain.png][png]], [[./figs/ine_open_loop_gain.pdf][pdf]])
2020-02-04 16:13:52 +01:00
[[file:figs/ine_open_loop_gain.png ]]
*** Diagonal Controller
We create the diagonal controller and we add a minus sign as we have a positive feedback architecture.
#+begin_src matlab
K_ine = -K_ine*eye(6);
#+end_src
We save the controller for further analysis.
#+begin_src matlab
save('./active_damping/mat/K_ine.mat', 'K_ine');
#+end_src
2020-02-06 17:07:11 +01:00
** Identification of the damped plant :noexport:
*** Identification
We initialize all the stages with the default parameters.
2020-02-04 16:13:52 +01:00
#+begin_src matlab
2020-02-06 17:07:11 +01:00
prepareLinearizeIdentification();
2020-02-04 16:13:52 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
We set the Inertial controller.
2020-02-04 16:13:52 +01:00
#+begin_src matlab
2020-02-06 17:07:11 +01:00
load('./active_damping/mat/K_ine.mat', 'K_ine');
2020-02-18 11:33:04 +01:00
initializeController('type', 'ine', 'K', K_ine);
2020-02-04 16:13:52 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
We identify the dynamics of the system using the =linearize= function.
2020-02-04 16:13:52 +01:00
#+begin_src matlab
2020-02-06 17:07:11 +01:00
%% Options for Linearized
options = linearizeOptions;
options.SampleTime = 0;
%% Name of the Simulink File
2020-02-18 11:33:04 +01:00
mdl = 'nass_model';
2020-02-06 17:07:11 +01:00
%% Input/Output definition
clear io; io_i = 1;
2020-02-18 13:57:55 +01:00
io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs
io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1;
2020-02-04 16:13:52 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
We identify the dynamics for the following sample mass.
2020-02-04 16:13:52 +01:00
#+begin_src matlab
2020-02-06 17:07:11 +01:00
load('./active_damping/mat/cart_plants.mat', 'masses');
2020-02-04 16:13:52 +01:00
#+end_src
2020-01-21 17:28:49 +01:00
#+begin_src matlab :exports none
2020-02-06 17:07:11 +01:00
G_cart_ine = {zeros(length(masses))};
2020-02-04 16:13:52 +01:00
2020-02-06 17:07:11 +01:00
load('mat/stages.mat', 'nano_hexapod');
2020-02-04 16:13:52 +01:00
2020-02-06 17:07:11 +01:00
for i = 1:length(masses)
initializeSample('mass', masses(i));
2020-02-04 16:13:52 +01:00
2020-02-06 17:07:11 +01:00
%% Run the linearization
G = linearize(mdl, io, 0.3, options);
G.InputName = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
G.OutputName = {'Dnx', 'Dny', 'Dnz', 'Rnx', 'Rny', 'Rnz'};
G_cart = G*inv(nano_hexapod.J');
G_cart.InputName = {'Fnx', 'Fny', 'Fnz', 'Mnx', 'Mny', 'Mnz'};
G_cart_ine(i) = {G_cart};
end
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
And we save them for further analysis.
#+begin_src matlab
save('./active_damping/mat/cart_plants.mat', 'G_cart_dvf', '-append');
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
*** Damped Plant
Now, look at the new damped plant to control.
#+begin_src matlab
load('./active_damping/mat/cart_plants.mat', 'masses', 'G_cart', 'G_cart_ine');
#+end_src
2020-02-04 16:13:52 +01:00
2020-02-06 17:07:11 +01:00
It damps the plant (resonance of the nano hexapod as well as other resonances) as shown in figure [[fig:plant_ine_damped ]].
2020-01-21 17:28:49 +01:00
#+begin_src matlab :exports none
2020-02-04 16:13:52 +01:00
freqs = logspace(0, 3, 1000);
figure;
2020-02-06 17:07:11 +01:00
ax1 = subplot(2, 1, 1);
2020-02-04 16:13:52 +01:00
hold on;
2020-02-06 17:07:11 +01:00
for i = 1:length(masses)
set(gca,'ColorOrderIndex',i);
p1 = plot(freqs, abs(squeeze(freqresp(G_cart_ine{i}('Dnx', 'Fnx'), freqs, 'Hz'))));
set(gca,'ColorOrderIndex',i);
p2 = plot(freqs, abs(squeeze(freqresp(G_cart_ine{i}('Dny', 'Fny'), freqs, 'Hz'))), '--');
set(gca,'ColorOrderIndex',i);
p3 = plot(freqs, abs(squeeze(freqresp(G_cart_ine{i}('Dnz', 'Fnz'), freqs, 'Hz'))), ':');
end
2020-02-04 16:13:52 +01:00
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); xlabel('Frequency [Hz]');
2020-02-06 17:07:11 +01:00
legend([p1,p2,p3], {'Fx/Dx', 'Fy/Dx', 'Fz/Dz'});
ax2 = subplot(2, 1, 2);
hold on;
for i = 1:length(masses)
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_ine{i}('Dnx', 'Fnx'), freqs, 'Hz')))), ...
'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_ine{i}('Dny', 'Fny'), freqs, 'Hz')))), '--', 'HandleVisibility', 'off');
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_ine{i}('Dnz', 'Fnz'), freqs, 'Hz')))), ':', 'HandleVisibility', 'off');
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
yticks([-540:180:540]);
2020-02-04 16:13:52 +01:00
legend('location', 'northeast');
2020-02-06 17:07:11 +01:00
linkaxes([ax1,ax2],'x');
2020-02-04 16:13:52 +01:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-06 17:07:11 +01:00
#+begin_src matlab :var filepath="figs/plant_ine_damped_translations.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
2020-02-04 16:13:52 +01:00
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:plant_ine_damped_translations
#+caption : Damped Plant for the translations after INE is applied ([[./figs/plant_ine_damped_translations.png][png]], [[./figs/plant_ine_damped_translations.pdf][pdf]])
[[file:figs/plant_ine_damped_translations.png ]]
2020-02-04 16:13:52 +01:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
2020-01-21 17:28:49 +01:00
figure;
2020-02-06 17:07:11 +01:00
ax1 = subplot(2, 1, 1);
2020-01-21 17:28:49 +01:00
hold on;
2020-02-06 17:07:11 +01:00
for i = 1:length(masses)
set(gca,'ColorOrderIndex',i);
p1 = plot(freqs, abs(squeeze(freqresp(G_cart_ine{i}('Rnx', 'Mnx'), freqs, 'Hz'))));
set(gca,'ColorOrderIndex',i);
p2 = plot(freqs, abs(squeeze(freqresp(G_cart_ine{i}('Rny', 'Mny'), freqs, 'Hz'))), '--');
set(gca,'ColorOrderIndex',i);
p3 = plot(freqs, abs(squeeze(freqresp(G_cart_ine{i}('Rnz', 'Mnz'), freqs, 'Hz'))), ':');
end
2020-01-21 17:28:49 +01:00
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
2020-02-04 16:13:52 +01:00
ylabel('Amplitude [m/N]'); xlabel('Frequency [Hz]');
2020-02-06 17:07:11 +01:00
legend([p1,p2,p3], {'Fx/Dx', 'Fy/Dx', 'Fz/Dz'});
2020-01-21 17:28:49 +01:00
2020-02-06 17:07:11 +01:00
ax2 = subplot(2, 1, 2);
2020-02-04 16:13:52 +01:00
hold on;
2020-02-06 17:07:11 +01:00
for i = 1:length(masses)
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_ine{i}('Rnx', 'Mnx'), freqs, 'Hz')))), ...
'DisplayName', sprintf('$M = %.0f$ [kg]', masses(i)));
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_ine{i}('Rny', 'Mny'), freqs, 'Hz')))), '--', 'HandleVisibility', 'off');
set(gca,'ColorOrderIndex',i);
plot(freqs, 180/pi*unwrap(angle(squeeze(freqresp(G_cart_ine{i}('Rnz', 'Mnz'), freqs, 'Hz')))), ':', 'HandleVisibility', 'off');
end
2020-01-21 17:28:49 +01:00
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
2020-02-06 17:07:11 +01:00
yticks([-540:180:540]);
legend('location', 'northeast');
2020-01-21 17:28:49 +01:00
2020-02-06 17:07:11 +01:00
linkaxes([ax1,ax2],'x');
2020-01-21 17:28:49 +01:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-06 17:07:11 +01:00
#+begin_src matlab :var filepath="figs/plant_ine_damped_rotations.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
2020-02-04 16:13:52 +01:00
<<plt-matlab >>
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:plant_ine_damped_rotations
#+caption : Damped Plant for the Rotations after INE is applied ([[./figs/plant_ine_damped_rotations.png][png]], [[./figs/plant_ine_damped_rotations.pdf][pdf]])
[[file:figs/plant_ine_damped_rotations.png ]]
2020-01-21 17:28:49 +01:00
#+begin_src matlab :exports none
2020-02-06 17:07:11 +01:00
freqs = logspace(1, 3, 1000);
2020-01-21 17:28:49 +01:00
figure;
2020-02-06 17:07:11 +01:00
for ix = 1:6
for iy = 1:6
subplot(6, 6, (ix-1)*6 + iy);
hold on;
plot(freqs, abs(squeeze(freqresp(G_cart{1}(ix, iy), freqs, 'Hz'))), 'k-');
plot(freqs, abs(squeeze(freqresp(G_cart_ine{1}(ix, iy), freqs, 'Hz'))), 'k--');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylim([1e-13, 1e-4]);
xticks([])
yticks([])
end
end
2020-01-21 17:28:49 +01:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
2020-02-06 17:07:11 +01:00
#+begin_src matlab :var filepath="figs/plant_ine_coupling.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
2020-01-21 17:28:49 +01:00
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:plant_ine_coupling
#+caption : Coupling induced by INE ([[./figs/plant_ine_coupling.png][png]], [[./figs/plant_ine_coupling.pdf][pdf]])
[[file:figs/plant_ine_coupling.png ]]
2020-01-21 17:28:49 +01:00
** Conclusion
2020-02-04 16:13:52 +01:00
#+begin_important
2020-02-06 17:07:11 +01:00
Inertial Control should not be used.
2020-02-04 16:13:52 +01:00
#+end_important
2020-01-21 17:28:49 +01:00
2020-02-06 17:07:11 +01:00
* TODO Comparison
2020-01-21 17:28:49 +01:00
<<sec:comparison >>
** Introduction :ignore:
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
<<matlab-dir >>
#+end_src
#+begin_src matlab :exports none :results silent :noweb yes
<<matlab-init >>
#+end_src
#+begin_src matlab
cd('../');
#+end_src
** Load the plants
#+begin_src matlab
load('./active_damping/mat/plants.mat', 'G', 'G_iff', 'G_ine', 'G_dvf');
#+end_src
2020-02-06 17:07:11 +01:00
** TODO Sensitivity to Disturbance
2020-01-21 17:28:49 +01:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
title('$D_{g,z}$ to $D_z$');
hold on;
plot(freqs, abs(squeeze(freqresp(G.G_gm( 'Dz', 'Dgz'), freqs, 'Hz'))), 'k-' , 'DisplayName', 'Undamped');
plot(freqs, abs(squeeze(freqresp(G_iff.G_gm('Dz', 'Dgz'), freqs, 'Hz'))), 'k:' , 'DisplayName', 'IFF');
plot(freqs, abs(squeeze(freqresp(G_ine.G_gm('Dz', 'Dgz'), freqs, 'Hz'))), 'k--', 'DisplayName', 'INE');
plot(freqs, abs(squeeze(freqresp(G_dvf.G_gm('Dz', 'Dgz'), freqs, 'Hz'))), 'k-.', 'DisplayName', 'DVF');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/m]'); xlabel('Frequency [Hz]');
legend('location', 'northeast');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/sensitivity_comp_ground_motion_z.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:sensitivity_comp_ground_motion_z
#+caption : Sensitivity to ground motion in the Z direction on the Z motion error ([[./figs/sensitivity_comp_ground_motion_z.png][png]], [[./figs/sensitivity_comp_ground_motion_z.pdf][pdf]])
2020-01-21 17:28:49 +01:00
[[file:figs/sensitivity_comp_ground_motion_z.png ]]
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
title('$F_{s,z}$ to $D_z$');
hold on;
plot(freqs, abs(squeeze(freqresp(G.G_fs( 'Dz', 'Fsz'), freqs, 'Hz'))), 'k-' , 'DisplayName', 'Undamped');
plot(freqs, abs(squeeze(freqresp(G_iff.G_fs('Dz', 'Fsz'), freqs, 'Hz'))), 'k:' , 'DisplayName', 'IFF');
plot(freqs, abs(squeeze(freqresp(G_ine.G_fs('Dz', 'Fsz'), freqs, 'Hz'))), 'k--', 'DisplayName', 'INE');
plot(freqs, abs(squeeze(freqresp(G_dvf.G_fs('Dz', 'Fsz'), freqs, 'Hz'))), 'k-.', 'DisplayName', 'DVF');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); xlabel('Frequency [Hz]');
legend('location', 'northeast');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/sensitivity_comp_direct_forces_z.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:sensitivity_comp_direct_forces_z
#+caption : Compliance in the Z direction: Sensitivity of direct forces applied on the sample in the Z direction on the Z motion error ([[./figs/sensitivity_comp_direct_forces_z.png][png]], [[./figs/sensitivity_comp_direct_forces_z.pdf][pdf]])
2020-01-21 17:28:49 +01:00
[[file:figs/sensitivity_comp_direct_forces_z.png ]]
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
title('$F_{rz,z}$ to $D_z$');
hold on;
plot(freqs, abs(squeeze(freqresp(G.G_dist( 'Dz', 'Frzz'), freqs, 'Hz'))), 'k-' , 'DisplayName', 'Undamped');
plot(freqs, abs(squeeze(freqresp(G_iff.G_dist('Dz', 'Frzz'), freqs, 'Hz'))), 'k:' , 'DisplayName', 'IFF');
plot(freqs, abs(squeeze(freqresp(G_ine.G_dist('Dz', 'Frzz'), freqs, 'Hz'))), 'k--', 'DisplayName', 'INE');
plot(freqs, abs(squeeze(freqresp(G_dvf.G_dist('Dz', 'Frzz'), freqs, 'Hz'))), 'k-.', 'DisplayName', 'DVF');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); xlabel('Frequency [Hz]');
legend('location', 'northeast');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/sensitivity_comp_spindle_z.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:sensitivity_comp_spindle_z
#+caption : Sensitivity to forces applied in the Z direction by the Spindle on the Z motion error ([[./figs/sensitivity_comp_spindle_z.png][png]], [[./figs/sensitivity_comp_spindle_z.pdf][pdf]])
2020-01-21 17:28:49 +01:00
[[file:figs/sensitivity_comp_spindle_z.png ]]
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
title('$F_{ty,z}$ to $D_z$');
hold on;
plot(freqs, abs(squeeze(freqresp(G.G_dist( 'Dz', 'Ftyz'), freqs, 'Hz'))), 'k-' , 'DisplayName', 'Undamped');
plot(freqs, abs(squeeze(freqresp(G_iff.G_dist('Dz', 'Ftyz'), freqs, 'Hz'))), 'k:' , 'DisplayName', 'IFF');
plot(freqs, abs(squeeze(freqresp(G_ine.G_dist('Dz', 'Ftyz'), freqs, 'Hz'))), 'k--', 'DisplayName', 'INE');
plot(freqs, abs(squeeze(freqresp(G_dvf.G_dist('Dz', 'Ftyz'), freqs, 'Hz'))), 'k-.', 'DisplayName', 'DVF');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); xlabel('Frequency [Hz]');
legend('location', 'northeast');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/sensitivity_comp_ty_z.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:sensitivity_comp_ty_z
#+caption : Sensitivity to forces applied in the Z direction by the Y translation stage on the Z motion error ([[./figs/sensitivity_comp_ty_z.png][png]], [[./figs/sensitivity_comp_ty_z.pdf][pdf]])
2020-01-21 17:28:49 +01:00
[[file:figs/sensitivity_comp_ty_z.png ]]
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
title('$F_{ty,x}$ to $D_x$');
hold on;
plot(freqs, abs(squeeze(freqresp(G.G_dist( 'Dx', 'Ftyx'), freqs, 'Hz'))), 'k-' , 'DisplayName', 'Undamped');
plot(freqs, abs(squeeze(freqresp(G_iff.G_dist('Dx', 'Ftyx'), freqs, 'Hz'))), 'k:' , 'DisplayName', 'IFF');
plot(freqs, abs(squeeze(freqresp(G_ine.G_dist('Dx', 'Ftyx'), freqs, 'Hz'))), 'k--', 'DisplayName', 'INE');
plot(freqs, abs(squeeze(freqresp(G_dvf.G_dist('Dx', 'Ftyx'), freqs, 'Hz'))), 'k-.', 'DisplayName', 'DVF');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); xlabel('Frequency [Hz]');
legend('location', 'northeast');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/sensitivity_comp_ty_x.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:sensitivity_comp_ty_x
#+caption : Sensitivity to forces applied in the X direction by the Y translation stage on the X motion error ([[./figs/sensitivity_comp_ty_x.png][png]], [[./figs/sensitivity_comp_ty_x.pdf][pdf]])
2020-01-21 17:28:49 +01:00
[[file:figs/sensitivity_comp_ty_x.png ]]
2020-02-06 17:07:11 +01:00
** TODO Damped Plant
2020-01-21 17:28:49 +01:00
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
title('$F_{n,z}$ to $D_z$');
ax1 = subplot(2, 1, 1);
hold on;
plot(freqs, abs(squeeze(freqresp(G.G_cart( 'Dz', 'Fnz'), freqs, 'Hz'))), 'k-' , 'DisplayName', 'Undamped');
plot(freqs, abs(squeeze(freqresp(G_iff.G_cart('Dz', 'Fnz'), freqs, 'Hz'))), 'k:' , 'DisplayName', 'IFF');
plot(freqs, abs(squeeze(freqresp(G_ine.G_cart('Dz', 'Fnz'), freqs, 'Hz'))), 'k--', 'DisplayName', 'INE');
plot(freqs, abs(squeeze(freqresp(G_dvf.G_cart('Dz', 'Fnz'), freqs, 'Hz'))), 'k-.', 'DisplayName', 'DVF');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
legend('location', 'northeast');
ax2 = subplot(2, 1, 2);
hold on;
plot(freqs, 180/pi*angle(squeeze(freqresp(G.G_cart ('Dz', 'Fnz'), freqs, 'Hz'))), 'k-');
plot(freqs, 180/pi*angle(squeeze(freqresp(G_iff.G_cart('Dz', 'Fnz'), freqs, 'Hz'))), 'k:');
plot(freqs, 180/pi*angle(squeeze(freqresp(G_ine.G_cart('Dz', 'Fnz'), freqs, 'Hz'))), 'k--');
plot(freqs, 180/pi*angle(squeeze(freqresp(G_dvf.G_cart('Dz', 'Fnz'), freqs, 'Hz'))), 'k-.');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
linkaxes([ax1,ax2],'x');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/plant_comp_damping_z.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:plant_comp_damping_z
#+caption : Plant for the $z$ direction for different active damping technique used ([[./figs/plant_comp_damping_z.png][png]], [[./figs/plant_comp_damping_z.pdf][pdf]])
2020-01-21 17:28:49 +01:00
[[file:figs/plant_comp_damping_z.png ]]
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
title('$F_{n,z}$ to $D_z$');
ax1 = subplot(2, 1, 1);
hold on;
plot(freqs, abs(squeeze(freqresp(G.G_cart( 'Dx', 'Fnx'), freqs, 'Hz'))), 'k-' , 'DisplayName', 'Undamped');
plot(freqs, abs(squeeze(freqresp(G_iff.G_cart('Dx', 'Fnx'), freqs, 'Hz'))), 'k:' , 'DisplayName', 'IFF');
plot(freqs, abs(squeeze(freqresp(G_ine.G_cart('Dx', 'Fnx'), freqs, 'Hz'))), 'k--', 'DisplayName', 'INE');
plot(freqs, abs(squeeze(freqresp(G_dvf.G_cart('Dx', 'Fnx'), freqs, 'Hz'))), 'k-.', 'DisplayName', 'DVF');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
legend('location', 'northeast');
ax2 = subplot(2, 1, 2);
hold on;
plot(freqs, 180/pi*angle(squeeze(freqresp(G.G_cart ('Dx', 'Fnx'), freqs, 'Hz'))), 'k-');
plot(freqs, 180/pi*angle(squeeze(freqresp(G_iff.G_cart('Dx', 'Fnx'), freqs, 'Hz'))), 'k:');
plot(freqs, 180/pi*angle(squeeze(freqresp(G_ine.G_cart('Dx', 'Fnx'), freqs, 'Hz'))), 'k--');
plot(freqs, 180/pi*angle(squeeze(freqresp(G_dvf.G_cart('Dx', 'Fnx'), freqs, 'Hz'))), 'k-.');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
linkaxes([ax1,ax2],'x');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/plant_comp_damping_x.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:plant_comp_damping_x
#+caption : Plant for the $x$ direction for different active damping technique used ([[./figs/plant_comp_damping_x.png][png]], [[./figs/plant_comp_damping_x.pdf][pdf]])
2020-01-21 17:28:49 +01:00
[[file:figs/plant_comp_damping_x.png ]]
#+begin_src matlab :exports none
freqs = logspace(0, 3, 1000);
figure;
title('$F_{n,x}$ to $R_z$');
ax1 = subplot(2, 1, 1);
hold on;
plot(freqs, abs(squeeze(freqresp(G.G_cart( 'Rz', 'Fnx'), freqs, 'Hz'))), 'k-' , 'DisplayName', 'Undamped');
plot(freqs, abs(squeeze(freqresp(G_iff.G_cart('Rz', 'Fnx'), freqs, 'Hz'))), 'k:' , 'DisplayName', 'IFF');
plot(freqs, abs(squeeze(freqresp(G_ine.G_cart('Rz', 'Fnx'), freqs, 'Hz'))), 'k--', 'DisplayName', 'INE');
plot(freqs, abs(squeeze(freqresp(G_dvf.G_cart('Rz', 'Fnx'), freqs, 'Hz'))), 'k-.', 'DisplayName', 'DVF');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
legend('location', 'northeast');
ax2 = subplot(2, 1, 2);
hold on;
plot(freqs, 180/pi*angle(squeeze(freqresp(G.G_cart ('Ry', 'Fnx'), freqs, 'Hz'))), 'k-');
plot(freqs, 180/pi*angle(squeeze(freqresp(G_iff.G_cart('Ry', 'Fnx'), freqs, 'Hz'))), 'k:');
plot(freqs, 180/pi*angle(squeeze(freqresp(G_ine.G_cart('Ry', 'Fnx'), freqs, 'Hz'))), 'k--');
plot(freqs, 180/pi*angle(squeeze(freqresp(G_dvf.G_cart('Ry', 'Fnx'), freqs, 'Hz'))), 'k-.');
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'lin');
ylabel('Phase [deg]'); xlabel('Frequency [Hz]');
ylim([-180, 180]);
yticks([-180, -90, 0, 90, 180]);
linkaxes([ax1,ax2],'x');
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/plant_comp_damping_coupling.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:plant_comp_damping_coupling
#+caption : Comparison of one off-diagonal plant for different damping technique applied ([[./figs/plant_comp_damping_coupling.png][png]], [[./figs/plant_comp_damping_coupling.pdf][pdf]])
2020-01-21 17:28:49 +01:00
[[file:figs/plant_comp_damping_coupling.png ]]
2020-02-06 17:07:11 +01:00
** Tomography Experiment - Frequency Domain analysis
2020-01-21 17:28:49 +01:00
#+begin_src matlab
2020-02-06 17:07:11 +01:00
load('./active_damping/mat/tomo_exp.mat', 'En', 'En_iff', 'En_dvf');
Fs = 1e3; % Sampling Frequency of the Data
t = (1/Fs)*[0:length(En(:,1))-1];
#+end_src
We remove the first 0.5 seconds where the transient behavior is fading out.
#+begin_src matlab
[~, i_start] = min(abs(t - 0.5)); % find the indice corresponding to 0.5s
t = t(i_start:end) - t(i_start);
En = En(i_start:end, :);
En_dvf = En_dvf(i_start:end, :);
En_iff = En_iff(i_start:end, :);
2020-01-21 17:28:49 +01:00
#+end_src
Window used for =pwelch= function.
#+begin_src matlab
2020-02-06 17:07:11 +01:00
n_av = 4;
2020-01-20 17:36:30 +01:00
han_win = hanning(ceil(length(En(:, 1))/n_av));
2020-01-15 16:23:40 +01:00
#+end_src
2020-01-20 17:36:30 +01:00
#+begin_src matlab :exports none
2020-01-20 17:20:50 +01:00
Ts = t(2)-t(1); % Sample Time for the Data [s]
2020-01-15 16:23:40 +01:00
2020-01-20 17:20:50 +01:00
[pxx, f] = pwelch(En(:, 1), han_win, [], [], 1/Ts);
[pxx_dvf, ~] = pwelch(En_dvf(:, 1), han_win, [], [], 1/Ts);
[pxx_iff, ~] = pwelch(En_iff(:, 1), han_win, [], [], 1/Ts);
[pyy, ~] = pwelch(En(:, 2), han_win, [], [], 1/Ts);
[pyy_dvf, ~] = pwelch(En_dvf(:, 2), han_win, [], [], 1/Ts);
[pyy_iff, ~] = pwelch(En_iff(:, 2), han_win, [], [], 1/Ts);
[pzz, ~] = pwelch(En(:, 3), han_win, [], [], 1/Ts);
[pzz_dvf, ~] = pwelch(En_dvf(:, 3), han_win, [], [], 1/Ts);
[pzz_iff, ~] = pwelch(En_iff(:, 3), han_win, [], [], 1/Ts);
[prx, ~] = pwelch(En(:, 4), han_win, [], [], 1/Ts);
[prx_dvf, ~] = pwelch(En_dvf(:, 4), han_win, [], [], 1/Ts);
[prx_iff, ~] = pwelch(En_iff(:, 4), han_win, [], [], 1/Ts);
[pry, ~] = pwelch(En(:, 5), han_win, [], [], 1/Ts);
[pry_dvf, ~] = pwelch(En_dvf(:, 5), han_win, [], [], 1/Ts);
[pry_iff, ~] = pwelch(En_iff(:, 5), han_win, [], [], 1/Ts);
[prz, ~] = pwelch(En(:, 6), han_win, [], [], 1/Ts);
[prz_dvf, ~] = pwelch(En_dvf(:, 6), han_win, [], [], 1/Ts);
[prz_iff, ~] = pwelch(En_iff(:, 6), han_win, [], [], 1/Ts);
#+end_src
2020-01-20 17:36:30 +01:00
#+begin_src matlab :exports none
figure;
hold on;
plot(f, pxx_dvf, 'DisplayName', 'DVF')
plot(f, pxx_iff, 'DisplayName', 'IFF')
plot(f, pxx, 'k--', 'DisplayName', 'Undamped')
hold off;
xlabel('Frequency [Hz]');
ylabel('Power Spectral Density [$m^2/Hz$]');
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
legend('location', 'northeast');
2020-02-06 17:07:11 +01:00
xlim([1, 500]);
2020-01-20 17:36:30 +01:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/act_damp_tomo_exp_comp_psd_trans.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_tomo_exp_comp_psd_trans
#+caption : PSD of the translation errors in the X direction for applied Active Damping techniques ([[./figs/act_damp_tomo_exp_comp_psd_trans.png][png]], [[./figs/act_damp_tomo_exp_comp_psd_trans.pdf][pdf]])
2020-01-20 17:36:30 +01:00
[[file:figs/act_damp_tomo_exp_comp_psd_trans.png ]]
#+begin_src matlab :exports none
2020-01-20 17:20:50 +01:00
figure;
hold on;
plot(f, prx_dvf, 'DisplayName', 'DVF')
plot(f, prx_iff, 'DisplayName', 'IFF')
plot(f, prx, 'k--', 'DisplayName', 'Undamped')
hold off;
xlabel('Frequency [Hz]');
2020-01-21 17:28:49 +01:00
ylabel('Power Spectral Density [$rad^2/Hz$]');
2020-01-20 17:20:50 +01:00
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
legend('location', 'northeast');
2020-02-06 17:07:11 +01:00
xlim([1, 500]);
2020-01-20 17:20:50 +01:00
#+end_src
2020-01-20 17:36:30 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/act_damp_tomo_exp_comp_psd_rot.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_tomo_exp_comp_psd_rot
#+caption : PSD of the rotation errors in the X direction for applied Active Damping techniques ([[./figs/act_damp_tomo_exp_comp_psd_rot.png][png]], [[./figs/act_damp_tomo_exp_comp_psd_rot.pdf][pdf]])
2020-01-20 17:36:30 +01:00
[[file:figs/act_damp_tomo_exp_comp_psd_rot.png ]]
#+begin_src matlab :exports none
2020-01-20 17:20:50 +01:00
figure;
hold on;
2020-01-20 17:36:30 +01:00
plot(f, flip(-cumtrapz(flip(f), flip(pxx_dvf))), 'DisplayName', 'DVF')
plot(f, flip(-cumtrapz(flip(f), flip(pxx_iff))), 'DisplayName', 'IFF')
plot(f, flip(-cumtrapz(flip(f), flip(pxx))), 'k--', 'DisplayName', 'Undamped')
hold off;
xlabel('Frequency [Hz]');
2020-01-21 17:28:49 +01:00
ylabel('Cumulative Power Spectrum [$m^2$]');
2020-01-20 17:36:30 +01:00
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
legend('location', 'northeast');
2020-02-06 17:07:11 +01:00
xlim([1, 500]);
2020-01-20 17:36:30 +01:00
#+end_src
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/act_damp_tomo_exp_comp_cps_trans.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_tomo_exp_comp_cps_trans
#+caption : CPS of the translation errors in the X direction for applied Active Damping techniques ([[./figs/act_damp_tomo_exp_comp_cps_trans.png][png]], [[./figs/act_damp_tomo_exp_comp_cps_trans.pdf][pdf]])
2020-01-20 17:36:30 +01:00
[[file:figs/act_damp_tomo_exp_comp_cps_trans.png ]]
#+begin_src matlab :exports none
figure;
hold on;
plot(f, flip(-cumtrapz(flip(f), flip(prx_dvf))), 'DisplayName', 'DVF')
plot(f, flip(-cumtrapz(flip(f), flip(prx_iff))), 'DisplayName', 'IFF')
plot(f, flip(-cumtrapz(flip(f), flip(prx))), 'k--', 'DisplayName', 'Undamped')
2020-01-20 17:20:50 +01:00
hold off;
xlabel('Frequency [Hz]');
2020-01-21 17:28:49 +01:00
ylabel('Cumulative Power Spectrum [$rad^2$]');
2020-01-20 17:20:50 +01:00
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
legend('location', 'northeast');
2020-02-06 17:07:11 +01:00
xlim([1, 400]);
2020-01-15 16:23:40 +01:00
#+end_src
2020-01-20 17:36:30 +01:00
#+HEADER : :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/act_damp_tomo_exp_comp_cps_rot.pdf" :var figsize= "full-tall" :post pdf2svg(file=*this*, ext= "png")
<<plt-matlab >>
#+end_src
2020-02-06 17:07:11 +01:00
#+name : fig:act_damp_tomo_exp_comp_cps_rot
#+caption : CPS of the rotation errors in the X direction for applied Active Damping techniques ([[./figs/act_damp_tomo_exp_comp_cps_rot.png][png]], [[./figs/act_damp_tomo_exp_comp_cps_rot.pdf][pdf]])
2020-01-20 17:36:30 +01:00
[[file:figs/act_damp_tomo_exp_comp_cps_rot.png ]]
2020-01-15 16:23:40 +01:00
* Useful Functions
2020-02-06 17:07:11 +01:00
** prepareLinearizeIdentification
:PROPERTIES:
:header-args:matlab+: :tangle src/prepareLinearizeIdentification.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:prepareLinearizeIdentification >>
This Matlab function is accessible [[file:src/prepareLinearizeIdentification.m ][here ]].
*** Function Description
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
function [] = prepareLinearizeIdentification(args)
#+end_src
*** Optional Parameters
:PROPERTIES:
:UNNUMBERED: t
:END:
#+begin_src matlab
arguments
args.nass_actuator char {mustBeMember(args.nass_actuator,{'piezo', 'lorentz'})} = 'piezo'
args.sample_mass (1,1) double {mustBeNumeric, mustBePositive} = 50 % [kg]
end
#+end_src
*** Initialize the Simulation
:PROPERTIES:
:UNNUMBERED: t
:END:
We initialize all the stages with the default parameters.
#+begin_src matlab
initializeGround();
initializeGranite();
initializeTy();
initializeRy();
initializeRz();
initializeMicroHexapod();
initializeAxisc();
initializeMirror();
#+end_src
The nano-hexapod is a piezoelectric hexapod and the sample has a mass of 50kg.
#+begin_src matlab
initializeNanoHexapod('actuator', args.nass_actuator);
initializeSample('mass', args.sample_mass);
#+end_src
We set the references and disturbances to zero.
#+begin_src matlab
initializeReferences();
initializeDisturbances('enable', false);
#+end_src
2020-02-18 11:33:04 +01:00
We set the controller type to Open-Loop.
2020-02-06 17:07:11 +01:00
#+begin_src matlab
2020-02-18 11:33:04 +01:00
initializeController('type', 'open-loop');
#+end_src
And we put some gravity.
#+begin_src matlab
initializeSimscapeConfiguration('gravity', true);
#+end_src
We do not need to log any signal.
#+begin_src matlab
initializeLoggingConfiguration('log', 'none');
2020-02-06 17:07:11 +01:00
#+end_src
2020-01-15 16:23:40 +01:00
** prepareTomographyExperiment
:PROPERTIES:
:header-args:matlab+: :tangle src/prepareTomographyExperiment.m
:header-args:matlab+: :comments none :mkdirp yes :eval no
:END:
<<sec:prepareTomographyExperiment >>
This Matlab function is accessible [[file:src/prepareTomographyExperiment.m ][here ]].
*** Function Description
2020-01-20 17:20:50 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-01-15 16:23:40 +01:00
#+begin_src matlab
function [] = prepareTomographyExperiment(args)
#+end_src
*** Optional Parameters
2020-01-20 17:20:50 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-01-15 16:23:40 +01:00
#+begin_src matlab
arguments
args.nass_actuator char {mustBeMember(args.nass_actuator,{'piezo', 'lorentz'})} = 'piezo'
2020-02-04 18:36:27 +01:00
args.sample_mass (1,1) double {mustBeNumeric, mustBePositive} = 50 % [kg]
args.Rz_period (1,1) double {mustBeNumeric, mustBePositive} = 1 % [s]
2020-01-15 16:23:40 +01:00
end
#+end_src
*** Initialize the Simulation
2020-01-20 17:20:50 +01:00
:PROPERTIES:
:UNNUMBERED: t
:END:
2020-01-15 16:23:40 +01:00
We initialize all the stages with the default parameters.
#+begin_src matlab
2019-10-25 16:02:23 +02:00
initializeGround();
initializeGranite();
initializeTy();
initializeRy();
initializeRz();
initializeMicroHexapod();
initializeAxisc();
initializeMirror();
#+end_src
2020-01-15 16:23:40 +01:00
The nano-hexapod is a piezoelectric hexapod and the sample has a mass of 50kg.
#+begin_src matlab
initializeNanoHexapod('actuator', args.nass_actuator);
initializeSample('mass', args.sample_mass);
#+end_src
2020-02-05 13:36:41 +01:00
We set the references that corresponds to a tomography experiment.
2020-01-15 16:23:40 +01:00
#+begin_src matlab
2020-02-04 18:36:27 +01:00
initializeReferences('Rz_type', 'rotating', 'Rz_period', args.Rz_period);
2020-01-15 16:23:40 +01:00
#+end_src
2020-02-05 13:36:41 +01:00
#+begin_src matlab
initializeDisturbances();
#+end_src
2020-02-18 11:33:04 +01:00
Open Loop.
#+begin_src matlab
initializeController('type', 'open-loop');
#+end_src
And we put some gravity.
#+begin_src matlab
initializeSimscapeConfiguration('gravity', true);
#+end_src
We log the signals.
2019-10-25 16:02:23 +02:00
#+begin_src matlab
2020-02-18 11:33:04 +01:00
initializeLoggingConfiguration('log', 'all');
2019-10-25 16:02:23 +02:00
#+end_src