From ed0c18829b83dfe9c34a5c469894cc47de60c1bc Mon Sep 17 00:00:00 2001 From: Thomas Dehaeze Date: Fri, 8 Jan 2021 15:54:58 +0100 Subject: [PATCH] Change all indentation --- docs/control-active-damping.html | 336 ++-- docs/control-tracking.html | 698 ++++---- docs/control-vibration-isolation.html | 674 ++++---- docs/cubic-configuration.html | 490 +++--- docs/dynamics-study.html | 190 +-- docs/flexible-stewart-platform.html | 564 +++---- docs/identification.html | 588 +++---- docs/kinematic-study.html | 614 ++++---- docs/nass.html | 40 +- docs/simscape-model.html | 282 ++-- docs/simulink-project.html | 28 +- docs/static-analysis.html | 4 +- docs/stewart-architecture.html | 2098 ++++++++++++------------- matlab/active_damping_dvf.m | 29 +- matlab/active_damping_iff.m | 63 +- matlab/active_damping_inertial.m | 29 +- org/control-active-damping.org | 814 +++++----- org/control-tracking.org | 1740 ++++++++++---------- org/control-vibration-isolation.org | 1378 ++++++++-------- org/cubic-configuration.org | 1138 +++++++------- org/dynamics-study.org | 306 ++-- org/flexible-stewart-platform.org | 2068 ++++++++++++------------ org/identification.org | 558 +++---- org/kinematic-study.org | 566 +++---- org/nass.org | 40 +- org/simscape-model.org | 214 +-- org/simulink-project.org | 24 +- org/static-analysis.org | 18 +- org/stewart-architecture.org | 1774 ++++++++++----------- 29 files changed, 8682 insertions(+), 8683 deletions(-) diff --git a/docs/control-active-damping.html b/docs/control-active-damping.html index 8c85d19..4266561 100644 --- a/docs/control-active-damping.html +++ b/docs/control-active-damping.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Stewart Platform - Decentralized Active Damping @@ -42,25 +42,25 @@
  • 1. Inertial Control
  • 2. Integral Force Feedback
  • 3. Direct Velocity Feedback
  • 4. Compliance and Transmissibility Comparison @@ -90,7 +90,7 @@ The following decentralized active damping techniques are briefly studied:

    -
    +

    The Matlab script corresponding to this section is accessible here.

    @@ -106,44 +106,44 @@ To run the script, open the Simulink Project, and type run active_damping_

    1.1 Identification of the Dynamics

    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    -  stewart = generateGeneralConfiguration(stewart);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart);
    -  stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    -  stewart = initializeCylindricalPlatforms(stewart);
    -  stewart = initializeCylindricalStruts(stewart);
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    -  stewart = initializeInertialSensor(stewart, 'type', 'accelerometer', 'freq', 5e3);
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    +stewart = generateGeneralConfiguration(stewart);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart);
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    +stewart = initializeCylindricalPlatforms(stewart);
    +stewart = initializeCylindricalStruts(stewart);
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart, 'type', 'accelerometer', 'freq', 5e3);
     
    -
      ground = initializeGround('type', 'rigid', 'rot_point', stewart.platform_F.FO_A);
    -  payload = initializePayload('type', 'none');
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'rigid', 'rot_point', stewart.platform_F.FO_A);
    +payload = initializePayload('type', 'none');
    +controller = initializeController('type', 'open-loop');
     
    -
      %% Options for Linearized
    -  options = linearizeOptions;
    -  options.SampleTime = 0;
    +
    %% Options for Linearized
    +options = linearizeOptions;
    +options.SampleTime = 0;
     
    -  %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +%% 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', [], 'Vm'); io_i = io_i + 1; % Absolute velocity of each leg [m/s]
    +%% 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', [], 'Vm'); io_i = io_i + 1; % Absolute velocity of each leg [m/s]
     
    -  %% Run the linearization
    -  G = linearize(mdl, io, options);
    -  G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G.OutputName = {'Vm1', 'Vm2', 'Vm3', 'Vm4', 'Vm5', 'Vm6'};
    +%% Run the linearization
    +G = linearize(mdl, io, options);
    +G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G.OutputName = {'Vm1', 'Vm2', 'Vm3', 'Vm4', 'Vm5', 'Vm6'};
     
    @@ -159,17 +159,17 @@ The transfer function from actuator forces to force sensors is shown in Figure <
    -
    -

    1.2 Effect of the Flexible Joint stiffness and Actuator amplification on the Dynamics

    +
    +

    1.2 Effect of the Flexible Joint stiffness and Actuator amplification on the Dynamics

    We add some stiffness and damping in the flexible joints and we re-identify the dynamics.

    -
      stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    -  Gf = linearize(mdl, io, options);
    -  Gf.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  Gf.OutputName = {'Vm1', 'Vm2', 'Vm3', 'Vm4', 'Vm5', 'Vm6'};
    +
    stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    +Gf = linearize(mdl, io, options);
    +Gf.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +Gf.OutputName = {'Vm1', 'Vm2', 'Vm3', 'Vm4', 'Vm5', 'Vm6'};
     
    @@ -177,10 +177,10 @@ We add some stiffness and damping in the flexible joints and we re-identify the We now use the amplified actuators and re-identify the dynamics

    -
      stewart = initializeAmplifiedStrutDynamics(stewart);
    -  Ga = linearize(mdl, io, options);
    -  Ga.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  Ga.OutputName = {'Vm1', 'Vm2', 'Vm3', 'Vm4', 'Vm5', 'Vm6'};
    +
    stewart = initializeAmplifiedStrutDynamics(stewart);
    +Ga = linearize(mdl, io, options);
    +Ga.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +Ga.OutputName = {'Vm1', 'Vm2', 'Vm3', 'Vm4', 'Vm5', 'Vm6'};
     
    @@ -196,8 +196,8 @@ The new dynamics from force actuator to force sensor is shown in Figure
    -
    -

    1.3 Obtained Damping

    +
    -
    -

    1.4 Conclusion

    +
    +

    1.4 Conclusion

    -
    +

    We do not have guaranteed stability with Inertial control. This is because of the flexibility inside the internal sensor.

    @@ -242,7 +242,7 @@ We do not have guaranteed stability with Inertial control. This is because of th

    -
    +

    The Matlab script corresponding to this section is accessible here.

    @@ -254,31 +254,31 @@ To run the script, open the Simulink Project, and type run active_damping_
    -
    -

    2.1 Identification of the Dynamics with perfect Joints

    +
    +

    2.1 Identification of the Dynamics with perfect Joints

    We first initialize the Stewart platform without joint stiffness.

    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    -  stewart = generateGeneralConfiguration(stewart);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart);
    -  stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    -  stewart = initializeCylindricalPlatforms(stewart);
    -  stewart = initializeCylindricalStruts(stewart);
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    -  stewart = initializeInertialSensor(stewart, 'type', 'none');
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    +stewart = generateGeneralConfiguration(stewart);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart);
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    +stewart = initializeCylindricalPlatforms(stewart);
    +stewart = initializeCylindricalStruts(stewart);
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart, 'type', 'none');
     
    -
      ground = initializeGround('type', 'rigid', 'rot_point', stewart.platform_F.FO_A);
    -  payload = initializePayload('type', 'none');
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'rigid', 'rot_point', stewart.platform_F.FO_A);
    +payload = initializePayload('type', 'none');
    +controller = initializeController('type', 'open-loop');
     
    @@ -286,18 +286,18 @@ We first initialize the Stewart platform without joint stiffness. And we identify the dynamics from force actuators to force sensors.

    -
      %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +
    %% 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', [], 'Taum'); io_i = io_i + 1; % Force Sensor Outputs [N]
    +%% 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', [], 'Taum'); io_i = io_i + 1; % Force Sensor Outputs [N]
     
    -  %% Run the linearization
    -  G = linearize(mdl, io);
    -  G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G.OutputName = {'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'};
    +%% Run the linearization
    +G = linearize(mdl, io);
    +G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G.OutputName = {'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'};
     
    @@ -313,17 +313,17 @@ The transfer function from actuator forces to force sensors is shown in Figure <
    -
    -

    2.2 Effect of the Flexible Joint stiffness and Actuator amplification on the Dynamics

    +
    +

    2.2 Effect of the Flexible Joint stiffness and Actuator amplification on the Dynamics

    We add some stiffness and damping in the flexible joints and we re-identify the dynamics.

    -
      stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    -  Gf = linearize(mdl, io);
    -  Gf.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  Gf.OutputName = {'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'};
    +
    stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    +Gf = linearize(mdl, io);
    +Gf.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +Gf.OutputName = {'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'};
     
    @@ -331,10 +331,10 @@ We add some stiffness and damping in the flexible joints and we re-identify the We now use the amplified actuators and re-identify the dynamics

    -
      stewart = initializeAmplifiedStrutDynamics(stewart);
    -  Ga = linearize(mdl, io);
    -  Ga.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  Ga.OutputName = {'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'};
    +
    stewart = initializeAmplifiedStrutDynamics(stewart);
    +Ga = linearize(mdl, io);
    +Ga.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +Ga.OutputName = {'Fm1', 'Fm2', 'Fm3', 'Fm4', 'Fm5', 'Fm6'};
     
    @@ -350,8 +350,8 @@ The new dynamics from force actuator to force sensor is shown in Figure
    -
    -

    2.3 Obtained Damping

    +
    -
    -

    2.4 Conclusion

    +
    +

    2.4 Conclusion

    -
    +

    The joint stiffness has a huge impact on the attainable active damping performance when using force sensors. Thus, if Integral Force Feedback is to be used in a Stewart platform with flexible joints, the rotational stiffness of the joints should be minimized. @@ -404,7 +404,7 @@ Thus, if Integral Force Feedback is to be used in a Stewart platform with flexib

    -
    +

    The Matlab script corresponding to this section is accessible here.

    @@ -416,31 +416,31 @@ To run the script, open the Simulink Project, and type run active_damping_
    -
    -

    3.1 Identification of the Dynamics with perfect Joints

    +
    +

    3.1 Identification of the Dynamics with perfect Joints

    We first initialize the Stewart platform without joint stiffness.

    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    -  stewart = generateGeneralConfiguration(stewart);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart);
    -  stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    -  stewart = initializeCylindricalPlatforms(stewart);
    -  stewart = initializeCylindricalStruts(stewart);
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    -  stewart = initializeInertialSensor(stewart, 'type', 'none');
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    +stewart = generateGeneralConfiguration(stewart);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart);
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    +stewart = initializeCylindricalPlatforms(stewart);
    +stewart = initializeCylindricalStruts(stewart);
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart, 'type', 'none');
     
    -
      ground = initializeGround('type', 'rigid', 'rot_point', stewart.platform_F.FO_A);
    -  payload = initializePayload('type', 'none');
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'rigid', 'rot_point', stewart.platform_F.FO_A);
    +payload = initializePayload('type', 'none');
    +controller = initializeController('type', 'open-loop');
     
    @@ -448,22 +448,22 @@ We first initialize the Stewart platform without joint stiffness. And we identify the dynamics from force actuators to force sensors.

    -
      %% Options for Linearized
    -  options = linearizeOptions;
    -  options.SampleTime = 0;
    +
    %% Options for Linearized
    +options = linearizeOptions;
    +options.SampleTime = 0;
     
    -  %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +%% 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]
    +%% 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]
     
    -  %% Run the linearization
    -  G = linearize(mdl, io, options);
    -  G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6'};
    +%% Run the linearization
    +G = linearize(mdl, io, options);
    +G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6'};
     
    @@ -480,17 +480,17 @@ The transfer function from actuator forces to relative motion sensors is shown i
    -
    -

    3.2 Effect of the Flexible Joint stiffness and Actuator amplification on the Dynamics

    +
    +

    3.2 Effect of the Flexible Joint stiffness and Actuator amplification on the Dynamics

    We add some stiffness and damping in the flexible joints and we re-identify the dynamics.

    -
      stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    -  Gf = linearize(mdl, io, options);
    -  Gf.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  Gf.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6'};
    +
    stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    +Gf = linearize(mdl, io, options);
    +Gf.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +Gf.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6'};
     
    @@ -498,10 +498,10 @@ We add some stiffness and damping in the flexible joints and we re-identify the We now use the amplified actuators and re-identify the dynamics

    -
      stewart = initializeAmplifiedStrutDynamics(stewart);
    -  Ga = linearize(mdl, io, options);
    -  Ga.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  Ga.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6'};
    +
    stewart = initializeAmplifiedStrutDynamics(stewart);
    +Ga = linearize(mdl, io, options);
    +Ga.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +Ga.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6'};
     
    @@ -517,8 +517,8 @@ The new dynamics from force actuator to relative motion sensor is shown in Figur
    -
    -

    3.3 Obtained Damping

    +
    +

    3.3 Obtained Damping

    The control is a performed in a decentralized manner. @@ -543,10 +543,10 @@ The root locus is shown in figure 10.

    -
    -

    3.4 Conclusion

    +
    +

    3.4 Conclusion

    -
    +

    Joint stiffness does increase the resonance frequencies of the system but does not change the attainable damping when using relative motion sensors.

    @@ -567,17 +567,17 @@ Joint stiffness does increase the resonance frequencies of the system but does n We first initialize the Stewart platform without joint stiffness.

    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    -  stewart = generateGeneralConfiguration(stewart);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart);
    -  stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    -  stewart = initializeCylindricalPlatforms(stewart);
    -  stewart = initializeCylindricalStruts(stewart);
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    -  stewart = initializeInertialSensor(stewart, 'type', 'none');
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    +stewart = generateGeneralConfiguration(stewart);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart);
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    +stewart = initializeCylindricalPlatforms(stewart);
    +stewart = initializeCylindricalStruts(stewart);
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart, 'type', 'none');
     
    @@ -585,9 +585,9 @@ We first initialize the Stewart platform without joint stiffness. The rotation point of the ground is located at the origin of frame \(\{A\}\).

    -
      ground = initializeGround('type', 'rigid', 'rot_point', stewart.platform_F.FO_A);
    -  payload = initializePayload('type', 'none');
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'rigid', 'rot_point', stewart.platform_F.FO_A);
    +payload = initializePayload('type', 'none');
    +controller = initializeController('type', 'open-loop');
     
    @@ -600,9 +600,9 @@ The rotation point of the ground is located at the origin of frame \(\{A\}\). Let’s first identify the transmissibility and compliance in the open-loop case.

    -
      controller = initializeController('type', 'open-loop');
    -  [T_ol, T_norm_ol, freqs] = computeTransmissibility();
    -  [C_ol, C_norm_ol, freqs] = computeCompliance();
    +
    controller = initializeController('type', 'open-loop');
    +[T_ol, T_norm_ol, freqs] = computeTransmissibility();
    +[C_ol, C_norm_ol, freqs] = computeCompliance();
     
    @@ -610,11 +610,11 @@ Let’s first identify the transmissibility and compliance in the open-loop Now, let’s identify the transmissibility and compliance for the Integral Force Feedback architecture.

    -
      controller = initializeController('type', 'iff');
    -  K_iff = (1e4/s)*eye(6);
    +
    controller = initializeController('type', 'iff');
    +K_iff = (1e4/s)*eye(6);
     
    -  [T_iff, T_norm_iff, ~] = computeTransmissibility();
    -  [C_iff, C_norm_iff, ~] = computeCompliance();
    +[T_iff, T_norm_iff, ~] = computeTransmissibility();
    +[C_iff, C_norm_iff, ~] = computeCompliance();
     
    @@ -622,11 +622,11 @@ Now, let’s identify the transmissibility and compliance for the Integral F And for the Direct Velocity Feedback.

    -
      controller = initializeController('type', 'dvf');
    -  K_dvf = 1e4*s/(1+s/2/pi/5000)*eye(6);
    +
    controller = initializeController('type', 'dvf');
    +K_dvf = 1e4*s/(1+s/2/pi/5000)*eye(6);
     
    -  [T_dvf, T_norm_dvf, ~] = computeTransmissibility();
    -  [C_dvf, C_norm_dvf, ~] = computeCompliance();
    +[T_dvf, T_norm_dvf, ~] = computeTransmissibility();
    +[C_dvf, C_norm_dvf, ~] = computeCompliance();
     
    @@ -661,7 +661,7 @@ And for the Direct Velocity Feedback.

    Author: Dehaeze Thomas

    -

    Created: 2021-01-08 ven. 15:30

    +

    Created: 2021-01-08 ven. 15:53

    diff --git a/docs/control-tracking.html b/docs/control-tracking.html index dae92a1..13ae1b4 100644 --- a/docs/control-tracking.html +++ b/docs/control-tracking.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Stewart Platform - Tracking Control @@ -41,42 +41,42 @@
  • 3. Hybrid Control Architecture - HAC-LAC with relative DVF
  • 4. Comparison of all the methods
  • @@ -144,8 +144,8 @@ The control configuration are compare in section 4.

    -
    -

    1.1 Control Schematic

    +
    +

    1.1 Control Schematic

    The control architecture is shown in Figure 1. @@ -168,64 +168,64 @@ Then, a diagonal (decentralized) controller \(\bm{K}_\mathcal{L}\) is used such

    -
    -

    1.2 Initialize the Stewart platform

    +
    +

    1.2 Initialize the Stewart platform

    -
        % Stewart Platform
    -    stewart = initializeStewartPlatform();
    -    stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    -    stewart = generateGeneralConfiguration(stewart);
    -    stewart = computeJointsPose(stewart);
    -    stewart = initializeStrutDynamics(stewart);
    -    stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    -    stewart = initializeCylindricalPlatforms(stewart);
    -    stewart = initializeCylindricalStruts(stewart);
    -    stewart = computeJacobian(stewart);
    -    stewart = initializeStewartPose(stewart);
    -    stewart = initializeInertialSensor(stewart, 'type', 'accelerometer', 'freq', 5e3);
    -  
    -    % Ground and Payload
    -    ground = initializeGround('type', 'rigid');
    -    payload = initializePayload('type', 'none');
    -  
    -    % Controller
    -    controller = initializeController('type', 'open-loop');
    -  
    -    % Disturbances and References
    -    disturbances = initializeDisturbances();
    -    references = initializeReferences(stewart);
    +
    % Stewart Platform
    +stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    +stewart = generateGeneralConfiguration(stewart);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart);
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    +stewart = initializeCylindricalPlatforms(stewart);
    +stewart = initializeCylindricalStruts(stewart);
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart, 'type', 'accelerometer', 'freq', 5e3);
    +
    +% Ground and Payload
    +ground = initializeGround('type', 'rigid');
    +payload = initializePayload('type', 'none');
    +
    +% Controller
    +controller = initializeController('type', 'open-loop');
    +
    +% Disturbances and References
    +disturbances = initializeDisturbances();
    +references = initializeReferences(stewart);
     
    -
    -

    1.3 Identification of the plant

    +
    +

    1.3 Identification of the plant

    Let’s identify the transfer function from \(\bm{\tau}\) to \(\bm{\mathcal{L}}\).

    -
      %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +
    %% 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]
    +%% 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]
     
    -  %% Run the linearization
    -  G = linearize(mdl, io);
    -  G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G.OutputName = {'L1', 'L2', 'L3', 'L4', 'L5', 'L6'};
    +%% Run the linearization
    +G = linearize(mdl, io);
    +G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G.OutputName = {'L1', 'L2', 'L3', 'L4', 'L5', 'L6'};
     
    -
    -

    1.4 Plant Analysis

    +
    +

    1.4 Plant Analysis

    The diagonal and off-diagonal terms of the plant are shown in Figure 2. @@ -245,8 +245,8 @@ We see that the plant is decoupled at low frequency which indicate that decentra

    -
    -

    1.5 Controller Design

    +
    +

    1.5 Controller Design

    The controller consists of: @@ -261,8 +261,8 @@ The obtained loop gains corresponding to the diagonal elements are shown in Figu

    -
      wc = 2*pi*30;
    -  Kl = diag(1./diag(abs(freqresp(G, wc)))) * wc/s * 1/(1 + s/3/wc);
    +
    wc = 2*pi*30;
    +Kl = diag(1./diag(abs(freqresp(G, wc)))) * wc/s * 1/(1 + s/3/wc);
     
    @@ -275,22 +275,22 @@ The obtained loop gains corresponding to the diagonal elements are shown in Figu
    -
    -

    1.6 Simulation

    +
    +

    1.6 Simulation

    Let’s define some reference path to follow.

    -
        t = [0:1e-4:10];
    -  
    -    r = zeros(6, length(t));
    -  
    -    r(1, :) = 1e-3.*t.*sin(2*pi*t);
    -    r(2, :) = 1e-3.*t.*cos(2*pi*t);
    -    r(3, :) = 1e-3.*t;
    -  
    -    references = initializeReferences(stewart, 't', t, 'r', r);
    +
    t = [0:1e-4:10];
    +
    +r = zeros(6, length(t));
    +
    +r(1, :) = 1e-3.*t.*sin(2*pi*t);
    +r(2, :) = 1e-3.*t.*cos(2*pi*t);
    +r(3, :) = 1e-3.*t;
    +
    +references = initializeReferences(stewart, 't', t, 'r', r);
     
    @@ -299,11 +299,11 @@ The reference path is shown in Figure 4.

    -
      figure;
    -  plot3(squeeze(references.r.Data(1,1,:)), squeeze(references.r.Data(2,1,:)), squeeze(references.r.Data(3,1,:)));
    -  xlabel('X [m]');
    -  ylabel('Y [m]');
    -  zlabel('Z [m]');
    +
    figure;
    +plot3(squeeze(references.r.Data(1,1,:)), squeeze(references.r.Data(2,1,:)), squeeze(references.r.Data(3,1,:)));
    +xlabel('X [m]');
    +ylabel('Y [m]');
    +zlabel('Z [m]');
     
    @@ -315,19 +315,19 @@ The reference path is shown in Figure 4.
    -
      controller = initializeController('type', 'ref-track-L');
    +
    controller = initializeController('type', 'ref-track-L');
     
    -
      set_param('stewart_platform_model', 'StopTime', '10')
    -  sim('stewart_platform_model');
    -  simout_D = simout;
    +
    set_param('stewart_platform_model', 'StopTime', '10')
    +sim('stewart_platform_model');
    +simout_D = simout;
     
    -
      save('./mat/control_tracking.mat', 'simout_D', '-append');
    +
    save('./mat/control_tracking.mat', 'simout_D', '-append');
     
    @@ -341,14 +341,14 @@ The reference path and the position of the mobile platform are shown in Figure <

    -
      figure;
    -  hold on;
    -  plot3(simout_D.x.Xr.Data(:, 1), simout_D.x.Xr.Data(:, 2), simout_D.x.Xr.Data(:, 3), 'k-');
    -  plot3(squeeze(references.r.Data(1,1,:)), squeeze(references.r.Data(2,1,:)), squeeze(references.r.Data(3,1,:)), '--');
    -  hold off;
    -  xlabel('X [m]'); ylabel('Y [m]'); zlabel('Z [m]');
    -  view([1,1,1])
    -  zlim([0, inf]);
    +
    figure;
    +hold on;
    +plot3(simout_D.x.Xr.Data(:, 1), simout_D.x.Xr.Data(:, 2), simout_D.x.Xr.Data(:, 3), 'k-');
    +plot3(squeeze(references.r.Data(1,1,:)), squeeze(references.r.Data(2,1,:)), squeeze(references.r.Data(3,1,:)), '--');
    +hold off;
    +xlabel('X [m]'); ylabel('Y [m]'); zlabel('Z [m]');
    +view([1,1,1])
    +zlim([0, inf]);
     
    @@ -375,8 +375,8 @@ The reference path and the position of the mobile platform are shown in Figure <
    -
    -

    1.8 Conclusion

    +
    +

    1.8 Conclusion

    Such control architecture is easy to implement and give good results. @@ -397,8 +397,8 @@ However, as \(\mathcal{X}\) is not directly measured, it is possible that import

    -
    -

    2.1 Control Schematic

    +
    +

    2.1 Control Schematic

    The centralized controller takes the position error \(\bm{\epsilon}_\mathcal{X}\) as an inputs and generate actuator forces \(\bm{\tau}\) (see Figure 8). @@ -426,7 +426,7 @@ Instead of designing a full MIMO controller \(K\), we first try to make the plan We can think of two ways to make the plant more diagonal that are described in sections 2.4 and 2.5.

    -
    +

    Note here that the subtraction shown in Figure 8 is not a real subtraction. It is indeed a more complex computation explained in section 5. @@ -436,57 +436,57 @@ It is indeed a more complex computation explained in section -

    2.2 Initialize the Stewart platform

    +
    +

    2.2 Initialize the Stewart platform

    -
        % Stewart Platform
    -    stewart = initializeStewartPlatform();
    -    stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    -    stewart = generateGeneralConfiguration(stewart);
    -    stewart = computeJointsPose(stewart);
    -    stewart = initializeStrutDynamics(stewart);
    -    stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    -    stewart = initializeCylindricalPlatforms(stewart);
    -    stewart = initializeCylindricalStruts(stewart);
    -    stewart = computeJacobian(stewart);
    -    stewart = initializeStewartPose(stewart);
    -    stewart = initializeInertialSensor(stewart, 'type', 'accelerometer', 'freq', 5e3);
    -  
    -    % Ground and Payload
    -    ground = initializeGround('type', 'rigid');
    -    payload = initializePayload('type', 'none');
    -  
    -    % Controller
    -    controller = initializeController('type', 'open-loop');
    -  
    -    % Disturbances and References
    -    disturbances = initializeDisturbances();
    -    references = initializeReferences(stewart);
    +
    % Stewart Platform
    +stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    +stewart = generateGeneralConfiguration(stewart);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart);
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    +stewart = initializeCylindricalPlatforms(stewart);
    +stewart = initializeCylindricalStruts(stewart);
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart, 'type', 'accelerometer', 'freq', 5e3);
    +
    +% Ground and Payload
    +ground = initializeGround('type', 'rigid');
    +payload = initializePayload('type', 'none');
    +
    +% Controller
    +controller = initializeController('type', 'open-loop');
    +
    +% Disturbances and References
    +disturbances = initializeDisturbances();
    +references = initializeReferences(stewart);
     
    -
    -

    2.3 Identification of the plant

    +
    -
    -

    2.4.1 Control Architecture

    +
    +

    2.4.1 Control Architecture

    The pose error \(\bm{\epsilon}_\mathcal{X}\) is first converted in the frame of the leg by using the Jacobian matrix. @@ -521,16 +521,16 @@ Note here that the transformation from the pose error \(\bm{\epsilon}_\mathcal{X

    -
    -

    2.4.2 Plant Analysis

    +
    +

    2.4.2 Plant Analysis

    We now multiply the plant by the Jacobian matrix as shown in Figure 9 to obtain a more diagonal plant.

    -
      Gl = stewart.kinematics.J*G;
    -  Gl.OutputName  = {'D1', 'D2', 'D3', 'D4', 'D5', 'D6'};
    +
    Gl = stewart.kinematics.J*G;
    +Gl.OutputName  = {'D1', 'D2', 'D3', 'D4', 'D5', 'D6'};
     
    @@ -562,8 +562,8 @@ Thus \(J \cdot G(\omega = 0) = J \cdot \frac{\delta\bm{\mathcal{X}}}{\delta\bm{\
    -
    -

    2.4.3 Controller Design

    +
    +

    2.4.3 Controller Design

    The controller consists of: @@ -578,8 +578,8 @@ The obtained loop gains corresponding to the diagonal elements are shown in Figu

    -
      wc = 2*pi*30;
    -  Kl = diag(1./diag(abs(freqresp(Gl, wc)))) * wc/s * 1/(1 + s/3/wc);
    +
    wc = 2*pi*30;
    +Kl = diag(1./diag(abs(freqresp(Gl, wc)))) * wc/s * 1/(1 + s/3/wc);
     
    @@ -594,33 +594,33 @@ The obtained loop gains corresponding to the diagonal elements are shown in Figu The controller \(\bm{K} = \bm{K}_\mathcal{L} \bm{J}\) is computed.

    -
      K = Kl*stewart.kinematics.J;
    +
    K = Kl*stewart.kinematics.J;
     
    -
    -

    2.4.4 Simulation

    +
    +

    2.4.4 Simulation

    We specify the reference path to follow.

    -
        t = [0:1e-4:10];
    -  
    -    r = zeros(6, length(t));
    -  
    -    r(1, :) = 1e-3.*t.*sin(2*pi*t);
    -    r(2, :) = 1e-3.*t.*cos(2*pi*t);
    -    r(3, :) = 1e-3.*t;
    -  
    -    references = initializeReferences(stewart, 't', t, 'r', r);
    +
    t = [0:1e-4:10];
    +
    +r = zeros(6, length(t));
    +
    +r(1, :) = 1e-3.*t.*sin(2*pi*t);
    +r(2, :) = 1e-3.*t.*cos(2*pi*t);
    +r(3, :) = 1e-3.*t;
    +
    +references = initializeReferences(stewart, 't', t, 'r', r);
     
    -
      controller = initializeController('type', 'ref-track-X');
    +
    controller = initializeController('type', 'ref-track-X');
     
    @@ -628,10 +628,10 @@ We specify the reference path to follow. We run the simulation and we save the results.

    -
      set_param('stewart_platform_model', 'StopTime', '10')
    -  sim('stewart_platform_model')
    -  simout_L = simout;
    -  save('./mat/control_tracking.mat', 'simout_L', '-append');
    +
    set_param('stewart_platform_model', 'StopTime', '10')
    +sim('stewart_platform_model')
    +simout_L = simout;
    +save('./mat/control_tracking.mat', 'simout_L', '-append');
     
    @@ -645,8 +645,8 @@ We run the simulation and we save the results.

    -
    -

    2.5.1 Control Architecture

    +
    +

    2.5.1 Control Architecture

    A diagonal controller \(\bm{K}_\mathcal{X}\) take the pose error \(\bm{\epsilon}_\mathcal{X}\) and generate cartesian forces \(\bm{\mathcal{F}}\) that are then converted to actuators forces using the Jacobian as shown in Figure e 12. @@ -665,16 +665,16 @@ The final implemented controller is \(\bm{K} = \bm{J}^{-T} \cdot \bm{K}_\mathcal

    -
    -

    2.5.2 Plant Analysis

    +
    +

    2.5.2 Plant Analysis

    We now multiply the plant by the Jacobian matrix as shown in Figure 12 to obtain a more diagonal plant.

    -
      Gx = G*inv(stewart.kinematics.J');
    -  Gx.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    +
    Gx = G*inv(stewart.kinematics.J');
    +Gx.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
     
    @@ -781,8 +781,8 @@ This control architecture can also give a dynamically decoupled plant if the Cen
    -
    -

    2.5.3 Controller Design

    +
    +

    2.5.3 Controller Design

    The controller consists of: @@ -797,8 +797,8 @@ The obtained loop gains corresponding to the diagonal elements are shown in Figu

    -
      wc = 2*pi*30;
    -  Kx = diag(1./diag(abs(freqresp(Gx, wc)))) * wc/s * 1/(1 + s/3/wc);
    +
    wc = 2*pi*30;
    +Kx = diag(1./diag(abs(freqresp(Gx, wc)))) * wc/s * 1/(1 + s/3/wc);
     
    @@ -813,33 +813,33 @@ The obtained loop gains corresponding to the diagonal elements are shown in Figu The controller \(\bm{K} = \bm{J}^{-T} \bm{K}_\mathcal{X}\) is computed.

    -
      K = inv(stewart.kinematics.J')*Kx;
    +
    K = inv(stewart.kinematics.J')*Kx;
     
    -
    -

    2.5.4 Simulation

    +
    +

    2.5.4 Simulation

    We specify the reference path to follow.

    -
        t = [0:1e-4:10];
    -  
    -    r = zeros(6, length(t));
    -  
    -    r(1, :) = 1e-3.*t.*sin(2*pi*t);
    -    r(2, :) = 1e-3.*t.*cos(2*pi*t);
    -    r(3, :) = 1e-3.*t;
    -  
    -    references = initializeReferences(stewart, 't', t, 'r', r);
    +
    t = [0:1e-4:10];
    +
    +r = zeros(6, length(t));
    +
    +r(1, :) = 1e-3.*t.*sin(2*pi*t);
    +r(2, :) = 1e-3.*t.*cos(2*pi*t);
    +r(3, :) = 1e-3.*t;
    +
    +references = initializeReferences(stewart, 't', t, 'r', r);
     
    -
      controller = initializeController('type', 'ref-track-X');
    +
    controller = initializeController('type', 'ref-track-X');
     
    @@ -847,10 +847,10 @@ We specify the reference path to follow. We run the simulation and we save the results.

    -
      set_param('stewart_platform_model', 'StopTime', '10')
    -  sim('stewart_platform_model')
    -  simout_X = simout;
    -  save('./mat/control_tracking.mat', 'simout_X', '-append');
    +
    set_param('stewart_platform_model', 'StopTime', '10')
    +sim('stewart_platform_model')
    +simout_X = simout;
    +save('./mat/control_tracking.mat', 'simout_X', '-append');
     
    @@ -864,8 +864,8 @@ We run the simulation and we save the results.

    -
    -

    2.6.1 Control Architecture

    +
    +

    2.6.1 Control Architecture

    The plant \(\bm{G}\) is pre-multiply by \(\bm{G}^{-1}(\omega = 0)\) such that the “shaped plant” \(\bm{G}_0 = \bm{G} \bm{G}^{-1}(\omega = 0)\) is diagonal at low frequency. @@ -888,8 +888,8 @@ The control architecture is shown in Figure 15.

    -
    -

    2.6.2 Plant Analysis

    +
    +

    2.6.2 Plant Analysis

    The plant is pre-multiplied by \(\bm{G}^{-1}(\omega = 0)\). @@ -897,7 +897,7 @@ The diagonal and off-diagonal elements of the shaped plant are shown in Figure <

    -
      G0 = G*inv(freqresp(G, 0));
    +
    G0 = G*inv(freqresp(G, 0));
     
    @@ -910,8 +910,8 @@ The diagonal and off-diagonal elements of the shaped plant are shown in Figure <
    -
    -

    2.6.3 Controller Design

    +
    +

    2.6.3 Controller Design

    We have that: @@ -977,8 +977,8 @@ This error is much lower when using the diagonal control in the frame of the leg

    -
    -

    2.8 Conclusion

    +
    +

    2.8 Conclusion

    Both control architecture gives similar results even tough the control in the Leg’s frame gives slightly better results. @@ -1061,8 +1061,8 @@ Thus, this method should be quite robust against parameter variation (e.g. the p

    -
    -

    3.1 Control Schematic

    +
    +

    3.1 Control Schematic

    Let’s consider the control schematic shown in Figure 19. @@ -1103,33 +1103,33 @@ This second loop is responsible for the reference tracking.

    -
    -

    3.2 Initialize the Stewart platform

    +
    +

    3.2 Initialize the Stewart platform

    -
        % Stewart Platform
    -    stewart = initializeStewartPlatform();
    -    stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    -    stewart = generateGeneralConfiguration(stewart);
    -    stewart = computeJointsPose(stewart);
    -    stewart = initializeStrutDynamics(stewart);
    -    stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    -    stewart = initializeCylindricalPlatforms(stewart);
    -    stewart = initializeCylindricalStruts(stewart);
    -    stewart = computeJacobian(stewart);
    -    stewart = initializeStewartPose(stewart);
    -    stewart = initializeInertialSensor(stewart, 'type', 'accelerometer', 'freq', 5e3);
    -  
    -    % Ground and Payload
    -    ground = initializeGround('type', 'rigid');
    -    payload = initializePayload('type', 'none');
    -  
    -    % Controller
    -    controller = initializeController('type', 'open-loop');
    -  
    -    % Disturbances and References
    -    disturbances = initializeDisturbances();
    -    references = initializeReferences(stewart);
    +
    % Stewart Platform
    +stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    +stewart = generateGeneralConfiguration(stewart);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart);
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    +stewart = initializeCylindricalPlatforms(stewart);
    +stewart = initializeCylindricalStruts(stewart);
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart, 'type', 'accelerometer', 'freq', 5e3);
    +
    +% Ground and Payload
    +ground = initializeGround('type', 'rigid');
    +payload = initializePayload('type', 'none');
    +
    +% Controller
    +controller = initializeController('type', 'open-loop');
    +
    +% Disturbances and References
    +disturbances = initializeDisturbances();
    +references = initializeReferences(stewart);
     
    @@ -1139,32 +1139,32 @@ This second loop is responsible for the reference tracking.

    3.3 First Control Loop - \(\bm{K}_\mathcal{L}\)

    -
    -

    3.3.1 Identification

    +
    +

    3.3.1 Identification

    Let’s identify the transfer function from \(\bm{\tau}\) to \(\bm{L}\).

    -
      %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +
    %% 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]
    +%% 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]
     
    -  %% Run the linearization
    -  Gl = linearize(mdl, io);
    -  Gl.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  Gl.OutputName = {'L1', 'L2', 'L3', 'L4', 'L5', 'L6'};
    +%% Run the linearization
    +Gl = linearize(mdl, io);
    +Gl.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +Gl.OutputName = {'L1', 'L2', 'L3', 'L4', 'L5', 'L6'};
     
    -
    -

    3.3.2 Obtained Plant

    +
    +

    3.3.2 Obtained Plant

    The obtained plant is shown in Figure 20. @@ -1179,8 +1179,8 @@ The obtained plant is shown in Figure 20.

    -
    -

    3.3.3 Controller Design

    +
    +

    3.3.3 Controller Design

    We apply a decentralized (diagonal) direct velocity feedback. @@ -1194,7 +1194,7 @@ The obtain loop gain is shown in Figure 21.

    -
      Kl = 1e4 * s / (1 + s/2/pi/1e4) * eye(6);
    +
    Kl = 1e4 * s / (1 + s/2/pi/1e4) * eye(6);
     
    @@ -1212,43 +1212,43 @@ The obtain loop gain is shown in Figure 21.

    3.4 Second Control Loop - \(\bm{K}_\mathcal{X}\)

    -
    -

    3.4.1 Identification

    +
    +

    3.4.1 Identification

    -
      Kx = tf(zeros(6));
    +
    Kx = tf(zeros(6));
     
    -  controller = initializeController('type', 'ref-track-hac-dvf');
    +controller = initializeController('type', 'ref-track-hac-dvf');
     
    -
      %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +
    %% 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]
    +%% 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'};
    +%% Run the linearization
    +G = linearize(mdl, io);
    +G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
     
    -
    -

    3.4.2 Obtained Plant

    +
    +

    3.4.2 Obtained Plant

    We use the Jacobian matrix to apply forces in the cartesian frame.

    -
      Gx = G*inv(stewart.kinematics.J');
    -  Gx.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    +
    Gx = G*inv(stewart.kinematics.J');
    +Gx.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
     
    @@ -1264,8 +1264,8 @@ The obtained plant is shown in Figure 22.
    -
    -

    3.4.3 Controller Design

    +
    +

    3.4.3 Controller Design

    The controller consists of: @@ -1278,14 +1278,14 @@ The controller consists of:

    -
      wc = 2*pi*200; % Bandwidth Bandwidth [rad/s]
    +
    wc = 2*pi*200; % Bandwidth Bandwidth [rad/s]
     
    -  h = 3; % Lead parameter
    +h = 3; % Lead parameter
     
    -  Kx = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * wc/s * ((s/wc*2 + 1)/(s/wc*2)) * (1/(1 + s/wc/3));
    +Kx = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * wc/s * ((s/wc*2 + 1)/(s/wc*2)) * (1/(1 + s/wc/3));
     
    -  % Normalization of the gain of have a loop gain of 1 at frequency wc
    -  Kx = Kx.*diag(1./diag(abs(freqresp(Gx*Kx, wc))));
    +% Normalization of the gain of have a loop gain of 1 at frequency wc
    +Kx = Kx.*diag(1./diag(abs(freqresp(Gx*Kx, wc))));
     
    @@ -1300,7 +1300,7 @@ The controller consists of: Then we include the Jacobian in the controller matrix.

    -
      Kx = inv(stewart.kinematics.J')*Kx;
    +
    Kx = inv(stewart.kinematics.J')*Kx;
     
    @@ -1314,15 +1314,15 @@ Then we include the Jacobian in the controller matrix. We specify the reference path to follow.

    -
        t = [0:1e-4:10];
    -  
    -    r = zeros(6, length(t));
    -  
    -    r(1, :) = 1e-3.*t.*sin(2*pi*t);
    -    r(2, :) = 1e-3.*t.*cos(2*pi*t);
    -    r(3, :) = 1e-3.*t;
    -  
    -    references = initializeReferences(stewart, 't', t, 'r', r);
    +
    t = [0:1e-4:10];
    +
    +r = zeros(6, length(t));
    +
    +r(1, :) = 1e-3.*t.*sin(2*pi*t);
    +r(2, :) = 1e-3.*t.*cos(2*pi*t);
    +r(3, :) = 1e-3.*t;
    +
    +references = initializeReferences(stewart, 't', t, 'r', r);
     
    @@ -1330,10 +1330,10 @@ We specify the reference path to follow. We run the simulation and we save the results.

    -
      set_param('stewart_platform_model', 'StopTime', '10')
    -  sim('stewart_platform_model')
    -  simout_H = simout;
    -  save('./mat/control_tracking.mat', 'simout_H', '-append');
    +
    set_param('stewart_platform_model', 'StopTime', '10')
    +sim('stewart_platform_model')
    +simout_H = simout;
    +save('./mat/control_tracking.mat', 'simout_H', '-append');
     
    @@ -1350,8 +1350,8 @@ The obtained position error is shown in Figure 24.
    -
    -

    3.6 Conclusion

    +
    +

    3.6 Conclusion

    @@ -1366,7 +1366,7 @@ The obtained position error is shown in Figure 24. Let’s load the simulation results and compare them in Figure 25.

    -
      load('./mat/control_tracking.mat', 'simout_D', 'simout_L', 'simout_X', 'simout_H');
    +
    load('./mat/control_tracking.mat', 'simout_D', 'simout_L', 'simout_X', 'simout_H');
     
    @@ -1403,12 +1403,12 @@ The center of the frame if \(O_W\) Reference Position with respect to fixed frame {W}: \({}^WT_R\)

    -
      Dxr = 0;
    -  Dyr = 0;
    -  Dzr = 0.1;
    -  Rxr = pi;
    -  Ryr = 0;
    -  Rzr = 0;
    +
    Dxr = 0;
    +Dyr = 0;
    +Dzr = 0.1;
    +Rxr = pi;
    +Ryr = 0;
    +Rzr = 0;
     
    @@ -1416,12 +1416,12 @@ Reference Position with respect to fixed frame {W}: \({}^WT_R\) Measured Position with respect to fixed frame {W}: \({}^WT_M\)

    -
      Dxm = 0;
    -  Dym = 0;
    -  Dzm = 0;
    -  Rxm = pi;
    -  Rym = 0;
    -  Rzm = 0;
    +
    Dxm = 0;
    +Dym = 0;
    +Dzm = 0;
    +Rxm = pi;
    +Rym = 0;
    +Rzm = 0;
     
    @@ -1430,19 +1430,19 @@ We measure the position and orientation (pose) of the element represented by the Thus we can compute the Homogeneous transformation matrix \({}^WT_M\).

    -
        %% Measured Pose
    -    WTm = zeros(4,4);
    +
    %% Measured Pose
    +WTm = zeros(4,4);
     
    -    WTm(1:3, 1:3) = [cos(Rzm) -sin(Rzm) 0;
    -         sin(Rzm)  cos(Rzm) 0;
    -         0        0         1] * ...
    -        [cos(Rym)  0        sin(Rym);
    -         0        1        0;
    -         -sin(Rym)  0        cos(Rym)] * ...
    -        [1        0        0;
    -         0        cos(Rxm) -sin(Rxm);
    -         0        sin(Rxm)  cos(Rxm)];
    -    WTm(1:4, 4) = [Dxm ; Dym ; Dzm; 1];
    +WTm(1:3, 1:3) = [cos(Rzm) -sin(Rzm) 0;
    +                 sin(Rzm)  cos(Rzm) 0;
    +                 0        0         1] * ...
    +    [cos(Rym)  0        sin(Rym);
    +     0        1        0;
    +     -sin(Rym)  0        cos(Rym)] * ...
    +    [1        0        0;
    +     0        cos(Rxm) -sin(Rxm);
    +     0        sin(Rxm)  cos(Rxm)];
    +WTm(1:4, 4) = [Dxm ; Dym ; Dzm; 1];
     
    @@ -1450,19 +1450,19 @@ Thus we can compute the Homogeneous transformation matrix \({}^WT_M\). We can also compute the Homogeneous transformation matrix \({}^WT_R\) corresponding to the transformation required to go from fixed frame \(\{W\}\) to the wanted frame \(\{R\}\).

    -
        %% Reference Pose
    -    WTr = zeros(4,4);
    +
    %% Reference Pose
    +WTr = zeros(4,4);
     
    -    WTr(1:3, 1:3) = [cos(Rzr) -sin(Rzr) 0;
    -         sin(Rzr)  cos(Rzr) 0;
    -         0        0         1] * ...
    -        [cos(Ryr)  0        sin(Ryr);
    -         0        1        0;
    -         -sin(Ryr)  0        cos(Ryr)] * ...
    -        [1        0        0;
    -         0        cos(Rxr) -sin(Rxr);
    -         0        sin(Rxr)  cos(Rxr)];
    -    WTr(1:4, 4) = [Dxr ; Dyr ; Dzr; 1];
    +WTr(1:3, 1:3) = [cos(Rzr) -sin(Rzr) 0;
    +                 sin(Rzr)  cos(Rzr) 0;
    +                 0        0         1] * ...
    +    [cos(Ryr)  0        sin(Ryr);
    +     0        1        0;
    +     -sin(Ryr)  0        cos(Ryr)] * ...
    +    [1        0        0;
    +     0        cos(Rxr) -sin(Rxr);
    +     0        sin(Rxr)  cos(Rxr)];
    +WTr(1:4, 4) = [Dxr ; Dyr ; Dzr; 1];
     
    @@ -1470,8 +1470,8 @@ We can also compute the Homogeneous transformation matrix \({}^WT_R\) correspond We can also compute \({}^WT_V\).

    -
      WTv = eye(4);
    -  WTv(1:3, 4) = WTm(1:3, 4);
    +
    WTv = eye(4);
    +WTv(1:3, 4) = WTm(1:3, 4);
     
    @@ -1482,8 +1482,8 @@ This homogeneous transformation can be computed from the previously computed mat

    -
        %% Wanted pose expressed in a frame corresponding to the actual measured pose
    -    MTr = [WTm(1:3,1:3)', -WTm(1:3,1:3)'*WTm(1:3,4) ; 0 0 0 1]*WTr;
    +
    %% Wanted pose expressed in a frame corresponding to the actual measured pose
    +MTr = [WTm(1:3,1:3)', -WTm(1:3,1:3)'*WTm(1:3,4) ; 0 0 0 1]*WTr;
     
    @@ -1492,22 +1492,22 @@ Now we want to express \({}^VT_R\): \[ {}^VT_R = ({{}^WT_V}^{-1}) {}^WT_R \]

    -
        %% Wanted pose expressed in a frame coincident with the actual position but with no rotation
    -    VTr = [WTv(1:3,1:3)', -WTv(1:3,1:3)'*WTv(1:3,4) ; 0 0 0 1] * WTr;
    +
    %% Wanted pose expressed in a frame coincident with the actual position but with no rotation
    +VTr = [WTv(1:3,1:3)', -WTv(1:3,1:3)'*WTv(1:3,4) ; 0 0 0 1] * WTr;
     
    -
        %% Extract Translations and Rotations from the Homogeneous Matrix
    -    T = MTr;
    -    Edx = T(1, 4);
    -    Edy = T(2, 4);
    -    Edz = T(3, 4);
    +
    %% Extract Translations and Rotations from the Homogeneous Matrix
    +T = MTr;
    +Edx = T(1, 4);
    +Edy = T(2, 4);
    +Edz = T(3, 4);
     
    -    % The angles obtained are u-v-w Euler angles (rotations in the moving frame)
    -    Ery = atan2( T(1, 3),          sqrt(T(1, 1)^2 + T(1, 2)^2));
    -    Erx = atan2(-T(2, 3)/cos(Ery), T(3, 3)/cos(Ery));
    -    Erz = atan2(-T(1, 2)/cos(Ery), T(1, 1)/cos(Ery));
    +% The angles obtained are u-v-w Euler angles (rotations in the moving frame)
    +Ery = atan2( T(1, 3),          sqrt(T(1, 1)^2 + T(1, 2)^2));
    +Erx = atan2(-T(2, 3)/cos(Ery), T(3, 3)/cos(Ery));
    +Erz = atan2(-T(1, 2)/cos(Ery), T(1, 1)/cos(Ery));
     
    @@ -1515,7 +1515,7 @@ Now we want to express \({}^VT_R\):

    Author: Dehaeze Thomas

    -

    Created: 2021-01-08 ven. 15:30

    +

    Created: 2021-01-08 ven. 15:53

    diff --git a/docs/control-vibration-isolation.html b/docs/control-vibration-isolation.html index f299bd2..62d5b9a 100644 --- a/docs/control-vibration-isolation.html +++ b/docs/control-vibration-isolation.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Stewart Platform - Vibration Isolation @@ -42,28 +42,28 @@
  • 1. HAC-LAC (Cascade) Control - Integral Control
  • -
    -

    1.3.1 HAC - Without LAC

    +
    +

    1.3.1 HAC - Without LAC

    -
      controller = initializeController('type', 'open-loop');
    +
    controller = initializeController('type', 'open-loop');
     
    -
      %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +
    %% 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, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Sensor [m, rad]
    +%% 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, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Sensor [m, rad]
     
    -  %% Run the linearization
    -  G_ol = linearize(mdl, io);
    -  G_ol.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G_ol.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
    +%% Run the linearization
    +G_ol = linearize(mdl, io);
    +G_ol.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G_ol.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
     
    -
    -

    1.3.2 HAC - IFF

    +
    +

    1.3.2 HAC - IFF

    -
      controller = initializeController('type', 'iff');
    -  K_iff = -(1e4/s)*eye(6);
    +
    controller = initializeController('type', 'iff');
    +K_iff = -(1e4/s)*eye(6);
     
    -
      %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +
    %% 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, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Sensor [m, rad]
    +%% 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, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Sensor [m, rad]
     
    -  %% Run the linearization
    -  G_iff = linearize(mdl, io);
    -  G_iff.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G_iff.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
    +%% Run the linearization
    +G_iff = linearize(mdl, io);
    +G_iff.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G_iff.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
     
    -
    -

    1.3.3 HAC - DVF

    +
    +

    1.3.3 HAC - DVF

    -
      controller = initializeController('type', 'dvf');
    -  K_dvf = -1e4*s/(1+s/2/pi/5000)*eye(6);
    +
    controller = initializeController('type', 'dvf');
    +K_dvf = -1e4*s/(1+s/2/pi/5000)*eye(6);
     
    -
      %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +
    %% 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, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Sensor [m, rad]
    +%% 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, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Sensor [m, rad]
     
    -  %% Run the linearization
    -  G_dvf = linearize(mdl, io);
    -  G_dvf.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G_dvf.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
    +%% Run the linearization
    +G_dvf = linearize(mdl, io);
    +G_dvf.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G_dvf.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
     
    @@ -290,14 +290,14 @@ We use the Jacobian to express the actuator forces in the cartesian frame, and t

    -
      Gc_ol = minreal(G_ol)/stewart.kinematics.J';
    -  Gc_ol.InputName = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    +
    Gc_ol = minreal(G_ol)/stewart.kinematics.J';
    +Gc_ol.InputName = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
     
    -  Gc_iff = minreal(G_iff)/stewart.kinematics.J';
    -  Gc_iff.InputName = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    +Gc_iff = minreal(G_iff)/stewart.kinematics.J';
    +Gc_iff.InputName = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
     
    -  Gc_dvf = minreal(G_dvf)/stewart.kinematics.J';
    -  Gc_dvf.InputName = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    +Gc_dvf = minreal(G_dvf)/stewart.kinematics.J';
    +Gc_dvf.InputName = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
     
    @@ -319,12 +319,12 @@ We then design a controller based on the transfer functions from \(\bm{\mathcal{
    -
    -

    1.6 HAC - DVF

    +
    +

    1.6 HAC - DVF

    -
    -

    1.6.1 Plant

    +
    +

    1.6.1 Plant

    @@ -335,8 +335,8 @@ We then design a controller based on the transfer functions from \(\bm{\mathcal{
    -
    -

    1.6.2 Controller Design

    +
    +

    1.6.2 Controller Design

    We design a diagonal controller with equal bandwidth for the 6 terms. @@ -344,12 +344,12 @@ The controller is a pure integrator with a small lead near the crossover.

    -
      wc = 2*pi*300; % Wanted Bandwidth [rad/s]
    +
    wc = 2*pi*300; % Wanted Bandwidth [rad/s]
     
    -  h = 1.2;
    -  H_lead = 1/h*(1 + s/(wc/h))/(1 + s/(wc*h));
    +h = 1.2;
    +H_lead = 1/h*(1 + s/(wc/h))/(1 + s/(wc*h));
     
    -  Kd_dvf = diag(1./abs(diag(freqresp(1/s*Gc_dvf, wc)))) .* H_lead .* 1/s;
    +Kd_dvf = diag(1./abs(diag(freqresp(1/s*Gc_dvf, wc)))) .* H_lead .* 1/s;
     
    @@ -365,37 +365,37 @@ The controller is a pure integrator with a small lead near the crossover. Finally, we pre-multiply the diagonal controller by \(\bm{J}^{-T}\) prior implementation.

    -
      K_hac_dvf = inv(stewart.kinematics.J')*Kd_dvf;
    +
    K_hac_dvf = inv(stewart.kinematics.J')*Kd_dvf;
     
    -
    -

    1.6.3 Obtained Performance

    +
    +

    1.6.3 Obtained Performance

    We identify the transmissibility and compliance of the system.

    -
      controller = initializeController('type', 'open-loop');
    -  [T_ol, T_norm_ol, freqs] = computeTransmissibility();
    -  [C_ol, C_norm_ol, ~] = computeCompliance();
    +
    controller = initializeController('type', 'open-loop');
    +[T_ol, T_norm_ol, freqs] = computeTransmissibility();
    +[C_ol, C_norm_ol, ~] = computeCompliance();
     
    -
      controller = initializeController('type', 'dvf');
    -  [T_dvf, T_norm_dvf, ~] = computeTransmissibility();
    -  [C_dvf, C_norm_dvf, ~] = computeCompliance();
    +
    controller = initializeController('type', 'dvf');
    +[T_dvf, T_norm_dvf, ~] = computeTransmissibility();
    +[C_dvf, C_norm_dvf, ~] = computeCompliance();
     
    -
      controller = initializeController('type', 'hac-dvf');
    -  [T_hac_dvf, T_norm_hac_dvf, ~] = computeTransmissibility();
    -  [C_hac_dvf, C_norm_hac_dvf, ~] = computeCompliance();
    +
    controller = initializeController('type', 'hac-dvf');
    +[T_hac_dvf, T_norm_hac_dvf, ~] = computeTransmissibility();
    +[C_hac_dvf, C_norm_hac_dvf, ~] = computeCompliance();
     
    @@ -409,12 +409,12 @@ We identify the transmissibility and compliance of the system.
    -
    -

    1.7 HAC - IFF

    +
    +

    1.7 HAC - IFF

    -
    -

    1.7.1 Plant

    +
    +

    1.7.1 Plant

    @@ -425,8 +425,8 @@ We identify the transmissibility and compliance of the system.
    -
    -

    1.7.2 Controller Design

    +
    +

    1.7.2 Controller Design

    We design a diagonal controller with equal bandwidth for the 6 terms. @@ -434,12 +434,12 @@ The controller is a pure integrator with a small lead near the crossover.

    -
      wc = 2*pi*300; % Wanted Bandwidth [rad/s]
    +
    wc = 2*pi*300; % Wanted Bandwidth [rad/s]
     
    -  h = 1.2;
    -  H_lead = 1/h*(1 + s/(wc/h))/(1 + s/(wc*h));
    +h = 1.2;
    +H_lead = 1/h*(1 + s/(wc/h))/(1 + s/(wc*h));
     
    -  Kd_iff = diag(1./abs(diag(freqresp(1/s*Gc_iff, wc)))) .* H_lead .* 1/s;
    +Kd_iff = diag(1./abs(diag(freqresp(1/s*Gc_iff, wc)))) .* H_lead .* 1/s;
     
    @@ -455,37 +455,37 @@ The controller is a pure integrator with a small lead near the crossover. Finally, we pre-multiply the diagonal controller by \(\bm{J}^{-T}\) prior implementation.

    -
      K_hac_iff = inv(stewart.kinematics.J')*Kd_iff;
    +
    K_hac_iff = inv(stewart.kinematics.J')*Kd_iff;
     
    -
    -

    1.7.3 Obtained Performance

    +
    +

    1.7.3 Obtained Performance

    We identify the transmissibility and compliance of the system.

    -
      controller = initializeController('type', 'open-loop');
    -  [T_ol, T_norm_ol, freqs] = computeTransmissibility();
    -  [C_ol, C_norm_ol, ~] = computeCompliance();
    +
    controller = initializeController('type', 'open-loop');
    +[T_ol, T_norm_ol, freqs] = computeTransmissibility();
    +[C_ol, C_norm_ol, ~] = computeCompliance();
     
    -
      controller = initializeController('type', 'iff');
    -  [T_iff, T_norm_iff, ~] = computeTransmissibility();
    -  [C_iff, C_norm_iff, ~] = computeCompliance();
    +
    controller = initializeController('type', 'iff');
    +[T_iff, T_norm_iff, ~] = computeTransmissibility();
    +[C_iff, C_norm_iff, ~] = computeCompliance();
     
    -
      controller = initializeController('type', 'hac-iff');
    -  [T_hac_iff, T_norm_hac_iff, ~] = computeTransmissibility();
    -  [C_hac_iff, C_norm_hac_iff, ~] = computeCompliance();
    +
    controller = initializeController('type', 'hac-iff');
    +[T_hac_iff, T_norm_hac_iff, ~] = computeTransmissibility();
    +[C_hac_iff, C_norm_hac_iff, ~] = computeCompliance();
     
    @@ -618,24 +618,24 @@ Let’s define the system as shown in figure 13.
    -
    -

    2.1 Initialization

    +
    +

    2.1 Initialization

    We first initialize the Stewart platform.

    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    -  stewart = generateGeneralConfiguration(stewart);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart);
    -  stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    -  stewart = initializeCylindricalPlatforms(stewart);
    -  stewart = initializeCylindricalStruts(stewart);
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    -  stewart = initializeInertialSensor(stewart, 'type', 'none');
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    +stewart = generateGeneralConfiguration(stewart);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart);
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    +stewart = initializeCylindricalPlatforms(stewart);
    +stewart = initializeCylindricalStruts(stewart);
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart, 'type', 'none');
     
    @@ -643,65 +643,65 @@ We first initialize the Stewart platform. The rotation point of the ground is located at the origin of frame \(\{A\}\).

    -
      ground = initializeGround('type', 'rigid', 'rot_point', stewart.platform_F.FO_A);
    -  payload = initializePayload('type', 'none');
    +
    ground = initializeGround('type', 'rigid', 'rot_point', stewart.platform_F.FO_A);
    +payload = initializePayload('type', 'none');
     
    -
    -

    2.2 Identification

    +
    +

    2.2 Identification

    -
    -

    2.2.1 HAC - Without LAC

    +
    +

    2.2.1 HAC - Without LAC

    -
      controller = initializeController('type', 'open-loop');
    +
    controller = initializeController('type', 'open-loop');
     
    -
      %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +
    %% 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, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Sensor [m, rad]
    +%% 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, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Sensor [m, rad]
     
    -  %% Run the linearization
    -  G_ol = linearize(mdl, io);
    -  G_ol.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G_ol.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
    +%% Run the linearization
    +G_ol = linearize(mdl, io);
    +G_ol.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G_ol.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
     
    -
    -

    2.2.2 HAC - DVF

    +
    +

    2.2.2 HAC - DVF

    -
      controller = initializeController('type', 'dvf');
    -  K_dvf = -1e4*s/(1+s/2/pi/5000)*eye(6);
    +
    controller = initializeController('type', 'dvf');
    +K_dvf = -1e4*s/(1+s/2/pi/5000)*eye(6);
     
    -
      %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +
    %% 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, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Sensor [m, rad]
    +%% 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, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Sensor [m, rad]
     
    -  %% Run the linearization
    -  G_dvf = linearize(mdl, io);
    -  G_dvf.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G_dvf.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
    +%% Run the linearization
    +G_dvf = linearize(mdl, io);
    +G_dvf.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G_dvf.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
     
    @@ -711,11 +711,11 @@ The rotation point of the ground is located at the origin of frame \(\{A\}\).

    2.2.3 Cartesian Frame

    -
      Gc_ol = minreal(G_ol)/stewart.kinematics.J';
    -  Gc_ol.InputName = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    +
    Gc_ol = minreal(G_ol)/stewart.kinematics.J';
    +Gc_ol.InputName = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
     
    -  Gc_dvf = minreal(G_dvf)/stewart.kinematics.J';
    -  Gc_dvf.InputName = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    +Gc_dvf = minreal(G_dvf)/stewart.kinematics.J';
    +Gc_dvf.InputName = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
     
    @@ -726,17 +726,17 @@ The rotation point of the ground is located at the origin of frame \(\{A\}\).

    2.3 Singular Value Decomposition

    -
      freqs = logspace(1, 4, 1000);
    +
    freqs = logspace(1, 4, 1000);
     
    -  U_ol = zeros(6,6,length(freqs));
    -  S_ol = zeros(6,length(freqs));
    -  V_ol = zeros(6,6,length(freqs));
    +U_ol = zeros(6,6,length(freqs));
    +S_ol = zeros(6,length(freqs));
    +V_ol = zeros(6,6,length(freqs));
     
    -  U_dvf = zeros(6,6,length(freqs));
    -  S_dvf = zeros(6,length(freqs));
    -  V_dvf = zeros(6,6,length(freqs));
    +U_dvf = zeros(6,6,length(freqs));
    +S_dvf = zeros(6,length(freqs));
    +V_dvf = zeros(6,6,length(freqs));
     
    -  for i = 1:length(freqs)
    +for i = 1:length(freqs)
         [U,S,V] = svd(freqresp(Gc_ol, freqs(i), 'Hz'));
         U_ol(:,:,i) = U;
         S_ol(:,i) = diag(S);
    @@ -746,7 +746,7 @@ The rotation point of the ground is located at the origin of frame \(\{A\}\).
         U_dvf(:,:,i) = U;
         S_dvf(:,i) = diag(S);
         V_dvf(:,:,i) = V;
    -  end
    +end
     
    @@ -779,24 +779,24 @@ There are mainly three different cases:
    -
    -

    3.1 Initialization

    +
    +

    3.1 Initialization

    We first initialize the Stewart platform.

    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    -  stewart = generateGeneralConfiguration(stewart);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart);
    -  stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    -  stewart = initializeCylindricalPlatforms(stewart);
    -  stewart = initializeCylindricalStruts(stewart);
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    -  stewart = initializeInertialSensor(stewart, 'type', 'none');
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    +stewart = generateGeneralConfiguration(stewart);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart);
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    +stewart = initializeCylindricalPlatforms(stewart);
    +stewart = initializeCylindricalStruts(stewart);
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart, 'type', 'none');
     
    @@ -804,35 +804,35 @@ We first initialize the Stewart platform. The rotation point of the ground is located at the origin of frame \(\{A\}\).

    -
      ground = initializeGround('type', 'rigid', 'rot_point', stewart.platform_F.FO_A);
    -  payload = initializePayload('type', 'none');
    +
    ground = initializeGround('type', 'rigid', 'rot_point', stewart.platform_F.FO_A);
    +payload = initializePayload('type', 'none');
     
    -
    -

    3.2 Identification

    +
    +

    3.2 Identification

    -
      controller = initializeController('type', 'dvf');
    -  K_dvf = -1e4*s/(1+s/2/pi/5000)*eye(6);
    +
    controller = initializeController('type', 'dvf');
    +K_dvf = -1e4*s/(1+s/2/pi/5000)*eye(6);
     
    -
      %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +
    %% 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, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Sensor [m, rad]
    +%% 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, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Sensor [m, rad]
     
    -  %% Run the linearization
    -  G_dvf = linearize(mdl, io);
    -  G_dvf.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G_dvf.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
    +%% Run the linearization
    +G_dvf = linearize(mdl, io);
    +G_dvf.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G_dvf.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
     
    @@ -849,7 +849,7 @@ The rotation point of the ground is located at the origin of frame \(\{A\}\). We choose \(W_1 = G^{-1}(0)\).

    -
      W1 = inv(freqresp(G_dvf, 0));
    +
    W1 = inv(freqresp(G_dvf, 0));
     
    @@ -857,7 +857,7 @@ We choose \(W_1 = G^{-1}(0)\). The (static) decoupled plant is \(G_s(s) = G(s) W_1\).

    -
      Gs = G_dvf*W1;
    +
    Gs = G_dvf*W1;
     
    @@ -900,12 +900,12 @@ We design a diagonal controller \(K_s(s)\) that consist of a pure integrator and

    -
      wc = 2*pi*300; % Wanted Bandwidth [rad/s]
    +
    wc = 2*pi*300; % Wanted Bandwidth [rad/s]
     
    -  h = 1.5;
    -  H_lead = 1/h*(1 + s/(wc/h))/(1 + s/(wc*h));
    +h = 1.5;
    +H_lead = 1/h*(1 + s/(wc/h))/(1 + s/(wc*h));
     
    -  Ks_dvf = diag(1./abs(diag(freqresp(1/s*Gs, wc)))) .* H_lead .* 1/s;
    +Ks_dvf = diag(1./abs(diag(freqresp(1/s*Gs, wc)))) .* H_lead .* 1/s;
     
    @@ -914,7 +914,7 @@ The overall controller is then \(K(s) = W_1 K_s(s)\) as shown in Figure
    -
      K_hac_dvf = W1 * Ks_dvf;
    +
    K_hac_dvf = W1 * Ks_dvf;
     
    @@ -927,24 +927,24 @@ The overall controller is then \(K(s) = W_1 K_s(s)\) as shown in Figure
    -
    -

    3.3.3 Results

    +
    +

    3.3.3 Results

    We identify the transmissibility and compliance of the Stewart platform under open-loop and closed-loop control.

    -
      controller = initializeController('type', 'open-loop');
    -  [T_ol, T_norm_ol, freqs] = computeTransmissibility();
    -  [C_ol, C_norm_ol, ~] = computeCompliance();
    +
    controller = initializeController('type', 'open-loop');
    +[T_ol, T_norm_ol, freqs] = computeTransmissibility();
    +[C_ol, C_norm_ol, ~] = computeCompliance();
     
    -
      controller = initializeController('type', 'hac-dvf');
    -  [T_hac_dvf, T_norm_hac_dvf, ~] = computeTransmissibility();
    -  [C_hac_dvf, C_norm_hac_dvf, ~] = computeCompliance();
    +
    controller = initializeController('type', 'hac-dvf');
    +[T_hac_dvf, T_norm_hac_dvf, ~] = computeTransmissibility();
    +[C_hac_dvf, C_norm_hac_dvf, ~] = computeCompliance();
     
    @@ -976,24 +976,24 @@ The results are shown in figure

    4 Time Domain Simulation

    -
    -

    4.1 Initialization

    +
    +

    4.1 Initialization

    We first initialize the Stewart platform.

    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    -  stewart = generateGeneralConfiguration(stewart);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart);
    -  stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    -  stewart = initializeCylindricalPlatforms(stewart);
    -  stewart = initializeCylindricalStruts(stewart);
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    -  stewart = initializeInertialSensor(stewart, 'type', 'none');
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    +stewart = generateGeneralConfiguration(stewart);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart);
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    +stewart = initializeCylindricalPlatforms(stewart);
    +stewart = initializeCylindricalStruts(stewart);
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart, 'type', 'none');
     
    @@ -1001,13 +1001,13 @@ We first initialize the Stewart platform. The rotation point of the ground is located at the origin of frame \(\{A\}\).

    -
      ground = initializeGround('type', 'rigid', 'rot_point', stewart.platform_F.FO_A);
    -  payload = initializePayload('type', 'none');
    +
    ground = initializeGround('type', 'rigid', 'rot_point', stewart.platform_F.FO_A);
    +payload = initializePayload('type', 'none');
     
    -
      load('./mat/motion_error_ol.mat', 'Eg')
    +
    load('./mat/motion_error_ol.mat', 'Eg')
     
    @@ -1017,40 +1017,40 @@ The rotation point of the ground is located at the origin of frame \(\{A\}\).

    4.2 HAC IFF

    -
      controller = initializeController('type', 'iff');
    -  K_iff = -(1e4/s)*eye(6);
    +
    controller = initializeController('type', 'iff');
    +K_iff = -(1e4/s)*eye(6);
     
    -  %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +%% 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, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Sensor [m, rad]
    +%% 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, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Sensor [m, rad]
     
    -  %% Run the linearization
    -  G_iff = linearize(mdl, io);
    -  G_iff.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G_iff.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
    +%% Run the linearization
    +G_iff = linearize(mdl, io);
    +G_iff.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G_iff.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
     
    -  Gc_iff = minreal(G_iff)/stewart.kinematics.J';
    -  Gc_iff.InputName = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    +Gc_iff = minreal(G_iff)/stewart.kinematics.J';
    +Gc_iff.InputName = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
     
    -
      wc = 2*pi*100; % Wanted Bandwidth [rad/s]
    +
    wc = 2*pi*100; % Wanted Bandwidth [rad/s]
     
    -  h = 1.2;
    -  H_lead = 1/h*(1 + s/(wc/h))/(1 + s/(wc*h));
    +h = 1.2;
    +H_lead = 1/h*(1 + s/(wc/h))/(1 + s/(wc*h));
     
    -  Kd_iff = diag(1./abs(diag(freqresp(1/s*Gc_iff, wc)))) .* H_lead .* 1/s;
    -  K_hac_iff = inv(stewart.kinematics.J')*Kd_iff;
    +Kd_iff = diag(1./abs(diag(freqresp(1/s*Gc_iff, wc)))) .* H_lead .* 1/s;
    +K_hac_iff = inv(stewart.kinematics.J')*Kd_iff;
     
    -
      controller = initializeController('type', 'hac-iff');
    +
    controller = initializeController('type', 'hac-iff');
     
    @@ -1060,69 +1060,69 @@ The rotation point of the ground is located at the origin of frame \(\{A\}\).

    4.3 HAC-DVF

    -
      controller = initializeController('type', 'dvf');
    -  K_dvf = -1e4*s/(1+s/2/pi/5000)*eye(6);
    +
    controller = initializeController('type', 'dvf');
    +K_dvf = -1e4*s/(1+s/2/pi/5000)*eye(6);
     
    -  %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +%% 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, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Sensor [m, rad]
    +%% 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, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Sensor [m, rad]
     
    -  %% Run the linearization
    -  G_dvf = linearize(mdl, io);
    -  G_dvf.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G_dvf.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
    +%% Run the linearization
    +G_dvf = linearize(mdl, io);
    +G_dvf.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G_dvf.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
     
    -  Gc_dvf = minreal(G_dvf)/stewart.kinematics.J';
    -  Gc_dvf.InputName = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    +Gc_dvf = minreal(G_dvf)/stewart.kinematics.J';
    +Gc_dvf.InputName = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
     
    -
      wc = 2*pi*100; % Wanted Bandwidth [rad/s]
    +
    wc = 2*pi*100; % Wanted Bandwidth [rad/s]
     
    -  h = 1.2;
    -  H_lead = 1/h*(1 + s/(wc/h))/(1 + s/(wc*h));
    +h = 1.2;
    +H_lead = 1/h*(1 + s/(wc/h))/(1 + s/(wc*h));
     
    -  Kd_dvf = diag(1./abs(diag(freqresp(1/s*Gc_dvf, wc)))) .* H_lead .* 1/s;
    +Kd_dvf = diag(1./abs(diag(freqresp(1/s*Gc_dvf, wc)))) .* H_lead .* 1/s;
     
    -  K_hac_dvf = inv(stewart.kinematics.J')*Kd_dvf;
    +K_hac_dvf = inv(stewart.kinematics.J')*Kd_dvf;
     
    -
      controller = initializeController('type', 'hac-dvf');
    +
    controller = initializeController('type', 'hac-dvf');
     
    -
    -

    4.4 Results

    +
    +

    4.4 Results

    -
      figure;
    -  subplot(1, 2, 1);
    -  hold on;
    -  plot(Eg.Time, Eg.Data(:, 1), 'DisplayName', 'X');
    -  plot(Eg.Time, Eg.Data(:, 2), 'DisplayName', 'Y');
    -  plot(Eg.Time, Eg.Data(:, 3), 'DisplayName', 'Z');
    -  hold off;
    -  xlabel('Time [s]');
    -  ylabel('Position error [m]');
    -  legend();
    +
    figure;
    +subplot(1, 2, 1);
    +hold on;
    +plot(Eg.Time, Eg.Data(:, 1), 'DisplayName', 'X');
    +plot(Eg.Time, Eg.Data(:, 2), 'DisplayName', 'Y');
    +plot(Eg.Time, Eg.Data(:, 3), 'DisplayName', 'Z');
    +hold off;
    +xlabel('Time [s]');
    +ylabel('Position error [m]');
    +legend();
     
    -  subplot(1, 2, 2);
    -  hold on;
    -  plot(simout.Xa.Time, simout.Xa.Data(:, 1));
    -  plot(simout.Xa.Time, simout.Xa.Data(:, 2));
    -  plot(simout.Xa.Time, simout.Xa.Data(:, 3));
    -  hold off;
    -  xlabel('Time [s]');
    -  ylabel('Orientation error [rad]');
    +subplot(1, 2, 2);
    +hold on;
    +plot(simout.Xa.Time, simout.Xa.Data(:, 1));
    +plot(simout.Xa.Time, simout.Xa.Data(:, 2));
    +plot(simout.Xa.Time, simout.Xa.Data(:, 3));
    +hold off;
    +xlabel('Time [s]');
    +ylabel('Orientation error [rad]');
     
    @@ -1145,13 +1145,13 @@ The rotation point of the ground is located at the origin of frame \(\{A\}\).

    Function description

    -
      function [controller] = initializeController(args)
    -  % initializeController - Initialize the Controller
    -  %
    -  % Syntax: [] = initializeController(args)
    -  %
    -  % Inputs:
    -  %    - args - Can have the following fields:
    +
    function [controller] = initializeController(args)
    +% initializeController - Initialize the Controller
    +%
    +% Syntax: [] = initializeController(args)
    +%
    +% Inputs:
    +%    - args - Can have the following fields:
     
    @@ -1161,9 +1161,9 @@ The rotation point of the ground is located at the origin of frame \(\{A\}\).

    Optional Parameters

    -
      arguments
    +
    arguments
         args.type   char   {mustBeMember(args.type, {'open-loop', 'iff', 'dvf', 'hac-iff', 'hac-dvf', 'ref-track-L', 'ref-track-X', 'ref-track-hac-dvf'})} = 'open-loop'
    -  end
    +end
     
    @@ -1173,7 +1173,7 @@ The rotation point of the ground is located at the origin of frame \(\{A\}\).

    Structure initialization

    -
      controller = struct();
    +
    controller = struct();
     
    @@ -1183,24 +1183,24 @@ The rotation point of the ground is located at the origin of frame \(\{A\}\).

    Add Type

    -
      switch args.type
    -    case 'open-loop'
    -      controller.type = 0;
    -    case 'iff'
    -      controller.type = 1;
    -    case 'dvf'
    -      controller.type = 2;
    -    case 'hac-iff'
    -      controller.type = 3;
    -    case 'hac-dvf'
    -      controller.type = 4;
    -    case 'ref-track-L'
    -      controller.type = 5;
    -    case 'ref-track-X'
    -      controller.type = 6;
    -    case 'ref-track-hac-dvf'
    -      controller.type = 7;
    -  end
    +
    switch args.type
    +  case 'open-loop'
    +    controller.type = 0;
    +  case 'iff'
    +    controller.type = 1;
    +  case 'dvf'
    +    controller.type = 2;
    +  case 'hac-iff'
    +    controller.type = 3;
    +  case 'hac-dvf'
    +    controller.type = 4;
    +  case 'ref-track-L'
    +    controller.type = 5;
    +  case 'ref-track-X'
    +    controller.type = 6;
    +  case 'ref-track-hac-dvf'
    +    controller.type = 7;
    +end
     
    @@ -1215,7 +1215,7 @@ The rotation point of the ground is located at the origin of frame \(\{A\}\).

    Author: Dehaeze Thomas

    -

    Created: 2021-01-08 ven. 15:29

    +

    Created: 2021-01-08 ven. 15:52

    diff --git a/docs/cubic-configuration.html b/docs/cubic-configuration.html index 0676bd4..d91283a 100644 --- a/docs/cubic-configuration.html +++ b/docs/cubic-configuration.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Cubic configuration for the Stewart Platform @@ -45,34 +45,34 @@
  • 1.2. Cubic Stewart platform centered with the cube center - Jacobian not estimated at the cube center
  • 1.3. Cubic Stewart platform not centered with the cube center - Jacobian estimated at the cube center
  • 1.4. Cubic Stewart platform not centered with the cube center - Jacobian estimated at the Stewart platform center
  • -
  • 1.5. Conclusion
  • +
  • 1.5. Conclusion
  • 2. Configuration with the Cube’s center above the mobile platform
  • 3. Cubic size analysis
  • 4. Dynamic Coupling in the Cartesian Frame
  • 5. Dynamic Coupling between actuators and sensors of each strut
  • 6. Functions @@ -128,7 +128,7 @@ In this document, the cubic architecture is analyzed:

    -
    +

    The Matlab script corresponding to this section is accessible here.

    @@ -182,21 +182,21 @@ The Jacobian matrix is estimated at the location of the center of the cube.

    -
      H = 100e-3;     % height of the Stewart platform [m]
    -  MO_B = -H/2;     % Position {B} with respect to {M} [m]
    -  Hc = H;         % Size of the useful part of the cube [m]
    -  FOc = H + MO_B; % Center of the cube with respect to {F}
    +
    H = 100e-3;     % height of the Stewart platform [m]
    +MO_B = -H/2;     % Position {B} with respect to {M} [m]
    +Hc = H;         % Size of the useful part of the cube [m]
    +FOc = H + MO_B; % Center of the cube with respect to {F}
     
    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', H, 'MO_B', MO_B);
    -  stewart = generateCubicConfiguration(stewart, 'Hc', Hc, 'FOc', FOc, 'FHa', 0, 'MHb', 0);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart, 'K', ones(6,1));
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeCylindricalPlatforms(stewart, 'Fpr', 175e-3, 'Mpr', 150e-3);
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', H, 'MO_B', MO_B);
    +stewart = generateCubicConfiguration(stewart, 'Hc', Hc, 'FOc', FOc, 'FHa', 0, 'MHb', 0);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart, 'K', ones(6,1));
    +stewart = computeJacobian(stewart);
    +stewart = initializeCylindricalPlatforms(stewart, 'Fpr', 175e-3, 'Mpr', 150e-3);
     
    @@ -291,21 +291,21 @@ The Jacobian matrix is not estimated at the location of the center of the cube.

    -
      H    = 100e-3; % height of the Stewart platform [m]
    -  MO_B = 20e-3;  % Position {B} with respect to {M} [m]
    -  Hc   = H;      % Size of the useful part of the cube [m]
    -  FOc  = H/2;    % Center of the cube with respect to {F}
    +
    H    = 100e-3; % height of the Stewart platform [m]
    +MO_B = 20e-3;  % Position {B} with respect to {M} [m]
    +Hc   = H;      % Size of the useful part of the cube [m]
    +FOc  = H/2;    % Center of the cube with respect to {F}
     
    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', H, 'MO_B', MO_B);
    -  stewart = generateCubicConfiguration(stewart, 'Hc', Hc, 'FOc', FOc, 'FHa', 0, 'MHb', 0);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart, 'K', ones(6,1));
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeCylindricalPlatforms(stewart, 'Fpr', 175e-3, 'Mpr', 150e-3);
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', H, 'MO_B', MO_B);
    +stewart = generateCubicConfiguration(stewart, 'Hc', Hc, 'FOc', FOc, 'FHa', 0, 'MHb', 0);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart, 'K', ones(6,1));
    +stewart = computeJacobian(stewart);
    +stewart = initializeCylindricalPlatforms(stewart, 'Fpr', 175e-3, 'Mpr', 150e-3);
     
    @@ -400,21 +400,21 @@ The Jacobian is estimated at the cube center.

    -
      H    = 80e-3; % height of the Stewart platform [m]
    -  MO_B = -30e-3;  % Position {B} with respect to {M} [m]
    -  Hc   = 100e-3;      % Size of the useful part of the cube [m]
    -  FOc  = H + MO_B;    % Center of the cube with respect to {F}
    +
    H    = 80e-3; % height of the Stewart platform [m]
    +MO_B = -30e-3;  % Position {B} with respect to {M} [m]
    +Hc   = 100e-3;      % Size of the useful part of the cube [m]
    +FOc  = H + MO_B;    % Center of the cube with respect to {F}
     
    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', H, 'MO_B', MO_B);
    -  stewart = generateCubicConfiguration(stewart, 'Hc', Hc, 'FOc', FOc, 'FHa', 0, 'MHb', 0);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart, 'K', ones(6,1));
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeCylindricalPlatforms(stewart, 'Fpr', 175e-3, 'Mpr', 150e-3);
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', H, 'MO_B', MO_B);
    +stewart = generateCubicConfiguration(stewart, 'Hc', Hc, 'FOc', FOc, 'FHa', 0, 'MHb', 0);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart, 'K', ones(6,1));
    +stewart = computeJacobian(stewart);
    +stewart = initializeCylindricalPlatforms(stewart, 'Fpr', 175e-3, 'Mpr', 150e-3);
     
    @@ -520,21 +520,21 @@ The center of the cube from the top platform is at \(z = 110 - 175 = -65\).

    -
      H    = 100e-3; % height of the Stewart platform [m]
    -  MO_B = -H/2;  % Position {B} with respect to {M} [m]
    -  Hc   = 1.5*H;      % Size of the useful part of the cube [m]
    -  FOc  = H/2 + 10e-3;    % Center of the cube with respect to {F}
    +
    H    = 100e-3; % height of the Stewart platform [m]
    +MO_B = -H/2;  % Position {B} with respect to {M} [m]
    +Hc   = 1.5*H;      % Size of the useful part of the cube [m]
    +FOc  = H/2 + 10e-3;    % Center of the cube with respect to {F}
     
    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', H, 'MO_B', MO_B);
    -  stewart = generateCubicConfiguration(stewart, 'Hc', Hc, 'FOc', FOc, 'FHa', 0, 'MHb', 0);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart, 'K', ones(6,1));
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeCylindricalPlatforms(stewart, 'Fpr', 215e-3, 'Mpr', 195e-3);
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', H, 'MO_B', MO_B);
    +stewart = generateCubicConfiguration(stewart, 'Hc', Hc, 'FOc', FOc, 'FHa', 0, 'MHb', 0);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart, 'K', ones(6,1));
    +stewart = computeJacobian(stewart);
    +stewart = initializeCylindricalPlatforms(stewart, 'Fpr', 215e-3, 'Mpr', 195e-3);
     
    @@ -620,10 +620,10 @@ The center of the cube from the top platform is at \(z = 110 - 175 = -65\).
    -
    -

    1.5 Conclusion

    +
    +

    1.5 Conclusion

    -
    +

    Here are the conclusion about the Stiffness matrix for the Cubic configuration:

    @@ -644,7 +644,7 @@ Here are the conclusion about the Stiffness matrix for the Cubic configuration:

    -
    +

    The Matlab script corresponding to this section is accessible here.

    @@ -676,8 +676,8 @@ Thus, we want the cube’s center to be located above the top center. Let’s fix the Height of the Stewart platform and the position of frames \(\{A\}\) and \(\{B\}\):

    -
      H    = 100e-3; % height of the Stewart platform [m]
    -  MO_B = 20e-3;  % Position {B} with respect to {M} [m]
    +
    H    = 100e-3; % height of the Stewart platform [m]
    +MO_B = 20e-3;  % Position {B} with respect to {M} [m]
     
    @@ -697,8 +697,8 @@ However, the rotational stiffnesses are increasing with the cube’s size bu

    -
      Hc   = 0.4*H;    % Size of the useful part of the cube [m]
    -  FOc  = H + MO_B; % Center of the cube with respect to {F}
    +
    Hc   = 0.4*H;    % Size of the useful part of the cube [m]
    +FOc  = H + MO_B; % Center of the cube with respect to {F}
     
    @@ -783,8 +783,8 @@ However, the rotational stiffnesses are increasing with the cube’s size bu
    -
      Hc   = 1.5*H;    % Size of the useful part of the cube [m]
    -  FOc  = H + MO_B; % Center of the cube with respect to {F}
    +
    Hc   = 1.5*H;    % Size of the useful part of the cube [m]
    +FOc  = H + MO_B; % Center of the cube with respect to {F}
     
    @@ -870,8 +870,8 @@ However, the rotational stiffnesses are increasing with the cube’s size bu
    -
      Hc   = 2.5*H;    % Size of the useful part of the cube [m]
    -  FOc  = H + MO_B; % Center of the cube with respect to {F}
    +
    Hc   = 2.5*H;    % Size of the useful part of the cube [m]
    +FOc  = H + MO_B; % Center of the cube with respect to {F}
     
    @@ -1049,10 +1049,10 @@ For a small cube:
    -
    -

    2.3 Conclusion

    +
    +

    2.3 Conclusion

    -
    +

    We found that we can have a diagonal stiffness matrix using the cubic architecture when \(\{A\}\) and \(\{B\}\) are located above the top platform. Depending on the cube’s size, we obtain 3 different configurations. @@ -1102,7 +1102,7 @@ Depending on the cube’s size, we obtain 3 different configurations.

    -
    +

    The Matlab script corresponding to this section is accessible here.

    @@ -1132,8 +1132,8 @@ We only vary the size of the cube. We initialize the wanted cube’s size.

    -
      Hcs = 1e-3*[250:20:350]; % Heights for the Cube [m]
    -  Ks = zeros(6, 6, length(Hcs));
    +
    Hcs = 1e-3*[250:20:350]; % Heights for the Cube [m]
    +Ks = zeros(6, 6, length(Hcs));
     
    @@ -1141,7 +1141,7 @@ We initialize the wanted cube’s size. The height of the Stewart platform is fixed:

    -
      H    = 100e-3; % height of the Stewart platform [m]
    +
    H    = 100e-3; % height of the Stewart platform [m]
     
    @@ -1149,8 +1149,8 @@ The height of the Stewart platform is fixed: The frames \(\{A\}\) and \(\{B\}\) are positioned at the Stewart platform center as well as the cube’s center:

    -
      MO_B = -50e-3;  % Position {B} with respect to {M} [m]
    -  FOc  = H + MO_B; % Center of the cube with respect to {F}
    +
    MO_B = -50e-3;  % Position {B} with respect to {M} [m]
    +FOc  = H + MO_B; % Center of the cube with respect to {F}
     
    @@ -1168,14 +1168,14 @@ We also find that \(k_{\theta_x} = k_{\theta_y}\) and \(k_{\theta_z}\) are varyi
    -
    -

    3.2 Conclusion

    +
    +

    3.2 Conclusion

    We observe that \(k_{\theta_x} = k_{\theta_y}\) and \(k_{\theta_z}\) increase linearly with the cube size.

    -
    +

    In order to maximize the rotational stiffness of the Stewart platform, the size of the cube should be the highest possible.

    @@ -1192,7 +1192,7 @@ In order to maximize the rotational stiffness of the Stewart platform, the size

    -
    +

    The Matlab script corresponding to this section is accessible here.

    @@ -1256,8 +1256,8 @@ Let’s create a Cubic Stewart Platform where the Center of Mass of the m We define the size of the Stewart platform and the position of frames \(\{A\}\) and \(\{B\}\).

    -
      H    = 200e-3; % height of the Stewart platform [m]
    -  MO_B = -10e-3;  % Position {B} with respect to {M} [m]
    +
    H    = 200e-3; % height of the Stewart platform [m]
    +MO_B = -10e-3;  % Position {B} with respect to {M} [m]
     
    @@ -1265,20 +1265,20 @@ We define the size of the Stewart platform and the position of frames \(\{A\}\) Now, we set the cube’s parameters such that the center of the cube is coincident with \(\{A\}\) and \(\{B\}\).

    -
      Hc   = 2.5*H;    % Size of the useful part of the cube [m]
    -  FOc  = H + MO_B; % Center of the cube with respect to {F}
    +
    Hc   = 2.5*H;    % Size of the useful part of the cube [m]
    +FOc  = H + MO_B; % Center of the cube with respect to {F}
     
    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', H, 'MO_B', MO_B);
    -  stewart = generateCubicConfiguration(stewart, 'Hc', Hc, 'FOc', FOc, 'FHa', 25e-3, 'MHb', 25e-3);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart, 'K', 1e6*ones(6,1), 'C', 1e1*ones(6,1));
    -  stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', H, 'MO_B', MO_B);
    +stewart = generateCubicConfiguration(stewart, 'Hc', Hc, 'FOc', FOc, 'FHa', 25e-3, 'MHb', 25e-3);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart, 'K', 1e6*ones(6,1), 'C', 1e1*ones(6,1));
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
     
    @@ -1286,10 +1286,10 @@ Now, we set the cube’s parameters such that the center of the cube is coin Now we set the geometry and mass of the mobile platform such that its center of mass is coincident with \(\{A\}\) and \(\{B\}\).

    -
      stewart = initializeCylindricalPlatforms(stewart, 'Fpr', 1.2*max(vecnorm(stewart.platform_F.Fa)), ...
    -                                                    'Mpm', 10, ...
    -                                                    'Mph', 20e-3, ...
    -                                                    'Mpr', 1.2*max(vecnorm(stewart.platform_M.Mb)));
    +
    stewart = initializeCylindricalPlatforms(stewart, 'Fpr', 1.2*max(vecnorm(stewart.platform_F.Fa)), ...
    +                                         'Mpm', 10, ...
    +                                         'Mph', 20e-3, ...
    +                                         'Mpr', 1.2*max(vecnorm(stewart.platform_M.Mb)));
     
    @@ -1297,8 +1297,8 @@ Now we set the geometry and mass of the mobile platform such that its center of And we set small mass for the struts.

    -
      stewart = initializeCylindricalStruts(stewart, 'Fsm', 1e-3, 'Msm', 1e-3);
    -  stewart = initializeInertialSensor(stewart);
    +
    stewart = initializeCylindricalStruts(stewart, 'Fsm', 1e-3, 'Msm', 1e-3);
    +stewart = initializeInertialSensor(stewart);
     
    @@ -1306,9 +1306,9 @@ And we set small mass for the struts. No flexibility below the Stewart platform and no payload.

    -
      ground = initializeGround('type', 'none');
    -  payload = initializePayload('type', 'none');
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'none');
    +payload = initializePayload('type', 'none');
    +controller = initializeController('type', 'open-loop');
     
    @@ -1327,24 +1327,24 @@ The obtain geometry is shown in figure 10. We now identify the dynamics from forces applied in each strut \(\bm{\tau}\) to the displacement of each strut \(d \bm{\mathcal{L}}\).

    -
      open('stewart_platform_model.slx')
    +
    open('stewart_platform_model.slx')
     
    -  %% Options for Linearized
    -  options = linearizeOptions;
    -  options.SampleTime = 0;
    +%% Options for Linearized
    +options = linearizeOptions;
    +options.SampleTime = 0;
     
    -  %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +%% 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]
    +%% 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]
     
    -  %% Run the linearization
    -  G = linearize(mdl, io, options);
    -  G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6'};
    +%% Run the linearization
    +G = linearize(mdl, io, options);
    +G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6'};
     
    @@ -1352,10 +1352,10 @@ We now identify the dynamics from forces applied in each strut \(\bm{\tau}\) to Now, thanks to the Jacobian (Figure 9), we compute the transfer function from \(\bm{\mathcal{F}}\) to \(\bm{\mathcal{X}}\).

    -
      Gc = inv(stewart.kinematics.J)*G*inv(stewart.kinematics.J');
    -  Gc = inv(stewart.kinematics.J)*G*stewart.kinematics.J;
    -  Gc.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    -  Gc.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
    +
    Gc = inv(stewart.kinematics.J)*G*inv(stewart.kinematics.J');
    +Gc = inv(stewart.kinematics.J)*G*stewart.kinematics.J;
    +Gc.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    +Gc.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
     
    @@ -1381,7 +1381,7 @@ It is interesting to note here that the system shown in Figure Figure 12: Alternative way to decouple the system

    -
    +

    The dynamics is well decoupled at all frequencies.

    @@ -1413,8 +1413,8 @@ This is because the Mass, Damping and Stiffness matrices are all diagonal. Let’s create a Stewart platform with a cubic architecture where the cube’s center is at the center of the Stewart platform.

    -
      H    = 200e-3; % height of the Stewart platform [m]
    -  MO_B = -100e-3;  % Position {B} with respect to {M} [m]
    +
    H    = 200e-3; % height of the Stewart platform [m]
    +MO_B = -100e-3;  % Position {B} with respect to {M} [m]
     
    @@ -1422,20 +1422,20 @@ Let’s create a Stewart platform with a cubic architecture where the cube&r Now, we set the cube’s parameters such that the center of the cube is coincident with \(\{A\}\) and \(\{B\}\).

    -
      Hc   = 2.5*H;    % Size of the useful part of the cube [m]
    -  FOc  = H + MO_B; % Center of the cube with respect to {F}
    +
    Hc   = 2.5*H;    % Size of the useful part of the cube [m]
    +FOc  = H + MO_B; % Center of the cube with respect to {F}
     
    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', H, 'MO_B', MO_B);
    -  stewart = generateCubicConfiguration(stewart, 'Hc', Hc, 'FOc', FOc, 'FHa', 25e-3, 'MHb', 25e-3);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart, 'K', 1e6*ones(6,1), 'C', 1e1*ones(6,1));
    -  stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', H, 'MO_B', MO_B);
    +stewart = generateCubicConfiguration(stewart, 'Hc', Hc, 'FOc', FOc, 'FHa', 25e-3, 'MHb', 25e-3);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart, 'K', 1e6*ones(6,1), 'C', 1e1*ones(6,1));
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
     
    @@ -1443,10 +1443,10 @@ Now, we set the cube’s parameters such that the center of the cube is coin However, the Center of Mass of the mobile platform is not located at the cube’s center.

    -
      stewart = initializeCylindricalPlatforms(stewart, 'Fpr', 1.2*max(vecnorm(stewart.platform_F.Fa)), ...
    -                                                    'Mpm', 10, ...
    -                                                    'Mph', 20e-3, ...
    -                                                    'Mpr', 1.2*max(vecnorm(stewart.platform_M.Mb)));
    +
    stewart = initializeCylindricalPlatforms(stewart, 'Fpr', 1.2*max(vecnorm(stewart.platform_F.Fa)), ...
    +                                         'Mpm', 10, ...
    +                                         'Mph', 20e-3, ...
    +                                         'Mpr', 1.2*max(vecnorm(stewart.platform_M.Mb)));
     
    @@ -1454,8 +1454,8 @@ However, the Center of Mass of the mobile platform is not located at the And we set small mass for the struts.

    -
      stewart = initializeCylindricalStruts(stewart, 'Fsm', 1e-3, 'Msm', 1e-3);
    -  stewart = initializeInertialSensor(stewart);
    +
    stewart = initializeCylindricalStruts(stewart, 'Fsm', 1e-3, 'Msm', 1e-3);
    +stewart = initializeInertialSensor(stewart);
     
    @@ -1463,9 +1463,9 @@ And we set small mass for the struts. No flexibility below the Stewart platform and no payload.

    -
      ground = initializeGround('type', 'none');
    -  payload = initializePayload('type', 'none');
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'none');
    +payload = initializePayload('type', 'none');
    +controller = initializeController('type', 'open-loop');
     
    @@ -1483,24 +1483,24 @@ The obtain geometry is shown in figure
    13. We now identify the dynamics from forces applied in each strut \(\bm{\tau}\) to the displacement of each strut \(d \bm{\mathcal{L}}\).

    -
      open('stewart_platform_model.slx')
    +
    open('stewart_platform_model.slx')
     
    -  %% Options for Linearized
    -  options = linearizeOptions;
    -  options.SampleTime = 0;
    +%% Options for Linearized
    +options = linearizeOptions;
    +options.SampleTime = 0;
     
    -  %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +%% 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]
    +%% 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]
     
    -  %% Run the linearization
    -  G = linearize(mdl, io, options);
    -  G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6'};
    +%% Run the linearization
    +G = linearize(mdl, io, options);
    +G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6'};
     
    @@ -1508,9 +1508,9 @@ We now identify the dynamics from forces applied in each strut \(\bm{\tau}\) to And we use the Jacobian to compute the transfer function from \(\bm{\mathcal{F}}\) to \(\bm{\mathcal{X}}\).

    -
      Gc = inv(stewart.kinematics.J)*G*inv(stewart.kinematics.J');
    -  Gc.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    -  Gc.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
    +
    Gc = inv(stewart.kinematics.J)*G*inv(stewart.kinematics.J');
    +Gc.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    +Gc.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
     
    @@ -1525,7 +1525,7 @@ The obtain dynamics \(\bm{G}_{c}(s) = \bm{J}^{-T} \bm{G}(s) \bm{J}^{-1}\) is sho

    Figure 14: Obtained Dynamics from \(\bm{\mathcal{F}}\) to \(\bm{\mathcal{X}}\) (png, pdf)

    -
    +

    The system is decoupled at low frequency (the Stiffness matrix being diagonal), but it is not decoupled at all frequencies.

    @@ -1538,10 +1538,10 @@ This was expected as the mass matrix is not diagonal (the Center of Mass of the
    -
    -

    4.3 Conclusion

    +
    +

    4.3 Conclusion

    -
    +

    Some conclusions can be drawn from the above analysis:

    @@ -1562,7 +1562,7 @@ Some conclusions can be drawn from the above analysis:

    -
    +

    The Matlab script corresponding to this section is accessible here.

    @@ -1593,28 +1593,28 @@ Let’s generate a Cubic architecture where the cube’s center and the

    -
      H    = 200e-3; % height of the Stewart platform [m]
    -  MO_B = -10e-3;  % Position {B} with respect to {M} [m]
    -  Hc   = 2.5*H;    % Size of the useful part of the cube [m]
    -  FOc  = H + MO_B; % Center of the cube with respect to {F}
    +
    H    = 200e-3; % height of the Stewart platform [m]
    +MO_B = -10e-3;  % Position {B} with respect to {M} [m]
    +Hc   = 2.5*H;    % Size of the useful part of the cube [m]
    +FOc  = H + MO_B; % Center of the cube with respect to {F}
     
    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', H, 'MO_B', MO_B);
    -  stewart = generateCubicConfiguration(stewart, 'Hc', Hc, 'FOc', FOc, 'FHa', 25e-3, 'MHb', 25e-3);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart, 'K', 1e6*ones(6,1), 'C', 1e1*ones(6,1));
    -  stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    -  stewart = initializeCylindricalPlatforms(stewart, 'Fpr', 1.2*max(vecnorm(stewart.platform_F.Fa)), ...
    -                                                    'Mpm', 10, ...
    -                                                    'Mph', 20e-3, ...
    -                                                    'Mpr', 1.2*max(vecnorm(stewart.platform_M.Mb)));
    -  stewart = initializeCylindricalStruts(stewart, 'Fsm', 1e-3, 'Msm', 1e-3);
    -  stewart = initializeInertialSensor(stewart);
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', H, 'MO_B', MO_B);
    +stewart = generateCubicConfiguration(stewart, 'Hc', Hc, 'FOc', FOc, 'FHa', 25e-3, 'MHb', 25e-3);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart, 'K', 1e6*ones(6,1), 'C', 1e1*ones(6,1));
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeCylindricalPlatforms(stewart, 'Fpr', 1.2*max(vecnorm(stewart.platform_F.Fa)), ...
    +                                         'Mpm', 10, ...
    +                                         'Mph', 20e-3, ...
    +                                         'Mpr', 1.2*max(vecnorm(stewart.platform_M.Mb)));
    +stewart = initializeCylindricalStruts(stewart, 'Fsm', 1e-3, 'Msm', 1e-3);
    +stewart = initializeInertialSensor(stewart);
     
    @@ -1622,15 +1622,15 @@ Let’s generate a Cubic architecture where the cube’s center and the No flexibility below the Stewart platform and no payload.

    -
      ground = initializeGround('type', 'none');
    -  payload = initializePayload('type', 'none');
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'none');
    +payload = initializePayload('type', 'none');
    +controller = initializeController('type', 'open-loop');
     
    -
      disturbances = initializeDisturbances();
    -  references = initializeReferences(stewart);
    +
    disturbances = initializeDisturbances();
    +references = initializeReferences(stewart);
     
    @@ -1669,26 +1669,26 @@ Now we generate a Stewart platform which is not cubic but with approximately the

    -
      H    = 200e-3; % height of the Stewart platform [m]
    -  MO_B = -10e-3;  % Position {B} with respect to {M} [m]
    +
    H    = 200e-3; % height of the Stewart platform [m]
    +MO_B = -10e-3;  % Position {B} with respect to {M} [m]
     
    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', H, 'MO_B', MO_B);
    -  stewart = generateGeneralConfiguration(stewart, 'FR', 250e-3, 'MR', 150e-3);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart, 'K', 1e6*ones(6,1), 'C', 1e1*ones(6,1));
    -  stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    -  stewart = initializeCylindricalPlatforms(stewart, 'Fpr', 1.2*max(vecnorm(stewart.platform_F.Fa)), ...
    -                                                    'Mpm', 10, ...
    -                                                    'Mph', 20e-3, ...
    -                                                    'Mpr', 1.2*max(vecnorm(stewart.platform_M.Mb)));
    -  stewart = initializeCylindricalStruts(stewart, 'Fsm', 1e-3, 'Msm', 1e-3);
    -  stewart = initializeInertialSensor(stewart);
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', H, 'MO_B', MO_B);
    +stewart = generateGeneralConfiguration(stewart, 'FR', 250e-3, 'MR', 150e-3);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart, 'K', 1e6*ones(6,1), 'C', 1e1*ones(6,1));
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal', 'type_M', 'spherical');
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeCylindricalPlatforms(stewart, 'Fpr', 1.2*max(vecnorm(stewart.platform_F.Fa)), ...
    +                                         'Mpm', 10, ...
    +                                         'Mph', 20e-3, ...
    +                                         'Mpr', 1.2*max(vecnorm(stewart.platform_M.Mb)));
    +stewart = initializeCylindricalStruts(stewart, 'Fsm', 1e-3, 'Msm', 1e-3);
    +stewart = initializeInertialSensor(stewart);
     
    @@ -1696,9 +1696,9 @@ Now we generate a Stewart platform which is not cubic but with approximately the No flexibility below the Stewart platform and no payload.

    -
      ground = initializeGround('type', 'none');
    -  payload = initializePayload('type', 'none');
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'none');
    +payload = initializePayload('type', 'none');
    +controller = initializeController('type', 'open-loop');
     
    @@ -1729,10 +1729,10 @@ And we identify the dynamics from the actuator forces \(\tau_{i}\) to the relati
    -
    -

    5.3 Conclusion

    +
    +

    5.3 Conclusion

    -
    +

    The Cubic architecture seems to not have any significant effect on the coupling between actuator and sensors of each strut and thus provides no advantages for decentralized control.

    @@ -1766,24 +1766,24 @@ This Matlab function is accessible Function description
    -
      function [stewart] = generateCubicConfiguration(stewart, args)
    -  % generateCubicConfiguration - Generate a Cubic Configuration
    -  %
    -  % Syntax: [stewart] = generateCubicConfiguration(stewart, args)
    -  %
    -  % Inputs:
    -  %    - stewart - A structure with the following fields
    -  %        - geometry.H [1x1] - Total height of the platform [m]
    -  %    - args - Can have the following fields:
    -  %        - Hc  [1x1] - Height of the "useful" part of the cube [m]
    -  %        - FOc [1x1] - Height of the center of the cube with respect to {F} [m]
    -  %        - FHa [1x1] - Height of the plane joining the points ai with respect to the frame {F} [m]
    -  %        - MHb [1x1] - Height of the plane joining the points bi with respect to the frame {M} [m]
    -  %
    -  % Outputs:
    -  %    - stewart - updated Stewart structure with the added fields:
    -  %        - platform_F.Fa  [3x6] - Its i'th column is the position vector of joint ai with respect to {F}
    -  %        - platform_M.Mb  [3x6] - Its i'th column is the position vector of joint bi with respect to {M}
    +
    function [stewart] = generateCubicConfiguration(stewart, args)
    +% generateCubicConfiguration - Generate a Cubic Configuration
    +%
    +% Syntax: [stewart] = generateCubicConfiguration(stewart, args)
    +%
    +% Inputs:
    +%    - stewart - A structure with the following fields
    +%        - geometry.H [1x1] - Total height of the platform [m]
    +%    - args - Can have the following fields:
    +%        - Hc  [1x1] - Height of the "useful" part of the cube [m]
    +%        - FOc [1x1] - Height of the center of the cube with respect to {F} [m]
    +%        - FHa [1x1] - Height of the plane joining the points ai with respect to the frame {F} [m]
    +%        - MHb [1x1] - Height of the plane joining the points bi with respect to the frame {M} [m]
    +%
    +% Outputs:
    +%    - stewart - updated Stewart structure with the added fields:
    +%        - platform_F.Fa  [3x6] - Its i'th column is the position vector of joint ai with respect to {F}
    +%        - platform_M.Mb  [3x6] - Its i'th column is the position vector of joint bi with respect to {M}
     
    @@ -1805,13 +1805,13 @@ This Matlab function is accessible
    Optional Parameters
    -
      arguments
    -      stewart
    -      args.Hc  (1,1) double {mustBeNumeric, mustBePositive} = 60e-3
    -      args.FOc (1,1) double {mustBeNumeric} = 50e-3
    -      args.FHa (1,1) double {mustBeNumeric, mustBeNonnegative} = 15e-3
    -      args.MHb (1,1) double {mustBeNumeric, mustBeNonnegative} = 15e-3
    -  end
    +
    arguments
    +    stewart
    +    args.Hc  (1,1) double {mustBeNumeric, mustBePositive} = 60e-3
    +    args.FOc (1,1) double {mustBeNumeric} = 50e-3
    +    args.FHa (1,1) double {mustBeNumeric, mustBeNonnegative} = 15e-3
    +    args.MHb (1,1) double {mustBeNumeric, mustBeNonnegative} = 15e-3
    +end
     
    @@ -1821,8 +1821,8 @@ This Matlab function is accessible
    Check the stewart structure elements
    -
      assert(isfield(stewart.geometry, 'H'),   'stewart.geometry should have attribute H')
    -  H = stewart.geometry.H;
    +
    assert(isfield(stewart.geometry, 'H'),   'stewart.geometry should have attribute H')
    +H = stewart.geometry.H;
     
    @@ -1837,18 +1837,18 @@ We define the useful points of the cube with respect to the Cube’s center.

    -
      sx = [ 2; -1; -1];
    -  sy = [ 0;  1; -1];
    -  sz = [ 1;  1;  1];
    +
    sx = [ 2; -1; -1];
    +sy = [ 0;  1; -1];
    +sz = [ 1;  1;  1];
     
    -  R = [sx, sy, sz]./vecnorm([sx, sy, sz]);
    +R = [sx, sy, sz]./vecnorm([sx, sy, sz]);
     
    -  L = args.Hc*sqrt(3);
    +L = args.Hc*sqrt(3);
     
    -  Cc = R'*[[0;0;L],[L;0;L],[L;0;0],[L;L;0],[0;L;0],[0;L;L]] - [0;0;1.5*args.Hc];
    +Cc = R'*[[0;0;L],[L;0;L],[L;0;0],[L;L;0],[0;L;0],[0;L;L]] - [0;0;1.5*args.Hc];
     
    -  CCf = [Cc(:,1), Cc(:,3), Cc(:,3), Cc(:,5), Cc(:,5), Cc(:,1)]; % CCf(:,i) corresponds to the bottom cube's vertice corresponding to the i'th leg
    -  CCm = [Cc(:,2), Cc(:,2), Cc(:,4), Cc(:,4), Cc(:,6), Cc(:,6)]; % CCm(:,i) corresponds to the top cube's vertice corresponding to the i'th leg
    +CCf = [Cc(:,1), Cc(:,3), Cc(:,3), Cc(:,5), Cc(:,5), Cc(:,1)]; % CCf(:,i) corresponds to the bottom cube's vertice corresponding to the i'th leg
    +CCm = [Cc(:,2), Cc(:,2), Cc(:,4), Cc(:,4), Cc(:,6), Cc(:,6)]; % CCm(:,i) corresponds to the top cube's vertice corresponding to the i'th leg
     
    @@ -1861,7 +1861,7 @@ We define the useful points of the cube with respect to the Cube’s center. We can compute the vector of each leg \({}^{C}\hat{\bm{s}}_{i}\) (unit vector from \({}^{C}C_{f}\) to \({}^{C}C_{m}\)).

    -
      CSi = (CCm - CCf)./vecnorm(CCm - CCf);
    +
    CSi = (CCm - CCf)./vecnorm(CCm - CCf);
     
    @@ -1869,8 +1869,8 @@ We can compute the vector of each leg \({}^{C}\hat{\bm{s}}_{i}\) (unit vector fr We now which to compute the position of the joints \(a_{i}\) and \(b_{i}\).

    -
      Fa = CCf + [0; 0; args.FOc] + ((args.FHa-(args.FOc-args.Hc/2))./CSi(3,:)).*CSi;
    -  Mb = CCf + [0; 0; args.FOc-H] + ((H-args.MHb-(args.FOc-args.Hc/2))./CSi(3,:)).*CSi;
    +
    Fa = CCf + [0; 0; args.FOc] + ((args.FHa-(args.FOc-args.Hc/2))./CSi(3,:)).*CSi;
    +Mb = CCf + [0; 0; args.FOc-H] + ((H-args.MHb-(args.FOc-args.Hc/2))./CSi(3,:)).*CSi;
     
    @@ -1880,8 +1880,8 @@ We now which to compute the position of the joints \(a_{i}\) and \(b_{i}\).

    Populate the stewart structure

    -
      stewart.platform_F.Fa = Fa;
    -  stewart.platform_M.Mb = Mb;
    +
    stewart.platform_F.Fa = Fa;
    +stewart.platform_M.Mb = Mb;
     
    @@ -1905,7 +1905,7 @@ We now which to compute the position of the joints \(a_{i}\) and \(b_{i}\).

    Author: Dehaeze Thomas

    -

    Created: 2021-01-08 ven. 15:30

    +

    Created: 2021-01-08 ven. 15:52

    diff --git a/docs/dynamics-study.html b/docs/dynamics-study.html index f070bdf..9647210 100644 --- a/docs/dynamics-study.html +++ b/docs/dynamics-study.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Stewart Platform - Dynamics Study @@ -43,13 +43,13 @@
  • 2. Comparison of the static transfer function and the Compliance matrix
  • @@ -71,17 +71,17 @@ In this section, we wish to compare the effect of forces/torques applied by the Let’s generate a Stewart platform.

    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    -  stewart = generateGeneralConfiguration(stewart);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart);
    -  stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    -  stewart = initializeCylindricalPlatforms(stewart);
    -  stewart = initializeCylindricalStruts(stewart);
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    -  stewart = initializeInertialSensor(stewart, 'type', 'none');
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    +stewart = generateGeneralConfiguration(stewart);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart);
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    +stewart = initializeCylindricalPlatforms(stewart);
    +stewart = initializeCylindricalStruts(stewart);
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart, 'type', 'none');
     
    @@ -90,9 +90,9 @@ We don’t put any flexibility below the Stewart platform such that its b We also don’t put any payload on top of the Stewart platform.

    -
      ground = initializeGround('type', 'none');
    -  payload = initializePayload('type', 'none');
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'none');
    +payload = initializePayload('type', 'none');
    +controller = initializeController('type', 'open-loop');
     
    @@ -100,22 +100,22 @@ We also don’t put any payload on top of the Stewart platform. The transfer function from actuator forces \(\bm{\tau}\) to the relative displacement of the mobile platform \(\mathcal{\bm{X}}\) is extracted.

    -
      %% Options for Linearized
    -  options = linearizeOptions;
    -  options.SampleTime = 0;
    +
    %% Options for Linearized
    +options = linearizeOptions;
    +options.SampleTime = 0;
     
    -  %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +%% Name of the Simulink File
    +mdl = 'stewart_platform_model';
     
    -  %% Input/Output definition
    -  clear io; io_i = 1;
    -  io(io_i) = linio([mdl, '/Controller'],              1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
    -  io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}
    +%% Input/Output definition
    +clear io; io_i = 1;
    +io(io_i) = linio([mdl, '/Controller'],              1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
    +io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}
     
    -  %% Run the linearization
    -  G = linearize(mdl, io, options);
    -  G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
    +%% Run the linearization
    +G = linearize(mdl, io, options);
    +G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
     
    @@ -123,8 +123,8 @@ The transfer function from actuator forces \(\bm{\tau}\) to the relative displac Using the Jacobian matrix, we compute the transfer function from force/torques applied by the actuators on the frame \(\{B\}\) fixed to the mobile platform:

    -
      Gc = minreal(G*inv(stewart.kinematics.J'));
    -  Gc.InputName = {'Fnx', 'Fny', 'Fnz', 'Mnx', 'Mny', 'Mnz'};
    +
    Gc = minreal(G*inv(stewart.kinematics.J'));
    +Gc.InputName = {'Fnx', 'Fny', 'Fnz', 'Mnx', 'Mny', 'Mnz'};
     
    @@ -132,15 +132,15 @@ Using the Jacobian matrix, we compute the transfer function from force/torques a We also extract the transfer function from external forces \(\bm{\mathcal{F}}_{\text{ext}}\) on the frame \(\{B\}\) fixed to the mobile platform to the relative displacement \(\mathcal{\bm{X}}\) of \(\{B\}\) with respect to frame \(\{A\}\):

    -
      %% Input/Output definition
    -  clear io; io_i = 1;
    -  io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'F_ext');  io_i = io_i + 1; % External forces/torques applied on {B}
    -  io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}
    +
    %% Input/Output definition
    +clear io; io_i = 1;
    +io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'F_ext');  io_i = io_i + 1; % External forces/torques applied on {B}
    +io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}
     
    -  %% Run the linearization
    -  Gd = linearize(mdl, io, options);
    -  Gd.InputName  = {'Fex', 'Fey', 'Fez', 'Mex', 'Mey', 'Mez'};
    -  Gd.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
    +%% Run the linearization
    +Gd = linearize(mdl, io, options);
    +Gd.InputName  = {'Fex', 'Fey', 'Fez', 'Mex', 'Mey', 'Mez'};
    +Gd.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
     
    @@ -175,7 +175,7 @@ This can be understood from figure 2 where \(\mathcal{ We now add a flexible support under the Stewart platform.

    -
      ground = initializeGround('type', 'flexible');
    +
    ground = initializeGround('type', 'flexible');
     
    @@ -183,28 +183,28 @@ We now add a flexible support under the Stewart platform. And we perform again the identification.

    -
      %% Input/Output definition
    -  clear io; io_i = 1;
    -  io(io_i) = linio([mdl, '/Controller'],              1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
    -  io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}
    +
    %% Input/Output definition
    +clear io; io_i = 1;
    +io(io_i) = linio([mdl, '/Controller'],              1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
    +io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}
     
    -  %% Run the linearization
    -  G = linearize(mdl, io, options);
    -  G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
    +%% Run the linearization
    +G = linearize(mdl, io, options);
    +G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
     
    -  Gc = minreal(G*inv(stewart.kinematics.J'));
    -  Gc.InputName = {'Fnx', 'Fny', 'Fnz', 'Mnx', 'Mny', 'Mnz'};
    +Gc = minreal(G*inv(stewart.kinematics.J'));
    +Gc.InputName = {'Fnx', 'Fny', 'Fnz', 'Mnx', 'Mny', 'Mnz'};
     
    -  %% Input/Output definition
    -  clear io; io_i = 1;
    -  io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'F_ext');  io_i = io_i + 1; % External forces/torques applied on {B}
    -  io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}
    +%% Input/Output definition
    +clear io; io_i = 1;
    +io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'F_ext');  io_i = io_i + 1; % External forces/torques applied on {B}
    +io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}
     
    -  %% Run the linearization
    -  Gd = linearize(mdl, io, options);
    -  Gd.InputName  = {'Fex', 'Fey', 'Fez', 'Mex', 'Mey', 'Mez'};
    -  Gd.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
    +%% Run the linearization
    +Gd = linearize(mdl, io, options);
    +Gd.InputName  = {'Fex', 'Fey', 'Fez', 'Mex', 'Mey', 'Mez'};
    +Gd.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
     
    @@ -235,10 +235,10 @@ And thus \(\mathcal{F}_{x}\) and \(\mathcal{F}_{x,\text{ext}}\) have clearly
    -
    -

    1.3 Conclusion

    +
    +

    1.3 Conclusion

    -
    +

    The transfer function from forces/torques applied by the actuators on the payload \(\bm{\mathcal{F}} = \bm{J}^T \bm{\tau}\) to the pose of the mobile platform \(\bm{\mathcal{X}}\) is the same as the transfer function from external forces/torques to \(\bm{\mathcal{X}}\) as long as the Stewart platform’s base is fixed.

    @@ -263,17 +263,17 @@ In this section, we see how the Compliance matrix of the Stewart platform is lin Initialization of the Stewart platform.

    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    -  stewart = generateGeneralConfiguration(stewart);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart);
    -  stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    -  stewart = initializeCylindricalPlatforms(stewart);
    -  stewart = initializeCylindricalStruts(stewart);
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    -  stewart = initializeInertialSensor(stewart, 'type', 'none');
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    +stewart = generateGeneralConfiguration(stewart);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart);
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    +stewart = initializeCylindricalPlatforms(stewart);
    +stewart = initializeCylindricalStruts(stewart);
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart, 'type', 'none');
     
    @@ -281,9 +281,9 @@ Initialization of the Stewart platform. No flexibility below the Stewart platform and no payload.

    -
      ground = initializeGround('type', 'none');
    -  payload = initializePayload('type', 'none');
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'none');
    +payload = initializePayload('type', 'none');
    +controller = initializeController('type', 'open-loop');
     
    @@ -291,28 +291,28 @@ No flexibility below the Stewart platform and no payload. Estimation of the transfer function from \(\mathcal{\bm{F}}\) to \(\mathcal{\bm{X}}\):

    -
      %% Options for Linearized
    -  options = linearizeOptions;
    -  options.SampleTime = 0;
    +
    %% Options for Linearized
    +options = linearizeOptions;
    +options.SampleTime = 0;
     
    -  %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +%% Name of the Simulink File
    +mdl = 'stewart_platform_model';
     
    -  %% Input/Output definition
    -  clear io; io_i = 1;
    -  io(io_i) = linio([mdl, '/Controller'],              1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
    -  io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}
    +%% Input/Output definition
    +clear io; io_i = 1;
    +io(io_i) = linio([mdl, '/Controller'],              1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
    +io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}
     
    -  %% Run the linearization
    -  G = linearize(mdl, io, options);
    -  G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
    +%% Run the linearization
    +G = linearize(mdl, io, options);
    +G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
     
    -
      Gc = minreal(G*inv(stewart.kinematics.J'));
    -  Gc.InputName = {'Fnx', 'Fny', 'Fnz', 'Mnx', 'Mny', 'Mnz'};
    +
    Gc = minreal(G*inv(stewart.kinematics.J'));
    +Gc.InputName = {'Fnx', 'Fny', 'Fnz', 'Mnx', 'Mny', 'Mnz'};
     
    @@ -470,10 +470,10 @@ And now at the Compliance matrix.
    -
    -

    2.2 Conclusion

    +
    +

    2.2 Conclusion

    -
    +

    The low frequency transfer function matrix from \(\mathcal{\bm{F}}\) to \(\mathcal{\bm{X}}\) corresponds to the compliance matrix of the Stewart platform.

    @@ -485,7 +485,7 @@ The low frequency transfer function matrix from \(\mathcal{\bm{F}}\) to \(\mathc

    Author: Dehaeze Thomas

    -

    Created: 2021-01-08 ven. 15:30

    +

    Created: 2021-01-08 ven. 15:52

    diff --git a/docs/flexible-stewart-platform.html b/docs/flexible-stewart-platform.html index bdf04a3..e7e650a 100644 --- a/docs/flexible-stewart-platform.html +++ b/docs/flexible-stewart-platform.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Stewart Platform with Flexible Elements @@ -24,48 +24,48 @@
    • 1. Simscape Model
    • 2. Control with flexible elements
    • 3. Flexible Joint Specifications
    • 4. Flexible Joint Specifications with the APA300ML
    • 5. Relative Motion Sensors
    • 6. Struts with Encoders @@ -82,11 +82,11 @@

      1 Simscape Model

      -
      -

      1.1 Flexible APA

      +
      +

      1.1 Flexible APA

      -
        apa = load('./mat/APA300ML.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K');
      +
      apa = load('./mat/APA300ML.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K');
       
      @@ -209,7 +209,7 @@

      1.2 Flexible Joint

      -
        flex_joint = load('./mat/flexor_025.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K');
      +
      flex_joint = load('./mat/flexor_025.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K');
       
      @@ -325,37 +325,37 @@
      -
      -

      1.3 Identification

      +
      +

      1.3 Identification

      And we identify the dynamics from force actuators to force sensors.

      -
        %% Options for Linearized
      -  options = linearizeOptions;
      -  options.SampleTime = 0;
      +
      %% Options for Linearized
      +options = linearizeOptions;
      +options.SampleTime = 0;
       
      -  %% Name of the Simulink File
      -  mdl = 'stewart_platform_model';
      +%% 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]
      +%% 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]
       
      -
        ground = initializeGround('type', 'none');
      -  payload = initializePayload('type', 'rigid', 'm', 50);
      -  controller = initializeController('type', 'open-loop');
      +
      ground = initializeGround('type', 'none');
      +payload = initializePayload('type', 'rigid', 'm', 50);
      +controller = initializeController('type', 'open-loop');
       
      -
        disturbances = initializeDisturbances();
      +
      disturbances = initializeDisturbances();
       
      @@ -365,36 +365,36 @@ And we identify the dynamics from force actuators to force sensors.

      1.4 No Flexible Elements

      -
        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);
      +
      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);
      +references = initializeReferences(stewart);
       
      -
        %% 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'};
      +
      %% 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'};
       
      @@ -411,32 +411,32 @@ And we identify the dynamics from force actuators to force sensors.
      -
        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);
      +
      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);
       
      -
        %% 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'};
      +
      %% 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'};
       
      -
      -

      1.6 Flexible APA

      +
      +

      1.6 Flexible APA

      @@ -446,34 +446,34 @@ And we identify the dynamics from force actuators to force sensors.
      -
        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);
      +
      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);
       
      -
        %% 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'};
      +
      %% 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'};
       
      @@ -490,24 +490,24 @@ And we identify the dynamics from force actuators to force sensors.
      -
        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);
      +
      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);
       
      -
        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'};
      +
      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'};
       
      @@ -517,7 +517,7 @@ And we identify the dynamics from force actuators to force sensors.

      1.8 Save

      -
        save('./mat/flexible_stewart_platform.mat', 'G', 'Gj', 'Ga', 'Gf');
      +
      save('./mat/flexible_stewart_platform.mat', 'G', 'Gj', 'Ga', 'Gf');
       
      @@ -566,10 +566,10 @@ In order to model a flexible element with only few mass-spring-damper elements:
    -
    -

    1.12 Conclusion

    +
    +

    1.12 Conclusion

    -
    +

    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. @@ -588,66 +588,66 @@ This permit to have a relatively sane number of states for the model.

    2.1 Flexible APA and Flexible Joint

    -
      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');
    +
    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');
     
    -
      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);
    +
    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);
     
    -
      ground = initializeGround('type', 'none');
    -  payload = initializePayload('type', 'rigid', 'm', 50);
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'none');
    +payload = initializePayload('type', 'rigid', 'm', 50);
    +controller = initializeController('type', 'open-loop');
     
    -
      disturbances = initializeDisturbances();
    -  references = initializeReferences(stewart);
    +
    disturbances = initializeDisturbances();
    +references = initializeReferences(stewart);
     
    -
    -

    2.2 Identification

    +
    +

    2.2 Identification

    And we identify the dynamics from force actuators to force sensors.

    -
      %% Options for Linearized
    -  options = linearizeOptions;
    -  options.SampleTime = 0;
    +
    %% Options for Linearized
    +options = linearizeOptions;
    +options.SampleTime = 0;
     
    -  %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +%% 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]
    +%% 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]
     
    -
      G = -linearize(mdl, io, options);
    -  G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -  G.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6'};
    +
    G = -linearize(mdl, io, options);
    +G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G.OutputName = {'Dm1', 'Dm2', 'Dm3', 'Dm4', 'Dm5', 'Dm6'};
     
    @@ -660,12 +660,12 @@ And we identify the dynamics from force actuators to force sensors. Controller Design

    -
      Kl = -1e5*s/(1 + s/2/pi/2e2)/(1 + s/2/pi/5e2) * eye(6);
    +
    Kl = -1e5*s/(1 + s/2/pi/2e2)/(1 + s/2/pi/5e2) * eye(6);
     
    -
      isstable(feedback(G(1:6,1:6)*Kl, eye(6), -1))
    +
    isstable(feedback(G(1:6,1:6)*Kl, eye(6), -1))
     
    @@ -679,37 +679,37 @@ Controller Design

    2.4 HAC

    -
      Kx = tf(zeros(6));
    +
    Kx = tf(zeros(6));
     
    -  controller = initializeController('type', 'ref-track-hac-dvf');
    +controller = initializeController('type', 'ref-track-hac-dvf');
     
    -
      %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +
    %% 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]
    +%% 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'};
    +%% Run the linearization
    +G = linearize(mdl, io);
    +G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +G.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
     
    -
      Gl = -stewart.kinematics.J*G;
    -  Gl.OutputName  = {'D1', 'D2', 'D3', 'D4', 'D5', 'D6'};
    +
    Gl = -stewart.kinematics.J*G;
    +Gl.OutputName  = {'D1', 'D2', 'D3', 'D4', 'D5', 'D6'};
     
    -
      wc = 2*pi*300;
    -  Kl = diag(1./diag(abs(freqresp(Gl, wc)))) * wc/s * 1/(1 + s/3/wc);
    +
    wc = 2*pi*300;
    +Kl = diag(1./diag(abs(freqresp(Gl, wc)))) * wc/s * 1/(1 + s/3/wc);
     
    @@ -720,39 +720,39 @@ Controller Design

    3 Flexible Joint Specifications

    -
    -

    3.1 Stewart Platform Initialization

    +
    +

    3.1 Stewart Platform Initialization

    -
      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);
    +
    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);
    +references = initializeReferences(stewart);
     
    -
      ground = initializeGround('type', 'none');
    -  payload = initializePayload('type', 'rigid', 'm', 50);
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'none');
    +payload = initializePayload('type', 'rigid', 'm', 50);
    +controller = initializeController('type', 'open-loop');
     
    -
      disturbances = initializeDisturbances();
    +
    disturbances = initializeDisturbances();
     
    -
      open('stewart_platform_model.slx')
    +
    open('stewart_platform_model.slx')
     
    @@ -762,7 +762,7 @@ Controller Design

    3.2 Effect of the Bending Stiffness

    -
      Kfs = [1, 10, 100, 1000]; % [Nm/rad]
    +
    Kfs = [1, 10, 100, 1000]; % [Nm/rad]
     
    @@ -772,7 +772,7 @@ Controller Design

    3.3 Effect of the Torsion Stiffness

    -
      Kts = [10, 100, 500, 1000]; % [Nm/rad]
    +
    Kts = [10, 100, 500, 1000]; % [Nm/rad]
     
    @@ -782,7 +782,7 @@ Controller Design

    3.4 Effect of the Axial Stiffness

    -
      Kas = [1e6, 1e7, 1e8, 5e8, 1e9]; % [N/m]
    +
    Kas = [1e6, 1e7, 1e8, 5e8, 1e9]; % [N/m]
     
    @@ -792,17 +792,17 @@ Controller Design

    3.5 Effect of the Radial (Shear) Stiffness

    -
      Krs = [1e4, 1e5, 1e6, 1e7]; % [N/m]
    +
    Krs = [1e4, 1e5, 1e6, 1e7]; % [N/m]
     
    -
    -

    3.6 Comparison of perfect joint and worst specified joint

    +
    +

    3.6 Comparison of perfect joint and worst specified joint

    -
    -

    3.7 Conclusion

    +
    +

    3.7 Conclusion

    Qualitatively: @@ -891,118 +891,118 @@ Quantitatively:

    4 Flexible Joint Specifications with the APA300ML

    -
    -

    4.1 Stewart Platform Initialization

    +
    +

    4.1 Stewart Platform Initialization

    -
      apa = load('./mat/APA300ML.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K');
    +
    apa = load('./mat/APA300ML.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K');
     
    -
      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);
    +
    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);
    +references = initializeReferences(stewart);
     
    -
      ground = initializeGround('type', 'none');
    -  payload = initializePayload('type', 'rigid', 'm', 50);
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'none');
    +payload = initializePayload('type', 'rigid', 'm', 50);
    +controller = initializeController('type', 'open-loop');
     
    -
      disturbances = initializeDisturbances();
    +
    disturbances = initializeDisturbances();
     
    -
      open('stewart_platform_model.slx')
    +
    open('stewart_platform_model.slx')
     
    -
    -

    4.2 Comparison of perfect joint and worst specified joint

    +
    +

    4.2 Comparison of perfect joint and worst specified joint

    5 Relative Motion Sensors

    -
    -

    5.1 Stewart Platform Initialization

    +
    +

    5.1 Stewart Platform Initialization

    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart);
    -  stewart = generateGeneralConfiguration(stewart);
    -  stewart = computeJointsPose(stewart);
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart);
    +stewart = generateGeneralConfiguration(stewart);
    +stewart = computeJointsPose(stewart);
     
    -
      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');
    +
    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');
     
    -
      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));
    +
    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));
     
    -
      stewart = initializeCylindricalPlatforms(stewart);
    +
    stewart = initializeCylindricalPlatforms(stewart);
     
    -
      stewart = initializeCylindricalStruts(stewart);
    +
    stewart = initializeCylindricalStruts(stewart);
     
    -
      stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    -  stewart = initializeInertialSensor(stewart);
    +
    stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart);
     
    -  references = initializeReferences(stewart);
    +references = initializeReferences(stewart);
     
    -
      ground = initializeGround('type', 'none');
    -  payload = initializePayload('type', 'rigid', 'm', 50);
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'none');
    +payload = initializePayload('type', 'rigid', 'm', 50);
    +controller = initializeController('type', 'open-loop');
     
    -
      disturbances = initializeDisturbances();
    +
    disturbances = initializeDisturbances();
     
    @@ -1017,7 +1017,7 @@ Quantitatively:

    6.1 Flexible Strut

    -
      apa = load('./mat/strut_encoder.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K');
    +
    apa = load('./mat/strut_encoder.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K');
     
    @@ -1148,60 +1148,60 @@ Quantitatively:

    6.2 Stewart Platform

    -
      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 = 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 = 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);
    +stewart = initializeSolidPlatforms(stewart);
    +stewart = initializeCylindricalStruts(stewart, 'type_F', 'none', 'type_M', 'none');
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart);
     
    -
      disturbances = initializeDisturbances();
    -  ground = initializeGround('type', 'none');
    -  payload = initializePayload('type', 'rigid', 'm', 1);
    -  controller = initializeController('type', 'open-loop');
    -  references = initializeReferences(stewart);
    +
    disturbances = initializeDisturbances();
    +ground = initializeGround('type', 'none');
    +payload = initializePayload('type', 'rigid', 'm', 1);
    +controller = initializeController('type', 'open-loop');
    +references = initializeReferences(stewart);
     
    -
      %% Options for Linearized
    -  options = linearizeOptions;
    -  options.SampleTime = 0;
    +
    %% Options for Linearized
    +options = linearizeOptions;
    +options.SampleTime = 0;
     
    -  %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +%% 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]
    +%% 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]
     
    -
      %% 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'};
    +
    %% 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'};
     
    @@ -1216,7 +1216,7 @@ Quantitatively:

    Author: Dehaeze Thomas

    -

    Created: 2021-01-08 ven. 15:29

    +

    Created: 2021-01-08 ven. 15:52

    diff --git a/docs/identification.html b/docs/identification.html index 6cf72b9..f0a8c49 100644 --- a/docs/identification.html +++ b/docs/identification.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Identification of the Stewart Platform using Simscape @@ -50,13 +50,13 @@
  • 2. Transmissibility Analysis
  • 3. Compliance Analysis
  • @@ -64,18 +64,18 @@ @@ -105,24 +105,24 @@ In this document, we discuss the various methods to identify the behavior of the

    1.1 Initialize the Stewart Platform

    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart);
    -  stewart = generateGeneralConfiguration(stewart);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart);
    -  stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    -  stewart = initializeCylindricalPlatforms(stewart);
    -  stewart = initializeCylindricalStruts(stewart);
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    -  stewart = initializeInertialSensor(stewart);
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart);
    +stewart = generateGeneralConfiguration(stewart);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart);
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    +stewart = initializeCylindricalPlatforms(stewart);
    +stewart = initializeCylindricalStruts(stewart);
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart);
     
    -
      ground = initializeGround('type', 'none');
    -  payload = initializePayload('type', 'none');
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'none');
    +payload = initializePayload('type', 'none');
    +controller = initializeController('type', 'open-loop');
     
    @@ -132,23 +132,23 @@ In this document, we discuss the various methods to identify the behavior of the

    1.2 Identification

    -
      %% Options for Linearized
    -  options = linearizeOptions;
    -  options.SampleTime = 0;
    +
    %% Options for Linearized
    +options = linearizeOptions;
    +options.SampleTime = 0;
     
    -  %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +%% Name of the Simulink File
    +mdl = 'stewart_platform_model';
     
    -  %% Input/Output definition
    -  clear io; io_i = 1;
    -  io(io_i) = linio([mdl, '/Controller'],              1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
    -  io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}
    -  io(io_i) = linio([mdl, '/Relative Motion Sensor'],  2, 'openoutput'); io_i = io_i + 1; % Velocity of {B} w.r.t. {A}
    +%% Input/Output definition
    +clear io; io_i = 1;
    +io(io_i) = linio([mdl, '/Controller'],              1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
    +io(io_i) = linio([mdl, '/Relative Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Position/Orientation of {B} w.r.t. {A}
    +io(io_i) = linio([mdl, '/Relative Motion Sensor'],  2, 'openoutput'); io_i = io_i + 1; % Velocity of {B} w.r.t. {A}
     
    -  %% Run the linearization
    -  G = linearize(mdl, io);
    -  % G.InputName  = {'tau1', 'tau2', 'tau3', 'tau4', 'tau5', 'tau6'};
    -  % G.OutputName = {'Xdx', 'Xdy', 'Xdz', 'Xrx', 'Xry', 'Xrz', 'Vdx', 'Vdy', 'Vdz', 'Vrx', 'Vry', 'Vrz'};
    +%% Run the linearization
    +G = linearize(mdl, io);
    +% G.InputName  = {'tau1', 'tau2', 'tau3', 'tau4', 'tau5', 'tau6'};
    +% G.OutputName = {'Xdx', 'Xdy', 'Xdz', 'Xrx', 'Xry', 'Xrz', 'Vdx', 'Vdy', 'Vdz', 'Vrx', 'Vry', 'Vrz'};
     
    @@ -156,7 +156,7 @@ In this document, we discuss the various methods to identify the behavior of the Let’s check the size of G:

    -
      size(G)
    +
    size(G)
     
    @@ -173,7 +173,7 @@ ans = We expect to have only 12 states (corresponding to the 6dof of the mobile platform).

    -
      Gm = minreal(G);
    +
    Gm = minreal(G);
     
    @@ -196,7 +196,7 @@ And indeed, we obtain 12 states. We can perform the following transformation using the ss2ss command.

    -
      Gt = ss2ss(Gm, Gm.C);
    +
    Gt = ss2ss(Gm, Gm.C);
     
    @@ -212,14 +212,14 @@ The measurements are the 6 displacement and 6 velocities of mobile platform with We could perform the transformation by hand:

    -
      At = Gm.C*Gm.A*pinv(Gm.C);
    +
    At = Gm.C*Gm.A*pinv(Gm.C);
     
    -  Bt = Gm.C*Gm.B;
    +Bt = Gm.C*Gm.B;
     
    -  Ct = eye(12);
    -  Dt = zeros(12, 6);
    +Ct = eye(12);
    +Dt = zeros(12, 6);
     
    -  Gt = ss(At, Bt, Ct, Dt);
    +Gt = ss(At, Bt, Ct, Dt);
     
    @@ -229,7 +229,7 @@ We could perform the transformation by hand:

    1.4 Analysis

    -
      [V,D] = eig(Gt.A);
    +
    [V,D] = eig(Gt.A);
     
    @@ -306,28 +306,28 @@ To visualize the i’th mode, we may excite the system using the inputs \(U_ Let’s first sort the modes and just take the modes corresponding to a eigenvalue with a positive imaginary part.

    -
      ws = imag(diag(D));
    -  [ws,I] = sort(ws)
    -  ws = ws(7:end); I = I(7:end);
    +
    ws = imag(diag(D));
    +[ws,I] = sort(ws)
    +ws = ws(7:end); I = I(7:end);
     
    -
      for i = 1:length(ws)
    +
    for i = 1:length(ws)
     
    -
      i_mode = I(i); % the argument is the i'th mode
    +
    i_mode = I(i); % the argument is the i'th mode
     
    -
      lambda_i = D(i_mode, i_mode);
    -  xi_i = V(:,i_mode);
    +
    lambda_i = D(i_mode, i_mode);
    +xi_i = V(:,i_mode);
     
    -  a_i = real(lambda_i);
    -  b_i = imag(lambda_i);
    +a_i = real(lambda_i);
    +b_i = imag(lambda_i);
     
    @@ -335,13 +335,13 @@ Let’s first sort the modes and just take the modes corresponding to a eige Let do 10 periods of the mode.

    -
      t = linspace(0, 10/(imag(lambda_i)/2/pi), 1000);
    -  U_i = pinv(Gt.B) * real(xi_i * lambda_i * (cos(b_i * t) + 1i*sin(b_i * t)));
    +
    t = linspace(0, 10/(imag(lambda_i)/2/pi), 1000);
    +U_i = pinv(Gt.B) * real(xi_i * lambda_i * (cos(b_i * t) + 1i*sin(b_i * t)));
     
    -
      U = timeseries(U_i, t);
    +
    U = timeseries(U_i, t);
     
    @@ -349,9 +349,9 @@ Let do 10 periods of the mode. Simulation:

    -
      load('mat/conf_simscape.mat');
    -  set_param(conf_simscape, 'StopTime', num2str(t(end)));
    -  sim(mdl);
    +
    load('mat/conf_simscape.mat');
    +set_param(conf_simscape, 'StopTime', num2str(t(end)));
    +sim(mdl);
     
    @@ -359,15 +359,15 @@ Simulation: Save the movie of the mode shape.

    -
      smwritevideo(mdl, sprintf('figs/mode%i', i), ...
    -               'PlaybackSpeedRatio', 1/(b_i/2/pi), ...
    -               'FrameRate', 30, ...
    -               'FrameSize', [800, 400]);
    +
    smwritevideo(mdl, sprintf('figs/mode%i', i), ...
    +             'PlaybackSpeedRatio', 1/(b_i/2/pi), ...
    +             'FrameRate', 30, ...
    +             'FrameSize', [800, 400]);
     
    -
      end
    +
    end
     
    @@ -402,21 +402,21 @@ Save the movie of the mode shape.

    -
    -

    2.1 Initialize the Stewart platform

    +
    +

    2.1 Initialize the Stewart platform

    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    -  stewart = generateGeneralConfiguration(stewart);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart);
    -  stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    -  stewart = initializeCylindricalPlatforms(stewart);
    -  stewart = initializeCylindricalStruts(stewart);
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    -  stewart = initializeInertialSensor(stewart, 'type', 'accelerometer', 'freq', 5e3);
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    +stewart = generateGeneralConfiguration(stewart);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart);
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    +stewart = initializeCylindricalPlatforms(stewart);
    +stewart = initializeCylindricalStruts(stewart);
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart, 'type', 'accelerometer', 'freq', 5e3);
     
    @@ -424,9 +424,9 @@ Save the movie of the mode shape. We set the rotation point of the ground to be at the same point at frames \(\{A\}\) and \(\{B\}\).

    -
      ground = initializeGround('type', 'rigid', 'rot_point', stewart.platform_F.FO_A);
    -  payload = initializePayload('type', 'rigid');
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'rigid', 'rot_point', stewart.platform_F.FO_A);
    +payload = initializePayload('type', 'rigid');
    +controller = initializeController('type', 'open-loop');
     
    @@ -436,45 +436,45 @@ We set the rotation point of the ground to be at the same point at frames \(\{A\

    2.2 Transmissibility

    -
      %% Options for Linearized
    -  options = linearizeOptions;
    -  options.SampleTime = 0;
    +
    %% Options for Linearized
    +options = linearizeOptions;
    +options.SampleTime = 0;
     
    -  %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +%% Name of the Simulink File
    +mdl = 'stewart_platform_model';
     
    -  %% Input/Output definition
    -  clear io; io_i = 1;
    -  io(io_i) = linio([mdl, '/Disturbances/D_w'],        1, 'openinput');  io_i = io_i + 1; % Base Motion [m, rad]
    -  io(io_i) = linio([mdl, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Motion [m, rad]
    +%% Input/Output definition
    +clear io; io_i = 1;
    +io(io_i) = linio([mdl, '/Disturbances/D_w'],        1, 'openinput');  io_i = io_i + 1; % Base Motion [m, rad]
    +io(io_i) = linio([mdl, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Motion [m, rad]
     
    -  %% Run the linearization
    -  T = linearize(mdl, io, options);
    -  T.InputName = {'Wdx', 'Wdy', 'Wdz', 'Wrx', 'Wry', 'Wrz'};
    -  T.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
    +%% Run the linearization
    +T = linearize(mdl, io, options);
    +T.InputName = {'Wdx', 'Wdy', 'Wdz', 'Wrx', 'Wry', 'Wrz'};
    +T.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
     
    -
      freqs = logspace(1, 4, 1000);
    +
    freqs = logspace(1, 4, 1000);
     
    -  figure;
    -  for ix = 1:6
    +figure;
    +for ix = 1:6
         for iy = 1:6
    -      subplot(6, 6, (ix-1)*6 + iy);
    -      hold on;
    -      plot(freqs, abs(squeeze(freqresp(T(ix, iy), freqs, 'Hz'))), 'k-');
    -      set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
    -      ylim([1e-5, 10]);
    -      xlim([freqs(1), freqs(end)]);
    -      if ix < 6
    -        xticklabels({});
    -      end
    -      if iy > 1
    -        yticklabels({});
    -      end
    +        subplot(6, 6, (ix-1)*6 + iy);
    +        hold on;
    +        plot(freqs, abs(squeeze(freqresp(T(ix, iy), freqs, 'Hz'))), 'k-');
    +        set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
    +        ylim([1e-5, 10]);
    +        xlim([freqs(1), freqs(end)]);
    +        if ix < 6
    +            xticklabels({});
    +        end
    +        if iy > 1
    +            yticklabels({});
    +        end
         end
    -  end
    +end
     
    @@ -487,13 +487,13 @@ From (Preumont et al. 2007), one can use the \end{align*}
    -
      freqs = logspace(1, 4, 1000);
    +
    freqs = logspace(1, 4, 1000);
     
    -  T_norm = zeros(length(freqs), 1);
    +T_norm = zeros(length(freqs), 1);
     
    -  for i = 1:length(freqs)
    +for i = 1:length(freqs)
         T_norm(i) = sqrt(trace(freqresp(T, freqs(i), 'Hz')*freqresp(T, freqs(i), 'Hz')'));
    -  end
    +end
     
    @@ -503,14 +503,14 @@ And we normalize by a factor \(\sqrt{6}\) to obtain a performance metric compara

    -
      Gamma = T_norm/sqrt(6);
    +
    Gamma = T_norm/sqrt(6);
     
    -
      figure;
    -  plot(freqs, Gamma)
    -  set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
    +
    figure;
    +plot(freqs, Gamma)
    +set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
     
    @@ -524,21 +524,21 @@ And we normalize by a factor \(\sqrt{6}\) to obtain a performance metric compara

    -
    -

    3.1 Initialize the Stewart platform

    +
    +

    3.1 Initialize the Stewart platform

    -
      stewart = initializeStewartPlatform();
    -  stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    -  stewart = generateGeneralConfiguration(stewart);
    -  stewart = computeJointsPose(stewart);
    -  stewart = initializeStrutDynamics(stewart);
    -  stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    -  stewart = initializeCylindricalPlatforms(stewart);
    -  stewart = initializeCylindricalStruts(stewart);
    -  stewart = computeJacobian(stewart);
    -  stewart = initializeStewartPose(stewart);
    -  stewart = initializeInertialSensor(stewart, 'type', 'accelerometer', 'freq', 5e3);
    +
    stewart = initializeStewartPlatform();
    +stewart = initializeFramesPositions(stewart, 'H', 90e-3, 'MO_B', 45e-3);
    +stewart = generateGeneralConfiguration(stewart);
    +stewart = computeJointsPose(stewart);
    +stewart = initializeStrutDynamics(stewart);
    +stewart = initializeJointDynamics(stewart, 'type_F', 'universal_p', 'type_M', 'spherical_p');
    +stewart = initializeCylindricalPlatforms(stewart);
    +stewart = initializeCylindricalStruts(stewart);
    +stewart = computeJacobian(stewart);
    +stewart = initializeStewartPose(stewart);
    +stewart = initializeInertialSensor(stewart, 'type', 'accelerometer', 'freq', 5e3);
     
    @@ -546,9 +546,9 @@ And we normalize by a factor \(\sqrt{6}\) to obtain a performance metric compara We set the rotation point of the ground to be at the same point at frames \(\{A\}\) and \(\{B\}\).

    -
      ground = initializeGround('type', 'none');
    -  payload = initializePayload('type', 'rigid');
    -  controller = initializeController('type', 'open-loop');
    +
    ground = initializeGround('type', 'none');
    +payload = initializePayload('type', 'rigid');
    +controller = initializeController('type', 'open-loop');
     
    @@ -558,45 +558,45 @@ We set the rotation point of the ground to be at the same point at frames \(\{A\

    3.2 Compliance

    -
      %% Options for Linearized
    -  options = linearizeOptions;
    -  options.SampleTime = 0;
    +
    %% Options for Linearized
    +options = linearizeOptions;
    +options.SampleTime = 0;
     
    -  %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +%% Name of the Simulink File
    +mdl = 'stewart_platform_model';
     
    -  %% Input/Output definition
    -  clear io; io_i = 1;
    -  io(io_i) = linio([mdl, '/Disturbances/F_ext'],        1, 'openinput');  io_i = io_i + 1; % Base Motion [m, rad]
    -  io(io_i) = linio([mdl, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Motion [m, rad]
    +%% Input/Output definition
    +clear io; io_i = 1;
    +io(io_i) = linio([mdl, '/Disturbances/F_ext'],        1, 'openinput');  io_i = io_i + 1; % Base Motion [m, rad]
    +io(io_i) = linio([mdl, '/Absolute Motion Sensor'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Motion [m, rad]
     
    -  %% Run the linearization
    -  C = linearize(mdl, io, options);
    -  C.InputName = {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'};
    -  C.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
    +%% Run the linearization
    +C = linearize(mdl, io, options);
    +C.InputName = {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'};
    +C.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
     
    -
      freqs = logspace(1, 4, 1000);
    +
    freqs = logspace(1, 4, 1000);
     
    -  figure;
    -  for ix = 1:6
    +figure;
    +for ix = 1:6
         for iy = 1:6
    -      subplot(6, 6, (ix-1)*6 + iy);
    -      hold on;
    -      plot(freqs, abs(squeeze(freqresp(C(ix, iy), freqs, 'Hz'))), 'k-');
    -      set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
    -      ylim([1e-10, 1e-3]);
    -      xlim([freqs(1), freqs(end)]);
    -      if ix < 6
    -        xticklabels({});
    -      end
    -      if iy > 1
    -        yticklabels({});
    -      end
    +        subplot(6, 6, (ix-1)*6 + iy);
    +        hold on;
    +        plot(freqs, abs(squeeze(freqresp(C(ix, iy), freqs, 'Hz'))), 'k-');
    +        set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
    +        ylim([1e-10, 1e-3]);
    +        xlim([freqs(1), freqs(end)]);
    +        if ix < 6
    +            xticklabels({});
    +        end
    +        if iy > 1
    +            yticklabels({});
    +        end
         end
    -  end
    +end
     
    @@ -605,20 +605,20 @@ We can try to use the Frobenius norm to obtain a scalar value representing the 6

    -
      freqs = logspace(1, 4, 1000);
    +
    freqs = logspace(1, 4, 1000);
     
    -  C_norm = zeros(length(freqs), 1);
    +C_norm = zeros(length(freqs), 1);
     
    -  for i = 1:length(freqs)
    +for i = 1:length(freqs)
         C_norm(i) = sqrt(trace(freqresp(C, freqs(i), 'Hz')*freqresp(C, freqs(i), 'Hz')'));
    -  end
    +end
     
    -
      figure;
    -  plot(freqs, C_norm)
    -  set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
    +
    figure;
    +plot(freqs, C_norm)
    +set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
     
    @@ -637,42 +637,42 @@ We can try to use the Frobenius norm to obtain a scalar value representing the 6

    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
      function [T, T_norm, freqs] = computeTransmissibility(args)
    -  % computeTransmissibility -
    -  %
    -  % Syntax: [T, T_norm, freqs] = computeTransmissibility(args)
    -  %
    -  % Inputs:
    -  %    - args - Structure with the following fields:
    -  %        - plots [true/false] - Should plot the transmissilibty matrix and its Frobenius norm
    -  %        - freqs [] - Frequency vector to estimate the Frobenius norm
    -  %
    -  % Outputs:
    -  %    - T      [6x6 ss] - Transmissibility matrix
    -  %    - T_norm [length(freqs)x1] - Frobenius norm of the Transmissibility matrix
    -  %    - freqs  [length(freqs)x1] - Frequency vector in [Hz]
    +
    function [T, T_norm, freqs] = computeTransmissibility(args)
    +% computeTransmissibility -
    +%
    +% Syntax: [T, T_norm, freqs] = computeTransmissibility(args)
    +%
    +% Inputs:
    +%    - args - Structure with the following fields:
    +%        - plots [true/false] - Should plot the transmissilibty matrix and its Frobenius norm
    +%        - freqs [] - Frequency vector to estimate the Frobenius norm
    +%
    +% Outputs:
    +%    - T      [6x6 ss] - Transmissibility matrix
    +%    - T_norm [length(freqs)x1] - Frobenius norm of the Transmissibility matrix
    +%    - freqs  [length(freqs)x1] - Frequency vector in [Hz]
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
        arguments
    -      args.plots logical {mustBeNumericOrLogical} = false
    -      args.freqs double {mustBeNumeric, mustBeNonnegative} = logspace(1,4,1000)
    -    end
    +
    arguments
    +    args.plots logical {mustBeNumericOrLogical} = false
    +    args.freqs double {mustBeNumeric, mustBeNonnegative} = logspace(1,4,1000)
    +end
     
    -
      freqs = args.freqs;
    +
    freqs = args.freqs;
     
    @@ -682,22 +682,22 @@ We can try to use the Frobenius norm to obtain a scalar value representing the 6

    Identification of the Transmissibility Matrix

    -
      %% Options for Linearized
    -  options = linearizeOptions;
    -  options.SampleTime = 0;
    +
    %% Options for Linearized
    +options = linearizeOptions;
    +options.SampleTime = 0;
     
    -  %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +%% Name of the Simulink File
    +mdl = 'stewart_platform_model';
     
    -  %% Input/Output definition
    -  clear io; io_i = 1;
    -  io(io_i) = linio([mdl, '/Disturbances/D_w'],        1, 'openinput');  io_i = io_i + 1; % Base Motion [m, rad]
    -  io(io_i) = linio([mdl, '/Absolute Motion Sensor'],  1, 'output'); io_i = io_i + 1; % Absolute Motion [m, rad]
    +%% Input/Output definition
    +clear io; io_i = 1;
    +io(io_i) = linio([mdl, '/Disturbances/D_w'],        1, 'openinput');  io_i = io_i + 1; % Base Motion [m, rad]
    +io(io_i) = linio([mdl, '/Absolute Motion Sensor'],  1, 'output'); io_i = io_i + 1; % Absolute Motion [m, rad]
     
    -  %% Run the linearization
    -  T = linearize(mdl, io, options);
    -  T.InputName = {'Wdx', 'Wdy', 'Wdz', 'Wrx', 'Wry', 'Wrz'};
    -  T.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
    +%% Run the linearization
    +T = linearize(mdl, io, options);
    +T.InputName = {'Wdx', 'Wdy', 'Wdz', 'Wrx', 'Wry', 'Wrz'};
    +T.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
     
    @@ -705,23 +705,23 @@ We can try to use the Frobenius norm to obtain a scalar value representing the 6 If wanted, the 6x6 transmissibility matrix is plotted.

    -
      p_handle = zeros(6*6,1);
    +
    p_handle = zeros(6*6,1);
     
    -  if args.plots
    +if args.plots
         fig = figure;
         for ix = 1:6
    -      for iy = 1:6
    -        p_handle((ix-1)*6 + iy) = subplot(6, 6, (ix-1)*6 + iy);
    -        hold on;
    -        plot(freqs, abs(squeeze(freqresp(T(ix, iy), freqs, 'Hz'))), 'k-');
    -        set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
    -        if ix < 6
    -            xticklabels({});
    +        for iy = 1:6
    +            p_handle((ix-1)*6 + iy) = subplot(6, 6, (ix-1)*6 + iy);
    +            hold on;
    +            plot(freqs, abs(squeeze(freqresp(T(ix, iy), freqs, 'Hz'))), 'k-');
    +            set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
    +            if ix < 6
    +                xticklabels({});
    +            end
    +            if iy > 1
    +                yticklabels({});
    +            end
             end
    -        if iy > 1
    -            yticklabels({});
    -        end
    -      end
         end
     
         linkaxes(p_handle, 'xy')
    @@ -733,37 +733,37 @@ If wanted, the 6x6 transmissibility matrix is plotted.
         han.YLabel.Visible = 'on';
         xlabel(han, 'Frequency [Hz]');
         ylabel(han, 'Transmissibility [m/m]');
    -  end
    +end
     
    -
    -

    Computation of the Frobenius norm

    -
    +
    +

    Computation of the Frobenius norm

    +
    -
      T_norm = zeros(length(freqs), 1);
    +
    T_norm = zeros(length(freqs), 1);
     
    -  for i = 1:length(freqs)
    +for i = 1:length(freqs)
         T_norm(i) = sqrt(trace(freqresp(T, freqs(i), 'Hz')*freqresp(T, freqs(i), 'Hz')'));
    -  end
    +end
     
    -
      T_norm = T_norm/sqrt(6);
    +
    T_norm = T_norm/sqrt(6);
     
    -
      if args.plots
    +
    if args.plots
         figure;
         plot(freqs, T_norm)
         set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
         xlabel('Frequency [Hz]');
         ylabel('Transmissibility - Frobenius Norm');
    -  end
    +end
     
    @@ -778,42 +778,42 @@ If wanted, the 6x6 transmissibility matrix is plotted.

    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
      function [C, C_norm, freqs] = computeCompliance(args)
    -  % computeCompliance -
    -  %
    -  % Syntax: [C, C_norm, freqs] = computeCompliance(args)
    -  %
    -  % Inputs:
    -  %    - args - Structure with the following fields:
    -  %        - plots [true/false] - Should plot the transmissilibty matrix and its Frobenius norm
    -  %        - freqs [] - Frequency vector to estimate the Frobenius norm
    -  %
    -  % Outputs:
    -  %    - C      [6x6 ss] - Compliance matrix
    -  %    - C_norm [length(freqs)x1] - Frobenius norm of the Compliance matrix
    -  %    - freqs  [length(freqs)x1] - Frequency vector in [Hz]
    +
    function [C, C_norm, freqs] = computeCompliance(args)
    +% computeCompliance -
    +%
    +% Syntax: [C, C_norm, freqs] = computeCompliance(args)
    +%
    +% Inputs:
    +%    - args - Structure with the following fields:
    +%        - plots [true/false] - Should plot the transmissilibty matrix and its Frobenius norm
    +%        - freqs [] - Frequency vector to estimate the Frobenius norm
    +%
    +% Outputs:
    +%    - C      [6x6 ss] - Compliance matrix
    +%    - C_norm [length(freqs)x1] - Frobenius norm of the Compliance matrix
    +%    - freqs  [length(freqs)x1] - Frequency vector in [Hz]
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
        arguments
    -      args.plots logical {mustBeNumericOrLogical} = false
    -      args.freqs double {mustBeNumeric, mustBeNonnegative} = logspace(1,4,1000)
    -    end
    +
    arguments
    +    args.plots logical {mustBeNumericOrLogical} = false
    +    args.freqs double {mustBeNumeric, mustBeNonnegative} = logspace(1,4,1000)
    +end
     
    -
      freqs = args.freqs;
    +
    freqs = args.freqs;
     
    @@ -823,22 +823,22 @@ If wanted, the 6x6 transmissibility matrix is plotted.

    Identification of the Compliance Matrix

    -
      %% Options for Linearized
    -  options = linearizeOptions;
    -  options.SampleTime = 0;
    +
    %% Options for Linearized
    +options = linearizeOptions;
    +options.SampleTime = 0;
     
    -  %% Name of the Simulink File
    -  mdl = 'stewart_platform_model';
    +%% Name of the Simulink File
    +mdl = 'stewart_platform_model';
     
    -  %% Input/Output definition
    -  clear io; io_i = 1;
    -  io(io_i) = linio([mdl, '/Disturbances/F_ext'],      1, 'openinput');  io_i = io_i + 1; % External forces [N, N*m]
    -  io(io_i) = linio([mdl, '/Absolute Motion Sensor'],  1, 'output'); io_i = io_i + 1; % Absolute Motion [m, rad]
    +%% Input/Output definition
    +clear io; io_i = 1;
    +io(io_i) = linio([mdl, '/Disturbances/F_ext'],      1, 'openinput');  io_i = io_i + 1; % External forces [N, N*m]
    +io(io_i) = linio([mdl, '/Absolute Motion Sensor'],  1, 'output'); io_i = io_i + 1; % Absolute Motion [m, rad]
     
    -  %% Run the linearization
    -  C = linearize(mdl, io, options);
    -  C.InputName  = {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'};
    -  C.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
    +%% Run the linearization
    +C = linearize(mdl, io, options);
    +C.InputName  = {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'};
    +C.OutputName = {'Edx', 'Edy', 'Edz', 'Erx', 'Ery', 'Erz'};
     
    @@ -846,23 +846,23 @@ If wanted, the 6x6 transmissibility matrix is plotted. If wanted, the 6x6 transmissibility matrix is plotted.

    -
      p_handle = zeros(6*6,1);
    +
    p_handle = zeros(6*6,1);
     
    -  if args.plots
    +if args.plots
         fig = figure;
         for ix = 1:6
    -      for iy = 1:6
    -        p_handle((ix-1)*6 + iy) = subplot(6, 6, (ix-1)*6 + iy);
    -        hold on;
    -        plot(freqs, abs(squeeze(freqresp(C(ix, iy), freqs, 'Hz'))), 'k-');
    -        set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
    -        if ix < 6
    -            xticklabels({});
    +        for iy = 1:6
    +            p_handle((ix-1)*6 + iy) = subplot(6, 6, (ix-1)*6 + iy);
    +            hold on;
    +            plot(freqs, abs(squeeze(freqresp(C(ix, iy), freqs, 'Hz'))), 'k-');
    +            set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
    +            if ix < 6
    +                xticklabels({});
    +            end
    +            if iy > 1
    +                yticklabels({});
    +            end
             end
    -        if iy > 1
    -            yticklabels({});
    -        end
    -      end
         end
     
         linkaxes(p_handle, 'xy')
    @@ -873,34 +873,34 @@ If wanted, the 6x6 transmissibility matrix is plotted.
         han.YLabel.Visible = 'on';
         xlabel(han, 'Frequency [Hz]');
         ylabel(han, 'Compliance [m/N, rad/(N*m)]');
    -  end
    +end
     
    -
    -

    Computation of the Frobenius norm

    -
    +
    +

    Computation of the Frobenius norm

    +
    -
      freqs = args.freqs;
    +
    freqs = args.freqs;
     
    -  C_norm = zeros(length(freqs), 1);
    +C_norm = zeros(length(freqs), 1);
     
    -  for i = 1:length(freqs)
    +for i = 1:length(freqs)
         C_norm(i) = sqrt(trace(freqresp(C, freqs(i), 'Hz')*freqresp(C, freqs(i), 'Hz')'));
    -  end
    +end
     
    -
      if args.plots
    +
    if args.plots
         figure;
         plot(freqs, C_norm)
         set(gca, 'XScale', 'log'); set(gca, 'YScale', 'log');
         xlabel('Frequency [Hz]');
         ylabel('Compliance - Frobenius Norm');
    -  end
    +end
     
    @@ -915,7 +915,7 @@ If wanted, the 6x6 transmissibility matrix is plotted.

    Author: Dehaeze Thomas

    -

    Created: 2021-01-08 ven. 15:29

    +

    Created: 2021-01-08 ven. 15:52

    diff --git a/docs/kinematic-study.html b/docs/kinematic-study.html index 7c4fd81..7720ab7 100644 --- a/docs/kinematic-study.html +++ b/docs/kinematic-study.html @@ -3,7 +3,7 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Kinematic Study of the Stewart Platform @@ -11,22 +11,22 @@ - + MathJax = { + svg: { + scale: 1, + fontCache: "global" + }, + tex: { + tags: "ams", + multlineWidth: "%MULTLINEWIDTH", + tagSide: "right", + macros: {bm: ["\\boldsymbol{#1}",1],}, + tagIndent: ".8em" + } + }; + +
    @@ -60,14 +60,14 @@
  • 4. Estimation of the range validity of the approximate inverse kinematics
  • 5. Estimated required actuator stroke from specified platform mobility