1719 lines
60 KiB
Org Mode
1719 lines
60 KiB
Org Mode
#+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: <link rel="stylesheet" type="text/css" href="https://research.tdehaeze.xyz/css/style.css"/>
|
|
#+HTML_HEAD: <script type="text/javascript" src="https://research.tdehaeze.xyz/js/script.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:
|
|
|
|
* 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)
|
|
<<matlab-dir>>
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none :results silent :noweb yes
|
|
<<matlab-init>>
|
|
#+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)
|
|
<<matlab-dir>>
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none :results silent :noweb yes
|
|
<<matlab-init>>
|
|
#+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)
|
|
<<matlab-dir>>
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none :results silent :noweb yes
|
|
<<matlab-init>>
|
|
#+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)
|
|
<<matlab-dir>>
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none :results silent :noweb yes
|
|
<<matlab-init>>
|
|
#+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)
|
|
<<matlab-dir>>
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none :results silent :noweb yes
|
|
<<matlab-init>>
|
|
#+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)
|
|
<<matlab-dir>>
|
|
#+end_src
|
|
|
|
#+begin_src matlab :exports none :results silent :noweb yes
|
|
<<matlab-init>>
|
|
#+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]]
|