Add figures to explain the multi-body model

This commit is contained in:
Thomas Dehaeze 2025-02-10 17:35:49 +01:00
parent 8153a9d87b
commit fca54e3d88
18 changed files with 7412 additions and 2502 deletions

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

View File

@ -13,11 +13,11 @@ function [nano_hexapod] = initializeSimplifiedNanoHexapod(args)
args.MTh (6,1) double {mustBeNumeric} = [255, 285, 15, 45, 135, 165]*(pi/180) % Angles of fixed joints [rad]
%% Actuators
args.actuator_type char {mustBeMember(args.actuator_type,{'1dof', '2dof', 'flexible'})} = '1dof'
args.actuator_k (1,1) double {mustBeNumeric, mustBePositive} = 380000
args.actuator_kp (1,1) double {mustBeNumeric, mustBeNonnegative} = 0
args.actuator_k (1,1) double {mustBeNumeric, mustBePositive} = 1e6
args.actuator_kp (1,1) double {mustBeNumeric, mustBeNonnegative} = 5e4
args.actuator_ke (1,1) double {mustBeNumeric, mustBePositive} = 4952605
args.actuator_ka (1,1) double {mustBeNumeric, mustBePositive} = 2476302
args.actuator_c (1,1) double {mustBeNumeric, mustBePositive} = 5
args.actuator_c (1,1) double {mustBeNumeric, mustBePositive} = 50
args.actuator_cp (1,1) double {mustBeNumeric, mustBeNonnegative} = 0
args.actuator_ce (1,1) double {mustBeNumeric, mustBePositive} = 100
args.actuator_ca (1,1) double {mustBeNumeric, mustBePositive} = 50

View File

