#+TITLE: Stewart Platform - Dynamics Study
: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: <script src="./js/jquery.min.js"></script>
#+HTML_HEAD: <script src="./js/bootstrap.min.js"></script>
#+HTML_HEAD: <script src="./js/jquery.stickytableheaders.min.js"></script>
#+HTML_HEAD: <script src="./js/readtheorg.js"></script>

#+PROPERTY: header-args:matlab  :session *MATLAB*
#+PROPERTY: header-args:matlab+ :comments org
#+PROPERTY: header-args:matlab+ :exports both
#+PROPERTY: header-args:matlab+ :results none
#+PROPERTY: header-args:matlab+ :eval no-export
#+PROPERTY: header-args:matlab+ :noweb yes
#+PROPERTY: header-args:matlab+ :mkdirp yes
#+PROPERTY: header-args:matlab+ :output-dir figs

#+PROPERTY: header-args:latex  :headers '("\\usepackage{tikz}" "\\usepackage{import}" "\\import{$HOME/Cloud/tikz/org/}{config.tex}")
#+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 file raw replace
#+PROPERTY: header-args:latex+ :buffer no
#+PROPERTY: header-args:latex+ :eval no-export
#+PROPERTY: header-args:latex+ :exports results
#+PROPERTY: header-args:latex+ :mkdirp yes
#+PROPERTY: header-args:latex+ :output-dir figs
#+PROPERTY: header-args:latex+ :post pdf2svg(file=*this*, ext="png")
:END:

* Compare external forces and forces applied by the actuators
** Introduction                                                      :ignore:
In this section, we wish to compare the effect of forces/torques applied by the actuators with the effect of external forces/torques on the displacement of the mobile platform.

** 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
  simulinkproject('../');
#+end_src

#+begin_src matlab
  open('stewart_platform_model.slx')
#+end_src

** Comparison with fixed support
Let's generate a Stewart platform.
#+begin_src matlab
  stewart = initializeStewartPlatform();
  stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
  stewart = generateGeneralConfiguration(stewart);
  stewart = computeJointsPose(stewart);
  stewart = initializeStrutDynamics(stewart);
  stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
  stewart = initializeCylindricalPlatforms(stewart);
  stewart = initializeCylindricalStruts(stewart);
  stewart = computeJacobian(stewart);
  stewart = initializeStewartPose(stewart);
  stewart = initializeInertialSensor(stewart, 'type', 'none');
#+end_src

We don't put any flexibility below the Stewart platform such that *its base is fixed to an inertial frame*.
We also don't put any payload on top of the Stewart platform.
#+begin_src matlab
  ground = initializeGround('type', 'none');
  payload = initializePayload('type', 'none');
  controller = initializeController('type', 'open-loop');
#+end_src

The transfer function from actuator forces $\bm{\tau}$ to the relative displacement of the mobile platform $\mathcal{\bm{X}}$ is extracted.
#+begin_src matlab
  %% Options for Linearized
  options = linearizeOptions;
  options.SampleTime = 0;

  %% Name of the Simulink File
  mdl = 'stewart_platform_model';

  %% Input/Output definition
  clear io; io_i = 1;
  io(io_i) = linio([mdl, '/Controller'],              1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
  io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}

  %% Run the linearization
  G = linearize(mdl, io, options);
  G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
  G.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
#+end_src

Using the Jacobian matrix, we compute the transfer function from force/torques applied by the actuators on the frame $\{B\}$ fixed to the mobile platform:
#+begin_src matlab
  Gc = minreal(G*inv(stewart.kinematics.J'));
  Gc.InputName = {'Fnx', 'Fny', 'Fnz', 'Mnx', 'Mny', 'Mnz'};
#+end_src

We also extract the transfer function from external forces $\bm{\mathcal{F}}_{\text{ext}}$ on the frame $\{B\}$ fixed to the mobile platform to the relative displacement $\mathcal{\bm{X}}$ of $\{B\}$ with respect to frame $\{A\}$:
#+begin_src matlab
  %% Input/Output definition
  clear io; io_i = 1;
  io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'F_ext');  io_i = io_i + 1; % External forces/torques applied on {B}
  io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}

  %% Run the linearization
  Gd = linearize(mdl, io, options);
  Gd.InputName  = {'Fex', 'Fey', 'Fez', 'Mex', 'Mey', 'Mez'};
  Gd.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
