Identification of Piezo parameters

This commit is contained in:
Thomas Dehaeze 2020-11-24 13:56:38 +01:00
parent 09eea08de1
commit ff9a33f2c3
14 changed files with 1321 additions and 1017 deletions

BIN
figs/APA95ML_nodes_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

BIN
figs/APA95ML_nodes_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 119 KiB

BIN
figs/gain_Va_to_Vs.pdf Normal file

Binary file not shown.

BIN
figs/gain_Va_to_Vs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
figs/gain_Va_to_d.pdf Normal file

Binary file not shown.

BIN
figs/gain_Va_to_d.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

1545
index.html

File diff suppressed because it is too large Load Diff

793
index.org
View File

@ -67,18 +67,442 @@ Here are the equipment used in the test bench:
- Low Noise Voltage Preamplifier from Ametek ([[file:doc/model_5113.pdf][doc]])
#+end_note
* Estimation of electrical/mechanical relationships
** Introduction :ignore:
In order to correctly model the piezoelectric actuator with Simscape, we need to determine:
1. $g_a$: the ratio of the generated force $F_a$ to the supply voltage $V_a$ across the piezoelectric stack
2. $g_s$: the ratio of the generated voltage $V_s$ across the piezoelectric stack when subject to a strain $\Delta h$
We estimate $g_a$ and $g_s$ using different approaches:
1. Section [[sec:estimation_datasheet]]: $g_a$ is estimated from the datasheet of the piezoelectric stack
2. Section [[sec:estimation_piezo_params]]: $g_a$ and $g_s$ are estimated using the piezoelectric constants
3. Section [[sec:estimation_identification]]: $g_a$ and $g_s$ are estimated experimentally
** 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
addpath('./matlab/mat/');
addpath('./matlab/');
#+end_src
#+begin_src matlab :eval no
addpath('./mat/');
#+end_src
** Estimation from Data-sheet
<<sec:estimation_datasheet>>
The stack parameters taken from the data-sheet are shown in Table [[tab:stack_parameters]].
#+name: tab:stack_parameters
#+caption: Stack Parameters
| Parameter | Unit | Value |
|----------------+-----------+----------|
| Nominal Stroke | $\mu m$ | 20 |
| Blocked force | $N$ | 4700 |
| Stiffness | $N/\mu m$ | 235 |
| Voltage Range | $V$ | -20..150 |
| Capacitance | $\mu F$ | 4.4 |
| Length | $mm$ | 20 |
| Stack Area | $mm^2$ | 10x10 |
Let's compute the generated force
The stroke is $L_{\max} = 20\mu m$ for a voltage range of $V_{\max} = 170 V$.
Furthermore, the stiffness is $k_a = 235 \cdot 10^6 N/m$.
The relation between the applied voltage and the generated force can be estimated as follows:
\begin{equation}
g_a = k_a \frac{L_{\max}}{V_{\max}}
\end{equation}
#+begin_src matlab
ka = 235e6; % [N/m]
Lmax = 20e-6; % [m]
Vmax = 170; % [V]
#+end_src
#+begin_src matlab :results value replace
ka*Lmax/Vmax % [N/V]
#+end_src
#+RESULTS:
: 27.647
From the parameters of the stack, it seems not possible to estimate the relation between the strain and the generated voltage.
** Estimation from Piezoelectric parameters
<<sec:estimation_piezo_params>>
In order to make the conversion from applied voltage to generated force or from the strain to the generated voltage, we need to defined some parameters corresponding to the piezoelectric material:
#+begin_src matlab
d33 = 300e-12; % Strain constant [m/V]
n = 80; % Number of layers per stack
ka = 235e6; % Stack stiffness [N/m]
#+end_src
The ratio of the developed force to applied voltage is:
#+name: eq:piezo_voltage_to_force
\begin{equation}
F_a = g_a V_a, \quad g_a = d_{33} n k_a
\end{equation}
where:
- $F_a$: developed force in [N]
- $n$: number of layers of the actuator stack
- $d_{33}$: strain constant in [m/V]
- $k_a$: actuator stack stiffness in [N/m]
- $V_a$: applied voltage in [V]
If we take the numerical values, we obtain:
#+begin_src matlab
ga = d33*n*ka; % [N/V]
#+end_src
#+begin_src matlab :results value replace :exports results :tangle no
sprintf('ga = %.1f [N/V]', ga)
#+end_src
#+RESULTS:
: ga = 5.6 [N/V]
From cite:fleming14_desig_model_contr_nanop_system (page 123), the relation between relative displacement of the sensor stack and generated voltage is:
#+name: eq:piezo_strain_to_voltage
\begin{equation}
V_s = \frac{d_{33}}{\epsilon^T s^D n} \Delta h
\end{equation}
where:
- $V_s$: measured voltage in [V]
- $d_{33}$: strain constant in [m/V]
- $\epsilon^T$: permittivity under constant stress in [F/m]
- $s^D$: elastic compliance under constant electric displacement in [m^2/N]
- $n$: number of layers of the sensor stack
- $\Delta h$: relative displacement in [m]
If we take the numerical values, we obtain:
#+begin_src matlab
d33 = 300e-12; % Strain constant [m/V]
n = 80; % Number of layers per stack
eT = 5.3e-9; % Permittivity under constant stress [F/m]
sD = 2e-11; % Compliance under constant electric displacement [m2/N]
#+end_src
#+begin_src matlab
gs = d33/(eT*sD*n); % [V/m]
#+end_src
#+begin_src matlab :results value replace :exports results :tangle no
sprintf('gs = %.1f [V/um]', 1e-6*gs)
#+end_src
#+RESULTS:
: gs = 35.4 [V/um]
** Estimation from Experiment
<<sec:estimation_identification>>
*** Introduction :ignore:
The idea here is to obtain the parameters $g_a$ and $g_s$ from the comparison of an experimental identification and the identification using Simscape.
Using the experimental identification, we can easily obtain the gain from the applied voltage to the generated displacement, but not to the generated force.
However, from the Simscape model, we can easily have the link from the generated force to the displacement, them we can computed $g_a$.
Similarly, it is fairly easy to experimentally obtain the gain from the stack displacement to the generated voltage across the stack.
To link that to the strain of the sensor stack, the simscape model is used.
*** From actuator voltage $V_a$ to actuator force $F_a$
The data from the identification test is loaded.
#+begin_src matlab
load('apa95ml_5kg_Amp_E505.mat', 't', 'um', 'y');
% Any offset value is removed:
um = detrend(um, 0); % Amplifier Input Voltage [V]
y = detrend(y , 0); % Mass displacement [m]
#+end_src
Now we add a factor 10 to take into account the gain of the voltage amplifier and thus obtain the voltage across the piezoelectric stack.
#+begin_src matlab
um = 10*um; % Stack Actuator Input Voltage [V]
#+end_src
Then, the transfer function from the stack voltage to the vertical displacement is computed.
#+begin_src matlab
Ts = t(end)/(length(t)-1);
Fs = 1/Ts;
win = hanning(ceil(1*Fs));
[tf_est, f] = tfestimate(um, y, win, [], [], 1/Ts);
#+end_src
The gain from input voltage of the stack to the vertical displacement is determined:
#+begin_src matlab
g_d_Va = 4e-7; % [m/V]
#+end_src
#+begin_src matlab :exports none
freqs = logspace(0, 4, 1000);
figure;
hold on;
plot(f, abs(tf_est), 'DisplayName', 'Identification')
plot([f(2) f(end)], [g_d_Va g_d_Va], '--', 'DisplayName', sprintf('$d/V_a \\approx %.0g\\ m/V$', g_d_Va))
hold off;
set(gca, 'Xscale', 'log'); set(gca, 'Yscale', 'log');
xlabel('Frequency [Hz]'); ylabel('Amplitude $d/V_a$ [m/V]');
xlim([10, 5e3]); ylim([1e-8, 1e-5]);
legend('location', 'southwest');
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/gain_Va_to_d.pdf', 'width', 'wide', 'height', 'normal');
#+end_src
#+name: fig:gain_Va_to_d
#+caption: Transfer function from actuator stack voltage $V_a$ to vertical displacement of the mass $d$
#+RESULTS:
[[file:figs/gain_Va_to_d.png]]
Then, the transfer function from forces applied by the stack actuator to the vertical displacement of the mass is identified from the Simscape model.
#+begin_src matlab :exports none
% Load Parameters
K = readmatrix('APA95ML_K.CSV');
M = readmatrix('APA95ML_M.CSV');
[int_xyz, int_i, n_xyz, n_i, nodes] = extractNodes('APA95ML_out_nodes_3D.txt');
% Define parameters just for the simulation
ga = 1; % [N/V]
gs = 1; % [V/m]
#+end_src
#+begin_src matlab
m = 5.5;
%% Name of the Simulink File
mdl = 'piezo_amplified_3d';
%% Input/Output definition
clear io; io_i = 1;
io(io_i) = linio([mdl, '/Fa'], 1, 'openinput'); io_i = io_i + 1; % Actuator Force [N]
io(io_i) = linio([mdl, '/y'], 1, 'openoutput'); io_i = io_i + 1; % Vertical Displacement [m]
Gd = linearize(mdl, io);
#+end_src
The DC gain the the identified dynamics
#+begin_src matlab
g_d_Fa = abs(dcgain(Gd)); % [m/N]
#+end_src
#+begin_src matlab :results value replace :exports results :tangle no
sprintf('G_d_Fa = %.2g [m/N]', g_d_Fa)
#+end_src
#+RESULTS:
: G_d_Fa = 1.2e-08 [m/N]
And finally, the gain $g_a$ from the the actuator voltage $V_a$ to the generated force $F_a$ can be computed:
\begin{equation}
g_a = \frac{F_a}{V_a} = \frac{F_a}{d} \frac{d}{V_a}
\end{equation}
#+begin_src matlab
ga = g_d_Va/g_d_Fa;
#+end_src
#+begin_src matlab :results value replace :exports results :tangle no
sprintf('ga = %.1f [N/V]', ga)
#+end_src
#+RESULTS:
: ga = 33.7 [N/V]
The obtained comparison between the Simscape model and the identified dynamics is shown in Figure [[fig:compare_Gd_id_simscape]].
#+begin_src matlab :exports none
freqs = logspace(1, 4, 1000);
figure;
hold on;
plot(f, abs(tf_est), 'DisplayName', 'Identification')
plot(f, ga*abs(squeeze(freqresp(Gd, f, 'Hz'))), 'DisplayName', 'Simscape Model')
set(gca, 'Xscale', 'log'); set(gca, 'Yscale', 'log');
ylabel('Amplitude $d/V_a$ [m/V]'); xlabel('Frequency [Hz]');
hold off;
xlim([1, 5e3]); ylim([1e-9, 1e-5]);
legend('location', 'southwest');
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/compare_Gd_id_simscape.pdf', 'width', 'wide', 'height', 'normal');
#+end_src
#+name: fig:compare_Gd_id_simscape
#+caption: Comparison of the identified transfer function between actuator voltage $V_a$ and vertical mass displacement $d$
#+RESULTS:
[[file:figs/compare_Gd_id_simscape.png]]
*** From stack strain $\Delta h$ to generated voltage $V_s$
Now, the gain from the stack strain $\Delta h$ to the generated voltage $V_s$ is estimated.
We can determine the gain from actuator voltage $V_a$ to sensor voltage $V_s$ thanks to the identification.
Using the simscape model, we can have the transfer function from the actuator voltage $V_a$ (using the previously estimated gain $g_a$) to the sensor stack strain $\Delta h$.
Finally, using these two values, we can compute the gain $g_s$ from the stack strain $\Delta h$ to the generated Voltage $V_s$.
Identification data is loaded.
#+begin_src matlab
load('apa95ml_5kg_2a_1s.mat', 't', 'u', 'v');
u = detrend(u, 0); % Input Voltage of the Amplifier [V]
v = detrend(v, 0); % Voltage accross the stack sensor [V]
#+end_src
Here, an amplifier with a gain of 20 is used.
#+begin_src matlab
u = 20*u; % Input Voltage of the Amplifier [V]
#+end_src
Then, the transfer function from $V_a$ to $V_s$ is identified and its DC gain is estimated (Figure [[fig:gain_Va_to_Vs]]).
#+begin_src matlab
Ts = t(end)/(length(t)-1);
Fs = 1/Ts;
win = hann(ceil(10/Ts));
[tf_est, f] = tfestimate(u, v, win, [], [], 1/Ts);
#+end_src
#+begin_src matlab
g_Vs_Va = 0.022; % [V/V]
#+end_src
#+begin_src matlab :exports none
freqs = logspace(1, 4, 1000);
figure;
hold on;
plot(f, abs(tf_est), 'DisplayName', 'Identification')
plot([f(2); f(end)], [g_Vs_Va; g_Vs_Va], '--', 'DisplayName', sprintf('$V_s/V_a \\approx %.0g\\ m/V$', g_Vs_Va))
hold off;
set(gca, 'Xscale', 'log'); set(gca, 'Yscale', 'log');
ylabel('Amplitude $V_s/V_a$ [V/V]'); xlabel('Frequency [Hz]');
xlim([5e-1 5e3]); ylim([1e-3, 1e1]);
legend('location', 'northwest');
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/gain_Va_to_Vs.pdf', 'width', 'wide', 'height', 'normal');
#+end_src
#+name: fig:gain_Va_to_Vs
#+caption: Transfer function from actuator stack voltage $V_a$ to sensor stack voltage $V_s$
#+RESULTS:
[[file:figs/gain_Va_to_Vs.png]]
Now the transfer function from the actuator stack voltage to the sensor stack strain is estimated using the Simscape model.
#+begin_src matlab
m = 5.5;
%% Name of the Simulink File
mdl = 'piezo_amplified_3d';
%% Input/Output definition
clear io; io_i = 1;
io(io_i) = linio([mdl, '/Va'], 1, 'openinput'); io_i = io_i + 1; % Actuator Voltage [V]
io(io_i) = linio([mdl, '/dL'], 1, 'openoutput'); io_i = io_i + 1; % Sensor Stack displacement [m]
Gf = linearize(mdl, io);
#+end_src
The gain from the actuator stack voltage to the sensor stack strain is estimated below.
#+begin_src matlab
G_dh_Va = abs(dcgain(Gf));
#+end_src
#+begin_src matlab :results value replace :exports results :tangle no
sprintf('G_dh_Va = %.2g [m/V]', G_dh_Va);
#+end_src
#+RESULTS:
: G_dh_Va = 6.2e-09 [m/V]
And finally, the gain $g_s$ from the sensor stack strain to the generated voltage can be estimated:
\begin{equation}
g_s = \frac{V_s}{\Delta h} = \frac{V_s}{V_a} \frac{V_a}{\Delta h}
\end{equation}
#+begin_src matlab
gs = g_Vs_Va/G_dh_Va; % [V/m]
#+end_src
#+begin_src matlab :results value replace :exports results :tangle no
sprintf('gs = %.1f [V/um]', 1e-6*gs)
#+end_src
#+RESULTS:
: gs = 3.5 [V/um]
#+begin_src matlab :exports none
freqs = logspace(1, 4, 1000);
figure;
hold on;
plot(f, abs(tf_est), 'DisplayName', 'Identification')
plot(f, gs*abs(squeeze(freqresp(Gf, f, 'Hz'))), 'DisplayName', 'Simscape Model')
set(gca, 'Xscale', 'log'); set(gca, 'Yscale', 'log');
ylabel('Amplitude $V_s/V_a$ [V/V]'); xlabel('Frequency [Hz]');
hold off;
xlim([1, 5e3]); ylim([1e-3, 1e1]);
legend('location', 'southwest');
#+end_src
#+begin_src matlab :tangle no :exports results :results file replace
exportFig('figs/compare_Gf_id_simscape.pdf', 'width', 'wide', 'height', 'normal');
#+end_src
#+name: fig:compare_Gf_id_simscape
#+caption: Comparison of the identified transfer function between actuator voltage $V_a$ and sensor stack voltage
#+RESULTS:
[[file:figs/compare_Gf_id_simscape.png]]
** Conclusion
The obtained parameters $g_a$ and $g_s$ are not consistent between the different methods.
The one using the experimental data are saved and further used.
#+begin_src matlab :tangle no
save('./matlab/mat/apa95ml_params.mat', 'ga', 'gs');
#+end_src
#+begin_src matlab :exports none :eval no
save('./mat/apa95ml_params.mat', 'ga', 'gs');
#+end_src
* Simscape model of the test-bench
:PROPERTIES:
:header-args:matlab+: :tangle matlab/simscape_model.m
:header-args:matlab+: :comments org :mkdirp yes
:END:
<<sec:simscape_model>>
** Introduction :ignore:
The idea here is to model the test-bench using Simscape.
Whereas the suspended mass and metrology frame can be considered as rigid bodies in the frequency range of interest, the Amplified Piezoelectric Actuator (APA) is flexible.
To model the APA, a Finite Element Model (FEM) is used and imported into Simscape.
To model the APA, a Finite Element Model (FEM) is used (Figure [[fig:APA95ML_FEM]]) and imported into Simscape.
#+name: fig:APA95ML_FEM
#+caption: Finite Element Model of the APA95ML
[[file:figs/APA95ML_FEM.png]]
** Matlab Init :noexport:ignore:
#+begin_src matlab :tangle no :exports none :results silent :noweb yes :var current_dir=(file-name-directory buffer-file-name)
@ -101,8 +525,8 @@ To model the APA, a Finite Element Model (FEM) is used and imported into Simscap
** Import Mass Matrix, Stiffness Matrix, and Interface Nodes Coordinates
We first extract the stiffness and mass matrices.
#+begin_src matlab
K = extractMatrix('APA95ML_K.txt');
M = extractMatrix('APA95ML_M.txt');
K = readmatrix('APA95ML_K.CSV');
M = readmatrix('APA95ML_M.CSV');
#+end_src
#+begin_src matlab :exports results :results value table replace :tangle no
@ -111,16 +535,16 @@ We first extract the stiffness and mass matrices.
#+caption: First 10x10 elements of the Stiffness matrix
#+RESULTS:
| 300000000.0 | -30000.0 | 8000.0 | -200.0 | -30.0 | -60000.0 | 20000000.0 | -4000.0 | 500.0 | 8 |
| -30000.0 | 100000000.0 | 400.0 | 30.0 | 200.0 | -1 | 4000.0 | -8000000.0 | 800.0 | 7 |
| 8000.0 | 400.0 | 50000000.0 | -800000.0 | -300.0 | -40.0 | 300.0 | 100.0 | 5000000.0 | 40000.0 |
| -200.0 | 30.0 | -800000.0 | 20000.0 | 5 | 1 | -10.0 | -2 | -40000.0 | -300.0 |
| -30.0 | 200.0 | -300.0 | 5 | 40000.0 | 0.3 | -4 | -10.0 | 40.0 | 0.4 |
| -60000.0 | -1 | -40.0 | 1 | 0.3 | 3000.0 | 7000.0 | 0.8 | -1 | 0.0003 |
| 20000000.0 | 4000.0 | 300.0 | -10.0 | -4 | 7000.0 | 300000000.0 | 20000.0 | 3000.0 | 80.0 |
| -4000.0 | -8000000.0 | 100.0 | -2 | -10.0 | 0.8 | 20000.0 | 100000000.0 | -4000.0 | -100.0 |
| 500.0 | 800.0 | 5000000.0 | -40000.0 | 40.0 | -1 | 3000.0 | -4000.0 | 50000000.0 | 800000.0 |
| 8 | 7 | 40000.0 | -300.0 | 0.4 | 0.0003 | 80.0 | -100.0 | 800000.0 | 20000.0 |
| 300000000.0 | -1000.0 | -30000.0 | -40.0 | 70000.0 | 300.0 | 20000000.0 | -30.0 | -5000.0 | 5 |
| -1000.0 | 50000000.0 | -7000.0 | 800000.0 | -20.0 | 300.0 | 3000.0 | 5000000.0 | 400.0 | -40000.0 |
| -30000.0 | -7000.0 | 100000000.0 | -200.0 | -60.0 | 70.0 | 3000.0 | 3000.0 | -8000000.0 | -30.0 |
| -40.0 | 800000.0 | -200.0 | 20000.0 | -0.4 | 4 | 30.0 | 40000.0 | 7 | -300.0 |
| 70000.0 | -20.0 | -60.0 | -0.4 | 3000.0 | 1 | -6000.0 | 10.0 | 8 | -0.1 |
| 300.0 | 300.0 | 70.0 | 4 | 1 | 40000.0 | -10.0 | -10.0 | 30.0 | 0.1 |
| 20000000.0 | 3000.0 | 3000.0 | 30.0 | -6000.0 | -10.0 | 300000000.0 | 2000.0 | 9000.0 | -100.0 |
| -30.0 | 5000000.0 | 3000.0 | 40000.0 | 10.0 | -10.0 | 2000.0 | 50000000.0 | -3000.0 | -800000.0 |
| -5000.0 | 400.0 | -8000000.0 | 7 | 8 | 30.0 | 9000.0 | -3000.0 | 100000000.0 | 100.0 |
| 5 | -40000.0 | -30.0 | -300.0 | -0.1 | 0.1 | -100.0 | -800000.0 | 100.0 | 20000.0 |
#+begin_src matlab :exports results :results value table replace :tangle no
@ -129,16 +553,16 @@ We first extract the stiffness and mass matrices.
#+caption: First 10x10 elements of the Mass matrix
#+RESULTS:
| 0.03 | 2e-06 | -2e-07 | 1e-08 | 2e-08 | 0.0002 | -0.001 | 2e-07 | -8e-08 | -9e-10 |
| 2e-06 | 0.02 | -5e-07 | 7e-09 | 3e-08 | 2e-08 | -3e-07 | 0.0003 | -1e-08 | 1e-10 |
| -2e-07 | -5e-07 | 0.02 | -9e-05 | 4e-09 | -1e-08 | 2e-07 | -2e-08 | -0.0006 | -5e-06 |
| 1e-08 | 7e-09 | -9e-05 | 1e-06 | 6e-11 | 4e-10 | -1e-09 | 3e-11 | 5e-06 | 3e-08 |
| 2e-08 | 3e-08 | 4e-09 | 6e-11 | 1e-06 | 2e-10 | -2e-09 | 2e-10 | -7e-09 | -4e-11 |
| 0.0002 | 2e-08 | -1e-08 | 4e-10 | 2e-10 | 2e-06 | -2e-06 | -1e-09 | -7e-10 | -9e-12 |
| -0.001 | -3e-07 | 2e-07 | -1e-09 | -2e-09 | -2e-06 | 0.03 | -2e-06 | -1e-07 | -5e-09 |
| 2e-07 | 0.0003 | -2e-08 | 3e-11 | 2e-10 | -1e-09 | -2e-06 | 0.02 | -8e-07 | -1e-08 |
| -8e-08 | -1e-08 | -0.0006 | 5e-06 | -7e-09 | -7e-10 | -1e-07 | -8e-07 | 0.02 | 9e-05 |
| -9e-10 | 1e-10 | -5e-06 | 3e-08 | -4e-11 | -9e-12 | -5e-09 | -1e-08 | 9e-05 | 1e-06 |
| 0.03 | 7e-08 | 2e-06 | -3e-09 | -0.0002 | -6e-08 | -0.001 | 8e-07 | 6e-07 | -8e-09 |
| 7e-08 | 0.02 | -1e-06 | 9e-05 | -3e-09 | -4e-09 | -1e-06 | -0.0006 | -4e-08 | 5e-06 |
| 2e-06 | -1e-06 | 0.02 | -3e-08 | -4e-08 | 1e-08 | 1e-07 | -2e-07 | 0.0003 | 1e-09 |
| -3e-09 | 9e-05 | -3e-08 | 1e-06 | -3e-11 | -3e-13 | -7e-09 | -5e-06 | -3e-10 | 3e-08 |
| -0.0002 | -3e-09 | -4e-08 | -3e-11 | 2e-06 | 6e-10 | 2e-06 | -7e-09 | -2e-09 | 7e-11 |
| -6e-08 | -4e-09 | 1e-08 | -3e-13 | 6e-10 | 1e-06 | 1e-08 | 3e-09 | -2e-09 | 2e-13 |
| -0.001 | -1e-06 | 1e-07 | -7e-09 | 2e-06 | 1e-08 | 0.03 | 4e-08 | -2e-06 | 8e-09 |
| 8e-07 | -0.0006 | -2e-07 | -5e-06 | -7e-09 | 3e-09 | 4e-08 | 0.02 | -9e-07 | -9e-05 |
| 6e-07 | -4e-08 | 0.0003 | -3e-10 | -2e-09 | -2e-09 | -2e-06 | -9e-07 | 0.02 | 2e-08 |
| -8e-09 | 5e-06 | 1e-09 | 3e-08 | 7e-11 | 2e-13 | 8e-09 | -9e-05 | 2e-08 | 1e-06 |
Then, we extract the coordinates of the interface nodes.
@ -146,100 +570,47 @@ Then, we extract the coordinates of the interface nodes.
[int_xyz, int_i, n_xyz, n_i, nodes] = extractNodes('APA95ML_out_nodes_3D.txt');
#+end_src
The interface nodes are shown in Figure [[fig:APA95ML_nodes_1]] and their coordinates are listed in Table [[tab:apa95ml_nodes_coordinates]].
#+begin_src matlab :exports results :results value table replace :tangle no
data2orgtable([length(n_i); length(int_i); size(M,1) - 6*length(int_i); size(M,1)], {'Total number of Nodes', 'Number of interface Nodes', 'Number of Modes', 'Size of M and K matrices'}, {}, ' %.0f ');
#+end_src
#+RESULTS:
| Total number of Nodes | 168959 |
| Number of interface Nodes | 13 |
| Number of Modes | 30 |
| Size of M and K matrices | 108 |
| Total number of Nodes | 7 |
| Number of interface Nodes | 7 |
| Number of Modes | 6 |
| Size of M and K matrices | 48 |
#+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*)
data2orgtable([[1:length(int_i)]', int_i, int_xyz], {}, {'Node i', 'Node Number', 'x [m]', 'y [m]', 'z [m]'}, ' %f ');
#+end_src
#+name: tab:apa95ml_nodes_coordinates
#+caption: Coordinates of the interface nodes
#+RESULTS:
| Node i | Node Number | x [m] | y [m] | z [m] |
|--------+-------------+--------+-------+-------|
| 1.0 | 168947.0 | 0.0 | 0.03 | 0.0 |
| 2.0 | 168949.0 | 0.0 | -0.03 | 0.0 |
| 3.0 | 168950.0 | -0.035 | 0.0 | 0.0 |
| 4.0 | 168951.0 | -0.028 | 0.0 | 0.0 |
| 5.0 | 168952.0 | -0.021 | 0.0 | 0.0 |
| 6.0 | 168953.0 | -0.014 | 0.0 | 0.0 |
| 7.0 | 168954.0 | -0.007 | 0.0 | 0.0 |
| 8.0 | 168955.0 | 0.0 | 0.0 | 0.0 |
| 9.0 | 168956.0 | 0.007 | 0.0 | 0.0 |
| 10.0 | 168957.0 | 0.014 | 0.0 | 0.0 |
| 11.0 | 168958.0 | 0.021 | 0.0 | 0.0 |
| 12.0 | 168959.0 | 0.035 | 0.0 | 0.0 |
| 13.0 | 168960.0 | 0.028 | 0.0 | 0.0 |
| Node i | Node Number | x [m] | y [m] | z [m] |
|--------+-------------+--------+-------+-----------|
| 1.0 | 40467.0 | 0.0 | 0.0 | 0.029997 |
| 2.0 | 40469.0 | 0.0 | 0.0 | -0.029997 |
| 3.0 | 40470.0 | -0.035 | 0.0 | 0.0 |
| 4.0 | 40475.0 | -0.015 | 0.0 | 0.0 |
| 5.0 | 40476.0 | -0.005 | 0.0 | 0.0 |
| 6.0 | 40477.0 | 0.015 | 0.0 | 0.0 |
| 7.0 | 40478.0 | 0.035 | 0.0 | 0.0 |
#+name: fig:APA95ML_nodes_1
#+caption: Interface Nodes chosen for the APA95ML
[[file:figs/APA95ML_nodes_1.png]]
Using =K=, =M= and =int_xyz=, we can use the =Reduced Order Flexible Solid= simscape block.
** Piezoelectric parameters
In order to make the conversion from applied voltage to generated force or from the strain to the generated voltage, we need to defined some parameters corresponding to the piezoelectric material:
#+begin_src matlab
d33 = 300e-12; % Strain constant [m/V]
n = 80; % Number of layers per stack
eT = 1.6e-8; % Permittivity under constant stress [F/m]
sD = 1e-11; % Compliance under constant electric displacement [m2/N]
ka = 235e6; % Stack stiffness [N/m]
C = 5e-6; % Stack capactiance [F]
#+end_src
The ratio of the developed force to applied voltage is:
#+name: eq:piezo_voltage_to_force
\begin{equation}
F_a = g_a V_a, \quad g_a = d_{33} n k_a
\end{equation}
where:
- $F_a$: developed force in [N]
- $n$: number of layers of the actuator stack
- $d_{33}$: strain constant in [m/V]
- $k_a$: actuator stack stiffness in [N/m]
- $V_a$: applied voltage in [V]
If we take the numerical values, we obtain:
#+begin_src matlab :results replace value
d33*n*ka % [N/V]
#+end_src
#+RESULTS:
: 5.64
From cite:fleming14_desig_model_contr_nanop_system (page 123), the relation between relative displacement of the sensor stack and generated voltage is:
#+name: eq:piezo_strain_to_voltage
\begin{equation}
V_s = \frac{d_{33}}{\epsilon^T s^D n} \Delta h
\end{equation}
where:
- $V_s$: measured voltage in [V]
- $d_{33}$: strain constant in [m/V]
- $\epsilon^T$: permittivity under constant stress in [F/m]
- $s^D$: elastic compliance under constant electric displacement in [m^2/N]
- $n$: number of layers of the sensor stack
- $\Delta h$: relative displacement in [m]
If we take the numerical values, we obtain:
#+begin_src matlab :results replace value
1e-6*d33/(eT*sD*n) % [V/um]
#+end_src
#+RESULTS:
: 23.438
** Simscape Model
The flexible element is imported using the =Reduced Order Flexible Solid= Simscape block.
To model the actuator, an =Internal Force= block is added between the nodes 3 and 12.
A =Relative Motion Sensor= block is added between the nodes 1 and 2 to measure the displacement and the amplified piezo.
- [ ] Add schematic of the model with interface nodes
One mass is fixed at one end of the piezo-electric stack actuator, the other end is fixed to the world frame.
#+begin_src matlab
m = 5;
@ -354,236 +725,6 @@ The obtained dynamics is shown in Figure [[fig:dynamics_force_force_sensor_comp_
save('mat/fem_simscape_models.mat', 'Ghm', 'Gfm')
#+end_src
* TODO Estimation of piezoelectric parameters
** 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
addpath('./matlab/mat/');
addpath('./matlab/');
#+end_src
#+begin_src matlab :eval no
addpath('./mat/');
#+end_src
** From actuator voltage to vertical displacement
The data from the "noise test" and the identification test are loaded.
#+begin_src matlab
load('apa95ml_5kg_Amp_E505.mat', 't', 'um', 'y');
#+end_src
Any offset value is removed:
#+begin_src matlab
um = detrend(um, 0); % Amplifier Input Voltage [V]
y = detrend(y , 0); % Mass displacement [m]
#+end_src
Now we add a factor 10 to take into account the gain of the voltage amplifier.
#+begin_src matlab
um = 10*um; % Stack Actuator Input Voltage [V]
#+end_src
#+begin_src matlab
Ts = t(end)/(length(t)-1);
Fs = 1/Ts;
win = hanning(ceil(1*Fs));
#+end_src
#+begin_src matlab
[tf_est, f] = tfestimate(um, y, win, [], [], 1/Ts);
#+end_src
The gain from input voltage of the stack to the vertical displacement is determined:
#+begin_src matlab
gD = 4e-7; % [m/V]
#+end_src
#+begin_src matlab :exports none
freqs = logspace(0, 4, 1000);
figure;
hold on;
plot(f, abs(tf_est))
plot([f(2) f(end)], [gD gD])
hold off;
set(gca, 'Xscale', 'log'); set(gca, 'Yscale', 'log');
ylabel('Amplitude [m/V]'); set(gca, 'XTickLabel', []);
xlim([10, 5e3]);
#+end_src
#+begin_src matlab
K = extractMatrix('APA95ML_K.txt');
M = extractMatrix('APA95ML_M.txt');
[int_xyz, int_i, n_xyz, n_i, nodes] = extractNodes('APA95ML_out_nodes_3D.txt');
#+end_src
Define parameters just for the simulation. Should not change any results
#+begin_src matlab
d33 = 1; % Strain constant [m/V]
n = 1; % Number of layers per stack
eT = 1; % Permittivity under constant stress [F/m]
sD = 1; % Compliance under constant electric displacement [m2/N]
ka = 1; % Stack stiffness [N/m]
C = 1; % Stack capactiance [F]
#+end_src
#+begin_src matlab
m = 5;
%% Name of the Simulink File
mdl = 'piezo_amplified_3d';
%% Input/Output definition
clear io; io_i = 1;
io(io_i) = linio([mdl, '/Fa'], 1, 'openinput'); io_i = io_i + 1; % Actuator Force [N]
io(io_i) = linio([mdl, '/y'], 1, 'openoutput'); io_i = io_i + 1; % Vertical Displacement [m]
Gd = linearize(mdl, io);
#+end_src
#+begin_src matlab :results value replace
gF = abs(dcgain(Gd)); % [m/N]
ans = gF
#+end_src
#+RESULTS:
: 6.1695e-09
\[ g_a = g_D/g_F \]
in [N/V]
#+begin_src matlab :results value replace
ga = gD/gF
ans = ga
#+end_src
#+RESULTS:
: 64.835
#+begin_src matlab :results value replace
na = 2; ns = 1; d33 = 300e-12; n = 80; ka = 235e6; gL = 1.7;
na/(na+ns)*gL*d33*n*ka
#+end_src
#+RESULTS:
: 6.392
- [ ] Why is there a factor 10 with the "theoretical estimation?"
#+begin_src matlab :exports none
freqs = logspace(1, 4, 1000);
figure;
hold on;
plot(f, abs(tf_est))
plot(f, ga*abs(squeeze(freqresp(Gd, f, 'Hz'))))
set(gca, 'Xscale', 'log'); set(gca, 'Yscale', 'log');
ylabel('Amplitude'); xlabel('Frequency [Hz]');
hold off;
#+end_src
** From actuator voltage to sensor Voltage
#+begin_src matlab
load('apa95ml_5kg_2a_1s.mat', 't', 'u', 'v');
#+end_src
#+begin_src matlab
u = detrend(u, 0); % Input Voltage of the Amplifier [V]
v = detrend(v, 0); % Voltage accross the stack sensor [V]
#+end_src
#+begin_src matlab
u = 20*u; % Input Voltage of the Amplifier [V]
#+end_src
#+begin_src matlab
Ts = t(end)/(length(t)-1);
Fs = 1/Ts;
win = hann(ceil(10/Ts));
[tf_est, f] = tfestimate(u, v, win, [], [], 1/Ts);
#+end_src
#+begin_src matlab
gV = 0.022; % [V/V]
#+end_src
#+begin_src matlab :exports none
freqs = logspace(1, 4, 1000);
figure;
hold on;
plot(f, abs(tf_est))
plot([f(2); f(end)], [gV; gV])
hold off;
set(gca, 'Xscale', 'log'); set(gca, 'Yscale', 'log');
ylabel('Amplitude'); xlabel('Frequency [Hz]');
ylim([1e-3, 1e1]);
#+end_src
#+begin_src matlab
m = 5;
%% Name of the Simulink File
mdl = 'piezo_amplified_3d';
%% Input/Output definition
clear io; io_i = 1;
io(io_i) = linio([mdl, '/Fa'], 1, 'openinput'); io_i = io_i + 1; % Actuator Force [N]
io(io_i) = linio([mdl, '/dL'], 1, 'openoutput'); io_i = io_i + 1; % Sensor Stack displacement [m]
Gf = linearize(mdl, io);
#+end_src
$g_F$ in [m/N]
#+begin_src matlab :results value replace
gF = abs(dcgain(Gf));
ans = gF
#+end_src
#+RESULTS:
: 2.1546e-10
Finally, we compute the gain from strain of the sensor stack to its generated voltage:
\[ g_S = \frac{g_V}{g_F g_a} \]
Gs in [V/m]
#+begin_src matlab :results value replace
gS = gV/gF/ga;
ans = gS
#+end_src
#+RESULTS:
: 15749000.0
#+begin_src matlab :results value replace
d33 = 300e-12; eT = 5.3e-9; sD = 2e-11; n = 80;
d33/(eT*sD*n)
#+end_src
#+RESULTS:
: 35377000.0
#+begin_src matlab :exports none
freqs = logspace(1, 4, 1000);
figure;
hold on;
plot(f, abs(tf_est))
plot(f, ga*gS*abs(squeeze(freqresp(Gf, f, 'Hz'))))
set(gca, 'Xscale', 'log'); set(gca, 'Yscale', 'log');
ylabel('Amplitude'); xlabel('Frequency [Hz]');
hold off;
ylim([1e-3, 1e1]);
#+end_src
* Huddle Test
:PROPERTIES:
:header-args:matlab+: :tangle matlab/huddle_test.m