#+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: #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: #+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/thesis/latex/}{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) <> #+end_src #+begin_src matlab :exports none :results silent :noweb yes <> #+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") <> #+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") <> #+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) <> #+end_src #+begin_src matlab :exports none :results silent :noweb yes <> #+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