#+end_src

The comparison of the two transfer functions is shown in Figure [[fig:comparison_Fext_F_fixed_base]].

#+begin_src matlab :exports none
  freqs = logspace(1, 4, 1000);

  figure;

  ax1 = subplot(2, 1, 1);
  hold on;
  plot(freqs, abs(squeeze(freqresp(Gc(1,1), freqs, 'Hz'))), '-');
  plot(freqs, abs(squeeze(freqresp(Gd(1,1), freqs, 'Hz'))), '--');
  hold off;
  set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
  ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);

  ax2 = subplot(2, 1, 2);
  hold on;
  plot(freqs, 180/pi*angle(squeeze(freqresp(Gc(1,1), freqs, 'Hz'))), '-');
  plot(freqs, 180/pi*angle(squeeze(freqresp(Gd(1,1), freqs, 'Hz'))), '--');
  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({'$\mathcal{X}_{x}/\mathcal{F}_{x}$', '$\mathcal{X}_{x}/\mathcal{F}_{x,ext}$'});

  linkaxes([ax1,ax2],'x');
#+end_src

#+header: :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/comparison_Fext_F_fixed_base.pdf" :var figsize="full-tall" :post pdf2svg(file=*this*, ext="png")
<<plt-matlab>>
#+end_src

#+name: fig:comparison_Fext_F_fixed_base
#+caption: Comparison of the transfer functions from $\bm{\mathcal{F}}$ to $\mathcal{\bm{X}}$ and from $\bm{\mathcal{F}}_{\text{ext}}$ to $\mathcal{\bm{X}}$ ([[./figs/comparison_Fext_F_fixed_base.png][png]], [[./figs/comparison_Fext_F_fixed_base.pdf][pdf]])
[[file:figs/comparison_Fext_F_fixed_base.png]]

This can be understood from figure [[fig:1dof_actuator_external_forces]] where $\mathcal{F}_{x}$ and $\mathcal{F}_{x,\text{ext}}$ have clearly the same effect on $\mathcal{X}_{x}$.

#+begin_src latex :file 1dof_actuator_external_forces.pdf
  \begin{tikzpicture}
    \draw[ground] (-1, 0) -- (1, 0);

    \draw[spring]   (-0.6, 0) -- (-0.6, 1.5) node[midway, left=0.1]{$k$};
    \draw[actuator] ( 0.6, 0) -- ( 0.6, 1.5) node[midway, left=0.1](F){$\mathcal{F}_{x}$};

    \draw[fill=white] (-1, 1.5) rectangle (1, 2) node[pos=0.5]{$m$};

    \draw[dashed] (1, 2) -- ++(0.5, 0);
    \draw[->] (1.5, 2) -- ++(0, 0.5) node[right]{$\mathcal{X}_{x}$};

    \draw[->] (0, 2) node[]{$\bullet$} -- (0, 2.8) node[below right]{$\mathcal{F}_{x,\text{ext}}$};
  \end{tikzpicture}
#+end_src

#+name: fig:1dof_actuator_external_forces
#+caption: Schematic representation of the stewart platform on a rigid support
#+RESULTS:
[[file:figs/1dof_actuator_external_forces.png]]

** Comparison with a flexible support
We now add a flexible support under the Stewart platform.
#+begin_src matlab
  ground = initializeGround('type', 'flexible');
#+end_src

And we perform again the identification.
#+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 Force Inputs [N]
  io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}

  %% Run the linearization
  G = linearize(mdl, io, options);
  G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
  G.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};

  Gc = minreal(G*inv(stewart.kinematics.J'));
  Gc.InputName = {'Fnx', 'Fny', 'Fnz', 'Mnx', 'Mny', 'Mnz'};

  %% Input/Output definition
  clear io; io_i = 1;
  io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'F_ext');  io_i = io_i + 1; % External forces/torques applied on {B}
  io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}

  %% Run the linearization
  Gd = linearize(mdl, io, options);
  Gd.InputName  = {'Fex', 'Fey', 'Fez', 'Mex', 'Mey', 'Mez'};
  Gd.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
#+end_src

The comparison between the obtained transfer functions is shown in Figure [[fig:comparison_Fext_F_flexible_base]].