@ -10,6 +10,18 @@
@article{stewart65_platf_with_six_degrees_freed,
author = {Stewart, Doug},
title = {A Platform With Six Degrees of Freedom},
journal = {Proceedings of the institution of mechanical engineers},
volume = 180,
number = 1,
pages = {371--386},
year = 1965,
publisher = {Sage Publications Sage UK: London, England},
}
@article{preumont07_six_axis_singl_stage_activ,
author = {A. Preumont and M. Horodinca and I. Romanescu and B. de
Marneffe and M. Avraam and A. Deraemaeker and F. Bossens and

View File

@ -896,29 +896,41 @@ Both have no stiffness along their DoF and are mass-less.
**** Actuators
In its simplest form, the actuators are modelled with one prismatic joint having some internal stiffness and damping.
In its simplest form, the actuators are modelled with one prismatic joint having some internal stiffness $k_a$ and damping $c_a$, and a force source $f$.
As was shown
As was shown using the 3DoF rotating model, having a parallel stiffness $k_p$ with the force sensor permits to regain the guaranteed stability of decentralized IFF when the spindle is rotating.
- [ ] Add schematic of the 1DoF model (possibly with added parallel stiffness)
- [ ] Add model parameters for the 2DoF actuator used for the model (choose something reasonable for an APA)
A force sensor with output $f_m$ is added as well as a relative motion sensor with output $d_L$.
The model of the nano-hexapod actuators used during the conceptual phase are shown in Figure ref:fig:nhexa_actuator_model with the parameters summarized in Table ref:tab:nhexa_actuator_parameters.
Thanks to the flexibility of the multi-body model, the model of the actuators can later be refined.
- Actuators: can be modelled as wanted
- Talk about 2DoF and 1DoF
During the conceptual design: Actuators = 1DoF + Encoder (mass-less)
- k = 1N/um
- Force sensor
#+attr_latex: :options [b]{0.6\linewidth}
#+begin_minipage
#+name: fig:nhexa_actuator_model
#+caption: Model of the nano-hexapod actuators
#+attr_latex: :float nil :scale 1
[[file:figs/nhexa_actuator_model.png]]
#+end_minipage
\hfill
#+attr_latex: :options [b]{0.38\linewidth}
#+begin_minipage
#+begin_scriptsize
#+latex: \centering
#+attr_latex: :environment tabularx :width 0.4\linewidth :placement [b] :align Xl
#+attr_latex: :booktabs t :float nil :center nil
| | Value |
|-------+-----------------|
| $k_a$ | $1\,N/\mu m$ |
| $c_a$ | $50\,N/(m/s)$ |
| $k_p$ | $0.05\,N/\mu m$ |
#+latex: \captionof{table}{\label{tab:nhexa_actuator_parameters}Actuator parameters}
#+end_scriptsize
#+end_minipage
** Model Dynamics
<<ssec:nhexa_model_dynamics>>
- [ ] Make schematic with inputs and outputs (maybe add frames {F} and {M} to connect to outside world)
- [ ] Screenshot of the obtained multi-body model ?
- If all is perfect (mass-less struts, perfect joints, etc...), maybe compare analytical model with simscape model?
- Say something about the model order
Model order is 12, and that we can compute modes from matrices M and K, compare with the Simscape model
@ -926,6 +938,22 @@ During the conceptual design: Actuators = 1DoF + Encoder (mass-less)
- Compare with analytical formulas (see number of states)
- [ ] Effect of parallel on IFF plant?
#+attr_latex: :options [b]{0.6\linewidth}
#+begin_minipage
#+name: fig:nhexa_stewart_model_input_outputs
#+caption: Nano-Hexapod plant with inputs and outputs. Frames $\{F\}$ and $\{M\}$ can be connected to other elements in the multi-body models.
#+attr_latex: :scale 1 :float nil
[[file:figs/nhexa_stewart_model_input_outputs.png]]
#+end_minipage
\hfill
#+attr_latex: :options [b]{0.35\linewidth}
#+begin_minipage
#+name: fig:nhexa_simscape_screenshot
#+caption: 3D representation of the multi-body model
#+attr_latex: :width 0.90\linewidth :float nil
[[file:figs/nhexa_simscape_screenshot.jpg]]
#+end_minipage
#+begin_src matlab
%% Plant using Analytical Equations
% Stewart platform definition
@ -1088,6 +1116,105 @@ xlim([freqs(1), freqs(end)]);
#+begin_src matlab
initializeSimplifiedNanoHexapod();
initializeSample('type', 'cylindrical', 'm', 50);
initializeLoggingConfiguration('log', 'none');
initializeController('type', 'open-loop');
#+end_src
#+begin_src matlab
% Input/Output definition
clear io; io_i = 1;
io(io_i) = linio([mdl, '/Controller'], 1, 'openinput'); io_i = io_i + 1; % Actuator Inputs [N]
io(io_i) = linio([mdl, '/plant'], 2, 'openoutput', [], 'dL'); io_i = io_i + 1; % Encoders [m]
io(io_i) = linio([mdl, '/plant'], 2, 'openoutput', [], 'fn'); io_i = io_i + 1; % Force Sensors [N]
% With no payload
G = linearize(mdl, io);
G.InputName = {'f1', 'f2', 'f3', 'f4', 'f5', 'f6'};
G.OutputName = {'dL1', 'dL2', 'dL3', 'dL4', 'dL5', 'dL6', ...
'fn1', 'fn2', 'fn3', 'fn4', 'fn5', 'fn6'};
#+end_src
#+begin_src matlab :exports none
%% Diagonal elements of the FRF matrix from u to de
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G(1,1), freqs, 'Hz'))), 'color', colors(2,:), ...
'DisplayName', '$d_{ei}/u_i$ - Model')
for i = 2:6
plot(freqs, abs(squeeze(freqresp(G(i,i), freqs, 'Hz'))), 'color', colors(2,:), ...
'HandleVisibility', 'off');
end
for i = 1:5
for j = i+1:6
plot(freqs, abs(squeeze(freqresp(G(i,j), freqs, 'Hz'))), 'color', [0, 0, 0, 0.2], ...
'HandleVisibility', 'off');
end
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);
ylim([1e-9, 1e-4]);
leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15;
ax2 = nexttile;
hold on;
for i = 1:6
plot(freqs, 180/pi*angle(squeeze(freqresp(G(i,i), freqs, 'Hz'))), 'color', [colors(2,:),0.5]);
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]);
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
#+end_src
#+begin_src matlab :exports none
%% Diagonal elements of the FRF matrix from u to de
figure;
tiledlayout(3, 1, 'TileSpacing', 'Compact', 'Padding', 'None');
ax1 = nexttile([2,1]);
hold on;
plot(freqs, abs(squeeze(freqresp(G(6+1,1), freqs, 'Hz'))), 'color', colors(2,:), ...
'DisplayName', '$d_{ei}/u_i$ - Model')
for i = 2:6
plot(freqs, abs(squeeze(freqresp(G(6+i,i), freqs, 'Hz'))), 'color', colors(2,:), ...
'HandleVisibility', 'off');
end
for i = 1:5
for j = i+1:6
plot(freqs, abs(squeeze(freqresp(G(6+i,j), freqs, 'Hz'))), 'color', [0, 0, 0, 0.2], ...
'HandleVisibility', 'off');
end
end
hold off;
set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
ylabel('Amplitude [N/N]'); set(gca, 'XTickLabel',[]);
ylim([1e-5, 1e2]);
leg = legend('location', 'southwest', 'FontSize', 8, 'NumColumns', 1);
leg.ItemTokenSize(1) = 15;
ax2 = nexttile;
hold on;
for i = 1:6
plot(freqs, 180/pi*angle(squeeze(freqresp(G(6+i,i), freqs, 'Hz'))), 'color', [colors(2,:),0.5]);
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]);
linkaxes([ax1,ax2],'x');
xlim([freqs(1), freqs(end)]);
#+end_src
** Conclusion
@ -1447,11 +1574,11 @@ function [nano_hexapod] = initializeSimplifiedNanoHexapod(args)
args.MTh (6,1) double {mustBeNumeric} = [255, 285, 15, 45, 135, 165]*(pi/180) % Angles of fixed joints [rad]
%% Actuators
args.actuator_type char {mustBeMember(args.actuator_type,{'1dof', '2dof', 'flexible'})} = '1dof'
args.actuator_k (1,1) double {mustBeNumeric, mustBePositive} = 380000
args.actuator_kp (1,1) double {mustBeNumeric, mustBeNonnegative} = 0
args.actuator_k (1,1) double {mustBeNumeric, mustBePositive} = 1e6
args.actuator_kp (1,1) double {mustBeNumeric, mustBeNonnegative} = 5e4
args.actuator_ke (1,1) double {mustBeNumeric, mustBePositive} = 4952605
args.actuator_ka (1,1) double {mustBeNumeric, mustBePositive} = 2476302
args.actuator_c (1,1) double {mustBeNumeric, mustBePositive} = 5
args.actuator_c (1,1) double {mustBeNumeric, mustBePositive} = 50
args.actuator_cp (1,1) double {mustBeNumeric, mustBeNonnegative} = 0
args.actuator_ce (1,1) double {mustBeNumeric, mustBePositive} = 100
args.actuator_ca (1,1) double {mustBeNumeric, mustBePositive} = 50

