Update huddle test analysis

This commit is contained in:
Thomas Dehaeze 2019-09-20 09:25:34 +02:00
parent af603e4e4a
commit 3e77b37759
7 changed files with 894 additions and 558 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

BIN
figs/huddle_test_4qd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

BIN
figs/huddle_test_Va.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
figs/huddle_test_psd_va.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

1017
index.html

File diff suppressed because it is too large Load Diff

435
index.org
View File

@ -1791,73 +1791,27 @@ The file =mat/plant.mat= is accessible [[./mat/plant.mat][here]].
save('mat/plant.mat', 'sys', 'Gi', 'Zc', 'Ga', 'Gc', 'Gn', 'Gd');
#+end_src
* Active Damping
** 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
freqs = logspace(1, 3, 1000);
#+end_src
** Load Plant
#+begin_src matlab
load('mat/plant.mat', 'sys', 'Gi', 'Zc', 'Ga', 'Gc', 'Gn', 'Gd');
#+end_src
** Test
#+begin_src matlab
bode(sys({'Vch', 'Vcv'}, {'Uch', 'Ucv'}));
#+end_src
#+begin_src matlab
Kppf = blkdiag(-10000/s, tf(0));
Kppf.InputName = {'Vch', 'Vcv'};
Kppf.OutputName = {'Uch', 'Ucv'};
#+end_src
#+begin_src matlab :exports none
figure;
% Magnitude
ax1 = subaxis(2,1,1);
hold on;
plot(freqs, abs(squeeze(freqresp(G, freqs, 'Hz'))), 'k-');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
set(gca, 'XTickLabel',[]);
ylabel('Magnitude [dB]');
hold off;
% Phase
ax2 = subaxis(2,1,2);
hold on;
plot(freqs, 180/pi*angle(squeeze(freqresp(G, freqs, 'Hz'))), 'k-');
set(gca,'xscale','log');
yticks(-360:90:180);
ylim([-360 0]);
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
#+end_src
#+begin_src matlab
inputs = {'Uch', 'Ucv', 'Unh', 'Unv'};
outputs = {'Ich', 'Icv', 'Rh', 'Rv', 'Vph', 'Vpv'};
sys_cl = connect(sys, Kppf, inputs, outputs);
figure; bode(sys_cl({'Vph', 'Vpv'}, {'Uch', 'Ucv'}), sys({'Vph', 'Vpv'}, {'Uch', 'Ucv'}))
#+end_src
* Huddle Test
:PROPERTIES:
:header-args:matlab+: :tangle matlab/huddle_test.m
:header-args:matlab+: :comments org :mkdirp yes
:END:
<<sec:huddle_test>>
** Introduction :ignore:
The goal is to determine the noise of the photodiodes as well as the noise of the Attocube interferometer.
Multiple measurements are done with different experimental configuration as follow:
#+name: tab:huddle_tests
#+caption: Experimental Configuration for the various Huddle test
| Number | OL/CL | Compensation Unit | Aluminum |
|--------+-------------+-------------------+----------|
| 1 | Open Loop | | |
| 2 | Open Loop | Compensation Unit | |
| 3 | Closed Loop | Compensation Unit | |
| 4 | Open Loop | Compensation Unit | Aluminum |
| 5 | Closed Loop | Compensation Unit | Aluminum |
** 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>>
@ -1867,103 +1821,227 @@ The file =mat/plant.mat= is accessible [[./mat/plant.mat][here]].
<<matlab-init>>
#+end_src
** Load data
We load the data taken during the Huddle Test.
** Load Data
#+begin_src matlab
load('mat/data_huddle_test.mat', ...
't', 'Uch', 'Ucv', ...
'Unh', 'Unv', ...
'Vph', 'Vpv', ...
'Vch', 'Vcv', ...
'Vnh', 'Vnv', ...
'Va');
ht_1 = load('./mat/data_huddle_test_1.mat', 't', 'Vph', 'Vpv', 'Va');
ht_2 = load('./mat/data_huddle_test_2.mat', 't', 'Vph', 'Vpv', 'Va');
ht_3 = load('./mat/data_huddle_test_3.mat', 't', 'Uch', 'Ucv', 'Vph', 'Vpv', 'Va');
ht_4 = load('./mat/data_huddle_test_4.mat', 't', 'Vph', 'Vpv', 'Va');
% ht_5 = load('./mat/data_huddle_test_5.mat', 't', 'Uch', 'Ucv', 'Vph', 'Vpv', 'Va');
#+end_src
#+begin_src matlab
fs = 1e4;
#+end_src
** Pre-processing
We remove the first second of data where everything is settling down.
#+begin_src matlab
t0 = 1;
t0 = 1; % [s]
Uch(t<t0) = [];
Ucv(t<t0) = [];
Unh(t<t0) = [];
Unv(t<t0) = [];
Vph(t<t0) = [];
Vpv(t<t0) = [];
Vch(t<t0) = [];
Vcv(t<t0) = [];
Vnh(t<t0) = [];
Vnv(t<t0) = [];
Va(t<t0) = [];
t(t<t0) = [];
tend = 100; % [s]
t = t - t(1); % We start at t=0
ht_s = {ht_1 ht_2 ht_3 ht_4}
for i = 1:length(ht_s)
ht_s{i}.Vph(ht_s{i}.t<t0) = [];
ht_s{i}.Vpv(ht_s{i}.t<t0) = [];
ht_s{i}.Va(ht_s{i}.t<t0) = [];
ht_s{i}.t(ht_s{i}.t<t0) = [];
ht_s{i}.t = ht_s{i}.t - ht_s{i}.t(1); % We start at t=0
ht_s{i}.Vph(tend*fs+1:end) = [];
ht_s{i}.Vpv(tend*fs+1:end) = [];
ht_s{i}.Va(tend*fs+1:end) = [];
ht_s{i}.t(tend*fs+1:end) = [];
ht_s{i}.Va = ht_s{i}.Va - mean(ht_s{i}.Va);
end
ht_1 = ht_s{1};
ht_2 = ht_s{2};
ht_3 = ht_s{3};
ht_4 = ht_s{4};
#+end_src
** Time Domain Data
** Time domain plots
#+begin_src matlab :exports none
figure;
ax1 = subaxis(2, 2, 1)
hold on;
plot(t, Uch, 'DisplayName', '$Vp_h$');
plot(t, Ucv, 'DisplayName', '$Vp_v$');
plot(ht_1.t, 1e9*ht_1.Va);
hold off;
ylabel('Displacement [nm]');
set(gca, 'XTickLabel',[]);
title('OL');
ax2 = subaxis(2, 2, 2)
hold on;
plot(ht_2.t, 1e9*ht_2.Va);
hold off;
set(gca, 'XTickLabel',[]);
set(gca, 'YTickLabel',[]);
title('OL + CU');
ax3 = subaxis(2, 2, 3)
hold on;
plot(ht_3.t, 1e9*ht_3.Va);
hold off;
xlabel('Time [s]');
ylabel('Amplitude [V]');
xlim([t(1), t(end)]);
legend();
ylabel('Displacement [nm]');
title('CL + CU');
ax4 = subaxis(2, 2, 4)
hold on;
plot(ht_4.t, 1e9*ht_4.Va);
hold off;
xlabel('Time [s]');
set(gca, 'YTickLabel',[]);
title('OL + CU + AL');
linkaxes([ax1 ax2 ax3 ax4], 'xy');
#+end_src
We compute the Power Spectral Density of the horizontal and vertical positions of the beam as measured by the 4 quadrant diode.
#+HEADER: :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/huddle_test_Va.pdf" :var figsize="full-tall" :post pdf2svg(file=*this*, ext="png")
<<plt-matlab>>
#+end_src
#+NAME: fig:huddle_test_Va
#+CAPTION: Measurement of the Attocube during Huddle Test ([[./figs/huddle_test_Va.png][png]], [[./figs/huddle_test_Va.pdf][pdf]])
[[file:figs/huddle_test_Va.png]]
#+begin_src matlab :exports none
figure;
ax1 = subaxis(2, 2, 1)
hold on;
plot(ht_1.t, ht_1.Vph);
plot(ht_1.t, ht_1.Vpv);
hold off;
ylabel('Voltage [V]');
set(gca, 'XTickLabel',[]);
title('OL');
ax2 = subaxis(2, 2, 2)
hold on;
plot(ht_2.t, ht_2.Vph);
plot(ht_2.t, ht_2.Vpv);
hold off;
set(gca, 'XTickLabel',[]);
set(gca, 'YTickLabel',[]);
title('OL + CU');
ax3 = subaxis(2, 2, 3)
hold on;
plot(ht_3.t, ht_3.Vph);
plot(ht_3.t, ht_3.Vpv);
hold off;
xlabel('Time [s]');
ylabel('Voltage [V]');
title('CL + CU');
ax4 = subaxis(2, 2, 4)
hold on;
plot(ht_4.t, ht_4.Vph);
plot(ht_4.t, ht_4.Vpv);
hold off;
xlabel('Time [s]');
set(gca, 'YTickLabel',[]);
title('OL + CU + AL');
linkaxes([ax1 ax2 ax3 ax4], 'xy');
#+end_src
#+HEADER: :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/huddle_test_4qd.pdf" :var figsize="full-tall" :post pdf2svg(file=*this*, ext="png")
<<plt-matlab>>
#+end_src
#+NAME: fig:huddle_test_4qd
#+CAPTION: Measurement of the 4QD during the Huddle tests ([[./figs/huddle_test_4qd.png][png]], [[./figs/huddle_test_4qd.pdf][pdf]])
[[file:figs/huddle_test_4qd.png]]
** Power Spectral Density
#+begin_src matlab
[psd_Vph, f] = pwelch(Vph, hanning(ceil(1*fs)), [], [], fs);
[psd_Vpv, ~] = pwelch(Vpv, hanning(ceil(1*fs)), [], [], fs);
win = hanning(ceil(1*fs));
#+end_src
#+begin_src matlab
[psd_Va1, f] = pwelch(ht_1.Va, win, [], [], fs);
[psd_Va2, ~] = pwelch(ht_2.Va, win, [], [], fs);
[psd_Va3, ~] = pwelch(ht_3.Va, win, [], [], fs);
[psd_Va4, ~] = pwelch(ht_4.Va, win, [], [], fs);
#+end_src
#+begin_src matlab
[psd_Vph1, ~] = pwelch(ht_1.Vph, win, [], [], fs);
[psd_Vph2, ~] = pwelch(ht_2.Vph, win, [], [], fs);
[psd_Vph3, ~] = pwelch(ht_3.Vph, win, [], [], fs);
[psd_Vph4, ~] = pwelch(ht_4.Vph, win, [], [], fs);
#+end_src
#+begin_src matlab
[psd_Vpv1, ~] = pwelch(ht_1.Vpv, win, [], [], fs);
[psd_Vpv2, ~] = pwelch(ht_2.Vpv, win, [], [], fs);
[psd_Vpv3, ~] = pwelch(ht_3.Vpv, win, [], [], fs);
[psd_Vpv4, ~] = pwelch(ht_4.Vpv, win, [], [], fs);
#+end_src
#+begin_src matlab :exports none
figure;
hold on;
plot(f, sqrt(psd_Vph), 'DisplayName', '$\Gamma_{Vp_h}$');
plot(f, sqrt(psd_Vpv), 'DisplayName', '$\Gamma_{Vp_v}$');
plot(f, sqrt(psd_Va1), 'DisplayName', 'OL');
plot(f, sqrt(psd_Va2), 'DisplayName', 'OL + CU');
plot(f, sqrt(psd_Va3), 'DisplayName', 'CL + CU');
plot(f, sqrt(psd_Va4), 'DisplayName', 'OL + CU + AL');
hold off;
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD $\left[\frac{V}{\sqrt{Hz}}\right]$')
legend('Location', 'southwest');
xlabel('Frequency [Hz]');
ylabel('ASD $\left[\frac{m}{\sqrt{Hz}}\right]$');
legend('location', 'northeast');
xlim([1, 1000]);
#+end_src
#+begin_src matlab :exports none
figure;
hold on;
plot(t, Vch, 'DisplayName', '$Vc_h$');
plot(t, Vcv, 'DisplayName', '$Vc_v$');
hold off;
xlabel('Time [s]');
ylabel('Amplitude [V]');
xlim([t(1), t(end)]);
legend();
#+HEADER: :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/huddle_test_psd_va.pdf" :var figsize="full-tall" :post pdf2svg(file=*this*, ext="png")
<<plt-matlab>>
#+end_src
We compute the Power Spectral Density of the voltage across the inductance used for horizontal and vertical positioning of the Cercalo.
#+begin_src matlab
[psd_Vch, f] = pwelch(Vch, hanning(ceil(1*fs)), [], [], fs);
[psd_Vcv, ~] = pwelch(Vcv, hanning(ceil(1*fs)), [], [], fs);
#+end_src
#+NAME: fig:huddle_test_psd_va
#+CAPTION: PSD of the Interferometer measurement during Huddle tests ([[./figs/huddle_test_psd_va.png][png]], [[./figs/huddle_test_psd_va.pdf][pdf]])
[[file:figs/huddle_test_psd_va.png]]
#+begin_src matlab :exports none
figure;
hold on;
plot(f, sqrt(psd_Vch), 'DisplayName', '$\Gamma_{Vc_h}$');
plot(f, sqrt(psd_Vcv), 'DisplayName', '$\Gamma_{Vc_v}$');
plot(f, sqrt(psd_Vph1), 'DisplayName', 'OL');
plot(f, sqrt(psd_Vph2), 'DisplayName', 'OL + CU');
plot(f, sqrt(psd_Vph3), 'DisplayName', 'CL + CU');
plot(f, sqrt(psd_Vph4), 'DisplayName', 'OL + CU + AL');
hold off;
set(gca, 'xscale', 'log'); set(gca, 'yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('ASD $\left[\frac{V}{\sqrt{Hz}}\right]$')
legend('Location', 'southwest');
xlabel('Frequency [Hz]');
ylabel('ASD $\left[\frac{m}{\sqrt{Hz}}\right]$');
legend('location', 'northeast');
xlim([1, 1000]);
#+end_src
#+HEADER: :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/huddle_test_4qd_psd.pdf" :var figsize="full-tall" :post pdf2svg(file=*this*, ext="png")
<<plt-matlab>>
#+end_src
#+NAME: fig:huddle_test_4qd_psd
#+CAPTION: PSD of the 4QD signal during Huddle tests ([[./figs/huddle_test_4qd_psd.png][png]], [[./figs/huddle_test_4qd_psd.pdf][pdf]])
[[file:figs/huddle_test_4qd_psd.png]]
** Conclusion
The Attocube's "Environmental Compensation Unit" does not have a significant effect on the stability of the measurement.
* Budget Error
<<sec:budget_error>>
** Introduction :ignore:
*Goals*:
- List all sources of error and compute their effects on the Attocube measurement
@ -2039,7 +2117,7 @@ The geometrical parameters of the setup are defined below.
#+end_src
#+NAME: fig:angle_error_schematic_cercalo
#+CAPTION: Caption
#+CAPTION: Schematic of the geometry used to evaluate the effect of $\delta \theta_c$ on the measured distance $\delta L$
#+RESULTS:
[[file:figs/angle_error_schematic_cercalo.png]]
@ -2554,16 +2632,21 @@ This corresponds to a measurement error of the Attocube equals to (in [m])
#+end_important
* Plant Scaling
| | Value | Unit | |
|------------------------+-------+-------------+----------|
| Expected perturbations | 1 | [V] | $U_n$ |
| Maximum input usage | 10 | [V] | $U_c$ |
| Maximum wanted error | 10 | [$\mu rad$] | $\theta$ |
| Measured noise | 5 | [$\mu rad$] | |
<<sec:plant_scaling>>
** Introduction :ignore:
The goal is the scale the plant prior to control synthesis.
This will simplify the choice of weighting functions and will yield useful insight on the controllability of the plant.
** General Configuration
#+name: tab:plant_scaling_values
#+caption: Maximum wanted values for various signals
| | Value | Unit | Variable Name |
|------------------------+-------+-------------+---------------|
| Expected perturbations | 1 | [V] | $U_n$ |
| Maximum input usage | 10 | [V] | $U_c$ |
| Maximum wanted error | 10 | [$\mu rad$] | $\theta$ |
| Measured noise | 5 | [$\mu rad$] | |
* Control Objective
** Control Objective
The maximum expected stroke is $y_\text{max} = 3mm \approx 5e^{-2} rad$ at $1Hz$.
The maximum wanted error is $e_\text{max} = 10 \mu rad$.
@ -2576,8 +2659,17 @@ Thus, we require the sensitivity function at $\omega_0 = 1\text{ Hz}$:
In terms of loop gain, this is equivalent to:
\[ |L(j\omega_0)| > 5 \cdot 10^{3} \]
** General Configuration
The plant is put in a general configuration as shown in Fig. [[fig:general_control_names]].
#+name: fig:general_control_names
#+caption: General Control Configuration
[[file:figs/general_control_names.png]]
* Plant Analysis
** Matlab Init :noexport:ignore:
<<sec:plant_analysis>>
** 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
@ -2629,17 +2721,90 @@ In terms of loop gain, this is equivalent to:
G0 = freqresp(G, 0);
#+end_src
* Active Damping
:PROPERTIES:
:header-args:matlab+: :tangle matlab/active_damping.m
:header-args:matlab+: :comments org :mkdirp yes
:END:
<<sec:active_damping>>
** 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
freqs = logspace(1, 3, 1000);
#+end_src
** Load Plant
#+begin_src matlab
load('mat/plant.mat', 'sys', 'Gi', 'Zc', 'Ga', 'Gc', 'Gn', 'Gd');
#+end_src
** Integral Force Feedback
#+begin_src matlab
bode(sys({'Vch', 'Vcv'}, {'Uch', 'Ucv'}));
#+end_src
#+begin_src matlab
Kppf = blkdiag(-10000/s, tf(0));
Kppf.InputName = {'Vch', 'Vcv'};
Kppf.OutputName = {'Uch', 'Ucv'};
#+end_src
#+begin_src matlab :exports none
figure;
% Magnitude
ax1 = subaxis(2,1,1);
hold on;
plot(freqs, abs(squeeze(freqresp(G, freqs, 'Hz'))), 'k-');
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
set(gca, 'XTickLabel',[]);
ylabel('Magnitude [dB]');
hold off;
% Phase
ax2 = subaxis(2,1,2);
hold on;
plot(freqs, 180/pi*angle(squeeze(freqresp(G, freqs, 'Hz'))), 'k-');
set(gca,'xscale','log');
yticks(-360:90:180);
ylim([-360 0]);
xlabel('Frequency [Hz]'); ylabel('Phase [deg]');
hold off;
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
#+end_src
#+begin_src matlab
inputs = {'Uch', 'Ucv', 'Unh', 'Unv'};
outputs = {'Ich', 'Icv', 'Rh', 'Rv', 'Vph', 'Vpv'};
sys_cl = connect(sys, Kppf, inputs, outputs);
figure; bode(sys_cl({'Vph', 'Vpv'}, {'Uch', 'Ucv'}), sys({'Vph', 'Vpv'}, {'Uch', 'Ucv'}))
#+end_src
** Conclusion
Active damping does not seems to be applicable here.
* Decentralized Control of the Cercalo
:PROPERTIES:
:header-args:matlab+: :tangle matlab/decentralized_control.m
:header-args:matlab+: :comments org :mkdirp yes
:END:
<<sec:decentralized_control>>
** Introduction :ignore:
In this section, we try to implement a simple decentralized controller.
** ZIP file containing the data and matlab files :ignore:
** ZIP file containing the data and matlab files :ignore:
#+begin_src bash :exports none :results none
if [ matlab/decentralized_control.m -nt data/decentralized_control.zip ]; then
cp matlab/decentralized_control.m decentralized_control.m;
@ -2767,6 +2932,7 @@ The diagonal controller is accessible [[./mat/K_diag.mat][here]].
#+end_src
* Newport Control
<<sec:newport_control>>
** Introduction :ignore:
In this section, we try to implement a simple decentralized controller for the Newport.
This can be used to align the 4QD:
@ -2843,6 +3009,7 @@ The controllers can be downloaded [[./mat/K_newport.mat][here]].
#+end_src
* Measurement of the non-repeatability
<<sec:non_rep_meas>>
** Introduction :ignore:
- Explanation of the procedure