#+begin_src matlab :exports none
  freqs = logspace(1, 4, 1000);

  figure;

  ax1 = subplot(2, 1, 1);
  hold on;
  plot(freqs, abs(squeeze(freqresp(Gc(1,1), freqs, 'Hz'))), '-');
  plot(freqs, abs(squeeze(freqresp(Gd(1,1), freqs, 'Hz'))), '--');
  hold off;
  set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
  ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]);

  ax2 = subplot(2, 1, 2);
  hold on;
  plot(freqs, 180/pi*angle(squeeze(freqresp(Gc(1,1), freqs, 'Hz'))), '-');
  plot(freqs, 180/pi*angle(squeeze(freqresp(Gd(1,1), freqs, 'Hz'))), '--');
  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({'$\mathcal{X}_{x}/\mathcal{F}_{x}$', '$\mathcal{X}_{x}/\mathcal{F}_{x,ext}$'});

  linkaxes([ax1,ax2],'x');
#+end_src

#+header: :tangle no :exports results :results none :noweb yes
#+begin_src matlab :var filepath="figs/comparison_Fext_F_flexible_base.pdf" :var figsize="full-tall" :post pdf2svg(file=*this*, ext="png")
<<plt-matlab>>
#+end_src

#+name: fig:comparison_Fext_F_flexible_base
#+caption: Comparison of the transfer functions from $\bm{\mathcal{F}}$ to $\mathcal{\bm{X}}$ and from $\bm{\mathcal{F}}_{\text{ext}}$ to $\mathcal{\bm{X}}$ ([[./figs/comparison_Fext_F_flexible_base.png][png]], [[./figs/comparison_Fext_F_flexible_base.pdf][pdf]])
[[file:figs/comparison_Fext_F_flexible_base.png]]

The addition of a flexible support can be schematically represented in Figure [[fig:2dof_actuator_external_forces]].
We see that $\mathcal{F}_{x}$ applies a force both on $m$ and $m^{\prime}$ whereas $\mathcal{F}_{x,\text{ext}}$ only applies a force on $m$.
And thus $\mathcal{F}_{x}$ and $\mathcal{F}_{x,\text{ext}}$ have clearly *not* the same effect on $\mathcal{X}_{x}$.

#+begin_src latex :file 2dof_actuator_external_forces.pdf
  \begin{tikzpicture}
    \draw[ground] (-1, 0) -- (1, 0);

    \draw[spring]   (0, 0) -- (0, 1.5) node[midway, left=0.1]{$k^{\prime}$};
    \draw[fill=white] (-1, 1.5) rectangle (1, 2) node[pos=0.5]{$m^{\prime}$};

    \draw[spring]   (-0.6, 2) -- (-0.6, 3.5) node[midway, left=0.1]{$k$};
    \draw[actuator] ( 0.6, 2) -- ( 0.6, 3.5) node[midway, left=0.1](F){$\mathcal{F}_{x}$};

    \draw[fill=white] (-1, 3.5) rectangle (1, 4) node[pos=0.5]{$m$};

    \draw[dashed] (1, 4) -- ++(0.5, 0);
    \draw[->] (1.5, 4) -- ++(0, 0.5) node[right]{$\mathcal{X}_{x}$};

    \draw[->] (0, 4) node[]{$\bullet$} -- (0, 4.8) node[below right]{$\mathcal{F}_{x,\text{ext}}$};
  \end{tikzpicture}
#+end_src

#+name: fig:2dof_actuator_external_forces
#+caption: Schematic representation of the stewart platform on top of a flexible support
#+RESULTS:
[[file:figs/2dof_actuator_external_forces.png]]


** Conclusion
#+begin_important
The transfer function from forces/torques applied by the actuators on the payload $\bm{\mathcal{F}} = \bm{J}^T \bm{\tau}$ to the pose of the mobile platform $\bm{\mathcal{X}}$ is the same as the transfer function from external forces/torques to $\bm{\mathcal{X}}$ as long as the Stewart platform's base is fixed.
#+end_important

* Comparison of the static transfer function and the Compliance matrix
** Introduction                                                      :ignore:
In this section, we see how the Compliance matrix of the Stewart platform is linked to the static relation between $\mathcal{\bm{F}}$ to $\mathcal{\bm{X}}$.