Binary file not shown.

View File

@ -1,4 +1,4 @@
% Created 2025-02-10 Mon 14:23
% Created 2025-02-10 Mon 17:32
% Intended LaTeX compiler: pdflatex
\documentclass[a4paper, 10pt, DIV=12, parskip=full, bibliography=totoc]{scrreprt}
@ -235,18 +235,18 @@ Equation \eqref{eq:nhexa_loop_closure_velocity_bis} can be rearranged in a matri
The matrix \(\bm{J}\) is called the Jacobian matrix, and is defined by \eqref{eq:nhexa_jacobian}, with:
\begin{itemize}
\item \(\hat{\bm{s}}_i\) the orientation of the struts expressed in \(\{A\}\)
\item \(\bm{b}_i\) the position of the joints with respect to \(O_B\) and express in \(\{A\}\)
\item \({}^A\hat{\bm{s}}_i\) the orientation of the struts expressed in \(\{A\}\)
\item \({}^A\bm{b}_i\) the position of the joints with respect to \(O_B\) and express in \(\{A\}\)
\end{itemize}
\begin{equation}\label{eq:nhexa_jacobian}
\bm{J} = \begin{bmatrix}
{\hat{\bm{s}}_1}^T & (\bm{b}_1 \times \hat{\bm{s}}_1)^T \\
{\hat{\bm{s}}_2}^T & (\bm{b}_2 \times \hat{\bm{s}}_2)^T \\
{\hat{\bm{s}}_3}^T & (\bm{b}_3 \times \hat{\bm{s}}_3)^T \\
{\hat{\bm{s}}_4}^T & (\bm{b}_4 \times \hat{\bm{s}}_4)^T \\
{\hat{\bm{s}}_5}^T & (\bm{b}_5 \times \hat{\bm{s}}_5)^T \\
{\hat{\bm{s}}_6}^T & (\bm{b}_6 \times \hat{\bm{s}}_6)^T
{{}^A\hat{\bm{s}}_1}^T & ({}^A\bm{b}_1 \times {}^A\hat{\bm{s}}_1)^T \\
{{}^A\hat{\bm{s}}_2}^T & ({}^A\bm{b}_2 \times {}^A\hat{\bm{s}}_2)^T \\
{{}^A\hat{\bm{s}}_3}^T & ({}^A\bm{b}_3 \times {}^A\hat{\bm{s}}_3)^T \\
{{}^A\hat{\bm{s}}_4}^T & ({}^A\bm{b}_4 \times {}^A\hat{\bm{s}}_4)^T \\
{{}^A\hat{\bm{s}}_5}^T & ({}^A\bm{b}_5 \times {}^A\hat{\bm{s}}_5)^T \\
{{}^A\hat{\bm{s}}_6}^T & ({}^A\bm{b}_6 \times {}^A\hat{\bm{s}}_6)^T
\end{bmatrix}
\end{equation}
@ -284,7 +284,7 @@ It can be computed once at the rest position and used for both forward and inver
\begin{figure}[htbp]
\centering
\includegraphics[scale=1]{figs/nhexa_forward_kinematics_approximate_errors.png}
\caption{\label{fig:nhexa_forward_kinematics_approximate_errors}Errors associated with the use of the Jacobian matrix to solve the forward kinematic problem}
\caption{\label{fig:nhexa_forward_kinematics_approximate_errors}Errors associated with the use of the Jacobian matrix to solve the forward kinematic problem. A Stewart platform with an height of \(100\,mm\) was used to perform this analysis}
\end{figure}
\paragraph{Static Forces}
@ -425,73 +425,140 @@ While a reasonable geometric configuration will be used to validate the NASS dur
\chapter{Multi-Body Model}
\label{sec:nhexa_model}
\textbf{Goal}:
\begin{itemize}
\item Study the dynamics of Stewart platform
\item Instead of working with complex analytical models: a multi-body model is used.
Complex because has to model the inertia of the struts.
Cite papers that tries to model the stewart platform analytically
Advantage: it will be easily included in the model of the NASS
\item[{$\square$}] Have a table somewhere that summarizes the main characteristics of the nano-hexapod model
\begin{itemize}
\item location of joints
\item size / mass of platforms, etc\ldots{}
\end{itemize}
\end{itemize}
\section{Model Definition}
\label{ssec:nhexa_model_def}
\paragraph{Geometry}
\begin{itemize}
\item[{$\square$}] Make a schematic of the definition process (for instance knowing the ai, bi points + \{A\} and \{B\} allows to compute Jacobian, etc\ldots{})
The geometry of the Stewart platform (see Figure \ref{fig:nhexa_stewart_model_def}) is defined by the position of frame \(\{F\}\) with respect to \(\{M\}\) and by the locations of the joints \({}^Fa_i\) and \({}^Mb_i\).
The point of interest, indicated by frame \(\{A\}\) is located \(150\,mm\) above the top platform (i.e. above the \(\{M\}\) frame).
Parameters that defines the geometry of the nano-hexapod multi-body models are summarized in Table \ref{tab:nhexa_stewart_model_geometry}.
\item What is important for the model:
\begin{itemize}
\item Inertia of plates and struts
\item Positions of joints / Orientation of struts
\item Definition of frames (for Jacobian, stiffness analysis, etc\ldots{})
\end{itemize}
\end{itemize}
From this, the orientation \(\hat{s}_i\) and length \(l_i\) of the struts can be computed, the Jacobian matrix \(\bm{J}\) can be computed, and the kinematics of the Stewart platform can be studied.
Then, several things can be computed:
\begin{itemize}
\item Kinematics, stiffness, platform mobility, dynamics, etc\ldots{}
\end{itemize}
\begin{minipage}[b]{0.6\linewidth}
\begin{center}
\includegraphics[scale=1,scale=1]{figs/nhexa_stewart_model_def.png}
\captionof{figure}{\label{fig:nhexa_stewart_model_def}Geometry of the stewart platform}
\end{center}
\end{minipage}
\hfill
\begin{minipage}[b]{0.38\linewidth}
\begin{scriptsize}
\centering
\begin{tabularx}{0.75\linewidth}{Xrrr}
\toprule
& \(\bm{x}\) & \(\bm{y}\) & \(\bm{z}\)\\
\midrule
\({}^MO_B\) & \(0\) & \(0\) & \(150\)\\
\({}^FO_M\) & \(0\) & \(0\) & \(95\)\\
\({}^Fa_1\) & \(-92\) & \(-77\) & \(20\)\\
\({}^Fa_2\) & \(92\) & \(-77\) & \(20\)\\
\({}^Fa_3\) & \(113\) & \(-41\) & \(20\)\\
\({}^Fa_4\) & \(21\) & \(118\) & \(20\)\\
\({}^Fa_5\) & \(-21\) & \(118\) & \(20\)\\
\({}^Fa_6\) & \(-113\) & \(-41\) & \(20\)\\
\({}^Mb_1\) & \(-28\) & \(-106\) & \(-20\)\\
\({}^Mb_2\) & \(28\) & \(-106\) & \(-20\)\\
\({}^Mb_3\) & \(106\) & \(28\) & \(-20\)\\
\({}^Mb_4\) & \(78\) & \(78\) & \(-20\)\\
\({}^Mb_5\) & \(-78\) & \(78\) & \(-20\)\\
\({}^Mb_6\) & \(-106\) & \(28\) & \(-20\)\\
\bottomrule
\end{tabularx}
\captionof{table}{\label{tab:nhexa_stewart_model_geometry}Parameter values in [mm]}
\end{scriptsize}
\end{minipage}
\paragraph{Inertia of Plates}
\begin{itemize}
\item Joints: can be 2dof to 6dof
\item Actuators: can be modelled as wanted
\end{itemize}
Both the fixed base and the top platform are modelled are solid bodies.
The bottom plate is a cylinder with radius of \(120\,mm\) (matching the size of the micro-hexapod's top platform) and a thickness of \(15\,mm\).
The top plate is also modelled as a cylinder with a radius of \(110\,mm\) and a thickness of \(15,mm\).
Both have a mass of \(5\,kg\).
\section{Nano Hexapod}
\label{ssec:nhexa_model_nano_hexapod}
\paragraph{Joints}
Start simple:
\begin{itemize}
\item Perfect joints, massless actuators
\end{itemize}
The top and bottom joints, different number of DoF can be considered.
universal joint, spherical joint, with added axial stiffness and even with added lateral stiffnesses.
For each DoF, stiffnesses can be added.
Joints: perfect 2dof/3dof (+ mass-less)
Actuators: APA + Encoder (mass-less)
\begin{itemize}
\item k = 1N/um
\item Force sensor
\end{itemize}
During the conceptual design phase, bottom joints are modelled with universal joints (2-DoF) while top joints are modelled with spherical joints (3-DoF).
Both have no stiffness along their DoF and are mass-less.
Definition of each part + Plant with defined inputs/outputs (force sensor, relative displacement sensor, etc\ldots{})
\paragraph{Actuators}
In its simplest form, the actuators are modelled with one prismatic joint having some internal stiffness \(k_a\) and damping \(c_a\), and a force source \(f\).
As was shown using the 3DoF rotating model, having a parallel stiffness \(k_p\) with the force sensor permits to regain the guaranteed stability of decentralized IFF when the spindle is rotating.
A force sensor with output \(f_m\) is added as well as a relative motion sensor with output \(d_L\).
The model of the nano-hexapod actuators used during the conceptual phase are shown in Figure \ref{fig:nhexa_actuator_model} with the parameters summarized in Table \ref{tab:nhexa_actuator_parameters}.
Thanks to the flexibility of the multi-body model, the model of the actuators can later be refined.
\begin{minipage}[b]{0.6\linewidth}
\begin{center}
\includegraphics[scale=1,scale=1]{figs/nhexa_actuator_model.png}
\captionof{figure}{\label{fig:nhexa_actuator_model}Model of the nano-hexapod actuators}
\end{center}
\end{minipage}
\hfill
\begin{minipage}[b]{0.38\linewidth}
\begin{scriptsize}
\centering
\begin{tabularx}{0.4\linewidth}{Xl}
\toprule
& Value\\
\midrule
\(k_a\) & \(1\,N/\mu m\)\\
\(c_a\) & \(50\,N/(m/s)\)\\
\(k_p\) & \(0.05\,N/\mu m\)\\
\bottomrule
\end{tabularx}
\captionof{table}{\label{tab:nhexa_actuator_parameters}Actuator parameters}
\end{scriptsize}
\end{minipage}
\section{Model Dynamics}
\label{ssec:nhexa_model_dynamics}
\begin{itemize}
\item[{$\square$}] Screenshot of the obtained multi-body model ?
\end{itemize}
\begin{minipage}[b]{0.6\linewidth}
\begin{center}
\includegraphics[scale=1,scale=1]{figs/nhexa_stewart_model_input_outputs.png}
\captionof{figure}{\label{fig:nhexa_stewart_model_input_outputs}Nano-Hexapod plant with inputs and outputs. Frames \(\{F\}\) and \(\{M\}\) can be connected to other elements in the multi-body models.}
\end{center}
\end{minipage}
\hfill
\begin{minipage}[b]{0.35\linewidth}
\begin{center}
\includegraphics[scale=1,width=0.90\linewidth]{figs/nhexa_simscape_screenshot.jpg}
\captionof{figure}{\label{fig:nhexa_simscape_screenshot}3D representation of the multi-body model}
\end{center}
\end{minipage}
\begin{itemize}
\item If all is perfect (mass-less struts, perfect joints, etc\ldots{}), maybe compare analytical model with simscape model?
\item Say something about the model order
Model order is 12, and that we can compute modes from matrices M and K, compare with the Simscape model
\item 4 observed modes (due to symmetry, in reality 6 modes)
\item Compare with analytical formulas (see number of states)
\item Effect of 2DoF APA on IFF plant?
\item[{$\square$}] Effect of parallel on IFF plant?
\end{itemize}
\section{Nano Hexapod}
\section*{Conclusion}
\begin{itemize}
\item Validation of multi-body model in a simple case