#+TITLE: Stewart Platform with Flexible Elements :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: #+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: * Simscape Model ** 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 :results none :exports none simulinkproject('../'); #+end_src ** Flexible APA #+begin_src matlab apa = load('./mat/APA300ML.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K'); #+end_src #+begin_src matlab :exports results :results value table replace :tangle no data2orgtable([length(apa.n_i); length(apa.int_i); size(apa.M,1) - 6*length(apa.int_i); size(apa.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 | 7 | | Number of interface Nodes | 7 | | Number of Modes | 120 | | Size of M and K matrices | 162 | #+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*) data2orgtable([[1:length(apa.int_i)]', apa.int_i, apa.int_xyz], {}, {'Node i', 'Node Number', 'x [m]', 'y [m]', 'z [m]'}, ' %f '); #+end_src #+caption: Coordinates of the interface nodes #+RESULTS: | Node i | Node Number | x [m] | y [m] | z [m] | |--------+-------------+---------+-------+--------| | 1.0 | 697783.0 | 0.0 | 0.0 | -0.015 | | 2.0 | 697784.0 | 0.0 | 0.0 | 0.015 | | 3.0 | 697785.0 | -0.0325 | 0.0 | 0.0 | | 4.0 | 697786.0 | -0.0125 | 0.0 | 0.0 | | 5.0 | 697787.0 | -0.0075 | 0.0 | 0.0 | | 6.0 | 697788.0 | 0.0125 | 0.0 | 0.0 | | 7.0 | 697789.0 | 0.0325 | 0.0 | 0.0 | ** Flexible Joint #+begin_src matlab flex_joint = load('./mat/flexor_025.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K'); #+end_src #+begin_src matlab :exports results :results value table replace :tangle no data2orgtable([length(flex_joint.n_i); length(flex_joint.int_i); size(flex_joint.M,1) - 6*length(flex_joint.int_i); size(flex_joint.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 | 2 | | Number of interface Nodes | 2 | | Number of Modes | 6 | | Size of M and K matrices | 18 | #+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*) data2orgtable([[1:length(flex_joint.int_i)]', flex_joint.int_i, flex_joint.int_xyz], {}, {'Node i', 'Node Number', 'x [m]', 'y [m]', 'z [m]'}, ' %f '); #+end_src #+caption: Coordinates of the interface nodes #+RESULTS: | Node i | Node Number | x [m] | y [m] | z [m] | |--------+-------------+-------+-------+-------| | 1.0 | 528875.0 | 0.0 | 0.0 | 0.0 | | 2.0 | 528876.0 | 0.0 | 0.0 | -0.0 | #+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*) data2orgtable([1e-6*flex_joint.K(3,3), flex_joint.K(4,4), flex_joint.K(5,5), flex_joint.K(6,6)]', {'Axial Stiffness [N/um]', 'Bending Stiffness [Nm/rad]', 'Bending Stiffness [Nm/rad]', 'Torsion Stiffness [Nm/rad]'}, {'*Caracteristic*', '*Value*'}, ' %0.f '); #+end_src #+RESULTS: | *Caracteristic* | *Value* | |----------------------------+---------| | Axial Stiffness [N/um] | 94 | | Bending Stiffness [Nm/rad] | 5 | | Bending Stiffness [Nm/rad] | 5 | | Torsion Stiffness [Nm/rad] | 260 | ** Identification And we identify the dynamics from force actuators to force sensors. #+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, '/Stewart Platform'], 1, 'openoutput', [], 'dLm'); io_i = io_i + 1; % Relative Displacement Outputs [m] io(io_i) = linio([mdl, '/Stewart Platform'], 1, 'openoutput', [], 'Taum'); io_i = io_i + 1; % Force Sensors [N] #+end_src #+begin_src matlab ground = initializeGround('type', 'none'); payload = initializePayload('type', 'rigid', 'm', 50); controller = initializeController('type', 'open-loop'); #+end_src #+begin_src matlab disturbances = initializeDisturbances(); #+end_src ** No Flexible Elements #+begin_src matlab stewart = initializeStewartPlatform(); stewart = initializeFramesPositions(stewart); stewart = generateGeneralConfiguration(stewart); stewart = computeJointsPose(stewart); stewart = initializeAmplifiedStrutDynamics(stewart, 'Ke', 1.5e6*ones(6,1), 'Ka', 40.5e6*ones(6,1), 'K1', 0.4e6*ones(6,1)); stewart = initializeJointDynamics(stewart, 'type_M', 'spherical_3dof', ... 'Kr_M', flex_joint.K(1,1)*ones(6,1), ... 'Ka_M', flex_joint.K(3,3)*ones(6,1), ... 'Kf_M', flex_joint.K(4,4)*ones(6,1), ... 'Kt_M', flex_joint.K(6,6)*ones(6,1), ... 'type_F', 'universal_3dof', ... 'Kr_F', flex_joint.K(1,1)*ones(6,1), ... 'Ka_F', flex_joint.K(3,3)*ones(6,1), ... 'Kf_F', flex_joint.K(4,4)*ones(6,1), ... 'Kt_F', flex_joint.K(6,6)*ones(6,1)); stewart = initializeCylindricalPlatforms(stewart); stewart = initializeCylindricalStruts(stewart); stewart = computeJacobian(stewart); stewart = initializeStewartPose(stewart); stewart = initializeInertialSensor(stewart); references = initializeReferences(stewart); #+end_src #+begin_src matlab %% Run the linearization G = linearize(mdl, io, options); G.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'}; G.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6', 'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'}; #+end_src ** Flexible joints #+name: fig:simscape_flex_joints #+caption: Figure caption [[file:figs/simscape_flex_joints.png]] #+begin_src matlab stewart = initializeStewartPlatform(); stewart = initializeFramesPositions(stewart); stewart = generateGeneralConfiguration(stewart); stewart = computeJointsPose(stewart); stewart = initializeAmplifiedStrutDynamics(stewart, 'Ke', 1.5e6*ones(6,1), 'Ka', 40.5e6*ones(6,1), 'K1', 0.4e6*ones(6,1)); stewart = initializeJointDynamics(stewart, 'type_F', 'flexible', 'K_F', flex_joint.K, 'M_F', flex_joint.M, 'n_xyz_F', flex_joint.n_xyz, 'xi_F', 0.1, 'step_file_F', 'mat/flexor_ID16.STEP', 'type_M', 'flexible', 'K_M', flex_joint.K, 'M_M', flex_joint.M, 'n_xyz_M', flex_joint.n_xyz, 'xi_M', 0.1, 'step_file_M', 'mat/flexor_ID16.STEP'); stewart = initializeCylindricalPlatforms(stewart); stewart = initializeCylindricalStruts(stewart); stewart = computeJacobian(stewart); stewart = initializeStewartPose(stewart); stewart = initializeInertialSensor(stewart); #+end_src #+begin_src matlab %% Run the linearization Gj = linearize(mdl, io, options); Gj.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'}; Gj.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6', 'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'}; #+end_src ** Flexible APA #+name: fig:simscape_flex_apa #+caption: Figure caption [[file:figs/simscape_flex_apa.png]] #+begin_src matlab stewart = initializeStewartPlatform(); stewart = initializeFramesPositions(stewart); stewart = generateGeneralConfiguration(stewart); stewart = computeJointsPose(stewart); stewart = initializeFlexibleStrutDynamics(stewart, 'H', 0.03, 'K', apa.K, 'M', apa.M, 'n_xyz', apa.n_xyz, 'xi', 0.1, 'Gf', -2.65e7, 'step_file', 'mat/APA300ML.STEP'); stewart = initializeJointDynamics(stewart, 'type_M', 'spherical_3dof', ... 'Kr_M', flex_joint.K(1,1)*ones(6,1), ... 'Ka_M', flex_joint.K(3,3)*ones(6,1), ... 'Kf_M', flex_joint.K(4,4)*ones(6,1), ... 'Kt_M', flex_joint.K(6,6)*ones(6,1), ... 'type_F', 'universal_3dof', ... 'Kr_F', flex_joint.K(1,1)*ones(6,1), ... 'Ka_F', flex_joint.K(3,3)*ones(6,1), ... 'Kf_F', flex_joint.K(4,4)*ones(6,1), ... 'Kt_F', flex_joint.K(6,6)*ones(6,1)); stewart = initializeCylindricalPlatforms(stewart); stewart = initializeCylindricalStruts(stewart, 'type_F', 'none', 'type_M', 'none'); stewart = computeJacobian(stewart); stewart = initializeStewartPose(stewart); stewart = initializeInertialSensor(stewart); #+end_src #+begin_src matlab %% Run the linearization Ga = -linearize(mdl, io, options); Ga.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'}; Ga.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6', 'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'}; #+end_src ** Flexible Joints and APA #+name: fig:simscape_flexible #+caption: Figure caption [[file:figs/simscape_flexible.png]] #+begin_src matlab stewart = initializeStewartPlatform(); stewart = initializeFramesPositions(stewart); stewart = generateGeneralConfiguration(stewart); stewart = computeJointsPose(stewart); stewart = initializeFlexibleStrutDynamics(stewart, 'H', 0.03, 'K', apa.K, 'M', apa.M, 'n_xyz', apa.n_xyz, 'xi', 0.1, 'Gf', -2.65e7, 'step_file', 'mat/APA300ML.STEP'); stewart = initializeJointDynamics(stewart, 'type_F', 'flexible', 'K_F', flex_joint.K, 'M_F', flex_joint.M, 'n_xyz_F', flex_joint.n_xyz, 'xi_F', 0.1, 'step_file_F', 'mat/flexor_ID16.STEP', 'type_M', 'flexible', 'K_M', flex_joint.K, 'M_M', flex_joint.M, 'n_xyz_M', flex_joint.n_xyz, 'xi_M', 0.1, 'step_file_M', 'mat/flexor_ID16.STEP'); stewart = initializeCylindricalPlatforms(stewart); stewart = initializeCylindricalStruts(stewart, 'type_F', 'none', 'type_M', 'none'); stewart = computeJacobian(stewart); stewart = initializeStewartPose(stewart); stewart = initializeInertialSensor(stewart); #+end_src #+begin_src matlab Gf = -linearize(mdl, io, options); Gf.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'}; Gf.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6', 'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'}; #+end_src ** Save #+begin_src matlab save('./mat/flexible_stewart_platform.mat', 'G', 'Gj', 'Ga', 'Gf'); #+end_src ** Direct Velocity Feedback #+begin_src matlab :exports none freqs = logspace(0, 3, 1000); figure; ax1 = subplot(2, 1, 1); hold on; for i = 1:6 plot(freqs, abs(squeeze(freqresp(G(i,i), freqs, 'Hz'))), 'color', [0 0.4470 0.7410 0.2]); end for i = 1:6 plot(freqs, abs(squeeze(freqresp(Gj(i,i), freqs, 'Hz'))), 'color', [0.8500 0.3250 0.0980 0.2]); end for i = 1:6 plot(freqs, abs(squeeze(freqresp(Ga(i,i), freqs, 'Hz'))), 'color', [0.9290 0.6940 0.1250 0.2]); end for i = 1:6 plot(freqs, abs(squeeze(freqresp(Gf(i,i), freqs, 'Hz'))), 'color', [0.4940 0.1840 0.5560 0.2]); end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); ax2 = subplot(2, 1, 2); hold on; for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(G(i,i), freqs, 'Hz'))), 'color', [0 0.4470 0.7410 0.2]); end for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Gj(i,i), freqs, 'Hz'))), 'color', [0.8500 0.3250 0.0980 0.2]); end for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Ga(i,i), freqs, 'Hz'))), 'color', [0.9290 0.6940 0.1250 0.2]); end for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Gf(i,i), freqs, 'Hz'))), 'color', [0.4940 0.1840 0.5560 0.2]); end h = zeros(4, 1); h(1) = plot(NaN, NaN, 'color', [0 0.4470 0.7410 0.2]); h(2) = plot(NaN, NaN, 'color', [0.8500 0.3250 0.0980 0.2]); h(3) = plot(NaN, NaN, 'color', [0.9290 0.6940 0.1250 0.2]); h(4) = plot(NaN, NaN, 'color', [0.4940 0.1840 0.5560 0.2]); legend(h, 'No flexible', 'Flexible Joints', 'Flexible APA', 'All Flexible'); 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'); #+end_src #+begin_src matlab :tangle no :exports results :results file replace exportFig('figs/flexible_elements_effect_dvf.pdf', 'width', 'full', 'height', 'full'); #+end_src #+name: fig:flexible_elements_effect_dvf #+caption: Change of the DVF plant dynamics with the added flexible elements #+RESULTS: [[file:figs/flexible_elements_effect_dvf.png]] ** Integral Force Feedback #+begin_src matlab :exports none freqs = logspace(0, 3, 1000); figure; ax1 = subplot(2, 1, 1); hold on; for i = 1:6 plot(freqs, abs(squeeze(freqresp(G(6+i,i), freqs, 'Hz'))), 'color', [0 0.4470 0.7410 0.2]); end for i = 1:6 plot(freqs, abs(squeeze(freqresp(Gj(6+i,i), freqs, 'Hz'))), 'color', [0.8500 0.3250 0.0980 0.2]); end for i = 1:6 plot(freqs, abs(squeeze(freqresp(Ga(6+i,i), freqs, 'Hz'))), 'color', [0.9290 0.6940 0.1250 0.2]); end for i = 1:6 plot(freqs, abs(squeeze(freqresp(Gf(6+i,i), freqs, 'Hz'))), 'color', [0.4940 0.1840 0.5560 0.2]); end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [N/N]'); set(gca, 'XTickLabel',[]); ax2 = subplot(2, 1, 2); hold on; for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(G(6+i,i), freqs, 'Hz'))), 'color', [0 0.4470 0.7410 0.2]); end for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Gj(6+i,i), freqs, 'Hz'))), 'color', [0.8500 0.3250 0.0980 0.2]); end for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Ga(6+i,i), freqs, 'Hz'))), 'color', [0.9290 0.6940 0.1250 0.2]); end for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Gf(6+i,i), freqs, 'Hz'))), 'color', [0.4940 0.1840 0.5560 0.2]); end h = zeros(4, 1); h(1) = plot(NaN, NaN, 'color', [0 0.4470 0.7410 0.2]); h(2) = plot(NaN, NaN, 'color', [0.8500 0.3250 0.0980 0.2]); h(3) = plot(NaN, NaN, 'color', [0.9290 0.6940 0.1250 0.2]); h(4) = plot(NaN, NaN, 'color', [0.4940 0.1840 0.5560 0.2]); legend(h, 'No flexible', 'Flexible Joints', 'Flexible APA', 'All Flexible'); 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'); #+end_src #+begin_src matlab :tangle no :exports results :results file replace exportFig('figs/flexible_elements_effect_iff.pdf', 'width', 'full', 'height', 'full'); #+end_src #+name: fig:flexible_elements_effect_iff #+caption: Change of the IFF plant dynamics with the added flexible elements #+RESULTS: [[file:figs/flexible_elements_effect_iff.png]] ** Procedure to include flexible elements into Simscape In order to model a flexible element with only few mass-spring-damper elements: - FEM of the flexible element - Super-Element extraction - Parameters to extract - For the flexible joint: axial, shear, bending and torsion stiffnesses - For the APA: k1, ka, ke, c1 - This can be done directly from the Stiffness matrix or using identification from a simple Simscape model ** Conclusion #+begin_important The results seems to indicate that the model is well represented with only few degrees of freedom. This permit to have a relatively sane number of states for the model. #+end_important * Control with flexible elements ** 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 :results none :exports none simulinkproject('../'); #+end_src ** Flexible APA and Flexible Joint #+begin_src matlab apa = load('./mat/APA300ML.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K'); flex_joint = load('./mat/flexor_ID16.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K'); #+end_src #+begin_src matlab stewart = initializeStewartPlatform(); stewart = initializeFramesPositions(stewart); stewart = generateGeneralConfiguration(stewart); stewart = computeJointsPose(stewart); stewart = initializeFlexibleStrutDynamics(stewart, 'H', 0.03, 'K', apa.K, 'M', apa.M, 'n_xyz', apa.n_xyz, 'xi', 0.1, 'step_file', 'mat/APA300ML.STEP'); stewart = initializeJointDynamics(stewart, 'type_F', 'flexible', 'K_F', flex_joint.K, 'M_F', flex_joint.M, 'n_xyz_F', flex_joint.n_xyz, 'xi_F', 0.1, 'step_file_F', 'mat/flexor_ID16.STEP', 'type_M', 'flexible', 'K_M', flex_joint.K, 'M_M', flex_joint.M, 'n_xyz_M', flex_joint.n_xyz, 'xi_M', 0.1, 'step_file_M', 'mat/flexor_ID16.STEP'); stewart = initializeCylindricalPlatforms(stewart); stewart = initializeCylindricalStruts(stewart, 'type_F', 'none', 'type_M', 'none'); stewart = computeJacobian(stewart); stewart = initializeStewartPose(stewart); stewart = initializeInertialSensor(stewart); #+end_src #+begin_src matlab ground = initializeGround('type', 'none'); payload = initializePayload('type', 'rigid', 'm', 50); controller = initializeController('type', 'open-loop'); #+end_src #+begin_src matlab disturbances = initializeDisturbances(); references = initializeReferences(stewart); #+end_src ** Identification And we identify the dynamics from force actuators to force sensors. #+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, '/Stewart Platform'], 1, 'openoutput', [], 'dLm'); io_i = io_i + 1; % Relative Displacement Outputs [m] #+end_src #+begin_src matlab G = -linearize(mdl, io, options); G.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'}; G.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6'}; #+end_src ** Decentralized Direct Velocity Feedback #+begin_src matlab :exports none freqs = logspace(1, 4, 1000); figure; ax1 = subplot(2, 2, 1); hold on; for i = 1:6 plot(freqs, abs(squeeze(freqresp(G(i, i), freqs, 'Hz')))); end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); title('Diagonal elements of the Plant'); ax2 = subplot(2, 2, 3); hold on; for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(G(i, i), freqs, 'Hz'))), 'DisplayName', sprintf('$\\epsilon_{\\mathcal{L}_%i}/\\tau_%i$', i, i)); 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]); legend('location', 'northwest'); ax3 = subplot(2, 2, 2); hold on; 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]); end end set(gca,'ColorOrderIndex',1); plot(freqs, abs(squeeze(freqresp(G(1, 1), freqs, 'Hz')))); hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); title('Off-Diagonal elements of the Plant'); ax4 = subplot(2, 2, 4); hold on; for i = 1:5 for j = i+1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(G(i, j), freqs, 'Hz'))), 'color', [0, 0, 0, 0.2]); end end set(gca,'ColorOrderIndex',1); plot(freqs, 180/pi*angle(squeeze(freqresp(G(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]); linkaxes([ax1,ax2,ax3,ax4],'x'); #+end_src Controller Design #+begin_src matlab Kl = -1e5*s/(1 + s/2/pi/2e2)/(1 + s/2/pi/5e2) * eye(6); #+end_src #+begin_src matlab :exports none freqs = logspace(1, 4, 1000); figure; ax1 = subplot(2, 1, 1); hold on; plot(freqs, abs(squeeze(freqresp(G(1, 1)*Kl(1,1), freqs, 'Hz')))); hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Loop Gain'); set(gca, 'XTickLabel',[]); ax2 = subplot(2, 1, 2); hold on; plot(freqs, 180/pi*angle(squeeze(freqresp(G(1, 1)*Kl(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]); linkaxes([ax1,ax2],'x'); #+end_src #+begin_src matlab :results replace value isstable(feedback(G(1:6,1:6)*Kl, eye(6), -1)) #+end_src #+RESULTS: : 1 ** HAC #+begin_src matlab Kx = tf(zeros(6)); controller = initializeController('type', 'ref-track-hac-dvf'); #+end_src #+begin_src matlab %% Name of the Simulink File mdl = 'stewart_platform_model'; %% Input/Output definition clear io; io_i = 1; io(io_i) = linio([mdl, '/Controller'], 1, 'input'); io_i = io_i + 1; % Actuator Force Inputs [N] io(io_i) = linio([mdl, '/Relative Motion Sensor'], 1, 'openoutput'); io_i = io_i + 1; % Relative Displacement Outputs [m] %% Run the linearization G = linearize(mdl, io); G.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'}; G.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'}; #+end_src #+begin_src matlab Gl = -stewart.kinematics.J*G; Gl.OutputName = {'D1', 'D2', 'D3', 'D4', 'D5', 'D6'}; #+end_src #+begin_src matlab :exports none freqs = logspace(1, 4, 1000); figure; ax1 = subplot(2, 2, 1); hold on; for i = 1:6 plot(freqs, abs(squeeze(freqresp(Gl(i, i), freqs, 'Hz')))); end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); title('Diagonal elements of the Plant'); ax2 = subplot(2, 2, 3); hold on; for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Gl(i, i), freqs, 'Hz'))), 'DisplayName', sprintf('$\\epsilon_{\\mathcal{L}_%i}/\\tau_%i$', i, i)); 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]); legend('location', 'northwest'); ax3 = subplot(2, 2, 2); hold on; for i = 1:5 for j = i+1:6 plot(freqs, abs(squeeze(freqresp(Gl(i, j), freqs, 'Hz'))), 'color', [0, 0, 0, 0.2]); end end set(gca,'ColorOrderIndex',1); plot(freqs, abs(squeeze(freqresp(Gl(1, 1), freqs, 'Hz')))); hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); title('Off-Diagonal elements of the Plant'); ax4 = subplot(2, 2, 4); hold on; for i = 1:5 for j = i+1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Gl(i, j), freqs, 'Hz'))), 'color', [0, 0, 0, 0.2]); end end set(gca,'ColorOrderIndex',1); plot(freqs, 180/pi*angle(squeeze(freqresp(Gl(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]); linkaxes([ax1,ax2,ax3,ax4],'x'); #+end_src #+begin_src matlab wc = 2*pi*300; Kl = diag(1./diag(abs(freqresp(Gl, wc)))) * wc/s * 1/(1 + s/3/wc); #+end_src #+begin_src matlab :exports none freqs = logspace(1, 3, 1000); figure; ax1 = subplot(2, 1, 1); hold on; for i = 1:6 plot(freqs, abs(squeeze(freqresp(Kl(i, i)*Gl(i, i), freqs, 'Hz')))); end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Loop Gain'); set(gca, 'XTickLabel',[]); ax2 = subplot(2, 1, 2); hold on; for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Kl(i, i)*Gl(i, i), freqs, 'Hz')))); 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'); #+end_src * Flexible Joint Specifications ** 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 :results none :exports none simulinkproject('../'); #+end_src ** Stewart Platform Initialization #+begin_src matlab stewart = initializeStewartPlatform(); stewart = initializeFramesPositions(stewart); stewart = generateGeneralConfiguration(stewart); stewart = computeJointsPose(stewart); stewart = initializeAmplifiedStrutDynamics(stewart, 'Ke', 1.5e6*ones(6,1), 'Ka', 43e6*ones(6,1), 'K1', 0.4e6*ones(6,1), 'C1', 10*ones(6,1)); stewart = initializeCylindricalPlatforms(stewart); stewart = initializeCylindricalStruts(stewart); stewart = computeJacobian(stewart); stewart = initializeStewartPose(stewart); stewart = initializeInertialSensor(stewart); references = initializeReferences(stewart); #+end_src #+begin_src matlab ground = initializeGround('type', 'none'); payload = initializePayload('type', 'rigid', 'm', 50); controller = initializeController('type', 'open-loop'); #+end_src #+begin_src matlab disturbances = initializeDisturbances(); #+end_src #+begin_src matlab open('stewart_platform_model.slx') #+end_src ** Initialization :noexport: #+begin_src matlab freqs = logspace(0, 3, 1000); c1 = [ 0 0.4470 0.7410 0.2]; % Blue c2 = [0.8500 0.3250 0.0980 0.2]; % Orange c3 = [0.9290 0.6940 0.1250 0.2]; % Yellow c4 = [0.4940 0.1840 0.5560 0.2]; % Purple c5 = [0.4660 0.6740 0.1880 0.2]; % Green c6 = [0.3010 0.7450 0.9330 0.2]; % Light Blue c7 = [0.6350 0.0780 0.1840 0.2]; % Red colors = [c1; c2; c3; c4; c5; c6; c7]; #+end_src #+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, '/Stewart Platform'], 1, 'openoutput', [], 'dLm'); io_i = io_i + 1; % Relative Motion - Legs [m] io(io_i) = linio([mdl, '/Stewart Platform'], 1, 'openoutput', [], 'Taum'); io_i = io_i + 1; % Force Sensors [N] #+end_src ** Effect of the Bending Stiffness #+begin_src matlab Kfs = [1, 10, 100, 1000]; % [Nm/rad] #+end_src #+begin_src matlab :exports none Gs = {zeros(length(Kfs))}; for Kfs_i = 1:length(Kfs) stewart = initializeJointDynamics(stewart, 'type_F', 'universal', ... 'type_M', 'spherical', ... 'Kf_M', Kfs(Kfs_i)*ones(6,1), ... 'Kt_M', 0*ones(6,1), ... 'Kf_F', Kfs(Kfs_i)*ones(6,1), ... 'Kt_F', 0*ones(6,1), ... 'Ka_M', 0*ones(6,1), ... 'Kr_M', 0*ones(6,1), ... 'Ka_F', 0*ones(6,1), ... 'Kr_F', 0*ones(6,1)); G = linearize(mdl, io, options); G.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'}; G.OutputName = {'L1', 'L2', 'L3', 'L4', 'L5', 'L6', ... 'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'}; Gs(Kfs_i) = {G}; end #+end_src #+begin_src matlab :exports none figure; ax1 = subplot(2, 1, 1); hold on; for Kfs_i = 1:length(Kfs) plot(freqs, abs(squeeze(freqresp(Gs{Kfs_i}('L1','F1'), freqs, 'Hz'))), 'color', colors(Kfs_i, :), 'DisplayName', sprintf('$k_f = %.0f [Nm/rad]$', Kfs(Kfs_i))); for i = 2:6 plot(freqs, abs(squeeze(freqresp(Gs{Kfs_i}(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'color', colors(Kfs_i, :), 'HandleVisibility', 'off'); end end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); legend('location', 'northeast'); ax2 = subplot(2, 1, 2); hold on; for Kfs_i = 1:length(Kfs) for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Gs{Kfs_i}(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'color', colors(Kfs_i, :)); end 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'); #+end_src #+begin_src matlab :exports none figure; ax1 = subplot(2, 1, 1); hold on; for Kfs_i = 1:length(Kfs) plot(freqs, abs(squeeze(freqresp(Gs{Kfs_i}('Fm1','F1'), freqs, 'Hz'))), 'color', colors(Kfs_i, :), 'DisplayName', sprintf('$k_f = %.0f [Nm/rad]$', Kfs(Kfs_i))); for i = 2:6 plot(freqs, abs(squeeze(freqresp(Gs{Kfs_i}(sprintf('Fm%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'color', colors(Kfs_i, :), 'HandleVisibility', 'off'); end end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); legend('location', 'northeast'); ax2 = subplot(2, 1, 2); hold on; for Kfs_i = 1:length(Kfs) for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Gs{Kfs_i}(sprintf('Fm%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'color', colors(Kfs_i, :)); end 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'); #+end_src ** Effect of the Torsion Stiffness #+begin_src matlab Kts = [10, 100, 500, 1000]; % [Nm/rad] #+end_src #+begin_src matlab :exports none Gt = {zeros(length(Kts))}; for Kts_i = 1:length(Kts) stewart = initializeJointDynamics(stewart, 'type_F', 'universal', ... 'type_M', 'spherical', ... 'Kf_M', 0*ones(6,1), ... 'Kt_M', Kts(Kts_i)*ones(6,1), ... 'Kf_F', 0*ones(6,1), ... 'Kt_F', Kts(Kts_i)*ones(6,1), ... 'Ka_M', 0*ones(6,1), ... 'Kr_M', 0*ones(6,1), ... 'Ka_F', 0*ones(6,1), ... 'Kr_F', 0*ones(6,1)); G = linearize(mdl, io, options); G.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'}; G.OutputName = {'L1', 'L2', 'L3', 'L4', 'L5', 'L6', ... 'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'}; Gt(Kts_i) = {G}; end #+end_src #+begin_src matlab :exports none figure; ax1 = subplot(2, 1, 1); hold on; for Kts_i = 1:length(Kts) plot(freqs, abs(squeeze(freqresp(Gt{Kts_i}('L1','F1'), freqs, 'Hz'))), 'color', colors(Kts_i, :), 'DisplayName', sprintf('$k_t = %.0f [Nm/rad]$', Kts(Kts_i))); for i = 2:6 plot(freqs, abs(squeeze(freqresp(Gt{Kts_i}(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'color', colors(Kts_i, :), 'HandleVisibility', 'off'); end end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); legend('location', 'northeast'); ax2 = subplot(2, 1, 2); hold on; for Kts_i = 1:length(Kts) for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Gt{Kts_i}(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'color', colors(Kts_i, :)); end 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'); #+end_src #+begin_src matlab :exports none figure; ax1 = subplot(2, 1, 1); hold on; for Kts_i = 1:length(Kts) plot(freqs, abs(squeeze(freqresp(Gs{Kts_i}('Fm1','F1'), freqs, 'Hz'))), 'color', colors(Kts_i, :), 'DisplayName', sprintf('$k_f = %.0f [Nm/rad]$', Kts(Kts_i))); for i = 2:6 plot(freqs, abs(squeeze(freqresp(Gs{Kts_i}(sprintf('Fm%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'color', colors(Kts_i, :), 'HandleVisibility', 'off'); end end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); legend('location', 'northeast'); ax2 = subplot(2, 1, 2); hold on; for Kts_i = 1:length(Kts) for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Gs{Kts_i}(sprintf('Fm%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'color', colors(Kts_i, :)); end 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'); #+end_src ** Effect of the Axial Stiffness #+begin_src matlab Kas = [1e6, 1e7, 1e8, 5e8, 1e9]; % [N/m] #+end_src #+begin_src matlab :exports none Ga = {zeros(length(Kas))}; for Kas_i = 1:length(Kas) stewart = initializeJointDynamics(stewart, 'type_F', 'universal_3dof', ... 'type_M', 'spherical_3dof', ... 'Kf_M', 0*ones(6,1), ... 'Kt_M', 0*ones(6,1), ... 'Kf_F', 0*ones(6,1), ... 'Kt_F', 0*ones(6,1), ... 'Ka_M', Kas(Kas_i)*ones(6,1), ... 'Kr_M', 0*ones(6,1), ... 'Ka_F', Kas(Kas_i)*ones(6,1), ... 'Kr_F', 0*ones(6,1)); G = linearize(mdl, io, options); G.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'}; G.OutputName = {'L1', 'L2', 'L3', 'L4', 'L5', 'L6', ... 'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'}; Ga(Kas_i) = {G}; end #+end_src #+begin_src matlab :exports none figure; ax1 = subplot(2, 1, 1); hold on; for Kas_i = 1:length(Kas) plot(freqs, abs(squeeze(freqresp(Ga{Kas_i}('L1','F1'), freqs, 'Hz'))), 'color', colors(Kas_i, :), 'DisplayName', sprintf('$k_a = %.0e [N/m]$', Kas(Kas_i))); for i = 2:6 plot(freqs, abs(squeeze(freqresp(Ga{Kas_i}(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'color', colors(Kas_i, :), 'HandleVisibility', 'off'); end end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); legend('location', 'northeast'); ax2 = subplot(2, 1, 2); hold on; for Kas_i = 1:length(Kas) for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Ga{Kas_i}(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'color', colors(Kas_i, :)); end 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'); #+end_src #+begin_src matlab :exports none figure; ax1 = subplot(2, 1, 1); hold on; for Kas_i = 1:length(Kas) plot(freqs, abs(squeeze(freqresp(Ga{Kas_i}('Fm1','F1'), freqs, 'Hz'))), 'color', colors(Kas_i, :), 'DisplayName', sprintf('$k_a = %.0e [N/m]$', Kas(Kas_i))); for i = 2:6 plot(freqs, abs(squeeze(freqresp(Ga{Kas_i}(sprintf('Fm%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'color', colors(Kas_i, :), 'HandleVisibility', 'off'); end end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); legend('location', 'northeast'); ax2 = subplot(2, 1, 2); hold on; for Kas_i = 1:length(Kas) for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Ga{Kas_i}(sprintf('Fm%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'color', colors(Kas_i, :)); end 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'); #+end_src ** Effect of the Radial (Shear) Stiffness #+begin_src matlab Krs = [1e4, 1e5, 1e6, 1e7]; % [N/m] #+end_src #+begin_src matlab :exports none Gr = {zeros(length(Kas))}; for Krs_i = 1:length(Krs) stewart = initializeJointDynamics(stewart, 'type_F', 'universal_3dof', ... 'type_M', 'spherical_3dof', ... 'Kf_M', 0*ones(6,1), ... 'Kt_M', 0*ones(6,1), ... 'Kf_F', 0*ones(6,1), ... 'Kt_F', 0*ones(6,1), ... 'Ka_M', 1e15*ones(6,1), ... 'Kr_M', Krs(Krs_i)*ones(6,1), ... 'Ka_F', 1e15*ones(6,1), ... 'Kr_F', Krs(Krs_i)*ones(6,1)); G = linearize(mdl, io, options); G.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'}; G.OutputName = {'L1', 'L2', 'L3', 'L4', 'L5', 'L6', ... 'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'}; Gr(Krs_i) = {G}; end #+end_src #+begin_src matlab :exports none figure; ax1 = subplot(2, 1, 1); hold on; for Krs_i = 1:length(Krs) plot(freqs, abs(squeeze(freqresp(Gr{Krs_i}('L1','F1'), freqs, 'Hz'))), 'color', colors(Krs_i, :), 'DisplayName', sprintf('$k_r = %.0e [N/m]$', Krs(Krs_i))); for i = 2:6 plot(freqs, abs(squeeze(freqresp(Gr{Krs_i}(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'color', colors(Krs_i, :), 'HandleVisibility', 'off'); end end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); legend('location', 'northeast'); ax2 = subplot(2, 1, 2); hold on; for Krs_i = 1:length(Krs) for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Gr{Krs_i}(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'color', colors(Krs_i, :)); end 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'); #+end_src #+begin_src matlab :exports none figure; ax1 = subplot(2, 1, 1); hold on; for Krs_i = 1:length(Krs) plot(freqs, abs(squeeze(freqresp(Gr{Krs_i}('Fm1','F1'), freqs, 'Hz'))), 'color', colors(Krs_i, :), 'DisplayName', sprintf('$k_r = %.0e [N/m]$', Krs(Krs_i))); for i = 2:6 plot(freqs, abs(squeeze(freqresp(Gr{Krs_i}(sprintf('Fm%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'color', colors(Krs_i, :), 'HandleVisibility', 'off'); end end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); legend('location', 'northeast'); ax2 = subplot(2, 1, 2); hold on; for Krs_i = 1:length(Krs) for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Gr{Krs_i}(sprintf('Fm%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'color', colors(Krs_i, :)); end 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'); #+end_src ** Comparison of perfect joint and worst specified joint #+begin_src matlab :exports none stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', ... 'type_M', 'spherical_p'); Gp = linearize(mdl, io, options); Gp.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'}; Gp.OutputName = {'L1', 'L2', 'L3', 'L4', 'L5', 'L6', ... 'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'}; stewart = initializeJointDynamics(stewart, 'type_F', 'universal_3dof', ... 'type_M', 'spherical_3dof', ... 'Kf_M', 100*ones(6,1), ... 'Kt_M', 500*ones(6,1), ... 'Kf_F', 100*ones(6,1), ... 'Kt_F', 500*ones(6,1), ... 'Ka_M', 200e6*ones(6,1), ... 'Kr_M', 1e6*ones(6,1), ... 'Ka_F', 200e6*ones(6,1), ... 'Kr_F', 1e6*ones(6,1)); G = linearize(mdl, io, options); G.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'}; G.OutputName = {'L1', 'L2', 'L3', 'L4', 'L5', 'L6', ... 'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'}; #+end_src #+begin_src matlab :exports none figure; ax1 = subplot(2, 1, 1); hold on; plot(freqs, abs(squeeze(freqresp(G('L1','F1'), freqs, 'Hz'))), 'k-', 'DisplayName', 'Real Joints'); for i = 2:6 plot(freqs, abs(squeeze(freqresp(G(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'k-', 'HandleVisibility', 'off'); end plot(freqs, abs(squeeze(freqresp(Gp('L1','F1'), freqs, 'Hz'))), 'b-', 'DisplayName', 'Perfect Joints'); for i = 2:6 plot(freqs, abs(squeeze(freqresp(Gp(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'b-', 'HandleVisibility', 'off'); end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); legend('location', 'northeast'); ax2 = subplot(2, 1, 2); hold on; for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(G(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'k-'); end for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Gp(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'b-'); 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'); #+end_src #+begin_src matlab :exports none figure; ax1 = subplot(2, 1, 1); hold on; plot(freqs, abs(squeeze(freqresp(G('Fm1','F1'), freqs, 'Hz'))), 'k-', 'DisplayName', 'Real Joints'); for i = 2:6 plot(freqs, abs(squeeze(freqresp(G(sprintf('Fm%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'k-', 'HandleVisibility', 'off'); end plot(freqs, abs(squeeze(freqresp(Gp('Fm1','F1'), freqs, 'Hz'))), 'b-', 'DisplayName', 'Perfect Joints'); for i = 2:6 plot(freqs, abs(squeeze(freqresp(Gp(sprintf('Fm%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'b-', 'HandleVisibility', 'off'); end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); legend('location', 'northeast'); ax2 = subplot(2, 1, 2); hold on; for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(G(sprintf('Fm%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'k-'); end for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Gp(sprintf('Fm%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'b-'); 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'); #+end_src ** Conclusion Qualitatively: | | *Specification* | |-------------------+--------------------------------------------------| | Axial Stiffness | Much larger than the Actuator axial stiffness | | Shear Stiffness | | | Bending Stiffness | Much smaller than the Actuator bending stiffness | | Torsion Stiffness | | Quantitatively: | | *Specification* | |-------------------+-----------------| | Axial Stiffness | > 200 [N/um] | | Shear Stiffness | > 1 [N/um] | | Bending Stiffness | < 100 [Nm/rad] | | Torsion Stiffness | < 500 [Nm/rad] | * Flexible Joint Specifications with the APA300ML ** 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 :results none :exports none simulinkproject('../'); #+end_src ** Stewart Platform Initialization #+begin_src matlab apa = load('./mat/APA300ML.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K'); #+end_src #+begin_src matlab stewart = initializeStewartPlatform(); stewart = initializeFramesPositions(stewart); stewart = generateGeneralConfiguration(stewart); stewart = computeJointsPose(stewart); stewart = initializeFlexibleStrutDynamics(stewart, 'H', 0.03, 'K', apa.K, 'M', apa.M, 'n_xyz', apa.n_xyz, 'xi', 0.1, 'step_file', 'mat/APA300ML.STEP'); stewart = initializeCylindricalPlatforms(stewart); stewart = initializeCylindricalStruts(stewart, 'type_F', 'none', 'type_M', 'none'); stewart = computeJacobian(stewart); stewart = initializeStewartPose(stewart); stewart = initializeInertialSensor(stewart); references = initializeReferences(stewart); #+end_src #+begin_src matlab ground = initializeGround('type', 'none'); payload = initializePayload('type', 'rigid', 'm', 50); controller = initializeController('type', 'open-loop'); #+end_src #+begin_src matlab disturbances = initializeDisturbances(); #+end_src #+begin_src matlab open('stewart_platform_model.slx') #+end_src ** Initialization :noexport: #+begin_src matlab freqs = logspace(0, 3, 1000); c1 = [ 0 0.4470 0.7410 0.2]; % Blue c2 = [0.8500 0.3250 0.0980 0.2]; % Orange c3 = [0.9290 0.6940 0.1250 0.2]; % Yellow c4 = [0.4940 0.1840 0.5560 0.2]; % Purple c5 = [0.4660 0.6740 0.1880 0.2]; % Green c6 = [0.3010 0.7450 0.9330 0.2]; % Light Blue c7 = [0.6350 0.0780 0.1840 0.2]; % Red colors = [c1; c2; c3; c4; c5; c6; c7]; #+end_src #+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, '/Stewart Platform'], 1, 'openoutput', [], 'dLm'); io_i = io_i + 1; % Relative Motion - Legs [m] io(io_i) = linio([mdl, '/Stewart Platform'], 1, 'openoutput', [], 'Taum'); io_i = io_i + 1; % Force Sensors [N] #+end_src ** Comparison of perfect joint and worst specified joint #+begin_src matlab :exports none stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', ... 'type_M', 'spherical_p'); Gp = linearize(mdl, io, options); Gp.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'}; Gp.OutputName = {'L1', 'L2', 'L3', 'L4', 'L5', 'L6', ... 'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'}; stewart = initializeJointDynamics(stewart, 'type_F', 'universal_3dof', ... 'type_M', 'spherical_3dof', ... 'Kf_M', 100*ones(6,1), ... 'Kt_M', 500*ones(6,1), ... 'Kf_F', 100*ones(6,1), ... 'Kt_F', 500*ones(6,1), ... 'Ka_M', 200e6*ones(6,1), ... 'Kr_M', 1e6*ones(6,1), ... 'Ka_F', 200e6*ones(6,1), ... 'Kr_F', 1e6*ones(6,1)); G = linearize(mdl, io, options); G.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'}; G.OutputName = {'L1', 'L2', 'L3', 'L4', 'L5', 'L6', ... 'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'}; #+end_src #+begin_src matlab :exports none figure; ax1 = subplot(2, 1, 1); hold on; plot(freqs, abs(squeeze(freqresp(G('L1','F1'), freqs, 'Hz'))), 'k-', 'DisplayName', 'Real Joints'); for i = 2:6 plot(freqs, abs(squeeze(freqresp(G(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'k-', 'HandleVisibility', 'off'); end plot(freqs, abs(squeeze(freqresp(Gp('L1','F1'), freqs, 'Hz'))), 'b-', 'DisplayName', 'Perfect Joints'); for i = 2:6 plot(freqs, abs(squeeze(freqresp(Gp(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'b-', 'HandleVisibility', 'off'); end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); legend('location', 'northeast'); ax2 = subplot(2, 1, 2); hold on; for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(G(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'k-'); end for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Gp(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'b-'); 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'); #+end_src #+begin_src matlab :exports none figure; ax1 = subplot(2, 1, 1); hold on; plot(freqs, abs(squeeze(freqresp(G('Fm1','F1'), freqs, 'Hz'))), 'k-', 'DisplayName', 'Real Joints'); for i = 2:6 plot(freqs, abs(squeeze(freqresp(G(sprintf('Fm%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'k-', 'HandleVisibility', 'off'); end plot(freqs, abs(squeeze(freqresp(Gp('Fm1','F1'), freqs, 'Hz'))), 'b-', 'DisplayName', 'Perfect Joints'); for i = 2:6 plot(freqs, abs(squeeze(freqresp(Gp(sprintf('Fm%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'b-', 'HandleVisibility', 'off'); end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); legend('location', 'northeast'); ax2 = subplot(2, 1, 2); hold on; for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(G(sprintf('Fm%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'k-'); end for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(Gp(sprintf('Fm%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'b-'); 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'); #+end_src * Relative Motion Sensors ** 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 :results none :exports none simulinkproject('../'); #+end_src #+begin_src matlab open('stewart_platform_model.slx') #+end_src ** Stewart Platform Initialization #+begin_src matlab stewart = initializeStewartPlatform(); stewart = initializeFramesPositions(stewart); stewart = generateGeneralConfiguration(stewart); stewart = computeJointsPose(stewart); #+end_src #+begin_src matlab apa = load('./mat/APA300ML.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K'); stewart = initializeAmplifiedStrutDynamics(stewart, 'Ke', 1.5e6*ones(6,1), 'Ka', 40.5e6*ones(6,1), 'K1', 0.4e6*ones(6,1)); % stewart = initializeFlexibleStrutDynamics(stewart, 'H', 0.03, 'K', apa.K, 'M', apa.M, 'n_xyz', apa.n_xyz, 'xi', 0.1, 'step_file', 'mat/APA300ML.STEP'); #+end_src #+begin_src matlab flex_joint = load('./mat/flexor_025.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K'); stewart = initializeJointDynamics(stewart, 'type_M', 'spherical_3dof', ... 'Kr_M', flex_joint.K(1,1)*ones(6,1), ... 'Ka_M', flex_joint.K(3,3)*ones(6,1), ... 'Kf_M', flex_joint.K(4,4)*ones(6,1), ... 'Kt_M', flex_joint.K(6,6)*ones(6,1), ... 'type_F', 'universal_3dof', ... 'Kr_F', flex_joint.K(1,1)*ones(6,1), ... 'Ka_F', flex_joint.K(3,3)*ones(6,1), ... 'Kf_F', flex_joint.K(4,4)*ones(6,1), ... 'Kt_F', flex_joint.K(6,6)*ones(6,1)); #+end_src #+begin_src matlab stewart = initializeCylindricalPlatforms(stewart); #+end_src #+begin_src matlab stewart = initializeCylindricalStruts(stewart); #+end_src #+begin_src matlab stewart = computeJacobian(stewart); stewart = initializeStewartPose(stewart); stewart = initializeInertialSensor(stewart); references = initializeReferences(stewart); #+end_src #+begin_src matlab ground = initializeGround('type', 'none'); payload = initializePayload('type', 'rigid', 'm', 50); controller = initializeController('type', 'open-loop'); #+end_src #+begin_src matlab disturbances = initializeDisturbances(); #+end_src ** Initialization :noexport: #+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, '/Stewart Platform'], 1, 'openoutput', [], 'dLm'); io_i = io_i + 1; % Relative Motion - Actuators [m] io(io_i) = linio([mdl, '/Stewart Platform'], 1, 'openoutput', [], 'Lm'); io_i = io_i + 1; % Relative Motion - Legs [m] #+end_src #+begin_src matlab :exports none G = linearize(mdl, io, options); G.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'}; G.OutputName = {'L1', 'L2', 'L3', 'L4', 'L5', 'L6', ... 'D1', 'D2', 'D3', 'D4', 'D5', 'D6'}; #+end_src #+begin_src matlab :exports none freqs = logspace(1, 4, 5000); figure; ax1 = subplot(2, 1, 1); hold on; plot(freqs, abs(squeeze(freqresp(G('L1','F1'), freqs, 'Hz'))), 'k-', 'DisplayName', 'Actuator Stroke'); for i = 2:6 plot(freqs, abs(squeeze(freqresp(G(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'k-', 'HandleVisibility', 'off'); end plot(freqs, abs(squeeze(freqresp(G('D1','F1'), freqs, 'Hz'))), 'b-', 'DisplayName', 'Leg Stroke'); for i = 2:6 plot(freqs, abs(squeeze(freqresp(G(sprintf('D%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'b-', 'HandleVisibility', 'off'); end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); legend('location', 'northeast'); ax2 = subplot(2, 1, 2); hold on; for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(G(sprintf('L%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'k-'); end for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(G(sprintf('D%i', i),sprintf('F%i', i)), freqs, 'Hz'))), 'b-'); 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'); #+end_src #+begin_src matlab :tangle no :exports results :results file replace exportFig('figs/comp_relative_motion_sensor_act_leg.pdf', 'width', 'full', 'height', 'full'); #+end_src #+name: fig:comp_relative_motion_sensor_act_leg #+caption: Comparison of the dynamique from actuator to relative motion sensor located in parallel with the actuator or with the leg (flexible joints included) #+RESULTS: [[file:figs/comp_relative_motion_sensor_act_leg.png]] * Struts with Encoders ** 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 :results none :exports none simulinkproject('../'); #+end_src ** Flexible Strut #+begin_src matlab apa = load('./mat/strut_encoder.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K'); #+end_src #+begin_src matlab :exports results :results value table replace :tangle no data2orgtable([length(apa.n_i); length(apa.int_i); size(apa.M,1) - 6*length(apa.int_i); size(apa.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 | 8 | | Number of interface Nodes | 8 | | Number of Modes | 6 | | Size of M and K matrices | 54 | #+begin_src matlab :exports results :results value table replace :tangle no :post addhdr(*this*) data2orgtable([[1:length(apa.int_i)]', apa.int_i, apa.int_xyz], {}, {'Node i', 'Node Number', 'x [m]', 'y [m]', 'z [m]'}, ' %f '); #+end_src #+caption: Coordinates of the interface nodes #+RESULTS: | Node i | Node Number | x [m] | y [m] | z [m] | |--------+-------------+---------+--------+----------| | 1.0 | 504411.0 | 0.0 | 0.0 | 0.0405 | | 2.0 | 504412.0 | 0.0 | 0.0 | -0.0405 | | 3.0 | 504413.0 | -0.0325 | 0.0 | 0.0 | | 4.0 | 504414.0 | -0.0125 | 0.0 | 0.0 | | 5.0 | 504415.0 | -0.0075 | 0.0 | 0.0 | | 6.0 | 504416.0 | 0.0325 | 0.0 | 0.0 | | 7.0 | 504417.0 | 0.004 | 0.0145 | -0.00175 | | 8.0 | 504418.0 | 0.004 | 0.0166 | -0.00175 | ** Stewart Platform #+begin_src matlab stewart = initializeStewartPlatform(); stewart = initializeFramesPositions(stewart, 'H', 95e-3, 'MO_B', 220e-3); stewart = generateGeneralConfiguration(stewart, 'FH', 22.5e-3, 'FR', 114e-3, 'FTh', [ -11, 11, 120-11, 120+11, 240-11, 240+11]*(pi/180), ... 'MH', 22.5e-3, 'MR', 110e-3, 'MTh', [-60+15, 60-15, 60+15, 180-15, 180+15, -60-15]*(pi/180)); stewart = computeJointsPose(stewart); stewart = initializeFlexibleStrutAndJointDynamics(stewart, 'H', (apa.int_xyz(1,3) - apa.int_xyz(2,3)), ... 'K', apa.K, ... 'M', apa.M, ... 'n_xyz', apa.n_xyz, ... 'xi', 0.1, ... 'Gf', -2.65e7, ... 'step_file', 'mat/APA300ML.STEP'); stewart = initializeSolidPlatforms(stewart); stewart = initializeCylindricalStruts(stewart, 'type_F', 'none', 'type_M', 'none'); stewart = computeJacobian(stewart); stewart = initializeStewartPose(stewart); stewart = initializeInertialSensor(stewart); #+end_src #+begin_src matlab disturbances = initializeDisturbances(); ground = initializeGround('type', 'none'); payload = initializePayload('type', 'rigid', 'm', 1); controller = initializeController('type', 'open-loop'); references = initializeReferences(stewart); #+end_src #+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, '/Stewart Platform'], 1, 'openoutput', [], 'dLm'); io_i = io_i + 1; % Relative Displacement Outputs [m] io(io_i) = linio([mdl, '/Stewart Platform'], 1, 'openoutput', [], 'Lm'); io_i = io_i + 1; % Force Sensors [N] #+end_src #+begin_src matlab %% Run the linearization G = linearize(mdl, io, options); G.InputName = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'}; G.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6', ... 'D1', 'D2', 'D3', 'D4', 'D5', 'D6'}; #+end_src #+begin_src matlab :exports none freqs = logspace(0, 3, 1000); figure; ax1 = subplot(2, 1, 1); hold on; for i = 1:6 plot(freqs, abs(squeeze(freqresp(G(i,i), freqs, 'Hz'))), 'color', [0 0.4470 0.7410 0.2]); end for i = 1:6 plot(freqs, abs(squeeze(freqresp(G(6+i,i), freqs, 'Hz'))), 'color', [0.8500 0.3250 0.0980 0.2]); end hold off; set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log'); ylabel('Amplitude [m/N]'); set(gca, 'XTickLabel',[]); ax2 = subplot(2, 1, 2); hold on; for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(G(i,i), freqs, 'Hz'))), 'color', [0 0.4470 0.7410 0.2]); end for i = 1:6 plot(freqs, 180/pi*angle(squeeze(freqresp(G(6+i,i), freqs, 'Hz'))), 'color', [0.8500 0.3250 0.0980 0.2]); 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'); #+end_src #+begin_src matlab :tangle no :exports results :results file replace exportFig('figs/comp_relative_motion_sensor_act_leg_encoder.pdf', 'width', 'full', 'height', 'full'); #+end_src #+name: fig:comp_relative_motion_sensor_act_leg_encoder #+caption: #+RESULTS: [[file:figs/comp_relative_motion_sensor_act_leg_encoder.png]]