** 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
  simulinkproject('../');
#+end_src

#+begin_src matlab
  open('stewart_platform_model.slx')
#+end_src

** Analysis
Initialization of the Stewart platform.
#+begin_src matlab
  stewart = initializeStewartPlatform();
  stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
  stewart = generateGeneralConfiguration(stewart);
  stewart = computeJointsPose(stewart);
  stewart = initializeStrutDynamics(stewart);
  stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
  stewart = initializeCylindricalPlatforms(stewart);
  stewart = initializeCylindricalStruts(stewart);
  stewart = computeJacobian(stewart);
  stewart = initializeStewartPose(stewart);
  stewart = initializeInertialSensor(stewart, 'type', 'none');
#+end_src

No flexibility below the Stewart platform and no payload.
#+begin_src matlab
  ground = initializeGround('type', 'none');
  payload = initializePayload('type', 'none');
  controller = initializeController('type', 'open-loop');
#+end_src

Estimation of the transfer function from $\mathcal{\bm{F}}$ to $\mathcal{\bm{X}}$:
#+begin_src matlab
  %% Options for Linearized
  options = linearizeOptions;
  options.SampleTime = 0;

  %% Name of the Simulink File
  mdl = 'stewart_platform_model';

  %% Input/Output definition
  clear io; io_i = 1;
  io(io_i) = linio([mdl, '/Controller'],              1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
  io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}

  %% Run the linearization
  G = linearize(mdl, io, options);
  G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
  G.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
#+end_src

#+begin_src matlab
  Gc = minreal(G*inv(stewart.kinematics.J'));
  Gc.InputName = {'Fnx', 'Fny', 'Fnz', 'Mnx', 'Mny', 'Mnz'};
#+end_src

Let's first look at the low frequency transfer function matrix from $\mathcal{\bm{F}}$ to $\mathcal{\bm{X}}$.
#+begin_src matlab :exports results :results value table replace :tangle no
data2orgtable(real(freqresp(Gd, 0.1)), {}, {}, ' %.1e ');
#+end_src

#+RESULTS:
|  4.7e-08 | -7.2e-19 |  5.0e-18 | -8.9e-18 |  3.2e-07 |  9.9e-18 |
|  4.7e-18 |  4.7e-08 | -5.7e-18 | -3.2e-07 | -1.6e-17 | -1.7e-17 |
|  3.3e-18 | -6.3e-18 |  2.1e-08 |  4.4e-17 |  6.6e-18 |  7.4e-18 |
| -3.2e-17 | -3.2e-07 |  6.2e-18 |  5.2e-06 | -3.5e-16 |  6.3e-17 |
|  3.2e-07 |  2.7e-17 |  4.8e-17 | -4.5e-16 |  5.2e-06 | -1.2e-19 |
|  4.0e-17 | -9.5e-17 |  8.4e-18 |  4.3e-16 |  5.8e-16 |  1.7e-06 |

And now at the Compliance matrix.
#+begin_src matlab :exports results :results value table replace :tangle no
data2orgtable(stewart.kinematics.C, {}, {}, ' %.1e ');
#+end_src

#+RESULTS:
|  4.7e-08 | -2.0e-24 |  7.4e-25 |  5.9e-23 |  3.2e-07 |  5.9e-24 |
| -7.1e-25 |  4.7e-08 |  2.9e-25 | -3.2e-07 | -5.4e-24 | -3.3e-23 |
|  7.9e-26 | -6.4e-25 |  2.1e-08 |  1.9e-23 |  5.3e-25 | -6.5e-40 |
|  1.4e-23 | -3.2e-07 |  1.3e-23 |  5.2e-06 |  4.9e-22 | -3.8e-24 |
|  3.2e-07 |  7.6e-24 |  1.2e-23 |  6.9e-22 |  5.2e-06 | -2.6e-22 |
|  7.3e-24 | -3.2e-23 | -1.6e-39 |  9.9e-23 | -3.3e-22 |  1.7e-06 |

** Conclusion
#+begin_important
The low frequency transfer function matrix from $\mathcal{\bm{F}}$ to $\mathcal{\bm{X}}$ corresponds to the compliance matrix of the Stewart platform.
#+end_important
