diff --git a/docs/active_damping_uniaxial.html b/docs/active_damping_uniaxial.html index d696d5c..362a460 100644 --- a/docs/active_damping_uniaxial.html +++ b/docs/active_damping_uniaxial.html @@ -1,116 +1,120 @@ - - + Active Damping with an uni-axial model - - - - - - - - + + + +
UP | - HOME + HOME

Active Damping with an uni-axial model

Table of Contents

-First, in section 1, we will looked at the undamped system. +First, in section 1, we will looked at the undamped system.

Then, we will compare three active damping techniques:

@@ -130,13 +134,13 @@ The disturbances are:

  • Motion errors of all the stages
  • -
    -

    1 Undamped System

    +
    +

    1 Undamped System

    - +

    -
    +

    All the files (data and Matlab scripts) are accessible here.

    @@ -148,8 +152,8 @@ The performance of this undamped system will be compared with the damped system

    -
    -

    1.1 Init

    +
    +

    1.1 Init

    We initialize all the stages with the default parameters. @@ -157,17 +161,17 @@ The nano-hexapod is a piezoelectric hexapod and the sample has a mass of 50kg.

    -
    initializeReferences();
    -initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    -initializeNanoHexapod('actuator', 'piezo');
    -initializeSample('mass', 50);
    +
      initializeReferences();
    +  initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
    +  initializeNanoHexapod('actuator', 'piezo');
    +  initializeSample('mass', 50);
     
    @@ -175,27 +179,27 @@ initializeSample('mass', 50); All the controllers are set to 0.

    -
    K = tf(zeros(6));
    -save('./mat/controllers_uniaxial.mat', 'K', '-append');
    -K_iff = tf(zeros(6));
    -save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    -K_rmc = tf(zeros(6));
    -save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    -K_dvf = tf(zeros(6));
    -save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
    +
      K = tf(zeros(6));
    +  save('./mat/controllers_uniaxial.mat', 'K', '-append');
    +  K_iff = tf(zeros(6));
    +  save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    +  K_rmc = tf(zeros(6));
    +  save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    +  K_dvf = tf(zeros(6));
    +  save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
     
    -
    -

    1.2 Identification

    +
    +

    1.2 Identification

    We identify the various transfer functions of the system

    -
    G = identifyPlant();
    +
      G = identifyPlant();
     
    @@ -203,28 +207,28 @@ We identify the various transfer functions of the system And we save it for further analysis.

    -
    save('./mat/active_damping_uniaxial_plants.mat', 'G', '-append');
    +
      save('./mat/active_damping_uniaxial_plants.mat', 'G', '-append');
     
    -
    -

    1.3 Sensitivity to disturbances

    +
    +

    1.3 Sensitivity to disturbances

    -The sensitivity to disturbances are shown on figure 1. +The sensitivity to disturbances are shown on figure 1.

    -
    +

    sensitivity_dist_undamped.png

    Figure 1: Undamped sensitivity to disturbances (png, pdf)

    -
    +

    sensitivity_dist_stages.png

    Figure 2: Sensitivity to force disturbances in various stages (png, pdf)

    @@ -232,15 +236,15 @@ The sensitivity to disturbances are shown on figure 1.
    -
    -

    1.4 Undamped Plant

    +
    +

    1.4 Undamped Plant

    -The “plant” (transfer function from forces applied by the nano-hexapod to the measured displacement of the sample with respect to the granite) bode plot is shown on figure 1. +The “plant” (transfer function from forces applied by the nano-hexapod to the measured displacement of the sample with respect to the granite) bode plot is shown on figure 1.

    -
    +

    plant_undamped.png

    Figure 3: Transfer Function from cartesian forces to displacement for the undamped plant (png, pdf)

    @@ -249,13 +253,13 @@ The “plant” (transfer function from forces applied by the nano-hexap
    -
    -

    2 Integral Force Feedback

    +
    +

    2 Integral Force Feedback

    - +

    -
    +

    All the files (data and Matlab scripts) are accessible here.

    @@ -263,23 +267,23 @@ All the files (data and Matlab scripts) are accessible he

    Integral Force Feedback is applied. -In section 2.1, IFF is applied on a uni-axial system to understand its behavior. +In section 2.1, IFF is applied on a uni-axial system to understand its behavior. Then, it is applied on the simscape model.

    -
    -

    2.1 One degree-of-freedom example

    +
    +

    2.1 One degree-of-freedom example

    - +

    -
    -

    2.1.1 Equations

    +
    +

    2.1.1 Equations

    -
    +

    iff_1dof.png

    Figure 4: Integral Force Feedback applied to a 1dof system

    @@ -342,16 +346,16 @@ This is attainable if we have:
    -
    -

    2.1.2 Matlab Example

    +
    +

    2.1.2 Matlab Example

    Let define the system parameters.

    -
    m = 50; % [kg]
    -k = 1e6; % [N/m]
    -c = 1e3; % [N/(m/s)]
    +
      m = 50; % [kg]
    +  k = 1e6; % [N/m]
    +  c = 1e3; % [N/(m/s)]
     
    @@ -359,22 +363,22 @@ c = 1e3; % [N/(m/s)] The state space model of the system is defined below.

    -
    A = [-c/m -k/m;
    -     1     0];
    +
      A = [-c/m -k/m;
    +       1     0];
     
    -B = [1/m 1/m -1;
    -     0   0    0];
    +  B = [1/m 1/m -1;
    +       0   0    0];
     
    -C = [ 0  1;
    -     -c -k];
    +  C = [ 0  1;
    +       -c -k];
     
    -D = [0 0 0;
    -     1 0 0];
    +  D = [0 0 0;
    +       1 0 0];
     
    -sys = ss(A, B, C, D);
    -sys.InputName = {'F', 'Fd', 'wddot'};
    -sys.OutputName = {'d', 'Fm'};
    -sys.StateName = {'ddot', 'd'};
    +  sys = ss(A, B, C, D);
    +  sys.InputName = {'F', 'Fd', 'wddot'};
    +  sys.OutputName = {'d', 'Fm'};
    +  sys.StateName = {'ddot', 'd'};
     
    @@ -382,9 +386,9 @@ sys.StateName = {'ddot', -
    Kiff = -((sqrt(k*m)-c)/m)/s;
    -Kiff.InputName = {'Fm'};
    -Kiff.OutputName = {'F'};
    +
      Kiff = -((sqrt(k*m)-c)/m)/s;
    +  Kiff.InputName = {'Fm'};
    +  Kiff.OutputName = {'F'};
     
    @@ -392,12 +396,12 @@ Kiff.OutputName = {'F'}; And the closed loop system is computed below.

    -
    sys_iff = feedback(sys, Kiff, 'name', +1);
    +
      sys_iff = feedback(sys, Kiff, 'name', +1);
     
    -
    +

    iff_1dof_sensitivitiy.png

    Figure 5: Sensitivity to disturbance when IFF is applied on the 1dof system (png, pdf)

    @@ -406,23 +410,23 @@ And the closed loop system is computed below.
    -
    -

    2.2 Control Design

    +
    +

    2.2 Control Design

    Let’s load the undamped plant:

    -
    load('./mat/active_damping_uniaxial_plants.mat', 'G');
    +
      load('./mat/active_damping_uniaxial_plants.mat', 'G');
     

    -Let’s look at the transfer function from actuator forces in the nano-hexapod to the force sensor in the nano-hexapod legs for all 6 pairs of actuator/sensor (figure 6). +Let’s look at the transfer function from actuator forces in the nano-hexapod to the force sensor in the nano-hexapod legs for all 6 pairs of actuator/sensor (figure 6).

    -
    +

    iff_plant.png

    Figure 6: Transfer function from forces applied in the legs to force sensor (png, pdf)

    @@ -432,16 +436,16 @@ Let’s look at the transfer function from actuator forces in the nano-hexap The controller for each pair of actuator/sensor is:

    -
    K_iff = -1000/s;
    +
      K_iff = -1000/s;
     

    -The corresponding loop gains are shown in figure 7. +The corresponding loop gains are shown in figure 7.

    -
    +

    iff_open_loop.png

    Figure 7: Loop Gain for the Integral Force Feedback (png, pdf)

    @@ -449,24 +453,24 @@ The corresponding loop gains are shown in figure 7.
    -
    -

    2.3 Identification of the damped plant

    +
    +

    2.3 Identification of the damped plant

    Let’s initialize the system prior to identification.

    -
    initializeReferences();
    -initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    -initializeNanoHexapod('actuator', 'piezo');
    -initializeSample('mass', 50);
    +
      initializeReferences();
    +  initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
    +  initializeNanoHexapod('actuator', 'piezo');
    +  initializeSample('mass', 50);
     
    @@ -474,14 +478,14 @@ initializeSample('mass', 50); All the controllers are set to 0.

    -
    K = tf(zeros(6));
    -save('./mat/controllers_uniaxial.mat', 'K', '-append');
    -K_iff = -K_iff*eye(6);
    -save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    -K_rmc = tf(zeros(6));
    -save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    -K_dvf = tf(zeros(6));
    -save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
    +
      K = tf(zeros(6));
    +  save('./mat/controllers_uniaxial.mat', 'K', '-append');
    +  K_iff = -K_iff*eye(6);
    +  save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    +  K_rmc = tf(zeros(6));
    +  save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    +  K_dvf = tf(zeros(6));
    +  save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
     
    @@ -489,7 +493,7 @@ save('./mat/controllers_uniaxial.mat',
    -
    G_iff = identifyPlant();
    +
      G_iff = identifyPlant();
     
    @@ -497,17 +501,17 @@ We identify the system dynamics now that the IFF controller is ON. And we save the damped plant for further analysis

    -
    save('./mat/active_damping_uniaxial_plants.mat', 'G_iff', '-append');
    +
      save('./mat/active_damping_uniaxial_plants.mat', 'G_iff', '-append');
     
    -
    -

    2.4 Sensitivity to disturbances

    +
    +

    2.4 Sensitivity to disturbances

    -As shown on figure 8: +As shown on figure 8:

    • The top platform of the nano-hexapod how behaves as a “free-mass”.
    • @@ -517,13 +521,13 @@ However, as the goal is to make the relative displacement \(D\) as small as poss
    -
    +

    sensitivity_dist_iff.png

    Figure 8: Sensitivity to disturbance once the IFF controller is applied to the system (png, pdf)

    -
    +

    The order of the models are very high and thus the plots may be wrong. For instance, the plots are not the same when using minreal. @@ -532,7 +536,7 @@ For instance, the plots are not the same when using minreal.

    -
    +

    sensitivity_dist_stages_iff.png

    Figure 9: Sensitivity to force disturbances in various stages when IFF is applied (png, pdf)

    @@ -540,29 +544,29 @@ For instance, the plots are not the same when using minreal.
    -
    -

    2.5 Damped Plant

    +
    +

    2.5 Damped Plant

    Now, look at the new damped plant to control.

    -It damps the plant (resonance of the nano hexapod as well as other resonances) as shown in figure 10. +It damps the plant (resonance of the nano hexapod as well as other resonances) as shown in figure 10.

    -
    +

    plant_iff_damped.png

    Figure 10: Damped Plant after IFF is applied (png, pdf)

    -However, it increases coupling at low frequency (figure 11). +However, it increases coupling at low frequency (figure 11).

    -
    +

    plant_iff_coupling.png

    Figure 11: Coupling induced by IFF (png, pdf)

    @@ -570,10 +574,10 @@ However, it increases coupling at low frequency (figure 11
    -
    -

    2.6 Conclusion

    +
    +

    2.6 Conclusion

    -
    +

    Integral Force Feedback:

    @@ -588,13 +592,13 @@ Integral Force Feedback:
    -
    -

    3 Relative Motion Control

    +
    +

    3 Relative Motion Control

    - +

    -
    +

    All the files (data and Matlab scripts) are accessible here.

    @@ -605,18 +609,18 @@ In the Relative Motion Control (RMC), a derivative feedback is applied between t

    -
    -

    3.1 One degree-of-freedom example

    +
    +

    3.1 One degree-of-freedom example

    - +

    -
    -

    3.1.1 Equations

    +
    +

    3.1.1 Equations

    -
    +

    rmc_1dof.png

    Figure 12: Relative Motion Control applied to a 1dof system

    @@ -672,16 +676,16 @@ This corresponds to a gain:
    -
    -

    3.1.2 Matlab Example

    +
    +

    3.1.2 Matlab Example

    Let define the system parameters.

    -
    m = 50; % [kg]
    -k = 1e6; % [N/m]
    -c = 1e3; % [N/(m/s)]
    +
      m = 50; % [kg]
    +  k = 1e6; % [N/m]
    +  c = 1e3; % [N/(m/s)]
     
    @@ -689,22 +693,22 @@ c = 1e3; % [N/(m/s)] The state space model of the system is defined below.

    -
    A = [-c/m -k/m;
    -     1     0];
    +
      A = [-c/m -k/m;
    +       1     0];
     
    -B = [1/m 1/m -1;
    -     0   0    0];
    +  B = [1/m 1/m -1;
    +       0   0    0];
     
    -C = [ 0  1;
    -     -c -k];
    +  C = [ 0  1;
    +       -c -k];
     
    -D = [0 0 0;
    -     1 0 0];
    +  D = [0 0 0;
    +       1 0 0];
     
    -sys = ss(A, B, C, D);
    -sys.InputName = {'F', 'Fd', 'wddot'};
    -sys.OutputName = {'d', 'Fm'};
    -sys.StateName = {'ddot', 'd'};
    +  sys = ss(A, B, C, D);
    +  sys.InputName = {'F', 'Fd', 'wddot'};
    +  sys.OutputName = {'d', 'Fm'};
    +  sys.StateName = {'ddot', 'd'};
     
    @@ -712,9 +716,9 @@ sys.StateName = {'ddot', -
    Krmc = -(sqrt(k*m)-c)*s;
    -Krmc.InputName = {'d'};
    -Krmc.OutputName = {'F'};
    +
      Krmc = -(sqrt(k*m)-c)*s;
    +  Krmc.InputName = {'d'};
    +  Krmc.OutputName = {'F'};
     
    @@ -722,12 +726,12 @@ Krmc.OutputName = {'F'}; And the closed loop system is computed below.

    -
    sys_rmc = feedback(sys, Krmc, 'name', +1);
    +
      sys_rmc = feedback(sys, Krmc, 'name', +1);
     
    -
    +

    rmc_1dof_sensitivitiy.png

    Figure 13: Sensitivity to disturbance when RMC is applied on the 1dof system (png, pdf)

    @@ -736,23 +740,23 @@ And the closed loop system is computed below.
    -
    -

    3.2 Control Design

    +
    +

    3.2 Control Design

    Let’s load the undamped plant:

    -
    load('./mat/active_damping_uniaxial_plants.mat', 'G');
    +
      load('./mat/active_damping_uniaxial_plants.mat', 'G');
     

    -Let’s look at the transfer function from actuator forces in the nano-hexapod to the measured displacement of the actuator for all 6 pairs of actuator/sensor (figure 14). +Let’s look at the transfer function from actuator forces in the nano-hexapod to the measured displacement of the actuator for all 6 pairs of actuator/sensor (figure 14).

    -
    +

    rmc_plant.png

    Figure 14: Transfer function from forces applied in the legs to leg displacement sensor (png, pdf)

    @@ -763,16 +767,16 @@ The Relative Motion Controller is defined below. A Low pass Filter is added to make the controller transfer function proper.

    -
    K_rmc = s*50000/(1 + s/2/pi/10000);
    +
      K_rmc = s*50000/(1 + s/2/pi/10000);
     

    -The obtained loop gains are shown in figure 15. +The obtained loop gains are shown in figure 15.

    -
    +

    rmc_open_loop.png

    Figure 15: Loop Gain for the Integral Force Feedback (png, pdf)

    @@ -780,24 +784,24 @@ The obtained loop gains are shown in figure 15.
    -
    -

    3.3 Identification of the damped plant

    +
    +

    3.3 Identification of the damped plant

    Let’s initialize the system prior to identification.

    -
    initializeReferences();
    -initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    -initializeNanoHexapod('actuator', 'piezo');
    -initializeSample('mass', 50);
    +
      initializeReferences();
    +  initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
    +  initializeNanoHexapod('actuator', 'piezo');
    +  initializeSample('mass', 50);
     
    @@ -805,14 +809,14 @@ initializeSample('mass', 50); And initialize the controllers.

    -
    K = tf(zeros(6));
    -save('./mat/controllers_uniaxial.mat', 'K', '-append');
    -K_iff = tf(zeros(6));
    -save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    -K_rmc = -K_rmc*eye(6);
    -save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    -K_dvf = tf(zeros(6));
    -save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
    +
      K = tf(zeros(6));
    +  save('./mat/controllers_uniaxial.mat', 'K', '-append');
    +  K_iff = tf(zeros(6));
    +  save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    +  K_rmc = -K_rmc*eye(6);
    +  save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    +  K_dvf = tf(zeros(6));
    +  save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
     
    @@ -820,7 +824,7 @@ save('./mat/controllers_uniaxial.mat',
    -
    G_rmc = identifyPlant();
    +
      G_rmc = identifyPlant();
     
    @@ -828,28 +832,28 @@ We identify the system dynamics now that the RMC controller is ON. And we save the damped plant for further analysis.

    -
    save('./mat/active_damping_uniaxial_plants.mat', 'G_rmc', '-append');
    +
      save('./mat/active_damping_uniaxial_plants.mat', 'G_rmc', '-append');
     
    -
    -

    3.4 Sensitivity to disturbances

    +
    +

    3.4 Sensitivity to disturbances

    -As shown in figure 16, RMC control succeed in lowering the sensitivity to disturbances near resonance of the system. +As shown in figure 16, RMC control succeed in lowering the sensitivity to disturbances near resonance of the system.

    -
    +

    sensitivity_dist_rmc.png

    Figure 16: Sensitivity to disturbance once the RMC controller is applied to the system (png, pdf)

    -
    +

    sensitivity_dist_stages_rmc.png

    Figure 17: Sensitivity to force disturbances in various stages when RMC is applied (png, pdf)

    @@ -857,11 +861,11 @@ As shown in figure 16, RMC control succeed in lowering
    -
    -

    3.5 Damped Plant

    +
    +

    3.5 Damped Plant

    -
    +

    plant_rmc_damped.png

    Figure 18: Damped Plant after RMC is applied (png, pdf)

    @@ -869,10 +873,10 @@ As shown in figure 16, RMC control succeed in lowering
    -
    -

    3.6 Conclusion

    +
    +

    3.6 Conclusion

    -
    +

    Relative Motion Control:

    @@ -885,13 +889,13 @@ Relative Motion Control:
    -
    -

    4 Direct Velocity Feedback

    +
    +

    4 Direct Velocity Feedback

    - +

    -
    +

    All the files (data and Matlab scripts) are accessible here.

    @@ -902,18 +906,18 @@ In the Relative Motion Control (RMC), a feedback is applied between the measured

    -
    -

    4.1 One degree-of-freedom example

    +
    +

    4.1 One degree-of-freedom example

    - +

    -
    -

    4.1.1 Equations

    +
    +

    4.1.1 Equations

    -
    +

    dvf_1dof.png

    Figure 19: Direct Velocity Feedback applied to a 1dof system

    @@ -932,7 +936,7 @@ In terms of the stage deformation \(d = x - w\): (ms^2 + cs + k) d = -ms^2 w + F_d + F \end{equation}

    -The direct velocity feedback law shown in figure 19 is: +The direct velocity feedback law shown in figure 19 is:

    \begin{equation} K = -g @@ -969,16 +973,16 @@ This corresponds to a gain:
    -
    -

    4.1.2 Matlab Example

    +
    +

    4.1.2 Matlab Example

    Let define the system parameters.

    -
    m = 50; % [kg]
    -k = 1e6; % [N/m]
    -c = 1e3; % [N/(m/s)]
    +
      m = 50; % [kg]
    +  k = 1e6; % [N/m]
    +  c = 1e3; % [N/(m/s)]
     
    @@ -986,24 +990,24 @@ c = 1e3; % [N/(m/s)] The state space model of the system is defined below.

    -
    A = [-c/m -k/m;
    -     1     0];
    +
      A = [-c/m -k/m;
    +       1     0];
     
    -B = [1/m 1/m -1;
    -     0   0    0];
    +  B = [1/m 1/m -1;
    +       0   0    0];
     
    -C = [1 0;
    -     0 1;
    -     0 0];
    +  C = [1 0;
    +       0 1;
    +       0 0];
     
    -D = [0 0 0;
    -     0 0 0;
    -     0 0 1];
    +  D = [0 0 0;
    +       0 0 0;
    +       0 0 1];
     
    -sys = ss(A, B, C, D);
    -sys.InputName = {'F', 'Fd', 'wddot'};
    -sys.OutputName = {'ddot', 'd', 'wddot'};
    -sys.StateName = {'ddot', 'd'};
    +  sys = ss(A, B, C, D);
    +  sys.InputName = {'F', 'Fd', 'wddot'};
    +  sys.OutputName = {'ddot', 'd', 'wddot'};
    +  sys.StateName = {'ddot', 'd'};
     
    @@ -1011,10 +1015,10 @@ sys.StateName = {'ddot', -
    G_xdot = [1, 0, 1/s;
    -          0, 1, 0];
    -G_xdot.InputName = {'ddot', 'd', 'wddot'};
    -G_xdot.OutputName = {'xdot', 'd'};
    +
      G_xdot = [1, 0, 1/s;
    +            0, 1, 0];
    +  G_xdot.InputName = {'ddot', 'd', 'wddot'};
    +  G_xdot.OutputName = {'xdot', 'd'};
     
    @@ -1022,7 +1026,7 @@ G_xdot.OutputName = {'xdot', -
    sys = series(sys, G_xdot, [1 2 3], [1 2 3]);
    +
      sys = series(sys, G_xdot, [1 2 3], [1 2 3]);
     
    @@ -1030,9 +1034,9 @@ Finally, the system is described by sys as defined below. The controller \(K_\text{DVF}\) is:

    -
    Kdvf = tf(-(sqrt(k*m)-c));
    -Kdvf.InputName = {'xdot'};
    -Kdvf.OutputName = {'F'};
    +
      Kdvf = tf(-(sqrt(k*m)-c));
    +  Kdvf.InputName = {'xdot'};
    +  Kdvf.OutputName = {'F'};
     
    @@ -1040,15 +1044,15 @@ Kdvf.OutputName = {'F'}; And the closed loop system is computed below.

    -
    sys_dvf = feedback(sys, Kdvf, 'name', +1);
    +
      sys_dvf = feedback(sys, Kdvf, 'name', +1);
     

    -The obtained sensitivity to disturbances is shown in figure 20. +The obtained sensitivity to disturbances is shown in figure 20.

    -
    +

    dvf_1dof_sensitivitiy.png

    Figure 20: Sensitivity to disturbance when DVF is applied on the 1dof system (png, pdf)

    @@ -1057,39 +1061,39 @@ The obtained sensitivity to disturbances is shown in figure -

    4.2 Control Design

    +
    +

    4.2 Control Design

    Let’s load the undamped plant:

    -
    load('./mat/active_damping_uniaxial_plants.mat', 'G');
    +
      load('./mat/active_damping_uniaxial_plants.mat', 'G');
     

    -Let’s look at the transfer function from actuator forces in the nano-hexapod to the measured velocity of the nano-hexapod platform in the direction of the corresponding actuator for all 6 pairs of actuator/sensor (figure 21). +Let’s look at the transfer function from actuator forces in the nano-hexapod to the measured velocity of the nano-hexapod platform in the direction of the corresponding actuator for all 6 pairs of actuator/sensor (figure 21).

    -
    +

    dvf_plant.png

    Figure 21: Transfer function from forces applied in the legs to leg velocity sensor (png, pdf)

    -The controller is defined below and the obtained loop gain is shown in figure 22. +The controller is defined below and the obtained loop gain is shown in figure 22.

    -
    K_dvf = tf(3e4);
    +
      K_dvf = tf(3e4);
     
    -
    +

    dvf_open_loop_gain.png

    Figure 22: Loop Gain for DVF (png, pdf)

    @@ -1097,24 +1101,24 @@ The controller is defined below and the obtained loop gain is shown in figure
    -
    -

    4.3 Identification of the damped plant

    +
    +

    4.3 Identification of the damped plant

    Let’s initialize the system prior to identification.

    -
    initializeReferences();
    -initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    -initializeNanoHexapod('actuator', 'piezo');
    -initializeSample('mass', 50);
    +
      initializeReferences();
    +  initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
    +  initializeNanoHexapod('actuator', 'piezo');
    +  initializeSample('mass', 50);
     
    @@ -1122,14 +1126,14 @@ initializeSample('mass', 50); And initialize the controllers.

    -
    K = tf(zeros(6));
    -save('./mat/controllers_uniaxial.mat', 'K', '-append');
    -K_iff = tf(zeros(6));
    -save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    -K_rmc = tf(zeros(6));
    -save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    -K_dvf = -K_dvf*eye(6);
    -save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
    +
      K = tf(zeros(6));
    +  save('./mat/controllers_uniaxial.mat', 'K', '-append');
    +  K_iff = tf(zeros(6));
    +  save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    +  K_rmc = tf(zeros(6));
    +  save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    +  K_dvf = -K_dvf*eye(6);
    +  save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
     
    @@ -1137,7 +1141,7 @@ save('./mat/controllers_uniaxial.mat',
    -
    G_dvf = identifyPlant();
    +
      G_dvf = identifyPlant();
     
    @@ -1145,17 +1149,17 @@ We identify the system dynamics now that the RMC controller is ON. And we save the damped plant for further analysis.

    -
    save('./mat/active_damping_uniaxial_plants.mat', 'G_dvf', '-append');
    +
      save('./mat/active_damping_uniaxial_plants.mat', 'G_dvf', '-append');
     
    -
    -

    4.4 Sensitivity to disturbances

    +
    +

    4.4 Sensitivity to disturbances

    -
    +

    sensitivity_dist_dvf.png

    Figure 23: Sensitivity to disturbance once the DVF controller is applied to the system (png, pdf)

    @@ -1163,7 +1167,7 @@ And we save the damped plant for further analysis. -
    +

    sensitivity_dist_stages_dvf.png

    Figure 24: Sensitivity to force disturbances in various stages when DVF is applied (png, pdf)

    @@ -1171,11 +1175,11 @@ And we save the damped plant for further analysis.
    -
    -

    4.5 Damped Plant

    +
    +

    4.5 Damped Plant

    -
    +

    plant_dvf_damped.png

    Figure 25: Damped Plant after DVF is applied (png, pdf)

    @@ -1183,10 +1187,10 @@ And we save the damped plant for further analysis.
    -
    -

    4.6 Conclusion

    +
    +

    4.6 Conclusion

    -
    +

    Direct Velocity Feedback:

    @@ -1196,28 +1200,28 @@ Direct Velocity Feedback:
    -
    -

    5 Comparison

    +
    +

    5 Comparison

    - +

    -
    -

    5.1 Load the plants

    +
    +

    5.1 Load the plants

    -
    load('./mat/active_damping_uniaxial_plants.mat', 'G', 'G_iff', 'G_rmc', 'G_dvf');
    +
      load('./mat/active_damping_uniaxial_plants.mat', 'G', 'G_iff', 'G_rmc', 'G_dvf');
     
    -
    -

    5.2 Sensitivity to Disturbance

    +
    +

    5.2 Sensitivity to Disturbance

    -
    +

    sensitivity_comp_ground_motion_z.png

    Figure 26: caption (png, pdf)

    @@ -1225,21 +1229,21 @@ Direct Velocity Feedback: -
    +

    sensitivity_comp_direct_forces_z.png

    Figure 27: caption (png, pdf)

    -
    +

    sensitivity_comp_spindle_z.png

    Figure 28: caption (png, pdf)

    -
    +

    sensitivity_comp_ty_z.png

    Figure 29: caption (png, pdf)

    @@ -1247,7 +1251,7 @@ Direct Velocity Feedback: -
    +

    sensitivity_comp_ty_x.png

    Figure 30: caption (png, pdf)

    @@ -1255,25 +1259,25 @@ Direct Velocity Feedback:
    -
    -

    5.3 Damped Plant

    +
    +

    5.3 Damped Plant

    -
    +

    plant_comp_damping_z.png

    Figure 31: Plant for the \(z\) direction for different active damping technique used (png, pdf)

    -
    +

    plant_comp_damping_x.png

    Figure 32: Plant for the \(x\) direction for different active damping technique used (png, pdf)

    -
    +

    plant_comp_damping_coupling.png

    Figure 33: Comparison of one off-diagonal plant for different damping technique applied (png, pdf)

    @@ -1282,18 +1286,18 @@ Direct Velocity Feedback:
    -
    -

    6 Conclusion

    +
    +

    6 Conclusion

    - +

    Author: Dehaeze Thomas

    -

    Created: 2020-04-17 ven. 09:36

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/alternative-micro-station-architecture.html b/docs/alternative-micro-station-architecture.html index 4f43bc0..9bab082 100644 --- a/docs/alternative-micro-station-architecture.html +++ b/docs/alternative-micro-station-architecture.html @@ -1,45 +1,39 @@ - - - + Alternative Micro-Station Architecture - - - - - - + +

    Alternative Micro-Station Architecture

    -
    -

    1 Current Micro-Station Architecture

    +
    +

    1 Current Micro-Station Architecture

    Motion Requirements: @@ -62,11 +56,11 @@ For each of these motion requirements, a position stage is associated:

    -The architecture is shown in Figure 1. +The architecture is shown in Figure 1.

    -
    +

    nass_schematic.png

    Figure 1: Architecture of the Micro-Station

    @@ -92,8 +86,8 @@ Requirements on Tx an Rx motions are not specified.
    -
    -

    2 Alternative Micro-Station Architecture

    +
    +

    2 Alternative Micro-Station Architecture

    If we remove the requirement of having to control each motion with an independent position stage, we can think of other mechanical architectures. @@ -118,7 +112,7 @@ A short stroke hexapod with flexible hinges can be used to compensate the positi

    -The mechanical architecture can then be composed of (see Figures 2 and 3): +The mechanical architecture can then be composed of (see Figures 2 and 3):

    -
    h = 2.0;
    -Kl = 1e9 * eye(6) * ...
    -     1/h*(s/(2*pi*100/h) + 1)/(s/(2*pi*100*h) + 1) * ...
    -     1/h*(s/(2*pi*200/h) + 1)/(s/(2*pi*200*h) + 1) * ...
    -     (s/2/pi/10 + 1)/(s/2/pi/10) * ...
    -     1/(1 + s/2/pi/300);
    +
      h = 2.0;
    +  Kl = 1e9 * eye(6) * ...
    +       1/h*(s/(2*pi*100/h) + 1)/(s/(2*pi*100*h) + 1) * ...
    +       1/h*(s/(2*pi*200/h) + 1)/(s/(2*pi*200*h) + 1) * ...
    +       (s/2/pi/10 + 1)/(s/2/pi/10) * ...
    +       1/(1 + s/2/pi/300);
     
    -
    load('mat/stages.mat', 'nano_hexapod');
    -K = Kl*nano_hexapod.kinematics.J*diag([1, 1, 1, 1, 1, 0]);
    +
      load('mat/stages.mat', 'nano_hexapod');
    +  K = Kl*nano_hexapod.kinematics.J*diag([1, 1, 1, 1, 1, 0]);
     
    -
    -

    4.6 Sensibility to Disturbances and Noise Budget

    +
    +

    4.6 Sensibility to Disturbances and Noise Budget

    We identify the transfer function from disturbances to the position error of the sample when the HAC-LAC control is applied.

    -
    +

    opt_stiff_primary_control_L_psd_dist.png

    Figure 20: Amplitude Spectral Density of the vertical position error of the sample when the HAC-DVF control is applied due to both the ground motion and spindle vibrations

    -
    +

    opt_stiff_primary_control_L_psd_tot.png

    Figure 21: Amplitude Spectral Density of the vertical position error of the sample in Open-Loop and when the HAC-DVF control is applied

    -
    +

    opt_stiff_primary_control_L_cas_tot.png

    Figure 22: Cumulative Amplitude Spectrum of the vertical position error of the sample in Open-Loop and when the HAC-DVF control is applied

    @@ -1014,17 +1019,17 @@ We identify the transfer function from disturbances to the position error of the
    -
    -

    4.7 Simulations of Tomography Experiment

    +
    +

    4.7 Simulations of Tomography Experiment

    Let’s now simulate a tomography experiment. To do so, we include all disturbances except vibrations of the translation stage.

    -
    initializeDisturbances();
    -initializeSimscapeConfiguration('gravity', false);
    -initializeLoggingConfiguration('log', 'all');
    +
      initializeDisturbances();
    +  initializeSimscapeConfiguration('gravity', false);
    +  initializeLoggingConfiguration('log', 'all');
     
    @@ -1033,8 +1038,8 @@ And we run the simulation for all three payload Masses.

    -
    -

    4.8 Results

    +
    +

    4.8 Results

    Bibliography

    @@ -1047,7 +1052,7 @@ And we run the simulation for all three payload Masses.

    Author: Dehaeze Thomas

    -

    Created: 2020-09-01 mar. 13:48

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/centrifugal_forces.html b/docs/centrifugal_forces.html index 7b55930..6b745ce 100644 --- a/docs/centrifugal_forces.html +++ b/docs/centrifugal_forces.html @@ -1,44 +1,48 @@ - - + Centrifugal Forces - - - - - - - - + + + +

    Centrifugal Forces

    @@ -52,7 +56,7 @@ This is the case then the sample is moved by the micro-hexapod.

    -The centrifugal forces are defined as represented Figure 1 where: +The centrifugal forces are defined as represented Figure 1 where:

    • \(M\) is the total mass of the rotating elements in \([kg]\)
    • @@ -61,14 +65,14 @@ The centrifugal forces are defined as represented Figure 1
    -
    +

    centrifugal.png

    Figure 1: Centrifugal forces

    -
    -

    1 Parameters

    +
    +

    1 Parameters

    We define some parameters for the computation. @@ -79,8 +83,8 @@ The mass of the sample can vary from \(1\,kg\) to \(50\,kg\) to which is added t

    -
    M_light = 16; % mass of excentred parts mooving [kg]
    -M_heavy = 65; % [kg]
    +
      M_light = 16; % mass of excentred parts mooving [kg]
    +  M_heavy = 65; % [kg]
     
    @@ -88,8 +92,8 @@ M_heavy = 65; % [kg] For the light mass, the rotation speed is 60rpm whereas for the heavy mass, it is equal to 1rpm.

    -
    w_light = 2*pi; % rotational speed [rad/s]
    -w_heavy = 2*pi/60; % rotational speed [rad/s]
    +
      w_light = 2*pi; % rotational speed [rad/s]
    +  w_heavy = 2*pi/60; % rotational speed [rad/s]
     
    @@ -97,14 +101,14 @@ w_heavy = 2*pi/60; % rotational speed [rad/s] Finally, we consider a mass eccentricity of \(10\,mm\).

    -
    R = 0.01; % Excentricity [m]
    +
      R = 0.01; % Excentricity [m]
     
    -
    -

    2 Centrifugal forces for light and heavy sample

    +
    +

    2 Centrifugal forces for light and heavy sample

    From the formula \(F_c = m \omega^2 r\), we obtain the values shown below. @@ -139,15 +143,15 @@ From the formula \(F_c = m \omega^2 r\), we obtain the values shown below.

    -
    -

    3 Centrifugal forces as a function of the rotation speed

    +
    +

    3 Centrifugal forces as a function of the rotation speed

    -The centrifugal forces as a function of the rotation speed for light and heavy sample is shown on Figure 2. +The centrifugal forces as a function of the rotation speed for light and heavy sample is shown on Figure 2.

    -
    +

    centrifugal_forces_rpm.png

    Figure 2: Centrifugal forces function of the rotation speed

    @@ -155,29 +159,29 @@ The centrifugal forces as a function of the rotation speed for light and heavy s
    -
    -

    4 Maximum rotation speed as a function of the mass

    +
    +

    4 Maximum rotation speed as a function of the mass

    -We plot the maximum rotation speed as a function of the mass for different maximum force that we can use to counteract the centrifugal forces (Figure 3). +We plot the maximum rotation speed as a function of the mass for different maximum force that we can use to counteract the centrifugal forces (Figure 3).

    -From a specified maximum allowed centrifugal force (here set to \(10\,[N]\)), the maximum rotation speed as a function of the sample’s mass is shown in Figure 3. +From a specified maximum allowed centrifugal force (here set to \(10\,[N]\)), the maximum rotation speed as a function of the sample’s mass is shown in Figure 3.

    -
    F_max = 10; % Maximum accepted centrifugal forces [N]
    +
      F_max = 10; % Maximum accepted centrifugal forces [N]
     
    -R = 0.01;
    +  R = 0.01;
     
    -M_sample = 0:1:100;
    -M_reflector = 15;
    +  M_sample = 0:1:100;
    +  M_reflector = 15;
     
    -
    +

    max_force_rpm.png

    Figure 3: Maximum rotation speed as a function of the sample mass for an allowed centrifugal force of \(100\,[N]\)

    @@ -187,7 +191,7 @@ M_reflector = 15;

    Author: Dehaeze Thomas

    -

    Created: 2020-05-07 jeu. 14:05

    +

    Created: 2021-02-20 sam. 23:09

    diff --git a/docs/compensation_gravity_forces.html b/docs/compensation_gravity_forces.html index 5b1ac52..3e9e4fa 100644 --- a/docs/compensation_gravity_forces.html +++ b/docs/compensation_gravity_forces.html @@ -1,37 +1,32 @@ - - + Compensating the gravity forces to start at steady state - - - - - - + +

    Compensating the gravity forces to start at steady state

    @@ -41,19 +36,19 @@ In this file is shown a technique used to compensate the gravity forces at t=0.

    -The problem is that in presence of gravity, the system does not start at steady state and experience a transient phase (section 2). +The problem is that in presence of gravity, the system does not start at steady state and experience a transient phase (section 2).

    In order to start the simulation at steady state in presence of gravity:

      -
    • section 3: first the stages are initialize in such a way that they are rigid, and the forces/torques applied at the location of their joints is measured
    • -
    • section 4: Then, the equilibrium position of each joint is modified in such a way that at t=0, the forces in each joints exactly compensate the forces due to gravity forces
    • +
    • section 3: first the stages are initialize in such a way that they are rigid, and the forces/torques applied at the location of their joints is measured
    • +
    • section 4: Then, the equilibrium position of each joint is modified in such a way that at t=0, the forces in each joints exactly compensate the forces due to gravity forces
    -
    -

    1 Initialization of the Experimental Conditions

    +
    +

    1 Initialization of the Experimental Conditions

    We don’t inject any perturbations and no reference tracking. @@ -76,11 +71,11 @@ initializeLoggingConfiguration('log',

    -
    -

    2 Without compensation

    +
    +

    2 Without compensation

    - + Let’s simulate the system without any compensation of gravity forces.

    @@ -111,10 +106,10 @@ sim_no_compensation = simout;

    -And we can observe on Figure 1 that there are some motion in the system. +And we can observe on Figure 1 that there are some motion in the system.

    -
    +

    transient_phase_gravity_no_compensation.png

    Figure 1: Motion of the sample at the start of the simulation in presence of gravity (png, pdf)

    @@ -122,11 +117,11 @@ And we can observe on Figure 1 that there are some mot
    -
    -

    3 Simulation to compute the required force in each joint

    +
    +

    3 Simulation to compute the required force in each joint

    - + We here wish to simulate the system in order to compute the required force in each joint to compensate the gravity forces.

    @@ -318,11 +313,11 @@ We save these forces in Foffset.mat.
    -
    -

    4 New simulation with compensation of gravity forces

    +
    +

    4 New simulation with compensation of gravity forces

    - + We now initialize the stages with the option Foffset.

    @@ -358,17 +353,17 @@ sim_compensation = simout; Verification that nothing is moving

    -
    +

    transient_phase_gravity_compensation.png

    Figure 2: Motion of the sample at the start of the simulation in presence of gravity when compensating the gravity forces (png, pdf)

    -
    -

    5 Conclusion

    +
    +

    5 Conclusion

    -
    +

    This initialization technique permits to compute the required forces/torques to be applied in each joint in order to compensate for gravity forces. This initialization should be redone for each configuration (change of sample mass, change of tilt angle), but not when changing the stiffness of joints, for instant when changing from lorentz based nano-hexapod or piezo based. @@ -380,7 +375,7 @@ This initialization should be redone for each configuration (change of sample ma

    Author: Dehaeze Thomas

    -

    Created: 2020-04-17 ven. 09:34

    +

    Created: 2021-02-20 sam. 23:07

    diff --git a/docs/control.html b/docs/control.html index 301e0a1..be7c9cf 100644 --- a/docs/control.html +++ b/docs/control.html @@ -1,73 +1,77 @@ - - + Control of the Nano-Active-Stabilization-System - - - - - - - - + + + +

    Control of the Nano-Active-Stabilization-System

    Table of Contents

    @@ -75,7 +79,7 @@

    -The system consist of the following inputs and outputs (Figure 1): +The system consist of the following inputs and outputs (Figure 1):

    -
    +

    control_architecture_pos_error.png

    Figure 2: Block diagram corresponding to the computation of the position error in the frame of the nano-hexapod

    @@ -116,15 +120,15 @@ This can we considered as: In this document, we see how the different outputs of the system can be used to control of position \(\bm{\mathcal{X}}\).

    -
    -

    1 Control Configuration - Introduction

    +
    +

    1 Control Configuration - Introduction

    In this section, we discuss the control configuration for the NASS.

    -From skogestad07_multiv_feedb_contr: +From (Skogestad and Postlethwaite 2007):

    @@ -149,24 +153,24 @@ Decoupling elements will be used to convert quantities from the joint space to t

    -Decentralized controllers will be largely used both for Tracking control (Section 2) and for Active Damping techniques (Section 3) +Decentralized controllers will be largely used both for Tracking control (Section 2) and for Active Damping techniques (Section 3)

    -Combining both can be done in an HAC-LAC topology presented in Section 4. +Combining both can be done in an HAC-LAC topology presented in Section 4.

    -The use of decentralized controllers is proposed in Section 5. +The use of decentralized controllers is proposed in Section 5.

    -
    -

    2 Tracking Control in the Frame of the Nano-Hexapod - Basic Architectures

    +
    +

    2 Tracking Control in the Frame of the Nano-Hexapod - Basic Architectures

    - +

    In this section, we suppose that we want to track some reference position \(\bm{r}_{\mathcal{X}_n}\) corresponding to the pose of the nano-hexapod’s mobile platform with respect to its fixed base. @@ -184,11 +188,11 @@ However, thanks to the forward and inverse kinematics, the controller can either These to configuration are described in the next two sections.

    -
    -

    2.1 Control in the frame of the Legs

    +
    +

    2.1 Control in the frame of the Legs

    - +

    @@ -198,7 +202,7 @@ Finally, a diagonal (Decentralized) controller \(\bm{K}_\mathcal{L}\) can be use

    -
    +

    control_architecture_leg_frame.png

    Figure 3: Control in the frame of the legs

    @@ -206,11 +210,11 @@ Finally, a diagonal (Decentralized) controller \(\bm{K}_\mathcal{L}\) can be use
    -
    -

    2.2 Control in the Cartesian frame

    +
    +

    2.2 Control in the Cartesian frame

    - +

    @@ -221,7 +225,7 @@ These forces are then converted to forces applied in each of the nano-hexapod&rs

    -
    +

    control_architecture_cartesian_frame.png

    Figure 4: Control in the cartesian Frame (rotating frame attached to the nano-hexapod’s base)

    @@ -230,14 +234,14 @@ These forces are then converted to forces applied in each of the nano-hexapod&rs
    -
    -

    3 Active Damping Architecture - Collocated Control (link)

    +
    +

    3 Active Damping Architecture - Collocated Control (link)

    - +

    -From preumont18_vibrat_contr_activ_struc_fourt_edition: +From (Preumont 2018):

    @@ -258,11 +262,11 @@ These two active damping techniques are collocated control techniques. The active damping techniques are studied in this document.

    -
    -

    3.1 Integral Force Feedback

    +
    +

    3.1 Integral Force Feedback

    - +

    @@ -286,7 +290,7 @@ A lead-lag can also be used instead of a pure integrator.

    -
    +

    control_architecture_iff.png

    Figure 5: Integral Force Feedback

    @@ -294,11 +298,11 @@ A lead-lag can also be used instead of a pure integrator.
    -
    -

    3.2 Direct Relative Velocity Feedback

    +
    +

    3.2 Direct Relative Velocity Feedback

    - +

    @@ -315,7 +319,7 @@ Each diagonal element consists of: \end{equation} -

    +

    control_architecture_dvf.png

    Figure 6: Direct Velocity Feedback

    @@ -324,11 +328,11 @@ Each diagonal element consists of:
    -
    -

    4 HAC-LAC Architectures (link)

    +
    +

    4 HAC-LAC Architectures (link)

    - +

    Here we can combine Active Damping Techniques (Low authority control) with a tracking controller (high authority control). @@ -336,11 +340,11 @@ Usually, the low authority controller is designed first, and the high authority

    -From preumont18_vibrat_contr_activ_struc_fourt_edition: +From (Preumont 2018):

    -The HAC/LAC approach consist of combining the two approached in a dual-loop control as shown in Figure 7. +The HAC/LAC approach consist of combining the two approached in a dual-loop control as shown in Figure 7. The inner loop uses a set of collocated actuator/sensor pairs for decentralized active damping with guaranteed stability ; the outer loop consists of a non-collocated HAC based on a model of the actively damped structure. This approach has the following advantages:

    @@ -352,29 +356,29 @@ This approach has the following advantages:
    -
    +

    control_architecture_hac_lac.png

    Figure 7: HAC-LAC Control Architecture

    -If there is only one input to the system, the HAC-LAC topology can be represented as depicted in Figure 8. +If there is only one input to the system, the HAC-LAC topology can be represented as depicted in Figure 8. Usually, the Low Authority Controller is first design, and then the High Authority Controller is designed based on the damped plant.

    -
    +

    control_architecture_hac_lac_one_input.png

    Figure 8: HAC-LAC Architecture with a system having only one input

    -
    -

    4.1 HAC-LAC using IFF and Tracking control in the frame of the Legs

    +
    +

    4.1 HAC-LAC using IFF and Tracking control in the frame of the Legs

    -
    +

    control_architecture_hac_iff_L.png

    Figure 9: IFF + Control in the frame of the legs

    @@ -382,11 +386,11 @@ Usually, the Low Authority Controller is first design, and then the High Authori
    -
    -

    4.2 HAC-LAC using IFF and Tracking control in the Cartesian frame

    +
    +

    4.2 HAC-LAC using IFF and Tracking control in the Cartesian frame

    -
    +

    control_architecture_hac_iff_X.png

    Figure 10: IFF + Control in the cartesian frame

    @@ -394,44 +398,44 @@ Usually, the Low Authority Controller is first design, and then the High Authori
    -
    -

    4.3 HAC-LAC using IFF - the HAC controller is positioning the sample w.r.t. the granite in the task space

    +
    +

    4.3 HAC-LAC using IFF - the HAC controller is positioning the sample w.r.t. the granite in the task space

    -
    +

    control_architecture_hac_iff_pos_X.png

    -
    -

    4.4 HAC-LAC using IFF - the HAC controller is positioning the sample w.r.t. the granite in the space of the legs

    +
    +

    4.4 HAC-LAC using IFF - the HAC controller is positioning the sample w.r.t. the granite in the space of the legs

    -
    +

    control_architecture_hac_iff_pos_L.png

    -
    -

    4.5 HAC-LAC using DVF - the HAC controller is positioning the sample w.r.t. the granite in the task space

    +
    +

    4.5 HAC-LAC using DVF - the HAC controller is positioning the sample w.r.t. the granite in the task space

    -
    +

    control_architecture_hac_dvf_pos_X.png

    -
    -

    4.6 HAC-LAC using DVF - the HAC controller is positioning the sample w.r.t. the granite in the space of the legs

    +
    +

    4.6 HAC-LAC using DVF - the HAC controller is positioning the sample w.r.t. the granite in the space of the legs

    -
    +

    control_architecture_hac_dvf_pos_L.png

    @@ -439,26 +443,26 @@ Usually, the Low Authority Controller is first design, and then the High Authori
    -
    -

    5 Cascade Architectures (link)

    +
    +

    5 Cascade Architectures (link)

    - +

    -The principle of Cascade control is shown in Figure 15 and explained as follow: +The principle of Cascade control is shown in Figure 15 and explained as follow:

    To follow two objectives with different properties in one control system, usually a hierarchy of two feedback loops is used in practice. This kind of control topology is called cascade control, which is used when there are several measurements and one prime control variable. -Cascade control is implemented by nesting the control loops, as shown in Figure 15. -The output control loop is called the primary loop, while the inner loop is called the secondary loop and is used to fulfill a secondary objective in the closed-loop system. – taghirad13_paral +Cascade control is implemented by nesting the control loops, as shown in Figure 15. +The output control loop is called the primary loop, while the inner loop is called the secondary loop and is used to fulfill a secondary objective in the closed-loop system. – (Taghirad 2013)

    -
    +

    control_architecture_cascade_control.png

    Figure 15: Cascade Control Architecture

    @@ -479,11 +483,11 @@ In the NASS’s case: The inner loop can be composed of the system controlled with the HAC-LAC topology.

    -
    -

    5.1 Cascade Control with HAC-LAC Inner Loop and Primary Controller in the task space

    +
    +

    5.1 Cascade Control with HAC-LAC Inner Loop and Primary Controller in the task space

    -
    +

    control_architecture_cascade_L.png

    Figure 16: Cascaded Control consisting of (from inner to outer loop): IFF, Linearization Loop, Tracking Control in the frame of the Legs

    @@ -491,11 +495,11 @@ The inner loop can be composed of the system controlled with the HAC-LAC topolog
    -
    -

    5.2 Cascade Control with HAC-LAC Inner Loop and Primary Controller in the joint space

    +
    +

    5.2 Cascade Control with HAC-LAC Inner Loop and Primary Controller in the joint space

    -
    +

    control_architecture_cascade_X.png

    Figure 17: Cascaded Control consisting of (from inner to outer loop): IFF, Linearization Loop, Tracking Control in the Cartesian Frame

    @@ -504,8 +508,8 @@ The inner loop can be composed of the system controlled with the HAC-LAC topolog
    -
    -

    6 Force Control (link)

    +
    +

    6 Force Control (link)

    Signals: @@ -517,41 +521,41 @@ Signals: -

    +

    control_architecture_force.png

    -
    -

    7 Other Control Architectures

    +
    +

    7 Other Control Architectures

    -
    -

    7.1 Control to force the nano-hexapod to not do any vertical rotation

    +
    +

    7.1 Control to force the nano-hexapod to not do any vertical rotation

    As the sample rotation around the vertical axis is not measure, the best we can do with the nano-hexapod is to not rotate around this same axis.

    -One way to do it is shown in Figure 19. +One way to do it is shown in Figure 19.

    -The controller \(\bm{K}_{R_z}\) is decomposed as shown in Figure 20. +The controller \(\bm{K}_{R_z}\) is decomposed as shown in Figure 20.

    -
    +

    control_architecture_fixed_rz.png

    Figure 19: Figure caption

    -
    +

    control_architecture_fixed_Krz.png

    Figure 20: Figure caption

    @@ -563,16 +567,18 @@ The controller \(\bm{K}_{R_z}\) is decomposed as shown in Figure [skogestad07_multiv_feedb_contr] Skogestad & Postlethwaite, Multivariable Feedback Control: Analysis and Design, John Wiley (2007). -
  • [preumont18_vibrat_contr_activ_struc_fourt_edition] Andre Preumont, Vibration Control of Active Structures - Fourth Edition, Springer International Publishing (2018).
  • -
  • [taghirad13_paral] Taghirad, Parallel robots : mechanics and control, CRC Press (2013).
  • -

    + +

    Bibliography

    +
    +
    Preumont, Andre. 2018. Vibration Control of Active Structures - Fourth Edition. Solid Mechanics and Its Applications. Springer International Publishing. https://doi.org/10.1007/978-3-319-72296-2.
    +
    Skogestad, Sigurd, and Ian Postlethwaite. 2007. Multivariable Feedback Control: Analysis and Design. John Wiley.
    +
    Taghirad, Hamid. 2013. Parallel Robots : Mechanics and Control. Boca Raton, FL: CRC Press.
    +

    Author: Dehaeze Thomas

    -

    Created: 2020-04-17 ven. 09:35

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/control_active_damping.html b/docs/control_active_damping.html index 59928fa..57a676a 100644 --- a/docs/control_active_damping.html +++ b/docs/control_active_damping.html @@ -1,147 +1,151 @@ - - + Active Damping applied on the Simscape Model - - - - - - - - + + + +

    Active Damping applied on the Simscape Model

    Table of Contents

    -First, in section 1, we look at the undamped system and we identify the dynamics from the actuators to the three sensor types. +First, in section 1, we look at the undamped system and we identify the dynamics from the actuators to the three sensor types.

    -Then, in section 2, we study the change of dynamics for the active damping plants with respect to various experimental conditions such as the sample mass and the spindle rotation speed. +Then, in section 2, we study the change of dynamics for the active damping plants with respect to various experimental conditions such as the sample mass and the spindle rotation speed.

    Then, we will apply and compare the results of three active damping techniques:

      -
    • In section 3: Integral Force Feedback is applied
    • -
    • In section 4: Direct Velocity Feedback using a relative motion sensor is applied
    • -
    • In section 5: Inertial Control using a geophone is applied
    • +
    • In section 3: Integral Force Feedback is applied
    • +
    • In section 4: Direct Velocity Feedback using a relative motion sensor is applied
    • +
    • In section 5: Inertial Control using a geophone is applied

    @@ -189,11 +193,11 @@ For each of the active damping technique, we:

  • Compare the sensitivity from disturbances
  • -
    -

    1 Undamped System

    +
    +

    1 Undamped System

    - +

    In this section, we identify the dynamic of the system from forces applied in the nano-hexapod legs to the various sensors included in the nano-hexapod that could be use for Active Damping, namely: @@ -209,18 +213,18 @@ After that, a tomography experiment is simulation without any active damping tec

    -
    -

    1.1 Identification of the dynamics for Active Damping

    +
    +

    1.1 Identification of the dynamics for Active Damping

    -
    -

    1.1.1 Identification

    +
    +

    1.1.1 Identification

    We initialize all the stages with the default parameters.

    -
    prepareLinearizeIdentification();
    +
      prepareLinearizeIdentification();
     
    @@ -228,26 +232,26 @@ We initialize all the stages with the default parameters. We identify the dynamics of the system using the linearize function.

    -
    %% Options for Linearized
    -options = linearizeOptions;
    -options.SampleTime = 0;
    +
      %% Options for Linearized
    +  options = linearizeOptions;
    +  options.SampleTime = 0;
     
    -%% Name of the Simulink File
    -mdl = 'nass_model';
    +  %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller'],    1, 'openinput');               io_i = io_i + 1; % Actuator Inputs
    -io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Dnlm');  io_i = io_i + 1; % Relative Motion Outputs
    -io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm');  io_i = io_i + 1; % Force Sensors
    -io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Vlm');   io_i = io_i + 1; % Absolute Velocity Outputs
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller'],    1, 'openinput');               io_i = io_i + 1; % Actuator Inputs
    +  io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Dnlm');  io_i = io_i + 1; % Relative Motion Outputs
    +  io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm');  io_i = io_i + 1; % Force Sensors
    +  io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Vlm');   io_i = io_i + 1; % Absolute Velocity Outputs
     
    -%% Run the linearization
    -G = linearize(mdl, io, 0.5, options);
    -G.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    -G.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6', ...
    -                'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6', ...
    -                'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'};
    +  %% Run the linearization
    +  G = linearize(mdl, io, 0.5, options);
    +  G.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    +  G.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6', ...
    +                  'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6', ...
    +                  'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'};
     
    @@ -255,9 +259,9 @@ G.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6', ... We then create transfer functions corresponding to the active damping plants.

    -
    G_iff = minreal(G({'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}));
    -G_dvf = minreal(G({'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}));
    -G_ine = minreal(G({'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}));
    +
      G_iff = minreal(G({'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}));
    +  G_dvf = minreal(G({'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}));
    +  G_ine = minreal(G({'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'}, {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'}));
     
    @@ -265,36 +269,36 @@ G_ine = minreal(G({'Vnlm1', 'Vnlm2', 'Vnlm3', 'Vnlm4', 'Vnlm5', 'Vnlm6'}, {'Fnl1 And we save them for further analysis.

    -
    save('./mat/active_damping_undamped_plants.mat', 'G_iff', 'G_dvf', 'G_ine');
    +
      save('./mat/active_damping_undamped_plants.mat', 'G_iff', 'G_dvf', 'G_ine');
     
    -
    -

    1.1.2 Obtained Plants for Active Damping

    +
    +

    1.1.2 Obtained Plants for Active Damping

    -
    load('./mat/active_damping_undamped_plants.mat', 'G_iff', 'G_dvf', 'G_ine');
    +
      load('./mat/active_damping_undamped_plants.mat', 'G_iff', 'G_dvf', 'G_ine');
     
    -
    +

    nass_active_damping_iff_plant.png

    Figure 1: G_iff: Transfer functions from forces applied in the actuators to the force sensor in each actuator (png, pdf)

    -
    +

    nass_active_damping_dvf_plant.png

    Figure 2: G_dvf: Transfer functions from forces applied in the actuators to the relative motion sensor in each actuator (png, pdf)

    -
    +

    nass_active_damping_inertial_plant.png

    Figure 3: G_ine: Transfer functions from forces applied in the actuators to the geophone located in each leg measuring the absolute velocity of the top part of the leg in the direction of the leg (png, pdf)

    @@ -303,18 +307,18 @@ And we save them for further analysis.
    -
    -

    1.2 Identification of the dynamics for High Authority Control

    +
    +

    1.2 Identification of the dynamics for High Authority Control

    -
    -

    1.2.1 Identification

    +
    +

    1.2.1 Identification

    We initialize all the stages with the default parameters.

    -
    prepareLinearizeIdentification();
    +
      prepareLinearizeIdentification();
     
    @@ -322,22 +326,22 @@ We initialize all the stages with the default parameters. We identify the dynamics of the system using the linearize function.

    -
    %% Options for Linearized
    -options = linearizeOptions;
    -options.SampleTime = 0;
    +
      %% Options for Linearized
    +  options = linearizeOptions;
    +  options.SampleTime = 0;
     
    -%% Name of the Simulink File
    -mdl = 'nass_model';
    +  %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller'],     1, 'openinput');            io_i = io_i + 1; % Actuator Inputs
    -io(io_i) = linio([mdl, '/Tracking Error'], 1, 'openoutput', [], 'En'); io_i = io_i + 1; % Metrology Outputs
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller'],     1, 'openinput');            io_i = io_i + 1; % Actuator Inputs
    +  io(io_i) = linio([mdl, '/Tracking Error'], 1, 'openoutput', [], 'En'); io_i = io_i + 1; % Metrology Outputs
     
    -
    masses = [1, 10, 50]; % [kg]
    +
      masses = [1, 10, 50]; % [kg]
     
    @@ -345,22 +349,22 @@ io(io_i) = linio([mdl, '/Tracking Error'], 1, 'openoutput', [], 'En'); io_i = io And we save them for further analysis.

    -
    save('./mat/active_damping_cart_plants.mat', 'G_cart', 'masses');
    +
      save('./mat/active_damping_cart_plants.mat', 'G_cart', 'masses');
     
    -
    -

    1.2.2 Obtained Plants

    +
    +

    1.2.2 Obtained Plants

    -
    load('./mat/active_damping_cart_plants.mat', 'G_cart', 'masses');
    +
      load('./mat/active_damping_cart_plants.mat', 'G_cart', 'masses');
     
    -
    +

    undamped_hac_plant_translations.png

    Figure 4: Undamped Plant - Translations (png, pdf)

    @@ -368,7 +372,7 @@ And we save them for further analysis. -
    +

    undamped_hac_plant_rotations.png

    Figure 5: Undamped Plant - Rotations (png, pdf)

    @@ -377,18 +381,18 @@ And we save them for further analysis.
    -
    -

    1.3 Tomography Experiment

    +
    +

    1.3 Tomography Experiment

    -
    -

    1.3.1 Simulation

    +
    +

    1.3.1 Simulation

    We initialize elements for the tomography experiment.

    -
    prepareTomographyExperiment();
    +
      prepareTomographyExperiment();
     
    @@ -396,8 +400,8 @@ We initialize elements for the tomography experiment. We change the simulation stop time.

    -
    load('mat/conf_simulink.mat');
    -set_param(conf_simulink, 'StopTime', '4.5');
    +
      load('mat/conf_simulink.mat');
    +  set_param(conf_simulink, 'StopTime', '4.5');
     
    @@ -405,7 +409,7 @@ set_param(conf_simulink, 'StopTime', '4.5'); And we simulate the system.

    -
    sim('nass_model');
    +
      sim('nass_model');
     
    @@ -413,34 +417,34 @@ And we simulate the system. Finally, we save the simulation results for further analysis

    -
    save('./mat/active_damping_tomo_exp.mat', 'En', 'Eg', '-append');
    +
      save('./mat/active_damping_tomo_exp.mat', 'En', 'Eg', '-append');
     
    -
    -

    1.3.2 Results

    +
    +

    1.3.2 Results

    We load the results of tomography experiments.

    -
    load('./mat/active_damping_tomo_exp.mat', 'En');
    -Fs = 1e3; % Sampling Frequency of the Data
    -t = (1/Fs)*[0:length(En(:,1))-1];
    +
      load('./mat/active_damping_tomo_exp.mat', 'En');
    +  Fs = 1e3; % Sampling Frequency of the Data
    +  t = (1/Fs)*[0:length(En(:,1))-1];
     
    -
    +

    nass_act_damp_undamped_sim_tomo_trans.png

    Figure 6: Position Error during tomography experiment - Translations (png, pdf)

    -
    +

    nass_act_damp_undamped_sim_tomo_rot.png

    Figure 7: Position Error during tomography experiment - Rotations (png, pdf)

    @@ -450,22 +454,22 @@ t = (1/Fs)*[0:length(En(:,1))-1];
    -
    -

    2 Variability of the system dynamics for Active Damping

    +
    +

    2 Variability of the system dynamics for Active Damping

    - +

    The goal of this section is to study how the dynamics of the Active Damping plants are changing with the experimental conditions. These experimental conditions are:

      -
    • The mass of the sample (section 2.1)
    • -
    • The spindle angle with a null rotating speed (section 2.2)
    • -
    • The spindle rotation speed (section 2.3)
    • -
    • The tilt angle (section 2.4)
    • -
    • The scans of the translation stage (section 2.5)
    • +
    • The mass of the sample (section 2.1)
    • +
    • The spindle angle with a null rotating speed (section 2.2)
    • +
    • The spindle rotation speed (section 2.3)
    • +
    • The tilt angle (section 2.4)
    • +
    • The scans of the translation stage (section 2.5)

    @@ -474,11 +478,11 @@ This is done in order for the transient phase to be over.

    -
    -

    2.1 Variation of the Sample Mass

    +
    +

    2.1 Variation of the Sample Mass

    - +

    For all the identifications, the disturbances are disabled and no controller are used. @@ -487,7 +491,7 @@ For all the identifications, the disturbances are disabled and no controller are We initialize all the stages with the default parameters.

    -
    prepareLinearizeIdentification();
    +
      prepareLinearizeIdentification();
     
    @@ -495,25 +499,25 @@ We initialize all the stages with the default parameters. We identify the dynamics for the following sample mass.

    -
    masses = [1, 10, 50]; % [kg]
    +
      masses = [1, 10, 50]; % [kg]
     
    -
    +

    act_damp_variability_iff_sample_mass.png

    Figure 8: Variability of the dynamics from actuator force to force sensor with the Sample Mass (png, pdf)

    -
    +

    act_damp_variability_dvf_sample_mass.png

    Figure 9: Variability of the dynamics from actuator force to relative motion sensor with the Sample Mass (png, pdf)

    -
    +

    act_damp_variability_ine_sample_mass.png

    Figure 10: Variability of the dynamics from actuator force to absolute velocity with the Sample Mass (png, pdf)

    @@ -521,17 +525,17 @@ We identify the dynamics for the following sample mass.
    -
    -

    2.2 Variation of the Spindle Angle

    +
    +

    2.2 Variation of the Spindle Angle

    - +

    We initialize all the stages with the default parameters.

    -
    prepareLinearizeIdentification();
    +
      prepareLinearizeIdentification();
     
    @@ -539,25 +543,25 @@ We initialize all the stages with the default parameters. We identify the dynamics for the following Spindle angles.

    -
    Rz_amplitudes = [0, pi/4, pi/2, pi]; % [rad]
    +
      Rz_amplitudes = [0, pi/4, pi/2, pi]; % [rad]
     
    -
    +

    act_damp_variability_iff_spindle_angle.png

    Figure 11: Variability of the dynamics from the actuator force to the force sensor with the Spindle Angle (png, pdf)

    -
    +

    act_damp_variability_dvf_spindle_angle.png

    Figure 12: Variability of the dynamics from actuator force to relative motion sensor with the Spindle Angle (png, pdf)

    -
    +

    act_damp_variability_ine_spindle_angle.png

    Figure 13: Variability of the dynamics from actuator force to absolute velocity with the Spindle Angle (png, pdf)

    @@ -565,17 +569,17 @@ We identify the dynamics for the following Spindle angles.
    -
    -

    2.3 Variation of the Spindle Rotation Speed

    +
    +

    2.3 Variation of the Spindle Rotation Speed

    - +

    We initialize all the stages with the default parameters.

    -
    prepareLinearizeIdentification();
    +
      prepareLinearizeIdentification();
     
    @@ -583,7 +587,7 @@ We initialize all the stages with the default parameters. We identify the dynamics for the following Spindle rotation periods.

    -
    Rz_periods = [60, 6, 2, 1]; % [s]
    +
      Rz_periods = [60, 6, 2, 1]; % [s]
     
    @@ -591,46 +595,46 @@ We identify the dynamics for the following Spindle rotation periods. The identification of the dynamics is done at the same Spindle angle position.

    -
    -

    2.3.1 Dynamics of the Active Damping plants

    +
    +

    2.3.1 Dynamics of the Active Damping plants

    -
    +

    act_damp_variability_iff_spindle_speed.png

    Figure 14: Variability of the dynamics from the actuator force to the force sensor with the Spindle rotation speed (png, pdf)

    -
    +

    act_damp_variability_iff_spindle_speed_zoom.png

    Figure 15: Variability of the dynamics from the actuator force to the force sensor with the Spindle rotation speed (png, pdf)

    -
    +

    act_damp_variability_dvf_spindle_speed.png

    Figure 16: Variability of the dynamics from the actuator force to the relative motion sensor with the Spindle rotation speed (png, pdf)

    -
    +

    act_damp_variability_dvf_spindle_speed_zoom.png

    Figure 17: Variability of the dynamics from the actuator force to the relative motion sensor with the Spindle rotation speed (png, pdf)

    -
    +

    act_damp_variability_ine_spindle_speed.png

    Figure 18: Variability of the dynamics from the actuator force to the absolute velocity sensor with the Spindle rotation speed (png, pdf)

    -
    +

    act_damp_variability_ine_spindle_speed_zoom.png

    Figure 19: Variability of the dynamics from the actuator force to the absolute velocity sensor with the Spindle rotation speed (png, pdf)

    @@ -638,18 +642,18 @@ The identification of the dynamics is done at the same Spindle angle position.
    -
    -

    2.3.2 Variation of the poles and zeros with the Spindle rotation frequency

    +
    +

    2.3.2 Variation of the poles and zeros with the Spindle rotation frequency

    -
    +

    campbell_diagram_spindle_rotation.png

    Figure 20: Evolution of the pole with respect to the spindle rotation speed (png, pdf)

    -
    +

    variation_zeros_active_damping_plants.png

    Figure 21: Evolution of the zero with respect to the spindle rotation speed (png, pdf)

    @@ -658,17 +662,17 @@ The identification of the dynamics is done at the same Spindle angle position.
    -
    -

    2.4 Variation of the Tilt Angle

    +
    +

    2.4 Variation of the Tilt Angle

    - +

    We initialize all the stages with the default parameters.

    -
    prepareLinearizeIdentification();
    +
      prepareLinearizeIdentification();
     
    @@ -676,25 +680,25 @@ We initialize all the stages with the default parameters. We identify the dynamics for the following Tilt stage angles.

    -
    Ry_amplitudes = [-3*pi/180, 3*pi/180]; % [rad]
    +
      Ry_amplitudes = [-3*pi/180, 3*pi/180]; % [rad]
     
    -
    +

    act_damp_variability_iff_tilt_angle.png

    Figure 22: Variability of the dynamics from the actuator force to the force sensor with the Tilt stage Angle (png, pdf)

    -
    +

    act_damp_variability_dvf_tilt_angle.png

    Figure 23: Variability of the dynamics from the actuator force to the relative motion sensor with the Tilt Angle (png, pdf)

    -
    +

    act_damp_variability_ine_tilt_angle.png

    Figure 24: Variability of the dynamics from the actuator force to the absolute velocity sensor with the Tilt Angle (png, pdf)

    @@ -702,11 +706,11 @@ We identify the dynamics for the following Tilt stage angles.
    -
    -

    2.5 Scans of the Translation Stage

    +
    +

    2.5 Scans of the Translation Stage

    - +

    We want here to verify if the dynamics used for Active damping is varying when using the translation stage for scans. @@ -715,22 +719,22 @@ We want here to verify if the dynamics used for Active damping is varying when u We initialize all the stages with the default parameters.

    -
    prepareLinearizeIdentification();
    +
      prepareLinearizeIdentification();
     

    -We initialize the translation stage reference to be a sinus with an amplitude of 5mm and a period of 1s (Figure 25). +We initialize the translation stage reference to be a sinus with an amplitude of 5mm and a period of 1s (Figure 25).

    -
    initializeReferences('Dy_type', 'sinusoidal', ...
    -                     'Dy_amplitude', 5e-3, ... % [m]
    -                     'Dy_period', 1); % [s]
    +
      initializeReferences('Dy_type', 'sinusoidal', ...
    +                       'Dy_amplitude', 5e-3, ... % [m]
    +                       'Dy_period', 1); % [s]
     
    -
    +

    ty_scanning_reference_sinus.png

    Figure 25: Reference path for the translation stage (png, pdf)

    @@ -740,25 +744,25 @@ We initialize the translation stage reference to be a sinus with an amplitude of We identify the dynamics at different positions (times) when scanning with the Translation stage.

    -
    t_lin = [0.5, 0.75, 1, 1.25];
    +
      t_lin = [0.5, 0.75, 1, 1.25];
     
    -
    +

    act_damp_variability_iff_ty_scans.png

    Figure 26: Variability of the dynamics from the actuator force to the absolute velocity sensor plant at different Ty scan positions (png, pdf)

    -
    +

    act_damp_variability_dvf_ty_scans.png

    Figure 27: Variability of the dynamics from actuator force to relative displacement sensor at different Ty scan positions (png, pdf)

    -
    +

    act_damp_variability_ine_ty_scans.png

    Figure 28: Variability of the Inertial plant at different Ty scan positions (png, pdf)

    @@ -766,10 +770,10 @@ We identify the dynamics at different positions (times) when scanning with the T
    -
    -

    2.6 Conclusion

    +
    +

    2.6 Conclusion

    - +
    @@ -815,7 +819,7 @@ We identify the dynamics at different positions (times) when scanning with the T Also, for the Inertial Sensor, a RHP zero may appear when the spindle is rotating fast.

    -
    +

    When using either a force sensor or a relative motion sensor for active damping, the only “parameter” that induce a large change for the dynamics to be controlled is the sample mass. Thus, the developed damping techniques should be robust to variations of the sample mass. @@ -826,13 +830,13 @@ Thus, the developed damping techniques should be robust to variations of the sam

    -
    -

    3 Integral Force Feedback

    +
    +

    3 Integral Force Feedback

    - +

    -
    +

    All the files (data and Matlab scripts) are accessible here.

    @@ -847,39 +851,39 @@ The IFF control is applied in a decentralized way: there is on controller for ea

    -The control architecture is represented in figure 29 where one of the 6 nano-hexapod legs is represented. +The control architecture is represented in figure 29 where one of the 6 nano-hexapod legs is represented.

    -
    +

    iff_1dof.png

    Figure 29: Integral Force Feedback applied to a 1dof system

    -
    -

    3.1 Control Design

    +
    +

    3.1 Control Design

    -
    -

    3.1.1 Plant

    +
    +

    3.1.1 Plant

    Let’s load the previously identified undamped plant:

    -
    load('./mat/active_damping_undamped_plants.mat', 'G_iff');
    -load('./mat/active_damping_plants_variable.mat', 'masses', 'Gm_iff');
    +
      load('./mat/active_damping_undamped_plants.mat', 'G_iff');
    +  load('./mat/active_damping_plants_variable.mat', 'masses', 'Gm_iff');
     

    -Let’s look at the transfer function from actuator forces in the nano-hexapod to the force sensor in the nano-hexapod legs for all 6 pairs of actuator/sensor (figure 30). +Let’s look at the transfer function from actuator forces in the nano-hexapod to the force sensor in the nano-hexapod legs for all 6 pairs of actuator/sensor (figure 30).

    -
    +

    iff_plant.png

    Figure 30: Transfer function from forces applied in the legs to force sensor (png, pdf)

    @@ -887,24 +891,24 @@ Let’s look at the transfer function from actuator forces in the nano-hexap
    -
    -

    3.1.2 Control Design

    +
    +

    3.1.2 Control Design

    The controller for each pair of actuator/sensor is:

    -
    w0 = 2*pi*50;
    -K_iff = -5000/s * (s/w0)/(1 + s/w0);
    +
      w0 = 2*pi*50;
    +  K_iff = -5000/s * (s/w0)/(1 + s/w0);
     

    -The corresponding loop gains are shown in figure 31. +The corresponding loop gains are shown in figure 31.

    -
    +

    iff_open_loop.png

    Figure 31: Loop Gain for the Integral Force Feedback (png, pdf)

    @@ -912,15 +916,15 @@ The corresponding loop gains are shown in figure 31.
    -
    -

    3.1.3 Diagonal Controller

    +
    +

    3.1.3 Diagonal Controller

    We create the diagonal controller and we add a minus sign as we have a positive feedback architecture.

    -
    K_iff = -K_iff*eye(6);
    +
      K_iff = -K_iff*eye(6);
     
    @@ -928,25 +932,25 @@ feedback architecture. We save the controller for further analysis.

    -
    save('./mat/active_damping_K_iff.mat', 'K_iff');
    +
      save('./mat/active_damping_K_iff.mat', 'K_iff');
     
    -
    -

    3.2 Tomography Experiment

    +
    +

    3.2 Tomography Experiment

    -
    -

    3.2.1 Simulation with IFF Controller

    +
    +

    3.2.1 Simulation with IFF Controller

    We initialize elements for the tomography experiment.

    -
    prepareTomographyExperiment();
    +
      prepareTomographyExperiment();
     
    @@ -954,8 +958,8 @@ We initialize elements for the tomography experiment. We set the IFF controller.

    -
    load('./mat/active_damping_K_iff.mat', 'K_iff');
    -initializeController('type', 'iff');
    +
      load('./mat/active_damping_K_iff.mat', 'K_iff');
    +  initializeController('type', 'iff');
     
    @@ -963,8 +967,8 @@ initializeController('type', 'iff'); We change the simulation stop time.

    -
    load('mat/conf_simulink.mat');
    -set_param(conf_simulink, 'StopTime', '4.5');
    +
      load('mat/conf_simulink.mat');
    +  set_param(conf_simulink, 'StopTime', '4.5');
     
    @@ -972,7 +976,7 @@ set_param(conf_simulink, 'StopTime', '4.5'); And we simulate the system.

    -
    sim('nass_model');
    +
      sim('nass_model');
     
    @@ -980,33 +984,33 @@ And we simulate the system. Finally, we save the simulation results for further analysis

    -
    En_iff = En;
    -Eg_iff = Eg;
    -save('./mat/active_damping_tomo_exp.mat', 'En_iff', 'Eg_iff', '-append');
    +
      En_iff = En;
    +  Eg_iff = Eg;
    +  save('./mat/active_damping_tomo_exp.mat', 'En_iff', 'Eg_iff', '-append');
     
    -
    -

    3.2.2 Compare with Undamped system

    +
    +

    3.2.2 Compare with Undamped system

    -
    +

    nass_act_damp_iff_sim_tomo_xy.png

    Figure 32: Position Error during tomography experiment - XY Motion (png, pdf)

    -
    +

    nass_act_damp_iff_sim_tomo_trans.png

    Figure 33: Position Error during tomography experiment - Translations (png, pdf)

    -
    +

    nass_act_damp_iff_sim_tomo_rot.png

    Figure 34: Position Error during tomography experiment - Rotations (png, pdf)

    @@ -1015,10 +1019,10 @@ save('./mat/active_damping_tomo_exp.mat', 'En_iff', 'Eg_iff', '-append');
    -
    -

    3.3 Conclusion

    +
    +

    3.3 Conclusion

    -
    +

    Integral Force Feedback using a force sensor:

    @@ -1033,13 +1037,13 @@ Integral Force Feedback using a force sensor:
    -
    -

    4 Direct Velocity Feedback

    +
    +

    4 Direct Velocity Feedback

    - +

    -
    +

    All the files (data and Matlab scripts) are accessible here.

    @@ -1051,28 +1055,28 @@ The actuator displacement can be measured with a capacitive sensor for instance.

    -
    -

    4.1 Control Design

    +
    +

    4.1 Control Design

    -
    -

    4.1.1 Plant

    +
    +

    4.1.1 Plant

    Let’s load the undamped plant:

    -
    load('./mat/active_damping_undamped_plants.mat', 'G_dvf');
    -load('./mat/active_damping_plants_variable.mat', 'masses', 'Gm_dvf');
    +
      load('./mat/active_damping_undamped_plants.mat', 'G_dvf');
    +  load('./mat/active_damping_plants_variable.mat', 'masses', 'Gm_dvf');
     

    -Let’s look at the transfer function from actuator forces in the nano-hexapod to the measured displacement of the actuator for all 6 pairs of actuator/sensor (figure 35). +Let’s look at the transfer function from actuator forces in the nano-hexapod to the measured displacement of the actuator for all 6 pairs of actuator/sensor (figure 35).

    -
    +

    dvf_plant.png

    Figure 35: Transfer function from forces applied in the legs to leg displacement sensor (png, pdf)

    @@ -1080,24 +1084,24 @@ Let’s look at the transfer function from actuator forces in the nano-hexap
    -
    -

    4.1.2 Control Design

    +
    +

    4.1.2 Control Design

    The Direct Velocity Feedback is defined below. A Low pass Filter is added to make the controller transfer function proper.

    -
    K_dvf = s*30000/(1 + s/2/pi/10000);
    +
      K_dvf = s*30000/(1 + s/2/pi/10000);
     

    -The obtained loop gains are shown in figure 36. +The obtained loop gains are shown in figure 36.

    -
    +

    dvf_open_loop.png

    Figure 36: Loop Gain for the Integral Force Feedback (png, pdf)

    @@ -1105,14 +1109,14 @@ The obtained loop gains are shown in figure 36.
    -
    -

    4.1.3 Diagonal Controller

    +
    +

    4.1.3 Diagonal Controller

    We create the diagonal controller and we add a minus sign as we have a positive feedback architecture.

    -
    K_dvf = -K_dvf*eye(6);
    +
      K_dvf = -K_dvf*eye(6);
     
    @@ -1120,25 +1124,25 @@ We create the diagonal controller and we add a minus sign as we have a positive We save the controller for further analysis.

    -
    save('./mat/active_damping_K_dvf.mat', 'K_dvf');
    +
      save('./mat/active_damping_K_dvf.mat', 'K_dvf');
     
    -
    -

    4.2 Tomography Experiment

    +
    +

    4.2 Tomography Experiment

    -
    -

    4.2.1 Initialize the Simulation

    +
    +

    4.2.1 Initialize the Simulation

    We initialize elements for the tomography experiment.

    -
    prepareTomographyExperiment();
    +
      prepareTomographyExperiment();
     
    @@ -1146,8 +1150,8 @@ We initialize elements for the tomography experiment. We set the DVF controller.

    -
    load('./mat/active_damping_K_dvf.mat', 'K_dvf');
    -initializeController('type', 'dvf');
    +
      load('./mat/active_damping_K_dvf.mat', 'K_dvf');
    +  initializeController('type', 'dvf');
     
    @@ -1155,8 +1159,8 @@ initializeController('type', 'dvf'); We change the simulation stop time.

    -
    load('mat/conf_simulink.mat');
    -set_param(conf_simulink, 'StopTime', '4.5');
    +
      load('mat/conf_simulink.mat');
    +  set_param(conf_simulink, 'StopTime', '4.5');
     
    @@ -1164,7 +1168,7 @@ set_param(conf_simulink, 'StopTime', '4.5'); And we simulate the system.

    -
    sim('nass_model');
    +
      sim('nass_model');
     
    @@ -1172,33 +1176,33 @@ And we simulate the system. Finally, we save the simulation results for further analysis

    -
    En_dvf = En;
    -Eg_dvf = Eg;
    -save('./mat/active_damping_tomo_exp.mat', 'En_dvf', 'Eg_dvf', '-append');
    +
      En_dvf = En;
    +  Eg_dvf = Eg;
    +  save('./mat/active_damping_tomo_exp.mat', 'En_dvf', 'Eg_dvf', '-append');
     
    -
    -

    4.2.2 Compare with Undamped system

    +
    +

    4.2.2 Compare with Undamped system

    -
    +

    nass_act_damp_dvf_sim_tomo_xy.png

    Figure 37: Position Error during tomography experiment - XY Motion (png, pdf)

    -
    +

    nass_act_damp_dvf_sim_tomo_trans.png

    Figure 38: Position Error during tomography experiment - Translations (png, pdf)

    -
    +

    nass_act_damp_dvf_sim_tomo_rot.png

    Figure 39: Position Error during tomography experiment - Rotations (png, pdf)

    @@ -1207,10 +1211,10 @@ save('./mat/active_damping_tomo_exp.mat', 'En_dvf', 'Eg_dvf', '-append');
    -
    -

    4.3 Conclusion

    +
    +

    4.3 Conclusion

    -
    +

    Direct Velocity Feedback using a relative motion sensor:

    @@ -1223,13 +1227,13 @@ Direct Velocity Feedback using a relative motion sensor:
    -
    -

    5 Inertial Control

    +
    +

    5 Inertial Control

    - +

    -
    +

    All the files (data and Matlab scripts) are accessible here.

    @@ -1240,28 +1244,28 @@ In Inertial Control, a feedback is applied between the measured absolute

    -
    -

    5.1 Control Design

    +
    +

    5.1 Control Design

    -
    -

    5.1.1 Plant

    +
    +

    5.1.1 Plant

    Let’s load the undamped plant:

    -
    load('./mat/active_damping_undamped_plants.mat', 'G_ine');
    -load('./mat/active_damping_plants_variable.mat', 'masses', 'Gm_ine');
    +
      load('./mat/active_damping_undamped_plants.mat', 'G_ine');
    +  load('./mat/active_damping_plants_variable.mat', 'masses', 'Gm_ine');
     

    -Let’s look at the transfer function from actuator forces in the nano-hexapod to the measured velocity of the nano-hexapod platform in the direction of the corresponding actuator for all 6 pairs of actuator/sensor (figure 40). +Let’s look at the transfer function from actuator forces in the nano-hexapod to the measured velocity of the nano-hexapod platform in the direction of the corresponding actuator for all 6 pairs of actuator/sensor (figure 40).

    -
    +

    ine_plant.png

    Figure 40: Transfer function from forces applied in the legs to leg velocity sensor (png, pdf)

    @@ -1269,20 +1273,20 @@ Let’s look at the transfer function from actuator forces in the nano-hexap
    -
    -

    5.1.2 Control Design

    +
    +

    5.1.2 Control Design

    -The controller is defined below and the obtained loop gain is shown in figure 41. +The controller is defined below and the obtained loop gain is shown in figure 41.

    -
    K_ine = 2.5e4;
    +
      K_ine = 2.5e4;
     
    -
    +

    ine_open_loop_gain.png

    Figure 41: Loop Gain for Inertial Control (png, pdf)

    @@ -1290,14 +1294,14 @@ The controller is defined below and the obtained loop gain is shown in figure
    -
    -

    5.1.3 Diagonal Controller

    +
    +

    5.1.3 Diagonal Controller

    We create the diagonal controller and we add a minus sign as we have a positive feedback architecture.

    -
    K_ine = -K_ine*eye(6);
    +
      K_ine = -K_ine*eye(6);
     
    @@ -1305,17 +1309,17 @@ We create the diagonal controller and we add a minus sign as we have a positive We save the controller for further analysis.

    -
    save('./mat/active_damping_K_ine.mat', 'K_ine');
    +
      save('./mat/active_damping_K_ine.mat', 'K_ine');
     
    -
    -

    5.2 Conclusion

    +
    +

    5.2 Conclusion

    -
    +

    Inertial Control should not be used.

    @@ -1325,28 +1329,28 @@ Inertial Control should not be used.
    -
    -

    6 Comparison

    +
    +

    6 Comparison

    - +

    -
    -

    6.1 Load the plants

    +
    +

    6.1 Load the plants

    -
    load('./mat/active_damping_plants.mat', 'G', 'G_iff', 'G_ine', 'G_dvf');
    +
      load('./mat/active_damping_plants.mat', 'G', 'G_iff', 'G_ine', 'G_dvf');
     
    -
    -

    6.2 Sensitivity to Disturbance

    +
    +

    6.2 Sensitivity to Disturbance

    -
    +

    sensitivity_comp_ground_motion_z.png

    Figure 42: Sensitivity to ground motion in the Z direction on the Z motion error (png, pdf)

    @@ -1354,21 +1358,21 @@ Inertial Control should not be used. -
    +

    sensitivity_comp_direct_forces_z.png

    Figure 43: Compliance in the Z direction: Sensitivity of direct forces applied on the sample in the Z direction on the Z motion error (png, pdf)

    -
    +

    sensitivity_comp_spindle_z.png

    Figure 44: Sensitivity to forces applied in the Z direction by the Spindle on the Z motion error (png, pdf)

    -
    +

    sensitivity_comp_ty_z.png

    Figure 45: Sensitivity to forces applied in the Z direction by the Y translation stage on the Z motion error (png, pdf)

    @@ -1376,7 +1380,7 @@ Inertial Control should not be used. -
    +

    sensitivity_comp_ty_x.png

    Figure 46: Sensitivity to forces applied in the X direction by the Y translation stage on the X motion error (png, pdf)

    @@ -1384,25 +1388,25 @@ Inertial Control should not be used.
    -
    -

    6.3 Damped Plant

    +
    +

    6.3 Damped Plant

    -
    +

    plant_comp_damping_z.png

    Figure 47: Plant for the \(z\) direction for different active damping technique used (png, pdf)

    -
    +

    plant_comp_damping_x.png

    Figure 48: Plant for the \(x\) direction for different active damping technique used (png, pdf)

    -
    +

    plant_comp_damping_coupling.png

    Figure 49: Comparison of one off-diagonal plant for different damping technique applied (png, pdf)

    @@ -1410,13 +1414,13 @@ Inertial Control should not be used.
    -
    -

    6.4 Tomography Experiment - Frequency Domain analysis

    +
    +

    6.4 Tomography Experiment - Frequency Domain analysis

    -
    load('./mat/active_damping_tomo_exp.mat', 'En', 'En_iff', 'En_dvf');
    -Fs = 1e3; % Sampling Frequency of the Data
    -t = (1/Fs)*[0:length(En(:,1))-1];
    +
      load('./mat/active_damping_tomo_exp.mat', 'En', 'En_iff', 'En_dvf');
    +  Fs = 1e3; % Sampling Frequency of the Data
    +  t = (1/Fs)*[0:length(En(:,1))-1];
     
    @@ -1424,12 +1428,12 @@ t = (1/Fs)*[0:length(En(:,1))-1]; We remove the first 0.5 seconds where the transient behavior is fading out.

    -
    [~, i_start] = min(abs(t - 0.5)); % find the indice corresponding to 0.5s
    +
      [~, i_start] = min(abs(t - 0.5)); % find the indice corresponding to 0.5s
     
    -t = t(i_start:end) - t(i_start);
    -En = En(i_start:end, :);
    -En_dvf = En_dvf(i_start:end, :);
    -En_iff = En_iff(i_start:end, :);
    +  t = t(i_start:end) - t(i_start);
    +  En = En(i_start:end, :);
    +  En_dvf = En_dvf(i_start:end, :);
    +  En_iff = En_iff(i_start:end, :);
     
    @@ -1437,34 +1441,34 @@ En_iff = En_iff(i_start:end, :); Window used for pwelch function.

    -
    n_av = 4;
    -han_win = hanning(ceil(length(En(:, 1))/n_av));
    +
      n_av = 4;
    +  han_win = hanning(ceil(length(En(:, 1))/n_av));
     
    -
    +

    act_damp_tomo_exp_comp_psd_trans.png

    Figure 50: PSD of the translation errors in the X direction for applied Active Damping techniques (png, pdf)

    -
    +

    act_damp_tomo_exp_comp_psd_rot.png

    Figure 51: PSD of the rotation errors in the X direction for applied Active Damping techniques (png, pdf)

    -
    +

    act_damp_tomo_exp_comp_cps_trans.png

    Figure 52: CPS of the translation errors in the X direction for applied Active Damping techniques (png, pdf)

    -
    +

    act_damp_tomo_exp_comp_cps_rot.png

    Figure 53: CPS of the rotation errors in the X direction for applied Active Damping techniques (png, pdf)

    @@ -1473,15 +1477,15 @@ han_win = hanning(ceil(length(En(:, 1))/n_av));
    -
    -

    7 Useful Functions

    +
    +

    7 Useful Functions

    -
    -

    7.1 prepareLinearizeIdentification

    +
    +

    7.1 prepareLinearizeIdentification

    - +

    @@ -1489,44 +1493,44 @@ This Matlab function is accessible -

    Function Description

    -
    +
    +

    Function Description

    +
    -
    function [] = prepareLinearizeIdentification(args)
    +
      function [] = prepareLinearizeIdentification(args)
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    args.nass_actuator       char   {mustBeMember(args.nass_actuator,{'piezo', 'lorentz'})} = 'piezo'
    -    args.sample_mass   (1,1) double {mustBeNumeric, mustBePositive} = 50 % [kg]
    -end
    +
      arguments
    +      args.nass_actuator       char   {mustBeMember(args.nass_actuator,{'piezo', 'lorentz'})} = 'piezo'
    +      args.sample_mass   (1,1) double {mustBeNumeric, mustBePositive} = 50 % [kg]
    +  end
     
    -
    -

    Initialize the Simulation

    -
    +
    +

    Initialize the Simulation

    +

    We initialize all the stages with the default parameters.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
     
    @@ -1534,8 +1538,8 @@ initializeMirror(); The nano-hexapod is a piezoelectric hexapod and the sample has a mass of 50kg.

    -
    initializeNanoHexapod('actuator', args.nass_actuator);
    -initializeSample('mass', args.sample_mass);
    +
      initializeNanoHexapod('actuator', args.nass_actuator);
    +  initializeSample('mass', args.sample_mass);
     
    @@ -1543,8 +1547,8 @@ initializeSample('mass', args.sample_mass); We set the references and disturbances to zero.

    -
    initializeReferences();
    -initializeDisturbances('enable', false);
    +
      initializeReferences();
    +  initializeDisturbances('enable', false);
     
    @@ -1552,7 +1556,7 @@ initializeDisturbances('enable', false); We set the controller type to Open-Loop.

    -
    initializeController('type', 'open-loop');
    +
      initializeController('type', 'open-loop');
     
    @@ -1560,7 +1564,7 @@ We set the controller type to Open-Loop. And we put some gravity.

    -
    initializeSimscapeConfiguration('gravity', true);
    +
      initializeSimscapeConfiguration('gravity', true);
     
    @@ -1568,18 +1572,18 @@ And we put some gravity. We do not need to log any signal.

    -
    initializeLoggingConfiguration('log', 'none');
    +
      initializeLoggingConfiguration('log', 'none');
     
    -
    -

    7.2 prepareTomographyExperiment

    +
    +

    7.2 prepareTomographyExperiment

    - +

    @@ -1587,45 +1591,45 @@ This Matlab function is accessible h

    -
    -

    Function Description

    -
    +
    +

    Function Description

    +
    -
    function [] = prepareTomographyExperiment(args)
    +
      function [] = prepareTomographyExperiment(args)
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    args.nass_actuator       char   {mustBeMember(args.nass_actuator,{'piezo', 'lorentz'})} = 'piezo'
    -    args.sample_mass   (1,1) double {mustBeNumeric, mustBePositive} = 50 % [kg]
    -    args.Rz_period     (1,1) double {mustBeNumeric, mustBePositive} = 1 % [s]
    -end
    +
      arguments
    +      args.nass_actuator       char   {mustBeMember(args.nass_actuator,{'piezo', 'lorentz'})} = 'piezo'
    +      args.sample_mass   (1,1) double {mustBeNumeric, mustBePositive} = 50 % [kg]
    +      args.Rz_period     (1,1) double {mustBeNumeric, mustBePositive} = 1 % [s]
    +  end
     
    -
    -

    Initialize the Simulation

    -
    +
    +

    Initialize the Simulation

    +

    We initialize all the stages with the default parameters.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
     
    @@ -1633,8 +1637,8 @@ initializeMirror(); The nano-hexapod is a piezoelectric hexapod and the sample has a mass of 50kg.

    -
    initializeNanoHexapod('actuator', args.nass_actuator);
    -initializeSample('mass', args.sample_mass);
    +
      initializeNanoHexapod('actuator', args.nass_actuator);
    +  initializeSample('mass', args.sample_mass);
     
    @@ -1642,12 +1646,12 @@ initializeSample('mass', args.sample_mass); We set the references that corresponds to a tomography experiment.

    -
    initializeReferences('Rz_type', 'rotating', 'Rz_period', args.Rz_period);
    +
      initializeReferences('Rz_type', 'rotating', 'Rz_period', args.Rz_period);
     
    -
    initializeDisturbances();
    +
      initializeDisturbances();
     
    @@ -1655,7 +1659,7 @@ We set the references that corresponds to a tomography experiment. Open Loop.

    -
    initializeController('type', 'open-loop');
    +
      initializeController('type', 'open-loop');
     
    @@ -1663,7 +1667,7 @@ Open Loop. And we put some gravity.

    -
    initializeSimscapeConfiguration('gravity', true);
    +
      initializeSimscapeConfiguration('gravity', true);
     
    @@ -1671,7 +1675,7 @@ And we put some gravity. We log the signals.

    -
    initializeLoggingConfiguration('log', 'all');
    +
      initializeLoggingConfiguration('log', 'all');
     
    @@ -1681,7 +1685,7 @@ We log the signals.

    Author: Dehaeze Thomas

    -

    Created: 2020-05-05 mar. 10:34

    +

    Created: 2021-02-20 sam. 23:09

    diff --git a/docs/control_cascade.html b/docs/control_cascade.html index c011246..87b1ff1 100644 --- a/docs/control_cascade.html +++ b/docs/control_cascade.html @@ -1,75 +1,79 @@ - - + Cascade Control applied on the Simscape Model - - - - - - - - + + + +

    Cascade Control applied on the Simscape Model

    -The control architecture we wish here to study is shown in Figure 1. +The control architecture we wish here to study is shown in Figure 1.

    -
    +

    cascade_control_architecture.png

    Figure 1: Cascaded Control consisting of (from inner to outer loop): IFF, Linearization Loop, Tracking Control in the frame of the Legs

    @@ -79,28 +83,28 @@ The control architecture we wish here to study is shown in Figure -
  • In section 2: an active damping controller is designed. +
  • In section 2: an active damping controller is designed. This is based on the Integral Force Feedback and applied in a decentralized way
  • -
  • In section 3: a decentralized tracking control is designed in the frame of the legs. +
  • In section 3: a decentralized tracking control is designed in the frame of the legs. This controller is based on the displacement of each of the legs
  • -
  • In section 4: a controller is designed in the task space in order to follow the wanted reference path corresponding to the sample position with respect to the granite
  • +
  • In section 4: a controller is designed in the task space in order to follow the wanted reference path corresponding to the sample position with respect to the granite
  • -
    -

    1 Initialization

    +
    +

    1 Initialization

    We initialize all the stages with the default parameters.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
     
    @@ -108,8 +112,8 @@ initializeMirror(); The nano-hexapod is a piezoelectric hexapod and the sample has a mass of 50kg.

    -
    initializeNanoHexapod('actuator', 'piezo');
    -initializeSample('mass', 1);
    +
      initializeNanoHexapod('actuator', 'piezo');
    +  initializeSample('mass', 1);
     
    @@ -117,12 +121,12 @@ initializeSample('mass', 1); We set the references that corresponds to a tomography experiment.

    -
    initializeReferences('Rz_type', 'rotating', 'Rz_period', 1);
    +
      initializeReferences('Rz_type', 'rotating', 'Rz_period', 1);
     
    -
    initializeDisturbances();
    +
      initializeDisturbances();
     
    @@ -130,7 +134,7 @@ We set the references that corresponds to a tomography experiment. Open Loop.

    -
    initializeController('type', 'cascade-hac-lac');
    +
      initializeController('type', 'cascade-hac-lac');
     
    @@ -138,7 +142,7 @@ Open Loop. And we put some gravity.

    -
    initializeSimscapeConfiguration('gravity', true);
    +
      initializeSimscapeConfiguration('gravity', true);
     
    @@ -146,55 +150,55 @@ And we put some gravity. We log the signals.

    -
    initializeLoggingConfiguration('log', 'all');
    +
      initializeLoggingConfiguration('log', 'all');
     
    -
    Kp = tf(zeros(6));
    -Kl = tf(zeros(6));
    -Kiff = tf(zeros(6));
    +
      Kp = tf(zeros(6));
    +  Kl = tf(zeros(6));
    +  Kiff = tf(zeros(6));
     
    -
    -

    2 Low Authority Control - Integral Force Feedback \(\bm{K}_\text{IFF}\)

    +
    +

    2 Low Authority Control - Integral Force Feedback \(\bm{K}_\text{IFF}\)

    - +

    -
    -

    2.1 Identification

    +
    +

    2.1 Identification

    Let’s first identify the plant for the IFF controller.

    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller'],    1, 'openinput');               io_i = io_i + 1; % Actuator Inputs
    -io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm');  io_i = io_i + 1; % Force Sensors
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller'],    1, 'openinput');               io_i = io_i + 1; % Actuator Inputs
    +  io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm');  io_i = io_i + 1; % Force Sensors
     
    -%% Run the linearization
    -G_iff = linearize(mdl, io, 0);
    -G_iff.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    -G_iff.OutputName = {'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'};
    +  %% Run the linearization
    +  G_iff = linearize(mdl, io, 0);
    +  G_iff.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    +  G_iff.OutputName = {'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'};
     
    -
    -

    2.2 Plant

    +
    +

    2.2 Plant

    -
    +

    cascade_iff_plant.png

    Figure 2: IFF Plant (png, pdf)

    @@ -202,11 +206,11 @@ G_iff.OutputName = {'Fnlm1', -

    2.3 Root Locus

    +
    +

    2.3 Root Locus

    -
    +

    cascade_iff_root_locus.png

    Figure 3: Root Locus for the IFF control (png, pdf)

    @@ -218,21 +222,21 @@ The maximum damping is obtained for a control gain of \(\approx 3000\).
    -
    -

    2.4 Controller and Loop Gain

    +
    +

    2.4 Controller and Loop Gain

    We create the \(6 \times 6\) diagonal Integral Force Feedback controller. -The obtained loop gain is shown in Figure 4. +The obtained loop gain is shown in Figure 4.

    -
    w0 = 2*pi*50;
    -Kiff = -3000/s*eye(6);
    +
      w0 = 2*pi*50;
    +  Kiff = -3000/s*eye(6);
     
    -
    +

    cascade_iff_loop_gain.png

    Figure 4: Obtained Loop gain the IFF Control (png, pdf)

    @@ -241,32 +245,32 @@ Kiff = -3000/s
    -
    -

    3 High Authority Control in the joint space - \(\bm{K}_\mathcal{L}\)

    +
    +

    3 High Authority Control in the joint space - \(\bm{K}_\mathcal{L}\)

    - +

    -
    -

    3.1 Identification of the damped plant

    +
    +

    3.1 Identification of the damped plant

    -We now identify the transfer function from \(\tau^\prime\) to \(d\bm{\mathcal{L}}\) as shown in Figure 1. +We now identify the transfer function from \(\tau^\prime\) to \(d\bm{\mathcal{L}}\) as shown in Figure 1.

    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller'],    1, 'input');               io_i = io_i + 1; % Actuator Inputs
    -io(io_i) = linio([mdl, '/Micro-Station'], 3, 'output', [], 'Dnlm');  io_i = io_i + 1; % Leg Displacement
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller'],    1, 'input');               io_i = io_i + 1; % Actuator Inputs
    +  io(io_i) = linio([mdl, '/Micro-Station'], 3, 'output', [], 'Dnlm');  io_i = io_i + 1; % Leg Displacement
     
    -%% Run the linearization
    -Gl = linearize(mdl, io, 0);
    -Gl.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    -Gl.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'};
    +  %% Run the linearization
    +  Gl = linearize(mdl, io, 0);
    +  Gl.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    +  Gl.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'};
     
    @@ -275,19 +279,19 @@ There are some unstable poles in the Plant with very small imaginary parts. These unstable poles are probably not physical, and they disappear when taking the minimum realization of the plant.

    -
    isstable(Gl)
    -Gl = minreal(Gl);
    -isstable(Gl)
    +
      isstable(Gl)
    +  Gl = minreal(Gl);
    +  isstable(Gl)
     
    -
    -

    3.2 Obtained Plant

    +
    +

    3.2 Obtained Plant

    -The obtain plant is shown in Figure 5. +The obtain plant is shown in Figure 5.

    @@ -295,7 +299,7 @@ We can see that the plant is quite well decoupled.

    -
    +

    cascade_hac_joint_plant.png

    Figure 5: Plant for the High Authority Control in the Joint Space (png, pdf)

    @@ -304,8 +308,8 @@ We can see that the plant is quite well decoupled.
    -
    -

    3.3 Controller Design and Loop Gain

    +
    +

    3.3 Controller Design and Loop Gain

    The controller consists of: @@ -318,20 +322,20 @@ The controller consists of:

    -
    wc = 2*pi*400; % Bandwidth Bandwidth [rad/s]
    +
      wc = 2*pi*400; % Bandwidth Bandwidth [rad/s]
     
    -h = 2; % Lead parameter
    +  h = 2; % Lead parameter
     
    -% Kl = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * wc/s * ((s/wc*2 + 1)/(s/wc*2)) * (1/(1 + s/wc/2));
    -Kl = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * wc/s;
    +  % Kl = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * wc/s * ((s/wc*2 + 1)/(s/wc*2)) * (1/(1 + s/wc/2));
    +  Kl = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * wc/s;
     
    -% Normalization of the gain of have a loop gain of 1 at frequency wc
    -Kl = Kl.*diag(1./diag(abs(freqresp(Gl*Kl, wc))));
    +  % Normalization of the gain of have a loop gain of 1 at frequency wc
    +  Kl = Kl.*diag(1./diag(abs(freqresp(Gl*Kl, wc))));
     
    -
    +

    cascade_hac_joint_loop_gain.png

    Figure 6: Loop Gain for the High Autority Control in the joint space (png, pdf)

    @@ -340,32 +344,32 @@ Kl = Kl.*diag(1./dia
    -
    -

    4 Primary Controller in the task space - \(\bm{K}_\mathcal{X}\)

    +
    +

    4 Primary Controller in the task space - \(\bm{K}_\mathcal{X}\)

    - +

    -
    -

    4.1 Identification of the linearized plant

    +
    +

    4.1 Identification of the linearized plant

    We know identify the dynamics between \(\bm{r}_{\mathcal{X}_n}\) and \(\bm{r}_\mathcal{X}\).

    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller/Cascade-HAC-LAC/Kp'],  1, 'input'); io_i = io_i + 1;
    -io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En');      io_i = io_i + 1; % Position Errror
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller/Cascade-HAC-LAC/Kp'],  1, 'input'); io_i = io_i + 1;
    +  io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En');      io_i = io_i + 1; % Position Errror
     
    -%% Run the linearization
    -Gx = linearize(mdl, io, 0);
    -Gx.InputName  = {'rL1', 'rL2', 'rL3', 'rL4', 'rL5', 'rL6'};
    -Gx.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
    +  %% Run the linearization
    +  Gx = linearize(mdl, io, 0);
    +  Gx.InputName  = {'rL1', 'rL2', 'rL3', 'rL4', 'rL5', 'rL6'};
    +  Gx.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
     
    @@ -373,19 +377,19 @@ Gx.OutputName = {'Ex', As before, we take the minimum realization.

    -
    isstable(Gx)
    -Gx = minreal(Gx);
    -isstable(Gx)
    +
      isstable(Gx)
    +  Gx = minreal(Gx);
    +  isstable(Gx)
     
    -
    -

    4.2 Obtained Plant

    +
    +

    4.2 Obtained Plant

    -
    +

    cascade_primary_plant.png

    Figure 7: Plant for the Primary Controller (png, pdf)

    @@ -393,23 +397,23 @@ isstable(Gx)
    -
    -

    4.3 Controller Design

    +
    +

    4.3 Controller Design

    -
    wc = 2*pi*10; % Bandwidth Bandwidth [rad/s]
    +
      wc = 2*pi*10; % Bandwidth Bandwidth [rad/s]
     
    -h = 2; % Lead parameter
    +  h = 2; % Lead parameter
     
    -Kp = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * wc/s * (s + 2*pi*5)/s * 1/(1+s/2/pi/20);
    +  Kp = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * wc/s * (s + 2*pi*5)/s * 1/(1+s/2/pi/20);
     
    -% Normalization of the gain of have a loop gain of 1 at frequency wc
    -Kp = Kp.*diag(1./diag(abs(freqresp(Gx*Kp, wc))));
    +  % Normalization of the gain of have a loop gain of 1 at frequency wc
    +  Kp = Kp.*diag(1./diag(abs(freqresp(Gx*Kp, wc))));
     
    -
    +

    cascade_primary_loop_gain.png

    Figure 8: Loop Gain for the primary controller (outer loop) (png, pdf)

    @@ -418,12 +422,12 @@ Kp = Kp.*diag(1./dia
    -
    -

    5 Simulation

    +
    +

    5 Simulation

    -
    load('mat/conf_simulink.mat');
    -set_param(conf_simulink, 'StopTime', '2');
    +
      load('mat/conf_simulink.mat');
    +  set_param(conf_simulink, 'StopTime', '2');
     
    @@ -431,58 +435,58 @@ Kp = Kp.*diag(1./dia And we simulate the system.

    -
    sim('nass_model');
    +
      sim('nass_model');
     
    -
    cascade_hac_lac = simout;
    -save('./mat/cascade_hac_lac.mat', 'cascade_hac_lac');
    +
      cascade_hac_lac = simout;
    +  save('./mat/cascade_hac_lac.mat', 'cascade_hac_lac');
     
    -
    -

    6 Results

    +
    +

    6 Results

    -
    load('./mat/experiment_tomography.mat', 'tomo_align_dist');
    -load('./mat/cascade_hac_lac.mat', 'cascade_hac_lac');
    +
      load('./mat/experiment_tomography.mat', 'tomo_align_dist');
    +  load('./mat/cascade_hac_lac.mat', 'cascade_hac_lac');
     
    -
    n_av = 4;
    -han_win = hanning(ceil(length(cascade_hac_lac.Em.En.Data(:,1))/n_av));
    +
      n_av = 4;
    +  han_win = hanning(ceil(length(cascade_hac_lac.Em.En.Data(:,1))/n_av));
     
    -
    t = cascade_hac_lac.Em.En.Time;
    -Ts = t(2)-t(1);
    +
      t = cascade_hac_lac.Em.En.Time;
    +  Ts = t(2)-t(1);
     
    -[pxx_ol, f] = pwelch(tomo_align_dist.Em.En.Data, han_win, [], [], 1/Ts);
    -[pxx_ca, ~] = pwelch(cascade_hac_lac.Em.En.Data, han_win, [], [], 1/Ts);
    +  [pxx_ol, f] = pwelch(tomo_align_dist.Em.En.Data, han_win, [], [], 1/Ts);
    +  [pxx_ca, ~] = pwelch(cascade_hac_lac.Em.En.Data, han_win, [], [], 1/Ts);
     
    -
    +

    cascade_hac_lac_tomography_psd.png

    Figure 9: ASD of the position error (png, pdf)

    -
    +

    cascade_hac_lac_tomography_cas.png

    Figure 10: Cumulative Amplitude Spectrum of the position error (png, pdf)

    -
    +

    cascade_hac_lac_tomography.png

    Figure 11: Results of the Tomography Experiment (png, pdf)

    @@ -492,7 +496,7 @@ Ts = t(2)-t(1);

    Author: Dehaeze Thomas

    -

    Created: 2020-04-17 ven. 09:35

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/control_decentralized.html b/docs/control_decentralized.html index 1714059..a7c4a32 100644 --- a/docs/control_decentralized.html +++ b/docs/control_decentralized.html @@ -1,65 +1,69 @@ - - + Control in the Frame of the Legs applied on the Simscape Model - - - - - - - - + + + +

    Control in the Frame of the Legs applied on the Simscape Model

    @@ -68,15 +72,15 @@ In this document, we apply some decentralized control to the NASS and see what level of performance can be obtained.

    -
    -

    1 Decentralized Control

    +
    +

    1 Decentralized Control

    -
    -

    1.1 Control Schematic

    +
    +

    1.1 Control Schematic

    -The control architecture is shown in Figure 1. +The control architecture is shown in Figure 1.

    @@ -92,7 +96,7 @@ The signals are: -

    +

    decentralized_reference_tracking_L.png

    Figure 1: Decentralized control for reference tracking

    @@ -100,21 +104,21 @@ The signals are:
    -
    -

    1.2 Initialize the Simscape Model

    +
    +

    1.2 Initialize the Simscape Model

    We initialize all the stages with the default parameters.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
     
    @@ -122,8 +126,8 @@ initializeMirror(); The nano-hexapod is a piezoelectric hexapod and the sample has a mass of 50kg.

    -
    initializeNanoHexapod('actuator', 'piezo');
    -initializeSample('mass', 1);
    +
      initializeNanoHexapod('actuator', 'piezo');
    +  initializeSample('mass', 1);
     
    @@ -131,12 +135,12 @@ initializeSample('mass', 1); We set the references that corresponds to a tomography experiment.

    -
    initializeReferences('Rz_type', 'rotating', 'Rz_period', 1);
    +
      initializeReferences('Rz_type', 'rotating', 'Rz_period', 1);
     
    -
    initializeDisturbances();
    +
      initializeDisturbances();
     
    @@ -144,8 +148,8 @@ We set the references that corresponds to a tomography experiment. Open Loop.

    -
    initializeController('type', 'ref-track-L');
    -Kl = tf(zeros(6));
    +
      initializeController('type', 'ref-track-L');
    +  Kl = tf(zeros(6));
     
    @@ -153,7 +157,7 @@ Kl = tf(zeros(6)); And we put some gravity.

    -
    initializeSimscapeConfiguration('gravity', true);
    +
      initializeSimscapeConfiguration('gravity', true);
     
    @@ -161,41 +165,41 @@ And we put some gravity. We log the signals.

    -
    initializeLoggingConfiguration('log', 'all');
    +
      initializeLoggingConfiguration('log', 'all');
     
    -
    -

    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 = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller'],                          1, 'openinput');  io_i = io_i + 1; % Actuator Inputs
    -io(io_i) = linio([mdl, '/Controller/Reference-Tracking-L/Sum'], 1, 'openoutput'); io_i = io_i + 1; % Leg length error
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller'],                          1, 'openinput');  io_i = io_i + 1; % Actuator Inputs
    +  io(io_i) = linio([mdl, '/Controller/Reference-Tracking-L/Sum'], 1, 'openoutput'); io_i = io_i + 1; % Leg length error
     
    -%% Run the linearization
    -G = linearize(mdl, io, 0);
    -G.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    -G.OutputName = {'El1', 'El2', 'El3', 'El4', 'El5', 'El6'};
    +  %% Run the linearization
    +  G = linearize(mdl, io, 0);
    +  G.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    +  G.OutputName = {'El1', 'El2', 'El3', 'El4', 'El5', 'El6'};
     
    -
    -

    1.4 Plant Analysis

    +
    +

    1.4 Plant Analysis

    -The diagonal and off-diagonal terms of the plant are shown in Figure 2. +The diagonal and off-diagonal terms of the plant are shown in Figure 2.

    @@ -207,7 +211,7 @@ We can see that: -

    +

    decentralized_control_plant_L.png

    Figure 2: Transfer Functions from forces applied in each actuator \(\tau_i\) to the relative motion of each leg \(d\mathcal{L}_i\) (png, pdf)

    @@ -215,8 +219,8 @@ We can see that:
    -
    -

    1.5 Controller Design

    +
    +

    1.5 Controller Design

    The controller consists of: @@ -229,24 +233,24 @@ The controller consists of:

    -The obtained loop gains corresponding to the diagonal elements are shown in Figure 3. +The obtained loop gains corresponding to the diagonal elements are shown in Figure 3.

    -
    wc = 2*pi*20;
    -h = 1.5;
    +
      wc = 2*pi*20;
    +  h = 1.5;
     
    -Kl = diag(1./diag(abs(freqresp(G, wc)))) * ...
    -     wc/s * ... % Pure Integrator
    -     ((s/wc*2 + 1)/(s/wc*2)) * ... % Integrator up to wc/2
    -     1/h * (1 + s/wc*h)/(1 + s/wc/h) * ... % Lead
    -     1/(1 + s/3/wc) * ... % Low pass Filter
    -     1/(1 + s/3/wc);
    +  Kl = diag(1./diag(abs(freqresp(G, wc)))) * ...
    +       wc/s * ... % Pure Integrator
    +       ((s/wc*2 + 1)/(s/wc*2)) * ... % Integrator up to wc/2
    +       1/h * (1 + s/wc*h)/(1 + s/wc/h) * ... % Lead
    +       1/(1 + s/3/wc) * ... % Low pass Filter
    +       1/(1 + s/3/wc);
     
    -
    +

    decentralized_control_L_loop_gain.png

    Figure 3: Obtained Loop Gain (png, pdf)

    @@ -256,54 +260,54 @@ Kl = diag(1./diag(abs(freqresp(G, wc))))
    -
    Kl = -Kl;
    +
      Kl = -Kl;
     
    -
    -

    1.6 Simulation

    +
    +

    1.6 Simulation

    -
    initializeController('type', 'ref-track-L');
    +
      initializeController('type', 'ref-track-L');
     
    -
    load('mat/conf_simulink.mat');
    -set_param(conf_simulink, 'StopTime', '2');
    +
      load('mat/conf_simulink.mat');
    +  set_param(conf_simulink, 'StopTime', '2');
     
    -
    sim('nass_model');
    +
      sim('nass_model');
     
    -
    decentralized_L = simout;
    -save('./mat/tomo_exp_decentalized.mat', 'decentralized_L', '-append');
    +
      decentralized_L = simout;
    +  save('./mat/tomo_exp_decentalized.mat', 'decentralized_L', '-append');
     
    -
    -

    1.7 Results

    +
    +

    1.7 Results

    -The reference path and the position of the mobile platform are shown in Figure 4. +The reference path and the position of the mobile platform are shown in Figure 4.

    -
    load('./mat/experiment_tomography.mat', 'tomo_align_dist');
    -load('./mat/tomo_exp_decentalized.mat', 'decentralized_L');
    +
      load('./mat/experiment_tomography.mat', 'tomo_align_dist');
    +  load('./mat/tomo_exp_decentalized.mat', 'decentralized_L');
     
    -
    +

    decentralized_L_position_errors.png

    Figure 4: Position Errors when using the Decentralized Control Architecture (png, pdf)

    @@ -312,19 +316,19 @@ load('./mat/tomo_exp_decentalized.mat',
    -
    -

    2 HAC-LAC (IFF) Decentralized Control

    +
    +

    2 HAC-LAC (IFF) Decentralized Control

    We here add an Active Damping Loop (Integral Force Feedback) prior to using the Decentralized control architecture using \(\bm{\mathcal{L}}\).

    -
    -

    2.1 Control Schematic

    +
    +

    2.1 Control Schematic

    -The control architecture is shown in Figure 1. +The control architecture is shown in Figure 1.

    @@ -340,7 +344,7 @@ The signals are: -

    +

    decentralized_reference_tracking_L.png

    Figure 5: Decentralized control for reference tracking

    @@ -348,21 +352,21 @@ The signals are:
    -
    -

    2.2 Initialize the Simscape Model

    +
    +

    2.2 Initialize the Simscape Model

    We initialize all the stages with the default parameters.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
     
    @@ -370,8 +374,8 @@ initializeMirror(); The nano-hexapod is a piezoelectric hexapod and the sample has a mass of 50kg.

    -
    initializeNanoHexapod('actuator', 'piezo');
    -initializeSample('mass', 1);
    +
      initializeNanoHexapod('actuator', 'piezo');
    +  initializeSample('mass', 1);
     
    @@ -379,12 +383,12 @@ initializeSample('mass', 1); We set the references that corresponds to a tomography experiment.

    -
    initializeReferences('Rz_type', 'rotating', 'Rz_period', 1);
    +
      initializeReferences('Rz_type', 'rotating', 'Rz_period', 1);
     
    -
    initializeDisturbances();
    +
      initializeDisturbances();
     
    @@ -392,8 +396,8 @@ We set the references that corresponds to a tomography experiment. Open Loop.

    -
    initializeController('type', 'ref-track-L');
    -Kl = tf(zeros(6));
    +
      initializeController('type', 'ref-track-L');
    +  Kl = tf(zeros(6));
     
    @@ -401,7 +405,7 @@ Kl = tf(zeros(6)); And we put some gravity.

    -
    initializeSimscapeConfiguration('gravity', true);
    +
      initializeSimscapeConfiguration('gravity', true);
     
    @@ -409,149 +413,149 @@ And we put some gravity. We log the signals.

    -
    initializeLoggingConfiguration('log', 'all');
    +
      initializeLoggingConfiguration('log', 'all');
     
    -
    -

    2.3 Initialization

    +
    +

    2.3 Initialization

    -
    initializeController('type', 'ref-track-iff-L');
    -K_iff = tf(zeros(6));
    -Kl = tf(zeros(6));
    +
      initializeController('type', 'ref-track-iff-L');
    +  K_iff = tf(zeros(6));
    +  Kl = tf(zeros(6));
     
    -
    -

    2.4 Identification for IFF

    +
    +

    2.4 Identification for IFF

    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller'],                              1, 'openinput');  io_i = io_i + 1; % Actuator Inputs
    -io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm');  io_i = io_i + 1; % Force Sensors
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller'],                              1, 'openinput');  io_i = io_i + 1; % Actuator Inputs
    +  io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm');  io_i = io_i + 1; % Force Sensors
     
    -%% Run the linearization
    -G_iff = linearize(mdl, io, 0);
    -G_iff.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    -G_iff.OutputName = {'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'};
    +  %% Run the linearization
    +  G_iff = linearize(mdl, io, 0);
    +  G_iff.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    +  G_iff.OutputName = {'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'};
     
    -
    -

    2.5 Integral Force Feedback Controller

    +
    +

    2.5 Integral Force Feedback Controller

    -
    w0 = 2*pi*50;
    -K_iff = -5000/s * (s/w0)/(1 + s/w0) * eye(6);
    +
      w0 = 2*pi*50;
    +  K_iff = -5000/s * (s/w0)/(1 + s/w0) * eye(6);
     
    -
    K_iff = -K_iff;
    +
      K_iff = -K_iff;
     
    -
    -

    2.6 Identification of the damped plant

    +
    +

    2.6 Identification of the damped plant

    -
    %% Name of the Simulink  DehaezeFile
    -mdl = 'nass_model';
    +
      %% Name of the Simulink  DehaezeFile
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller'],                              1, 'input');  io_i = io_i + 1; % Actuator Inputs
    -io(io_i) = linio([mdl, '/Controller/Reference-Tracking-IFF-L/Sum'], 1, 'openoutput'); io_i = io_i + 1; % Leg length error
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller'],                              1, 'input');  io_i = io_i + 1; % Actuator Inputs
    +  io(io_i) = linio([mdl, '/Controller/Reference-Tracking-IFF-L/Sum'], 1, 'openoutput'); io_i = io_i + 1; % Leg length error
     
    -%% Run the linearization
    -Gd = linearize(mdl, io, 0);
    -Gd.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    -Gd.OutputName = {'El1', 'El2', 'El3', 'El4', 'El5', 'El6'};
    +  %% Run the linearization
    +  Gd = linearize(mdl, io, 0);
    +  Gd.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    +  Gd.OutputName = {'El1', 'El2', 'El3', 'El4', 'El5', 'El6'};
     
    -
    -

    2.7 Controller Design

    +
    +

    2.7 Controller Design

    -
    wc = 2*pi*300;
    -h = 3;
    +
      wc = 2*pi*300;
    +  h = 3;
     
    -Kl = diag(1./diag(abs(freqresp(Gd, wc)))) * ...
    -     ((s/(2*pi*20) + 1)/(s/(2*pi*20))) * ... % Pure Integrator
    -     ((s/(2*pi*50) + 1)/(s/(2*pi*50))) * ... % Integrator up to wc/2
    -     1/h * (1 + s/wc*h)/(1 + s/wc/h) * ...
    -     1/(1 + s/(2*wc)) * ...
    -     1/(1 + s/(3*wc));
    +  Kl = diag(1./diag(abs(freqresp(Gd, wc)))) * ...
    +       ((s/(2*pi*20) + 1)/(s/(2*pi*20))) * ... % Pure Integrator
    +       ((s/(2*pi*50) + 1)/(s/(2*pi*50))) * ... % Integrator up to wc/2
    +       1/h * (1 + s/wc*h)/(1 + s/wc/h) * ...
    +       1/(1 + s/(2*wc)) * ...
    +       1/(1 + s/(3*wc));
     
    -
    isstable(feedback(Gd*Kl, eye(6), -1))
    +
      isstable(feedback(Gd*Kl, eye(6), -1))
     
    -
    Kl = -Kl;
    +
      Kl = -Kl;
     
    -
    -

    2.8 Simulation

    +
    +

    2.8 Simulation

    -
    initializeController('type', 'ref-track-iff-L');
    +
      initializeController('type', 'ref-track-iff-L');
     
    -
    load('mat/conf_simulink.mat');
    -set_param(conf_simulink, 'StopTime', '2');
    +
      load('mat/conf_simulink.mat');
    +  set_param(conf_simulink, 'StopTime', '2');
     
    -
    sim('nass_model');
    +
      sim('nass_model');
     
    -
    decentralized_iff_L = simout;
    -save('./mat/tomo_exp_decentalized.mat', 'decentralized_iff_L', '-append');
    +
      decentralized_iff_L = simout;
    +  save('./mat/tomo_exp_decentalized.mat', 'decentralized_iff_L', '-append');
     
    -
    -

    2.9 Results

    +
    +

    2.9 Results

    -
    -

    3 Conclusion

    +
    +

    3 Conclusion

    Author: Dehaeze Thomas

    -

    Created: 2020-04-17 ven. 09:35

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/control_force.html b/docs/control_force.html index a6a93a7..427f60b 100644 --- a/docs/control_force.html +++ b/docs/control_force.html @@ -1,34 +1,38 @@ - - + Force Control applied on the Simscape Model - - - - - - - - + + + +

    Force Control applied on the Simscape Model

    @@ -47,20 +51,20 @@ Ideas: -

    +

    control_cascade_force_F.png

    -
    +

    control_cascade_force_tau.png

    Author: Dehaeze Thomas

    -

    Created: 2020-04-17 ven. 09:35

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/control_hac_lac.html b/docs/control_hac_lac.html index 73fe899..af92dbc 100644 --- a/docs/control_hac_lac.html +++ b/docs/control_hac_lac.html @@ -1,58 +1,62 @@ - - + HAC-LAC applied on the Simscape Model - - - - - - - - + + + +

    HAC-LAC applied on the Simscape Model

    @@ -66,27 +70,27 @@ It is then compare to the wanted position of the Sample \(\bm{r}_\mathcal{X}\) i

    -
    +

    hac_lac_control_schematic.png

    Figure 1: HAC-LAC Control Architecture used for the Control of the NASS

    -
    -

    1 Initialization

    +
    +

    1 Initialization

    We initialize all the stages with the default parameters.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
     
    @@ -94,8 +98,8 @@ initializeMirror(); The nano-hexapod is a piezoelectric hexapod and the sample has a mass of 50kg.

    -
    initializeNanoHexapod('actuator', 'piezo');
    -initializeSample('mass', 1);
    +
      initializeNanoHexapod('actuator', 'piezo');
    +  initializeSample('mass', 1);
     
    @@ -103,12 +107,12 @@ initializeSample('mass', 1); We set the references that corresponds to a tomography experiment.

    -
    initializeReferences('Rz_type', 'rotating', 'Rz_period', 1);
    +
      initializeReferences('Rz_type', 'rotating', 'Rz_period', 1);
     
    -
    initializeDisturbances();
    +
      initializeDisturbances();
     
    @@ -116,7 +120,7 @@ We set the references that corresponds to a tomography experiment. Open Loop.

    -
    initializeController('type', 'open-loop');
    +
      initializeController('type', 'open-loop');
     
    @@ -124,7 +128,7 @@ Open Loop. And we put some gravity.

    -
    initializeSimscapeConfiguration('gravity', true);
    +
      initializeSimscapeConfiguration('gravity', true);
     
    @@ -132,14 +136,14 @@ And we put some gravity. We log the signals.

    -
    initializeLoggingConfiguration('log', 'all');
    +
      initializeLoggingConfiguration('log', 'all');
     
    -
    -

    2 Low Authority Control - Direct Velocity Feedback \(\bm{K}_\mathcal{L}\)

    +
    +

    2 Low Authority Control - Direct Velocity Feedback \(\bm{K}_\mathcal{L}\)

    The first loop closed corresponds to a direct velocity feedback loop. @@ -150,106 +154,106 @@ The design of the associated decentralized controller is explained in -

    2.1 Identification

    +
    +

    2.1 Identification

    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller'],    1, 'openinput');               io_i = io_i + 1; % Actuator Inputs
    -io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Dnlm');  io_i = io_i + 1; % Relative Motion Outputs
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller'],    1, 'openinput');               io_i = io_i + 1; % Actuator Inputs
    +  io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Dnlm');  io_i = io_i + 1; % Relative Motion Outputs
     
    -%% Run the linearization
    -G_dvf = linearize(mdl, io, 0);
    -G_dvf.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    -G_dvf.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'};
    +  %% Run the linearization
    +  G_dvf = linearize(mdl, io, 0);
    +  G_dvf.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    +  G_dvf.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'};
     
    -
    -

    2.2 Plant

    +
    +

    2.2 Plant

    -
    -

    2.3 Root Locus

    +
    +

    2.3 Root Locus

    -
    -

    2.4 Controller and Loop Gain

    +
    +

    2.4 Controller and Loop Gain

    -
    K_dvf = s*15000/(1 + s/2/pi/10000);
    +
      K_dvf = s*15000/(1 + s/2/pi/10000);
     
    -
    K_dvf = -K_dvf*eye(6);
    +
      K_dvf = -K_dvf*eye(6);
     
    -
    -

    3 Uncertainty Improvements thanks to the LAC control

    +
    +

    3 Uncertainty Improvements thanks to the LAC control

    -
    K_dvf_backup = K_dvf;
    -initializeController('type', 'hac-dvf');
    +
      K_dvf_backup = K_dvf;
    +  initializeController('type', 'hac-dvf');
     
    -
    masses = [1, 10, 50]; % [kg]
    +
      masses = [1, 10, 50]; % [kg]
     
    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller'],     1, 'input');            io_i = io_i + 1; % Actuator Inputs
    -io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1; % Position Errror
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller'],     1, 'input');            io_i = io_i + 1; % Actuator Inputs
    +  io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1; % Position Errror
     
    -
    -

    4 High Authority Control - \(\bm{K}_\mathcal{X}\)

    +
    +

    4 High Authority Control - \(\bm{K}_\mathcal{X}\)

    -
    -

    4.1 Identification of the damped plant

    +
    +

    4.1 Identification of the damped plant

    -
    Kx = tf(zeros(6));
    +
      Kx = tf(zeros(6));
     
    -
    initializeController('type', 'hac-dvf');
    +
      initializeController('type', 'hac-dvf');
     
    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller'],     1, 'input');            io_i = io_i + 1; % Actuator Inputs
    -io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1; % Position Errror
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller'],     1, 'input');            io_i = io_i + 1; % Actuator Inputs
    +  io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1; % Position Errror
     
    -%% Run the linearization
    -G = linearize(mdl, io, 0);
    -G.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    -G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
    +  %% Run the linearization
    +  G = linearize(mdl, io, 0);
    +  G.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    +  G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
     
    @@ -257,17 +261,17 @@ G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'}; The minus sine is put here because there is already a minus sign included due to the computation of the position error.

    -
    load('mat/stages.mat', 'nano_hexapod');
    +
      load('mat/stages.mat', 'nano_hexapod');
     
    -Gx = -G*inv(nano_hexapod.kinematics.J');
    -Gx.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    +  Gx = -G*inv(nano_hexapod.kinematics.J');
    +  Gx.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
     
    -
    -

    4.2 Controller Design

    +
    +

    4.2 Controller Design

    The controller consists of: @@ -280,41 +284,41 @@ The controller consists of:

    -
    wc = 2*pi*15; % Bandwidth Bandwidth [rad/s]
    +
      wc = 2*pi*15; % Bandwidth Bandwidth [rad/s]
     
    -h = 1.5; % Lead parameter
    +  h = 1.5; % 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/2));
    +  Kx = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * wc/s * ((s/wc*2 + 1)/(s/wc*2)) * (1/(1 + s/wc/2));
     
    -% 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))));
     
    -
    isstable(feedback(Gx*Kx, eye(6), -1))
    +
      isstable(feedback(Gx*Kx, eye(6), -1))
     
    -
    Kx = inv(nano_hexapod.kinematics.J')*Kx;
    +
      Kx = inv(nano_hexapod.kinematics.J')*Kx;
     
    -
    isstable(feedback(G*Kx, eye(6), 1))
    +
      isstable(feedback(G*Kx, eye(6), 1))
     
    -
    -

    5 Simulation

    +
    +

    5 Simulation

    -
    load('mat/conf_simulink.mat');
    -set_param(conf_simulink, 'StopTime', '2');
    +
      load('mat/conf_simulink.mat');
    +  set_param(conf_simulink, 'StopTime', '2');
     
    @@ -322,27 +326,27 @@ set_param(conf_simulink, 'StopTime', '2'); And we simulate the system.

    -
    sim('nass_model');
    +
      sim('nass_model');
     
    -
    hac_dvf = simout;
    -save('./mat/tomo_exp_hac_lac.mat', 'hac_dvf');
    +
      hac_dvf = simout;
    +  save('./mat/tomo_exp_hac_lac.mat', 'hac_dvf');
     
    -
    -

    6 Results

    +
    +

    6 Results

    Let’s load the simulation when no control is applied.

    -
    load('./mat/experiment_tomography.mat', 'tomo_align_dist');
    -load('./mat/tomo_exp_hac_lac.mat', 'hac_dvf');
    +
      load('./mat/experiment_tomography.mat', 'tomo_align_dist');
    +  load('./mat/tomo_exp_hac_lac.mat', 'hac_dvf');
     
    @@ -350,7 +354,7 @@ load('./mat/tomo_exp_hac_lac.mat', 'hac_dvf');

    Author: Dehaeze Thomas

    -

    Created: 2020-05-05 mar. 10:34

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/control_requirements.html b/docs/control_requirements.html index 291d659..1d17cf9 100644 --- a/docs/control_requirements.html +++ b/docs/control_requirements.html @@ -1,85 +1,89 @@ - - + Control Requirements - - - - - - - - + + + +

    Control Requirements

    Table of Contents

    @@ -98,29 +102,29 @@ This can then be used for the control synthesis and for the design of the nano-h Ideal, specifications on the norm of closed loop transfer function should be written.

    -
    -

    1 Simplify Model for the Nano-Hexapod

    +
    +

    1 Simplify Model for the Nano-Hexapod

    -
    -

    1.1 Model of the nano-hexapod

    +
    +

    1.1 Model of the nano-hexapod

    -Let’s consider the simple mechanical system in Figure 1. +Let’s consider the simple mechanical system in Figure 1.

    -
    +

    nass_simple_model.png

    Figure 1: Simplified mechanical system for the nano-hexapod

    -The signals are described in table 1. +The signals are described in table 1.

    -
    Table 1: Conclusion on the variability of the system dynamics for active damping
    +
    @@ -222,11 +226,11 @@ This means that the nano-hexapod can be considered separately from the micro-sta

    -The nano-hexapod can thus be represented as in Figure 2. +The nano-hexapod can thus be represented as in Figure 2.

    -
    +

    nano_station_inputs_outputs.png

    Figure 2: Block representation of the nano-hexapod

    @@ -234,8 +238,8 @@ The nano-hexapod can thus be represented as in Figure 2
    -
    -

    1.2 How to include Ground Motion in the model?

    +
    +

    1.2 How to include Ground Motion in the model?

    What we measure is not the absolute motion \(x\), but the relative motion \(x - w\) where \(w\) is the motion of the granite. @@ -247,8 +251,8 @@ Also, \(w\) induces some motion \(x_\mu\) through the transmissibility of the mi

    -
    -

    1.3 Motion of the micro-station

    +
    +

    1.3 Motion of the micro-station

    As explained, we consider \(x_\mu\) as an external input (\(F\) has no influence on \(x_\mu\)). @@ -286,11 +290,11 @@ Also, here, we suppose that the granite is not moving.

    -If we now include the motion of the granite \(w\), we obtain the block diagram shown in Figure 3. +If we now include the motion of the granite \(w\), we obtain the block diagram shown in Figure 3.

    -
    +

    nano_station_ground_motion.png

    Figure 3: Ground Motion \(w\) included

    @@ -305,29 +309,29 @@ We can approximate this transfer function by a second order low pass filter:
    -
    -

    2 Control with the Stiff Nano-Hexapod

    +
    +

    2 Control with the Stiff Nano-Hexapod

    -
    -

    2.1 Definition of the values

    +
    +

    2.1 Definition of the values

    Let’s define the mass and stiffness of the nano-hexapod.

    -
    m = 50; % [kg]
    -k = 1e7; % [N/m]
    +
      m = 50; % [kg]
    +  k = 1e7; % [N/m]
     

    -Let’s define the Plant as shown in Figure 2: +Let’s define the Plant as shown in Figure 2:

    -
    Gn = 1/(m*s^2 + k)*[-k, k*m*s^2, m*s^2; 1, -m*s^2, 1; 1, k, 1];
    -Gn.InputName  = {'Fd', 'xmu', 'F'};
    -Gn.OutputName = {'Fm', 'd', 'x'};
    +
      Gn = 1/(m*s^2 + k)*[-k, k*m*s^2, m*s^2; 1, -m*s^2, 1; 1, k, 1];
    +  Gn.InputName  = {'Fd', 'xmu', 'F'};
    +  Gn.OutputName = {'Fm', 'd', 'x'};
     
    @@ -335,20 +339,20 @@ Gn.OutputName = {'Fm', Now, define the transmissibility transfer function \(T_\mu\) corresponding to the micro-station motion.

    -
    wmu = 2*pi*50; % [rad/s]
    +
      wmu = 2*pi*50; % [rad/s]
     
    -Tmu = 1/(1 + s/wmu);
    -Tmu.InputName = {'r1'};
    -Tmu.OutputName = {'ymu'};
    +  Tmu = 1/(1 + s/wmu);
    +  Tmu.InputName = {'r1'};
    +  Tmu.OutputName = {'ymu'};
     
    -
    w0 = 2*pi*40;
    -xi = 0.5;
    -Tw = 1/(1 + 2*xi*s/w0 + s^2/w0^2);
    -Tw.InputName = {'w1'};
    -Tw.OutputName = {'dw'};
    +
      w0 = 2*pi*40;
    +  xi = 0.5;
    +  Tw = 1/(1 + 2*xi*s/w0 + s^2/w0^2);
    +  Tw.InputName = {'w1'};
    +  Tw.OutputName = {'dw'};
     
    @@ -356,33 +360,33 @@ Tw.OutputName = {'dw'}; We add the fact that \(x_\mu = d_\mu + T_\mu r + T_w w\):

    -
    Wsplit = [tf(1); tf(1)];
    -Wsplit.InputName = {'w'};
    -Wsplit.OutputName = {'w1', 'w2'};
    +
      Wsplit = [tf(1); tf(1)];
    +  Wsplit.InputName = {'w'};
    +  Wsplit.OutputName = {'w1', 'w2'};
     
    -S = sumblk('xmu = ymu + dmu + dw');
    +  S = sumblk('xmu = ymu + dmu + dw');
     
    -Sw = sumblk('y = x - w2');
    +  Sw = sumblk('y = x - w2');
     
    -Gpz = connect(Gn, S, Wsplit, Tw, Tmu, Sw, {'Fd', 'dmu', 'r1', 'F', 'w'}, {'Fm', 'd', 'y'});
    +  Gpz = connect(Gn, S, Wsplit, Tw, Tmu, Sw, {'Fd', 'dmu', 'r1', 'F', 'w'}, {'Fm', 'd', 'y'});
     
    -
    -

    2.2 Control using \(d\)

    +
    +

    2.2 Control using \(d\)

    -
    -

    2.2.1 Control Architecture

    +
    +

    2.2.1 Control Architecture

    -Let’s consider a feedback loop using \(d\) as shown in Figure 4. +Let’s consider a feedback loop using \(d\) as shown in Figure 4.

    -
    +

    nano_station_control_d.png

    Figure 4: Feedback diagram using \(d\)

    @@ -390,8 +394,8 @@ Let’s consider a feedback loop using \(d\) as shown in Figure -

    2.2.2 Analytical Analysis

    +
    +

    2.2.2 Analytical Analysis

    Let’s apply a direct velocity feedback by deriving \(d\): @@ -423,11 +427,11 @@ And we finally obtain:

    -
    K_dvf = 2*sqrt(k*m)*s;
    -K_dvf.InputName = {'d'};
    -K_dvf.OutputName = {'F'};
    +
      K_dvf = 2*sqrt(k*m)*s;
    +  K_dvf.InputName = {'d'};
    +  K_dvf.OutputName = {'F'};
     
    -Gpz_dvf = feedback(Gpz, K_dvf, 'name');
    +  Gpz_dvf = feedback(Gpz, K_dvf, 'name');
     
    @@ -444,7 +448,7 @@ And \(\epsilon = r - x\): \[ \epsilon = \frac{1}{ms^2 + gs + k} F^\prime + \frac{1}{ms^2 + gs + k} F_d + \frac{gs + k}{ms^2 + gs + k} d_\mu + \frac{ms^2 + gs + k - T_\mu (gs + k)}{ms^2 + gs + k} r \]

    -
    +

    \[ \epsilon = \frac{1}{ms^2 + gs + k} F^\prime + \frac{1}{ms^2 + gs + k} F_d + \frac{gs + k}{ms^2 + gs + k} d_\mu + \frac{ms^2 - S_\mu(gs + k)}{ms^2 + gs + k} r \]

    @@ -454,19 +458,19 @@ And \(\epsilon = r - x\):
    -
    -

    2.3 Control using \(F_m\)

    +
    +

    2.3 Control using \(F_m\)

    -
    -

    2.3.1 Control Architecture

    +
    +

    2.3.1 Control Architecture

    -Let’s consider a feedback loop using \(Fm\) as shown in Figure 5. +Let’s consider a feedback loop using \(Fm\) as shown in Figure 5.

    -
    +

    nano_station_control_Fm.png

    Figure 5: Feedback diagram using \(F_m\)

    @@ -474,8 +478,8 @@ Let’s consider a feedback loop using \(Fm\) as shown in Figure -

    2.3.2 Pure Integrator

    +
    +

    2.3.2 Pure Integrator

    Let’s apply integral force feedback by integration \(F_m\): @@ -488,11 +492,11 @@ And we finally obtain:

    -
    K_iff = 2*sqrt(k/m)/s;
    -K_iff.InputName = {'Fm'};
    -K_iff.OutputName = {'F'};
    +
      K_iff = 2*sqrt(k/m)/s;
    +  K_iff.InputName = {'Fm'};
    +  K_iff.OutputName = {'F'};
     
    -Gpz_iff = feedback(Gpz, K_iff, 'name');
    +  Gpz_iff = feedback(Gpz, K_iff, 'name');
     
    @@ -509,7 +513,7 @@ And \(\epsilon = r - x\): \[ \epsilon = \frac{1}{ms^2 + mgs + k} F^\prime + \frac{1 + \frac{g}{s}}{ms^2 + mgs + k} F_d + \frac{k}{ms^2 + mgs + k} d_\mu + \frac{ms^2 + mgs + k - T_\mu k}{ms^2 + mgs + k} r \]

    -
    +

    \[ \epsilon = \frac{1}{ms^2 + mgs + k} F^\prime + \frac{1 + \frac{g}{s}}{ms^2 + mgs + k} F_d + \frac{k}{ms^2 + mgs + k} d_\mu + \frac{ms^2 + mgs + S_\mu k}{ms^2 + mgs + k} r \]

    @@ -518,29 +522,29 @@ And \(\epsilon = r - x\):
    -
    -

    2.3.3 Low pass filter

    +
    +

    2.3.3 Low pass filter

    Instead of a pure integrator, let’s use a low pass filter with a cut-off frequency above the bandwidth of the micro-station \(\omega_mu\)

    -
    % K_iff = (2*sqrt(k/m)/(2*wmu))*(1/(1 + s/(2*wmu)));
    -% K_iff.InputName = {'Fm'};
    -% K_iff.OutputName = {'F'};
    +
      % K_iff = (2*sqrt(k/m)/(2*wmu))*(1/(1 + s/(2*wmu)));
    +  % K_iff.InputName = {'Fm'};
    +  % K_iff.OutputName = {'F'};
     
    -% Gpz_iff = feedback(Gpz, K_iff, 'name');
    +  % Gpz_iff = feedback(Gpz, K_iff, 'name');
     
    -
    -

    2.4 Comparison

    +
    +

    2.4 Comparison

    -
    +

    comp_iff_dvf_simplified.png

    Figure 6: Obtained transfer functions for DVF and IFF (png, pdf)

    @@ -585,19 +589,19 @@ Instead of a pure integrator, let’s use a low pass filter with a cut-off f
    -
    -

    2.5 Control using \(x\)

    +
    +

    2.5 Control using \(x\)

    -
    -

    2.5.1 Analytical analysis

    +
    +

    2.5.1 Analytical analysis

    -Let’s first consider that only the output \(x\) is used for feedback (Figure 7) +Let’s first consider that only the output \(x\) is used for feedback (Figure 7)

    -
    +

    nano_station_control_x.png

    Figure 7: Feedback diagram using \(x\)

    @@ -611,7 +615,7 @@ We then have:

    And then:

    -
    +

    \[ \epsilon = \frac{-G_{\frac{x}{F_d}}}{1 + G_{\frac{x}{F}}K} F_d + \frac{-G_{\frac{x}{x_\mu}}}{1 + G_{\frac{x}{F}}K} d_\mu + \frac{1 - G_{\frac{x}{x_\mu}} T_\mu}{1 + G_{\frac{x}{F}}K} r \]

    @@ -650,10 +654,10 @@ In our case, we have \(\omega_\nu > \omega_\mu\) and thus we cannot lower this t

    -Some implications on the design are summarized on table 2. +Some implications on the design are summarized on table 2.

    -
    Table 1: Signals definition for the generalized plant
    +
    @@ -687,30 +691,30 @@ Some implications on the design are summarized on table 2< -
    -

    2.5.2 Control implementation

    +
    +

    2.5.2 Control implementation

    Controller for the damped plant using DVF.

    -
    wb = 2*pi*50; % control bandwidth [rad/s]
    +
      wb = 2*pi*50; % control bandwidth [rad/s]
     
    -% Lead
    -h = 2.0;
    -wz = wb/h; % [rad/s]
    -wp = wb*h; % [rad/s]
    +  % Lead
    +  h = 2.0;
    +  wz = wb/h; % [rad/s]
    +  wp = wb*h; % [rad/s]
     
    -H = 1/h*(1 + s/wz)/(1 + s/wp);
    +  H = 1/h*(1 + s/wz)/(1 + s/wp);
     
    -% Integrator until 10Hz
    -Hi = (1 + s/2/pi/10)/(s/2/pi/10);
    +  % Integrator until 10Hz
    +  Hi = (1 + s/2/pi/10)/(s/2/pi/10);
     
    -K = Hi*H*(1/s);
    +  K = Hi*H*(1/s);
     
    -Kpz_dvf = K/abs(freqresp(K*Gpz_dvf('y', 'F'), wb));
    -Kpz_dvf.InputName = {'e'};
    -Kpz_dvf.OutputName = {'Fi'};
    +  Kpz_dvf = K/abs(freqresp(K*Gpz_dvf('y', 'F'), wb));
    +  Kpz_dvf.InputName = {'e'};
    +  Kpz_dvf.OutputName = {'Fi'};
     
    @@ -718,23 +722,23 @@ Kpz_dvf.OutputName = {'Fi'}; Controller for the damped plant using IFF.

    -
    wb = 2*pi*50; % control bandwidth [rad/s]
    +
      wb = 2*pi*50; % control bandwidth [rad/s]
     
    -% Lead
    -h = 2.0;
    -wz = wb/h; % [rad/s]
    -wp = wb*h; % [rad/s]
    +  % Lead
    +  h = 2.0;
    +  wz = wb/h; % [rad/s]
    +  wp = wb*h; % [rad/s]
     
    -H = 1/h*(1 + s/wz)/(1 + s/wp);
    +  H = 1/h*(1 + s/wz)/(1 + s/wp);
     
    -% Integrator until 10Hz
    -Hi = (1 + s/2/pi/10)/(s/2/pi/10);
    +  % Integrator until 10Hz
    +  Hi = (1 + s/2/pi/10)/(s/2/pi/10);
     
    -K = Hi*H*(1/s);
    +  K = Hi*H*(1/s);
     
    -Kpz_iff = K/abs(freqresp(K*Gpz_iff('y', 'F'), wb));
    -Kpz_iff.InputName = {'e'};
    -Kpz_iff.OutputName = {'Fi'};
    +  Kpz_iff = K/abs(freqresp(K*Gpz_iff('y', 'F'), wb));
    +  Kpz_iff.InputName = {'e'};
    +  Kpz_iff.OutputName = {'Fi'};
     
    @@ -742,7 +746,7 @@ Kpz_iff.OutputName = {'Fi'}; Loop gain

    -
    +

    simple_loop_gain_pz.png

    Figure 8: Loop Gain (png, pdf)

    @@ -750,31 +754,31 @@ Loop gain

    -Let’s connect all the systems as shown in Figure 7. +Let’s connect all the systems as shown in Figure 7.

    -
    Sfb = sumblk('e = r2 - y');
    +
      Sfb = sumblk('e = r2 - y');
     
    -R = [tf(1); tf(1)];
    -R.InputName = {'r'};
    -R.OutputName = {'r1', 'r2'};
    +  R = [tf(1); tf(1)];
    +  R.InputName = {'r'};
    +  R.OutputName = {'r1', 'r2'};
     
    -F = [tf(1); tf(1)];
    -F.InputName = {'Fi'};
    -F.OutputName = {'F', 'Fu'};
    +  F = [tf(1); tf(1)];
    +  F.InputName = {'Fi'};
    +  F.OutputName = {'F', 'Fu'};
     
    -Gpz_fb_dvf = connect(Gpz_dvf, Kpz_dvf, R, Sfb, F, {'r', 'dmu', 'Fd', 'w'}, {'y', 'e', 'Fm', 'd', 'Fu'});
    -Gpz_fb_iff = connect(Gpz_iff, Kpz_iff, R, Sfb, F, {'r', 'dmu', 'Fd', 'w'}, {'y', 'e', 'Fm', 'd', 'Fu'});
    +  Gpz_fb_dvf = connect(Gpz_dvf, Kpz_dvf, R, Sfb, F, {'r', 'dmu', 'Fd', 'w'}, {'y', 'e', 'Fm', 'd', 'Fu'});
    +  Gpz_fb_iff = connect(Gpz_iff, Kpz_iff, R, Sfb, F, {'r', 'dmu', 'Fd', 'w'}, {'y', 'e', 'Fm', 'd', 'Fu'});
     
    -
    -

    2.5.3 Results

    +
    +

    2.5.3 Results

    -
    +

    simple_hac_lac_results.png

    Figure 9: Obtained closed-loop transfer functions (png, pdf)

    @@ -821,104 +825,104 @@ Gpz_fb_iff = connect(Gpz_iff, Kpz_iff, R, Sfb, F, {'r'<
    -
    -

    3 Comparison with the use of a Soft nano-hexapod

    +
    +

    3 Comparison with the use of a Soft nano-hexapod

    -
    m = 50; % [kg]
    -k = 1e3; % [N/m]
    +
      m = 50; % [kg]
    +  k = 1e3; % [N/m]
     
    -Gn = 1/(m*s^2 + k)*[-k, k*m*s^2, m*s^2; 1, -m*s^2, 1; 1, k, 1];
    -Gn.InputName  = {'Fd', 'xmu', 'F'};
    -Gn.OutputName = {'Fm', 'd', 'x'};
    +  Gn = 1/(m*s^2 + k)*[-k, k*m*s^2, m*s^2; 1, -m*s^2, 1; 1, k, 1];
    +  Gn.InputName  = {'Fd', 'xmu', 'F'};
    +  Gn.OutputName = {'Fm', 'd', 'x'};
     
    -
    wmu = 2*pi*50; % [rad/s]
    +
      wmu = 2*pi*50; % [rad/s]
     
    -Tmu = 1/(1 + s/wmu);
    -Tmu.InputName = {'r1'};
    -Tmu.OutputName = {'ymu'};
    +  Tmu = 1/(1 + s/wmu);
    +  Tmu.InputName = {'r1'};
    +  Tmu.OutputName = {'ymu'};
     
    -
    w0 = 2*pi*40;
    -xi = 0.5;
    -Tw = 1/(1 + 2*xi*s/w0 + s^2/w0^2);
    -Tw.InputName = {'w1'};
    -Tw.OutputName = {'dw'};
    +
      w0 = 2*pi*40;
    +  xi = 0.5;
    +  Tw = 1/(1 + 2*xi*s/w0 + s^2/w0^2);
    +  Tw.InputName = {'w1'};
    +  Tw.OutputName = {'dw'};
     
    -
    Wsplit = [tf(1); tf(1)];
    -Wsplit.InputName = {'w'};
    -Wsplit.OutputName = {'w1', 'w2'};
    +
      Wsplit = [tf(1); tf(1)];
    +  Wsplit.InputName = {'w'};
    +  Wsplit.OutputName = {'w1', 'w2'};
     
    -S = sumblk('xmu = ymu + dmu + dw');
    +  S = sumblk('xmu = ymu + dmu + dw');
     
    -Sw = sumblk('y = x - w2');
    +  Sw = sumblk('y = x - w2');
     
    -Gvc = connect(Gn, S, Wsplit, Tw, Tmu, Sw, {'Fd', 'dmu', 'r1', 'F', 'w'}, {'Fm', 'd', 'y'});
    +  Gvc = connect(Gn, S, Wsplit, Tw, Tmu, Sw, {'Fd', 'dmu', 'r1', 'F', 'w'}, {'Fm', 'd', 'y'});
     
    -
    Kvc_dvf = 2*sqrt(k*m)*s;
    -Kvc_dvf.InputName = {'d'};
    -Kvc_dvf.OutputName = {'F'};
    +
      Kvc_dvf = 2*sqrt(k*m)*s;
    +  Kvc_dvf.InputName = {'d'};
    +  Kvc_dvf.OutputName = {'F'};
     
    -Gvc_dvf = feedback(Gvc, Kvc_dvf, 'name');
    +  Gvc_dvf = feedback(Gvc, Kvc_dvf, 'name');
     
    -Kvc_iff = 2*sqrt(k/m)/s;
    -Kvc_iff.InputName = {'Fm'};
    -Kvc_iff.OutputName = {'F'};
    +  Kvc_iff = 2*sqrt(k/m)/s;
    +  Kvc_iff.InputName = {'Fm'};
    +  Kvc_iff.OutputName = {'F'};
     
    -Gvc_iff = feedback(Gvc, Kvc_iff, 'name');
    +  Gvc_iff = feedback(Gvc, Kvc_iff, 'name');
     
    -
    wb = 2*pi*100; % control bandwidth [rad/s]
    +
      wb = 2*pi*100; % control bandwidth [rad/s]
     
    -% Lead
    -h = 2.0;
    -wz = wb/h; % [rad/s]
    -wp = wb*h; % [rad/s]
    +  % Lead
    +  h = 2.0;
    +  wz = wb/h; % [rad/s]
    +  wp = wb*h; % [rad/s]
     
    -H = 1/h*(1 + s/wz)/(1 + s/wp);
    +  H = 1/h*(1 + s/wz)/(1 + s/wp);
     
    -Kvc_dvf = H/abs(freqresp(H*Gvc_dvf('y', 'F'), wb));
    -Kvc_dvf.InputName = {'e'};
    -Kvc_dvf.OutputName = {'Fi'};
    +  Kvc_dvf = H/abs(freqresp(H*Gvc_dvf('y', 'F'), wb));
    +  Kvc_dvf.InputName = {'e'};
    +  Kvc_dvf.OutputName = {'Fi'};
     
    -Kvc_iff = H/abs(freqresp(H*Gvc_iff('y', 'F'), wb));
    -Kvc_iff.InputName = {'e'};
    -Kvc_iff.OutputName = {'Fi'};
    +  Kvc_iff = H/abs(freqresp(H*Gvc_iff('y', 'F'), wb));
    +  Kvc_iff.InputName = {'e'};
    +  Kvc_iff.OutputName = {'Fi'};
     
    -
    Sfb = sumblk('e = r2 - y');
    +
      Sfb = sumblk('e = r2 - y');
     
    -R = [tf(1); tf(1)];
    -R.InputName = {'r'};
    -R.OutputName = {'r1', 'r2'};
    +  R = [tf(1); tf(1)];
    +  R.InputName = {'r'};
    +  R.OutputName = {'r1', 'r2'};
     
    -F = [tf(1); tf(1)];
    -F.InputName = {'Fi'};
    -F.OutputName = {'F', 'Fu'};
    +  F = [tf(1); tf(1)];
    +  F.InputName = {'Fi'};
    +  F.OutputName = {'F', 'Fu'};
     
     
    -Gvc_fb_dvf = connect(Gvc_dvf, Kvc_dvf, R, Sfb, F, {'r', 'dmu', 'Fd', 'w'}, {'y', 'e', 'Fm', 'd', 'Fu'});
    -Gvc_fb_iff = connect(Gvc_iff, Kvc_iff, R, Sfb, F, {'r', 'dmu', 'Fd', 'w'}, {'y', 'e', 'Fm', 'd', 'Fu'});
    +  Gvc_fb_dvf = connect(Gvc_dvf, Kvc_dvf, R, Sfb, F, {'r', 'dmu', 'Fd', 'w'}, {'y', 'e', 'Fm', 'd', 'Fu'});
    +  Gvc_fb_iff = connect(Gvc_iff, Kvc_iff, R, Sfb, F, {'r', 'dmu', 'Fd', 'w'}, {'y', 'e', 'Fm', 'd', 'Fu'});
     
    -
    +

    simple_hac_lac_results_soft.png

    Figure 10: Obtained closed-loop transfer functions (png, pdf)

    @@ -962,7 +966,7 @@ Gvc_fb_iff = connect(Gvc_iff, Kvc_iff, R, Sfb, F, {'r'<
    Table 2: Design recommendation
    -
    +

    simple_comp_vc_pz.png

    Figure 11: Comparison of the closed-loop transfer functions for Soft and Stiff nano-hexapod (png, pdf)

    @@ -1014,13 +1018,13 @@ Gvc_fb_iff = connect(Gvc_iff, Kvc_iff, R, Sfb, F, {'r'<
    -
    -

    4 Estimate the level of vibration

    +
    +

    4 Estimate the level of vibration

    -
    gm  = load('./mat/psd_gm.mat', 'f', 'psd_gm');
    -rz  = load('./mat/pxsp_r.mat', 'f', 'pxsp_r');
    -tyz = load('./mat/pxz_ty_r.mat', 'f', 'pxz_ty_r');
    +
      gm  = load('./mat/psd_gm.mat', 'f', 'psd_gm');
    +  rz  = load('./mat/pxsp_r.mat', 'f', 'pxsp_r');
    +  tyz = load('./mat/pxz_ty_r.mat', 'f', 'pxz_ty_r');
     
    @@ -1030,13 +1034,13 @@ If we note the PSD \(\Gamma\):

    -
    x_pz = abs(squeeze(freqresp(Gpz_fb_iff('y', 'dmu'), f, 'Hz'))).^2.*(psd_rz + psd_ty) + abs(squeeze(freqresp(Gpz_fb_iff('y', 'w'), f, 'Hz'))).^2.*(psd_gm);
    -x_vc = abs(squeeze(freqresp(Gvc_fb_iff('y', 'dmu'), f, 'Hz'))).^2.*(psd_rz + psd_ty) + abs(squeeze(freqresp(Gvc_fb_iff('y', 'w'), f, 'Hz'))).^2.*(psd_gm);
    +
      x_pz = abs(squeeze(freqresp(Gpz_fb_iff('y', 'dmu'), f, 'Hz'))).^2.*(psd_rz + psd_ty) + abs(squeeze(freqresp(Gpz_fb_iff('y', 'w'), f, 'Hz'))).^2.*(psd_gm);
    +  x_vc = abs(squeeze(freqresp(Gvc_fb_iff('y', 'dmu'), f, 'Hz'))).^2.*(psd_rz + psd_ty) + abs(squeeze(freqresp(Gvc_fb_iff('y', 'w'), f, 'Hz'))).^2.*(psd_gm);
     
    -
    +

    simple_asd_motion_error.png

    Figure 12: ASD of the position error due to Ground Motion and Vibration (png, pdf)

    @@ -1046,14 +1050,14 @@ x_vc = abs(squeeze(freqresp(Gvc_fb_iff('y',
    -
    F_pz = abs(squeeze(freqresp(Gpz_fb_iff('Fu', 'dmu'), f, 'Hz'))).^2.*(psd_rz + psd_ty) + abs(squeeze(freqresp(Gpz_fb_iff('Fu', 'w'), f, 'Hz'))).^2.*(psd_gm);
    -F_vc = abs(squeeze(freqresp(Gvc_fb_iff('Fu', 'dmu'), f, 'Hz'))).^2.*(psd_rz + psd_ty) + abs(squeeze(freqresp(Gvc_fb_iff('Fu', 'w'), f, 'Hz'))).^2.*(psd_gm);
    +
      F_pz = abs(squeeze(freqresp(Gpz_fb_iff('Fu', 'dmu'), f, 'Hz'))).^2.*(psd_rz + psd_ty) + abs(squeeze(freqresp(Gpz_fb_iff('Fu', 'w'), f, 'Hz'))).^2.*(psd_gm);
    +  F_vc = abs(squeeze(freqresp(Gvc_fb_iff('Fu', 'dmu'), f, 'Hz'))).^2.*(psd_rz + psd_ty) + abs(squeeze(freqresp(Gvc_fb_iff('Fu', 'w'), f, 'Hz'))).^2.*(psd_gm);
     
    -
    sqrt(trapz(f, F_pz))
    -sqrt(trapz(f, F_vc))
    +
      sqrt(trapz(f, F_pz))
    +  sqrt(trapz(f, F_vc))
     
    @@ -1068,41 +1072,41 @@ ans =
    -
    -

    5 Requirements on the norm of closed-loop transfer functions

    +
    +

    5 Requirements on the norm of closed-loop transfer functions

    -
    -

    5.1 Approximation of the ASD of perturbations

    +
    +

    5.1 Approximation of the ASD of perturbations

    -
    G_rz = 1e-9*1/(1 + s/2/pi/0.5)^2*(s + 2*pi*1)*(s + 2*pi*10)*(1/((1 + s/2/pi/100)^2));
    +
      G_rz = 1e-9*1/(1 + s/2/pi/0.5)^2*(s + 2*pi*1)*(s + 2*pi*10)*(1/((1 + s/2/pi/100)^2));
     
    -
    G_gm = 1e-8*1/s^2*(s + 2*pi*1)^2*(1/((1 + s/2/pi/10)^3));
    +
      G_gm = 1e-8*1/s^2*(s + 2*pi*1)^2*(1/((1 + s/2/pi/10)^3));
     
    -
    -

    5.2 Wanted ASD of outputs

    +
    +

    5.2 Wanted ASD of outputs

    Wanted ASD of motion error

    -
    y_wanted = 100e-9; % 10nm rms wanted
    -y_bw = 2*pi*100; % bandwidth [rad/s]
    +
      y_wanted = 100e-9; % 10nm rms wanted
    +  y_bw = 2*pi*100; % bandwidth [rad/s]
     
    -G_y = 2*y_wanted/sqrt(y_bw) * (1 + s/y_bw/10) / (1 + s/y_bw);
    +  G_y = 2*y_wanted/sqrt(y_bw) * (1 + s/y_bw/10) / (1 + s/y_bw);
     
    -
    sqrt(trapz(f, abs(squeeze(freqresp(G_y, f, 'Hz'))).^2))
    +
      sqrt(trapz(f, abs(squeeze(freqresp(G_y, f, 'Hz'))).^2))
     
    @@ -1114,19 +1118,19 @@ ans =
    -
    -

    5.3 Limiting the bandwidth

    +
    +

    5.3 Limiting the bandwidth

    -
    wF = 2*pi*10;
    -G_F = 100000*(wF + s)^2;
    +
      wF = 2*pi*10;
    +  G_F = 100000*(wF + s)^2;
     
    -
    -

    5.4 Generalized Weighted plant

    +
    +

    5.4 Generalized Weighted plant

    Let’s create a generalized weighted plant for controller synthesis. @@ -1186,12 +1190,12 @@ Let’s start simple: Add \(F\) as output.

    -
    F = [tf(1); tf(1)];
    -F.InputName = {'Fi'};
    -F.OutputName = {'F', 'Fu'};
    +
      F = [tf(1); tf(1)];
    +  F.InputName = {'Fi'};
    +  F.OutputName = {'F', 'Fu'};
     
    -P_pz = connect(F, Gpz_dvf, {'dmu', 'Fi'}, {'y', 'Fu', 'y'})
    -P_vc = connect(F, Gvc_dvf, {'dmu', 'Fi'}, {'y', 'Fu', 'y'})
    +  P_pz = connect(F, Gpz_dvf, {'dmu', 'Fi'}, {'y', 'Fu', 'y'})
    +  P_vc = connect(F, Gvc_dvf, {'dmu', 'Fi'}, {'y', 'Fu', 'y'})
     
    @@ -1203,60 +1207,60 @@ Normalization. We multiply the plant input by \(G_{rz}\) and the plant output by \(G_y^{-1}\):

    -
    P_pz_norm = blkdiag(inv(G_y), inv(G_F), 1)*P_pz*blkdiag(G_rz, 1);
    -P_pz_norm.OutputName = {'z', 'F', 'y'};
    -P_pz_norm.InputName  = {'w', 'u'};
    +
      P_pz_norm = blkdiag(inv(G_y), inv(G_F), 1)*P_pz*blkdiag(G_rz, 1);
    +  P_pz_norm.OutputName = {'z', 'F', 'y'};
    +  P_pz_norm.InputName  = {'w', 'u'};
     
    -P_vc_norm = blkdiag(inv(G_y), inv(G_F), 1)*P_vc*blkdiag(G_rz, 1);
    -P_vc_norm.OutputName = {'z', 'F', 'y'};
    -P_vc_norm.InputName  = {'w', 'u'};
    +  P_vc_norm = blkdiag(inv(G_y), inv(G_F), 1)*P_vc*blkdiag(G_rz, 1);
    +  P_vc_norm.OutputName = {'z', 'F', 'y'};
    +  P_vc_norm.InputName  = {'w', 'u'};
     
    -
    -

    5.5 Synthesis

    +
    +

    5.5 Synthesis

    -
    [Kpz_dvf,CL_vc,~] = hinfsyn(minreal(P_pz_norm), 1, 1, 'TOLGAM', 0.001, 'METHOD', 'LMI', 'DISPLAY', 'on');
    -Kpz_dvf.InputName = {'e'};
    -Kpz_dvf.OutputName = {'Fi'};
    +
      [Kpz_dvf,CL_vc,~] = hinfsyn(minreal(P_pz_norm), 1, 1, 'TOLGAM', 0.001, 'METHOD', 'LMI', 'DISPLAY', 'on');
    +  Kpz_dvf.InputName = {'e'};
    +  Kpz_dvf.OutputName = {'Fi'};
     
    -[Kvc_dvf,CL_pz,~] = hinfsyn(minreal(P_vc_norm), 1, 1, 'TOLGAM', 0.001, 'METHOD', 'LMI', 'DISPLAY', 'on');
    -Kvc_dvf.InputName = {'e'};
    -Kvc_dvf.OutputName = {'Fi'};
    +  [Kvc_dvf,CL_pz,~] = hinfsyn(minreal(P_vc_norm), 1, 1, 'TOLGAM', 0.001, 'METHOD', 'LMI', 'DISPLAY', 'on');
    +  Kvc_dvf.InputName = {'e'};
    +  Kvc_dvf.OutputName = {'Fi'};
     
    -
    -

    5.6 Loop Gain

    +
    +

    5.6 Loop Gain

    -
    Sfb = sumblk('e = r2 - y');
    +
      Sfb = sumblk('e = r2 - y');
     
    -R = [tf(1); tf(1)];
    -R.InputName = {'r'};
    -R.OutputName = {'r1', 'r2'};
    +  R = [tf(1); tf(1)];
    +  R.InputName = {'r'};
    +  R.OutputName = {'r1', 'r2'};
     
    -F = [tf(1); tf(1)];
    -F.InputName = {'Fi'};
    -F.OutputName = {'F', 'Fu'};
    +  F = [tf(1); tf(1)];
    +  F.InputName = {'Fi'};
    +  F.OutputName = {'F', 'Fu'};
     
    -Gpz_fb_dvf = connect(Gpz_dvf, -Kpz_dvf, R, Sfb, F, {'r', 'dmu', 'Fd', 'w'}, {'y', 'e', 'Fm', 'd', 'Fu'});
    -Gvc_fb_dvf = connect(Gvc_dvf, -Kvc_dvf, R, Sfb, F, {'r', 'dmu', 'Fd', 'w'}, {'y', 'e', 'Fm', 'd', 'Fu'});
    +  Gpz_fb_dvf = connect(Gpz_dvf, -Kpz_dvf, R, Sfb, F, {'r', 'dmu', 'Fd', 'w'}, {'y', 'e', 'Fm', 'd', 'Fu'});
    +  Gvc_fb_dvf = connect(Gvc_dvf, -Kvc_dvf, R, Sfb, F, {'r', 'dmu', 'Fd', 'w'}, {'y', 'e', 'Fm', 'd', 'Fu'});
     
    -
    -

    5.7 Results

    +
    +

    5.7 Results

    -
    -

    5.8 Requirements

    +
    +

    5.8 Requirements

    @@ -1294,7 +1298,7 @@ Gvc_fb_dvf = connect(Gvc_dvf, -Kvc_dvf, R, Sfb, F,

    Author: Dehaeze Thomas

    -

    Created: 2020-04-17 ven. 09:36

    +

    Created: 2021-02-20 sam. 23:09

    diff --git a/docs/control_virtual_mass.html b/docs/control_virtual_mass.html index dca22a8..6753011 100644 --- a/docs/control_virtual_mass.html +++ b/docs/control_virtual_mass.html @@ -1,78 +1,82 @@ - - +Decentralize control to add virtual mass - - - - - - - - + + + +

    Decentralize control to add virtual mass

    -
    -

    1 Initialization

    +
    +

    1 Initialization

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
     
    -initializeSimscapeConfiguration();
    -initializeDisturbances('enable', false);
    -initializeLoggingConfiguration('log', 'none');
    +  initializeSimscapeConfiguration();
    +  initializeDisturbances('enable', false);
    +  initializeLoggingConfiguration('log', 'none');
     
    -initializeController('type', 'hac-dvf');
    +  initializeController('type', 'hac-dvf');
     
    @@ -80,7 +84,7 @@ initializeController('type', 'hac-dvf'); The nano-hexapod has the following leg’s stiffness and damping.

    -
    initializeNanoHexapod('k', 1e5, 'c', 2e2);
    +
      initializeNanoHexapod('k', 1e5, 'c', 2e2);
     
    @@ -88,20 +92,20 @@ The nano-hexapod has the following leg’s stiffness and damping. We set the stiffness of the payload fixation:

    -
    Kp = 1e8; % [N/m]
    +
      Kp = 1e8; % [N/m]
     
    -
    -

    2 Identification

    +
    +

    2 Identification

    We identify the system for the following payload masses:

    -
    Ms = [1, 10, 50];
    +
      Ms = [1, 10, 50];
     
    @@ -111,15 +115,15 @@ Identification of the Primary plant without virtual add of mass

    -
    -

    3 Adding Virtual Mass in the Leg’s Space

    +
    +

    3 Adding Virtual Mass in the Leg’s Space

    -
    -

    3.1 Plant

    +
    +

    3.1 Plant

    -
    +

    virtual_mass_plant_L.png

    Figure 1: Transfer function from \(\tau_i\) to \(d\mathcal{L}_i\) for three payload masses

    @@ -127,16 +131,16 @@ Identification of the Primary plant without virtual add of mass
    -
    -

    3.2 Controller Design

    +
    +

    3.2 Controller Design

    -
    Kdvf = 10*s^2/(1+s/2/pi/500)^2*eye(6);
    +
      Kdvf = 10*s^2/(1+s/2/pi/500)^2*eye(6);
     
    -
    +

    virtual_mass_loop_gain_L.png

    Figure 2: Loop Gain for the addition of virtual mass in the leg’s space

    @@ -144,18 +148,18 @@ Identification of the Primary plant without virtual add of mass
    -
    -

    3.3 Identification of the Primary Plant

    +
    +

    3.3 Identification of the Primary Plant

    -
    +

    virtual_mass_L_primary_plant_X.png

    Figure 3: Comparison of the transfer function from \(\mathcal{F}_{x,y,z}\) to \(\mathcal{X}_{x,y,z}\) with and without the virtual addition of mass in the leg’s space

    -
    +

    virtual_mass_L_primary_plant_L.png

    Figure 4: Comparison of the transfer function from \(\tau_i\) to \(\mathcal{L}_{i}\) with and without the virtual addition of mass in the leg’s space

    @@ -164,12 +168,12 @@ Identification of the Primary plant without virtual add of mass
    -
    -

    4 Adding Virtual Mass in the Task Space

    +
    +

    4 Adding Virtual Mass in the Task Space

    -
    -

    4.1 Plant

    +
    +

    4.1 Plant

    Let’s look at the transfer function from \(\bm{\mathcal{F}}\) to \(d\bm{\mathcal{X}}\): @@ -177,7 +181,7 @@ Let’s look at the transfer function from \(\bm{\mathcal{F}}\) to \(d\bm{\m

    -
    +

    virtual_mass_plant_X.png

    Figure 5: Dynamics from \(\mathcal{F}_{x,y,z}\) to \(\mathcal{X}_{x,y,z}\) used for virtual mass addition in the task space

    @@ -185,40 +189,40 @@ Let’s look at the transfer function from \(\bm{\mathcal{F}}\) to \(d\bm{\m
    -
    -

    4.2 Controller Design

    +
    +

    4.2 Controller Design

    -
    KmX = (s^2*1/(1+s/2/pi/500)^2*diag([1 1 50 0 0 0]));
    +
      KmX = (s^2*1/(1+s/2/pi/500)^2*diag([1 1 50 0 0 0]));
     
    -
    +

    virtual_mass_loop_gain_X.png

    Figure 6: Loop gain for virtual mass addition in the task space

    -
    Kdvf = inv(nano_hexapod.kinematics.J')*KmX*inv(nano_hexapod.kinematics.J);
    +
      Kdvf = inv(nano_hexapod.kinematics.J')*KmX*inv(nano_hexapod.kinematics.J);
     
    -
    -

    4.3 Identification of the Primary Plant

    +
    +

    4.3 Identification of the Primary Plant

    -
    +

    virtual_mass_X_primary_plant_X.png

    Figure 7: Comparison of the transfer function from \(\mathcal{F}_{x,y,z}\) to \(\mathcal{X}_{x,y,z}\) with and without the virtual addition of mass in the task space

    -
    +

    virtual_mass_X_primary_plant_L.png

    Figure 8: Comparison of the transfer function from \(\tau_i\) to \(\mathcal{L}_{i}\) with and without the virtual addition of mass in the task space

    @@ -229,7 +233,7 @@ Let’s look at the transfer function from \(\bm{\mathcal{F}}\) to \(d\bm{\m

    Author: Dehaeze Thomas

    -

    Created: 2020-05-05 mar. 10:34

    +

    Created: 2021-02-20 sam. 23:09

    diff --git a/docs/control_voice_coil.html b/docs/control_voice_coil.html index 385c102..10780bd 100644 --- a/docs/control_voice_coil.html +++ b/docs/control_voice_coil.html @@ -1,116 +1,120 @@ - - + Control of the NASS with Voice coil actuators - - - - - - - - + + + +

    Control of the NASS with Voice coil actuators

    Table of Contents

    -
    -

    1 HAC-LAC + Cascade Control Topology

    +
    +

    1 HAC-LAC + Cascade Control Topology

    -
    +

    cascade_control_architecture.png

    Figure 1: Cascaded Control consisting of (from inner to outer loop): IFF, Linearization Loop, Tracking Control in the frame of the Legs

    -
    -

    1.1 Initialization

    +
    +

    1.1 Initialization

    We initialize all the stages with the default parameters.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
     
    @@ -152,8 +156,8 @@ initializeMirror(); The nano-hexapod is a voice coil based hexapod and the sample has a mass of 1kg.

    -
    initializeNanoHexapod('actuator', 'lorentz');
    -initializeSample('mass', 1);
    +
      initializeNanoHexapod('actuator', 'lorentz');
    +  initializeSample('mass', 1);
     
    @@ -161,22 +165,22 @@ initializeSample('mass', 1); We set the references that corresponds to a tomography experiment.

    -
    initializeReferences('Rz_type', 'rotating', 'Rz_period', 1);
    +
      initializeReferences('Rz_type', 'rotating', 'Rz_period', 1);
     
    -
    initializeDisturbances();
    +
      initializeDisturbances();
     
    -
    initializeController('type', 'cascade-hac-lac');
    +
      initializeController('type', 'cascade-hac-lac');
     
    -
    initializeSimscapeConfiguration('gravity', true);
    +
      initializeSimscapeConfiguration('gravity', true);
     
    @@ -184,59 +188,59 @@ We set the references that corresponds to a tomography experiment. We log the signals.

    -
    initializeLoggingConfiguration('log', 'all');
    +
      initializeLoggingConfiguration('log', 'all');
     
    -
    Kp = tf(zeros(6));
    -Kl = tf(zeros(6));
    -Kiff = tf(zeros(6));
    +
      Kp = tf(zeros(6));
    +  Kl = tf(zeros(6));
    +  Kiff = tf(zeros(6));
     
    -
    -

    1.2 Low Authority Control - Integral Force Feedback \(\bm{K}_\text{IFF}\)

    +
    +

    1.2 Low Authority Control - Integral Force Feedback \(\bm{K}_\text{IFF}\)

    - +

    -
    -

    1.2.1 Identification

    +
    +

    1.2.1 Identification

    Let’s first identify the plant for the IFF controller.

    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller'],    1, 'openinput');               io_i = io_i + 1; % Actuator Inputs
    -io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm');  io_i = io_i + 1; % Force Sensors
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller'],    1, 'openinput');               io_i = io_i + 1; % Actuator Inputs
    +  io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm');  io_i = io_i + 1; % Force Sensors
     
    -%% Run the linearization
    -G_iff = linearize(mdl, io, 0);
    -G_iff.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    -G_iff.OutputName = {'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'};
    +  %% Run the linearization
    +  G_iff = linearize(mdl, io, 0);
    +  G_iff.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    +  G_iff.OutputName = {'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'};
     
    -
    -

    1.2.2 Plant

    +
    +

    1.2.2 Plant

    -The obtained plant for IFF is shown in Figure 2. +The obtained plant for IFF is shown in Figure 2.

    -
    +

    cascade_vc_iff_plant.png

    Figure 2: IFF Plant (png, pdf)

    @@ -244,20 +248,20 @@ The obtained plant for IFF is shown in Figure 2.
    -
    -

    1.2.3 Root Locus

    +
    +

    1.2.3 Root Locus

    -As seen in the root locus (Figure 3, no damping can be added to modes corresponding to the resonance of the micro-station. +As seen in the root locus (Figure 3, no damping can be added to modes corresponding to the resonance of the micro-station.

    -However, critical damping can be achieve for the resonances of the nano-hexapod as shown in the zoomed part of the root (Figure 3, left part). +However, critical damping can be achieve for the resonances of the nano-hexapod as shown in the zoomed part of the root (Figure 3, left part). The maximum damping is obtained for a control gain of \(\approx 70\).

    -
    +

    cascade_vc_iff_root_locus.png

    Figure 3: Root Locus for the IFF control (png, pdf)

    @@ -265,20 +269,20 @@ The maximum damping is obtained for a control gain of \(\approx 70\).
    -
    -

    1.2.4 Controller and Loop Gain

    +
    +

    1.2.4 Controller and Loop Gain

    We create the \(6 \times 6\) diagonal Integral Force Feedback controller. -The obtained loop gain is shown in Figure 4. +The obtained loop gain is shown in Figure 4.

    -
    Kiff = -70/s*eye(6);
    +
      Kiff = -70/s*eye(6);
     
    -
    +

    cascade_vc_iff_loop_gain.png

    Figure 4: Obtained Loop gain the IFF Control (png, pdf)

    @@ -287,33 +291,33 @@ The obtained loop gain is shown in Figure 4.
    -
    -

    1.3 High Authority Control in the joint space - \(\bm{K}_\mathcal{L}\)

    +
    +

    1.3 High Authority Control in the joint space - \(\bm{K}_\mathcal{L}\)

    - +

    -
    -

    1.3.1 Identification of the damped plant

    +
    +

    1.3.1 Identification of the damped plant

    -Let’s identify the dynamics from \(\bm{\tau}^\prime\) to \(d\bm{\mathcal{L}}\) as shown in Figure 1. +Let’s identify the dynamics from \(\bm{\tau}^\prime\) to \(d\bm{\mathcal{L}}\) as shown in Figure 1.

    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller'],    1, 'input');               io_i = io_i + 1; % Actuator Inputs
    -io(io_i) = linio([mdl, '/Micro-Station'], 3, 'output', [], 'Dnlm');  io_i = io_i + 1; % Leg Displacement
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller'],    1, 'input');               io_i = io_i + 1; % Actuator Inputs
    +  io(io_i) = linio([mdl, '/Micro-Station'], 3, 'output', [], 'Dnlm');  io_i = io_i + 1; % Leg Displacement
     
    -%% Run the linearization
    -Gl = linearize(mdl, io, 0);
    -Gl.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    -Gl.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'};
    +  %% Run the linearization
    +  Gl = linearize(mdl, io, 0);
    +  Gl.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    +  Gl.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'};
     
    @@ -322,19 +326,19 @@ There are some unstable poles in the Plant with very small imaginary parts. These unstable poles are probably not physical, and they disappear when taking the minimum realization of the plant.

    -
    isstable(Gl)
    -Gl = minreal(Gl);
    -isstable(Gl)
    +
      isstable(Gl)
    +  Gl = minreal(Gl);
    +  isstable(Gl)
     
    -
    -

    1.3.2 Obtained Plant

    +
    +

    1.3.2 Obtained Plant

    -The obtained dynamics is shown in Figure 5. +The obtained dynamics is shown in Figure 5.

    @@ -347,7 +351,7 @@ Few things can be said on the dynamics: -

    +

    cascade_vc_hac_joint_plant.png

    Figure 5: Plant for the High Authority Control in the Joint Space (png, pdf)

    @@ -355,54 +359,54 @@ Few things can be said on the dynamics:
    -
    -

    1.3.3 Controller Design and Loop Gain

    +
    +

    1.3.3 Controller Design and Loop Gain

    As the plant is well decoupled, a diagonal plant is designed.

    -
    wc = 2*pi*10; % Bandwidth Bandwidth [rad/s]
    +
      wc = 2*pi*10; % Bandwidth Bandwidth [rad/s]
     
    -h = 2; % Lead parameter
    +  h = 2; % Lead parameter
     
    -Kl = (s + 2*pi*1)/s;
    +  Kl = (s + 2*pi*1)/s;
     
    -% Normalization of the gain of have a loop gain of 1 at frequency wc
    -Kl = Kl.*diag(1./diag(abs(freqresp(Gl*Kl, wc))));
    +  % Normalization of the gain of have a loop gain of 1 at frequency wc
    +  Kl = Kl.*diag(1./diag(abs(freqresp(Gl*Kl, wc))));
     
    -
    -

    1.4 Primary Controller in the task space - \(\bm{K}_\mathcal{X}\)

    +
    +

    1.4 Primary Controller in the task space - \(\bm{K}_\mathcal{X}\)

    - +

    -
    -

    1.4.1 Identification of the linearized plant

    +
    +

    1.4.1 Identification of the linearized plant

    We know identify the dynamics between \(\bm{r}_{\mathcal{X}_n}\) and \(\bm{r}_\mathcal{X}\).

    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller/Cascade-HAC-LAC/Kp'],  1, 'input'); io_i = io_i + 1;
    -io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En');      io_i = io_i + 1; % Position Errror
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller/Cascade-HAC-LAC/Kp'],  1, 'input'); io_i = io_i + 1;
    +  io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En');      io_i = io_i + 1; % Position Errror
     
    -%% Run the linearization
    -Gp = linearize(mdl, io, 0);
    -Gp.InputName  = {'rl1', 'rl2', 'rl3', 'rl4', 'rl5', 'rl6'};
    -Gp.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
    +  %% Run the linearization
    +  Gp = linearize(mdl, io, 0);
    +  Gp.InputName  = {'rl1', 'rl2', 'rl3', 'rl4', 'rl5', 'rl6'};
    +  Gp.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
     
    @@ -410,29 +414,29 @@ Gp.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'}; A minus sign is added because the minus sign is already included in the plant identification.

    -
    isstable(Gp)
    -Gp = -minreal(Gp);
    -isstable(Gp)
    +
      isstable(Gp)
    +  Gp = -minreal(Gp);
    +  isstable(Gp)
     
    -
    load('mat/stages.mat', 'nano_hexapod');
    -Gpx = Gp*inv(nano_hexapod.kinematics.J');
    -Gpx.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    +
      load('mat/stages.mat', 'nano_hexapod');
    +  Gpx = Gp*inv(nano_hexapod.kinematics.J');
    +  Gpx.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
     
    -Gpl = nano_hexapod.kinematics.J*Gp;
    -Gpl.OutputName  = {'El1', 'El2', 'El3', 'El4', 'El5', 'El6'};
    +  Gpl = nano_hexapod.kinematics.J*Gp;
    +  Gpl.OutputName  = {'El1', 'El2', 'El3', 'El4', 'El5', 'El6'};
     
    -
    -

    1.4.2 Obtained Plant

    +
    +

    1.4.2 Obtained Plant

    -
    +

    primary_plant_voice_coil_X.png

    Figure 6: Obtained Primary plant in the Task space (png, pdf)

    @@ -440,7 +444,7 @@ Gpl.OutputName = {'El1', 'El2', 'El3', 'El4', 'El5', 'El6'}; -
    +

    primary_plant_voice_coil_L.png

    Figure 7: Obtained Primary plant in the frame of the legs (png, pdf)

    @@ -449,25 +453,25 @@ Gpl.OutputName = {'El1', 'El2', 'El3', 'El4', 'El5', 'El6'};
    -
    -

    1.4.3 Controller Design

    +
    +

    1.4.3 Controller Design

    -
    wc = 2*pi*200; % Bandwidth Bandwidth [rad/s]
    +
      wc = 2*pi*200; % Bandwidth Bandwidth [rad/s]
     
    -h = 2; % Lead parameter
    +  h = 2; % Lead parameter
     
    -Kp = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * ...
    -     (1/h) * (1 + s/wc*h)/(1 + s/wc/h); % For Piezo
    -% Kp = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * (s + 2*pi*10)/s * (s + 2*pi*1)/s ; % For voice coil
    +  Kp = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * ...
    +       (1/h) * (1 + s/wc*h)/(1 + s/wc/h); % For Piezo
    +  % Kp = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * (s + 2*pi*10)/s * (s + 2*pi*1)/s ; % For voice coil
     
    -% Normalization of the gain of have a loop gain of 1 at frequency wc
    -Kp = Kp.*diag(1./diag(abs(freqresp(Gpx*Kp, wc))));
    +  % Normalization of the gain of have a loop gain of 1 at frequency wc
    +  Kp = Kp.*diag(1./diag(abs(freqresp(Gpx*Kp, wc))));
     
    -
    +

    loop_gain_primary_voice_coil_X.png

    Figure 8: Obtained Loop gain for the primary controller in the Task space (png, pdf)

    @@ -478,27 +482,27 @@ Kp = Kp.*diag(1./diag(abs(freqresp(Gpx*Kp, wc)))); And now we include the Jacobian inside the controller.

    -
    Kp = inv(nano_hexapod.kinematics.J')*Kp;
    +
      Kp = inv(nano_hexapod.kinematics.J')*Kp;
     
    -
    -

    1.5 Simulation

    +
    +

    1.5 Simulation

    Let’s first save the 3 controllers for further analysis:

    -
    save('mat/hac_lac_cascade_vc_controllers.mat', 'Kiff', 'Kl', 'Kp')
    +
      save('mat/hac_lac_cascade_vc_controllers.mat', 'Kiff', 'Kl', 'Kp')
     
    -
    load('mat/conf_simulink.mat');
    -set_param(conf_simulink, 'StopTime', '2');
    +
      load('mat/conf_simulink.mat');
    +  set_param(conf_simulink, 'StopTime', '2');
     
    @@ -506,38 +510,38 @@ set_param(conf_simulink, 'StopTime', '2'); And we simulate the system.

    -
    sim('nass_model');
    +
      sim('nass_model');
     
    -
    cascade_hac_lac_lorentz = simout;
    -save('./mat/cascade_hac_lac.mat', 'cascade_hac_lac_lorentz', '-append');
    +
      cascade_hac_lac_lorentz = simout;
    +  save('./mat/cascade_hac_lac.mat', 'cascade_hac_lac_lorentz', '-append');
     
    -
    -

    1.6 Results

    +
    +

    1.6 Results

    -
    -

    1.6.1 Load the simulation results

    +
    +

    1.6.1 Load the simulation results

    -
    load('./mat/experiment_tomography.mat', 'tomo_align_dist');
    -load('./mat/cascade_hac_lac.mat', 'cascade_hac_lac', 'cascade_hac_lac_lorentz');
    +
      load('./mat/experiment_tomography.mat', 'tomo_align_dist');
    +  load('./mat/cascade_hac_lac.mat', 'cascade_hac_lac', 'cascade_hac_lac_lorentz');
     
    -
    -

    1.6.2 Control effort

    +
    +

    1.6.2 Control effort

    -
    +

    actuator_force_torques_tomography_voice_coil.png

    Figure 9: Actuator Action during a tomography experiment when using Voice Coil actuators (png, pdf)

    @@ -545,41 +549,41 @@ load('./mat/cascade_hac_lac.mat', 'cascade_hac_lac', 'cascade_hac_lac_lorentz');
    -
    -

    1.6.3 Load the simulation results

    +
    +

    1.6.3 Load the simulation results

    -
    n_av = 4;
    -han_win = hanning(ceil(length(cascade_hac_lac.Em.En.Data(:,1))/n_av));
    +
      n_av = 4;
    +  han_win = hanning(ceil(length(cascade_hac_lac.Em.En.Data(:,1))/n_av));
     
    -
    t = cascade_hac_lac.Em.En.Time;
    -Ts = t(2)-t(1);
    +
      t = cascade_hac_lac.Em.En.Time;
    +  Ts = t(2)-t(1);
     
    -[pxx_ol, f] = pwelch(tomo_align_dist.Em.En.Data, han_win, [], [], 1/Ts);
    -[pxx_ca, ~] = pwelch(cascade_hac_lac.Em.En.Data, han_win, [], [], 1/Ts);
    -[pxx_vc, ~] = pwelch(cascade_hac_lac_lorentz.Em.En.Data, han_win, [], [], 1/Ts);
    +  [pxx_ol, f] = pwelch(tomo_align_dist.Em.En.Data, han_win, [], [], 1/Ts);
    +  [pxx_ca, ~] = pwelch(cascade_hac_lac.Em.En.Data, han_win, [], [], 1/Ts);
    +  [pxx_vc, ~] = pwelch(cascade_hac_lac_lorentz.Em.En.Data, han_win, [], [], 1/Ts);
     
    -
    +

    exp_tomography_voice_coil_psd_pos_error.png

    Figure 10: Power Spectral Density of the position error during a tomography experiment when using Voice Coil based nano-hexapod (png, pdf)

    -
    +

    exp_tomography_voice_coil_cap_pos_error.png

    Figure 11: Cumulative Amplitude Spectrum of the position error during a tomography experiment when using Voice Coil based nano-hexapod (png, pdf)

    -
    +

    exp_tomography_voice_coil_time_domain.png

    Figure 12: Position error during a tomography experiment when using Voice Coil based nano-hexapod (png, pdf)

    @@ -589,24 +593,24 @@ Ts = t(2)-t(1);
    -
    -

    1.7 Compliance of the nano-hexapod

    +
    +

    1.7 Compliance of the nano-hexapod

    -
    -

    1.7.1 Identification

    +
    +

    1.7.1 Identification

    Let’s identify the Compliance of the NASS:

    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Disturbances/Fd'], 1, 'openinput');       io_i = io_i + 1; % Direct Forces/Torques applied on the sample
    -io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1; % Position Errror
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Disturbances/Fd'], 1, 'openinput');       io_i = io_i + 1; % Direct Forces/Torques applied on the sample
    +  io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1; % Position Errror
     
    @@ -614,17 +618,17 @@ io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + First in open-loop:

    -
    Kp = tf(zeros(6));
    -Kl = tf(zeros(6));
    -Kiff = tf(zeros(6));
    +
      Kp = tf(zeros(6));
    +  Kl = tf(zeros(6));
    +  Kiff = tf(zeros(6));
     
    -
    %% Run the linearization
    -Gc_ol = linearize(mdl, io, 0);
    -Gc_ol.InputName  = {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'};
    -Gc_ol.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
    +
      %% Run the linearization
    +  Gc_ol = linearize(mdl, io, 0);
    +  Gc_ol.InputName  = {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'};
    +  Gc_ol.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
     
    @@ -632,15 +636,15 @@ Gc_ol.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'}; Then with the IFF control.

    -
    load('mat/hac_lac_cascade_vc_controllers.mat', 'Kiff')
    +
      load('mat/hac_lac_cascade_vc_controllers.mat', 'Kiff')
     
    -
    %% Run the linearization
    -Gc_iff = linearize(mdl, io, 0);
    -Gc_iff.InputName  = {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'};
    -Gc_iff.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
    +
      %% Run the linearization
    +  Gc_iff = linearize(mdl, io, 0);
    +  Gc_iff.InputName  = {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'};
    +  Gc_iff.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
     
    @@ -648,15 +652,15 @@ Gc_iff.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'}; With the HAC control added

    -
    load('mat/hac_lac_cascade_vc_controllers.mat', 'Kl')
    +
      load('mat/hac_lac_cascade_vc_controllers.mat', 'Kl')
     
    -
    %% Run the linearization
    -Gc_hac = linearize(mdl, io, 0);
    -Gc_hac.InputName  = {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'};
    -Gc_hac.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
    +
      %% Run the linearization
    +  Gc_hac = linearize(mdl, io, 0);
    +  Gc_hac.InputName  = {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'};
    +  Gc_hac.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
     
    @@ -664,25 +668,25 @@ Gc_hac.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'}; Finally with the primary controller

    -
    load('mat/hac_lac_cascade_vc_controllers.mat', 'Kp')
    +
      load('mat/hac_lac_cascade_vc_controllers.mat', 'Kp')
     
    -
    %% Run the linearization
    -Gc_pri = linearize(mdl, io, 0);
    -Gc_pri.InputName  = {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'};
    -Gc_pri.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
    +
      %% Run the linearization
    +  Gc_pri = linearize(mdl, io, 0);
    +  Gc_pri.InputName  = {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'};
    +  Gc_pri.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
     
    -
    -

    1.7.2 Obtained Compliance

    +
    +

    1.7.2 Obtained Compliance

    -
    +

    compliance_evolution_vc_cascade_control.png

    Figure 13: Evolution of the NASS compliance with each control loop added (png, pdf)

    @@ -690,14 +694,14 @@ Gc_pri.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
    -
    -

    1.7.3 Comparison with Piezo

    +
    +

    1.7.3 Comparison with Piezo

    Let’s initialize a nano-hexapod with piezoelectric actuators.

    -
    initializeNanoHexapod('actuator', 'piezo');
    +
      initializeNanoHexapod('actuator', 'piezo');
     
    @@ -705,22 +709,22 @@ Let’s initialize a nano-hexapod with piezoelectric actuators. We don’t use any controller.

    -
    Kp = tf(zeros(6));
    -Kl = tf(zeros(6));
    -Kiff = tf(zeros(6));
    +
      Kp = tf(zeros(6));
    +  Kl = tf(zeros(6));
    +  Kiff = tf(zeros(6));
     
    -
    %% Run the linearization
    -Gc_pz = linearize(mdl, io, 0);
    -Gc_pz.InputName  = {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'};
    -Gc_pz.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
    +
      %% Run the linearization
    +  Gc_pz = linearize(mdl, io, 0);
    +  Gc_pz.InputName  = {'Fdx', 'Fdy', 'Fdz', 'Mdx', 'Mdy', 'Mdz'};
    +  Gc_pz.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
     
    -
    +

    compliance_comp_pz_vc_cascade.png

    Figure 14: Comparison of the compliance using the open-loop piezo-nano hexapod and the voice coil nano-hexapod with the cascade control topology (png, pdf)

    @@ -730,59 +734,59 @@ Gc_pz.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
    -
    -

    1.8 Robustness to Payload Variability

    +
    +

    1.8 Robustness to Payload Variability

    -
    -

    1.8.1 Initialization

    +
    +

    1.8.1 Initialization

    Let’s change the payload mass, and see if the controller design for a payload mass of 1 still gives good performance.

    -
    initializeSample('mass', 50);
    +
      initializeSample('mass', 50);
     
    -
    Kp = tf(zeros(6));
    -Kl = tf(zeros(6));
    -Kiff = tf(zeros(6));
    +
      Kp = tf(zeros(6));
    +  Kl = tf(zeros(6));
    +  Kiff = tf(zeros(6));
     
    -
    -

    1.8.2 Low Authority Control

    +
    +

    1.8.2 Low Authority Control

    Let’s first identify the transfer function for the Low Authority control.

    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller'],    1, 'openinput');               io_i = io_i + 1; % Actuator Inputs
    -io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm');  io_i = io_i + 1; % Force Sensors
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller'],    1, 'openinput');               io_i = io_i + 1; % Actuator Inputs
    +  io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Fnlm');  io_i = io_i + 1; % Force Sensors
     
    -%% Run the linearization
    -G_iff_m = linearize(mdl, io, 0);
    -G_iff_m.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    -G_iff_m.OutputName = {'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'};
    +  %% Run the linearization
    +  G_iff_m = linearize(mdl, io, 0);
    +  G_iff_m.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    +  G_iff_m.OutputName = {'Fnlm1', 'Fnlm2', 'Fnlm3', 'Fnlm4', 'Fnlm5', 'Fnlm6'};
     

    -The obtained dynamics is compared when using a payload of 1Kg in Figure 15. +The obtained dynamics is compared when using a payload of 1Kg in Figure 15.

    -
    +

    voice_coil_variability_mass_iff.png

    Figure 15: Dynamics of the LAC plant when using a 50Kg payload (dashed) and when using a 1Kg payload (solid) (png, pdf)

    @@ -796,12 +800,12 @@ A gain of 50 will here suffice to obtain critical damping of the nano-hexapod mo Let’s load the IFF controller designed when the payload has a mass of 1Kg.

    -
    load('mat/hac_lac_cascade_vc_controllers.mat', 'Kiff')
    +
      load('mat/hac_lac_cascade_vc_controllers.mat', 'Kiff')
     
    -
    +

    voice_coil_variability_mass_iff_loop_gain.png

    Figure 16: Loop gain for the IFF Control when using a 50Kg payload (dashed) and when using a 1Kg payload (solid) (png, pdf)

    @@ -809,35 +813,35 @@ Let’s load the IFF controller designed when the payload has a mass of 1Kg.
    -
    -

    1.8.3 High Authority Control

    +
    +

    1.8.3 High Authority Control

    We use the Integral Force Feedback developed with a mass of 1Kg and we identify the dynamics for the High Authority Controller in the case of the 50Kg payload

    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller'],    1, 'input');               io_i = io_i + 1; % Actuator Inputs
    -io(io_i) = linio([mdl, '/Micro-Station'], 3, 'output', [], 'Dnlm');  io_i = io_i + 1; % Leg Displacement
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller'],    1, 'input');               io_i = io_i + 1; % Actuator Inputs
    +  io(io_i) = linio([mdl, '/Micro-Station'], 3, 'output', [], 'Dnlm');  io_i = io_i + 1; % Leg Displacement
     
    -%% Run the linearization
    -Gl_m = linearize(mdl, io, 0);
    -Gl_m.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    -Gl_m.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'};
    -
    -isstable(Gl_m)
    -Gl_m = minreal(Gl_m);
    -isstable(Gl_m)
    +  %% Run the linearization
    +  Gl_m = linearize(mdl, io, 0);
    +  Gl_m.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    +  Gl_m.OutputName = {'Dnlm1', 'Dnlm2', 'Dnlm3', 'Dnlm4', 'Dnlm5', 'Dnlm6'};
    + 
    +  isstable(Gl_m)
    +  Gl_m = minreal(Gl_m);
    +  isstable(Gl_m)
     
    -
    +

    voice_coil_variability_mass_hac_plant.png

    Figure 17: Dynamics of the HAC plant when using a 50Kg payload (dashed) and when using a 1Kg payload (solid) (png, pdf)

    @@ -847,12 +851,12 @@ isstable(Gl_m) We load the HAC controller design when the payload has a mass of 1Kg.

    -
    load('mat/hac_lac_cascade_vc_controllers.mat', 'Kl')
    +
      load('mat/hac_lac_cascade_vc_controllers.mat', 'Kl')
     
    -
    +

    voice_coil_variability_mass_hac_lool_gain.png

    Figure 18: Loop Gain of the HAC when using a 50Kg payload (dashed) and when using a 1Kg payload (solid) (png, pdf)

    @@ -860,25 +864,25 @@ We load the HAC controller design when the payload has a mass of 1Kg.
    -
    -

    1.8.4 Primary Plant

    +
    +

    1.8.4 Primary Plant

    We use the Low Authority Controller developed with a mass of 1Kg and we identify the dynamics for the Primary controller in the case of the 50Kg payload.

    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller/Cascade-HAC-LAC/Kp'],  1, 'input'); io_i = io_i + 1;
    -io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En');      io_i = io_i + 1; % Position Errror
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller/Cascade-HAC-LAC/Kp'],  1, 'input'); io_i = io_i + 1;
    +  io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En');      io_i = io_i + 1; % Position Errror
     
    -%% Run the linearization
    -Gp_m = linearize(mdl, io, 0);
    -Gp_m.InputName  = {'rl1', 'rl2', 'rl3', 'rl4', 'rl5', 'rl6'};
    -Gp_m.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
    +  %% Run the linearization
    +  Gp_m = linearize(mdl, io, 0);
    +  Gp_m.InputName  = {'rl1', 'rl2', 'rl3', 'rl4', 'rl5', 'rl6'};
    +  Gp_m.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
     
    @@ -886,23 +890,23 @@ Gp_m.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'}; A minus sign is added to cancel the minus sign already included in the identified plant.

    -
    isstable(Gp_m)
    -Gp_m = -minreal(Gp_m);
    -isstable(Gp_m)
    +
      isstable(Gp_m)
    +  Gp_m = -minreal(Gp_m);
    +  isstable(Gp_m)
     
    -
    load('mat/stages.mat', 'nano_hexapod');
    -Gpx_m = Gp_m*inv(nano_hexapod.kinematics.J');
    -Gpx_m.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    +
      load('mat/stages.mat', 'nano_hexapod');
    +  Gpx_m = Gp_m*inv(nano_hexapod.kinematics.J');
    +  Gpx_m.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
     
    -Gpl_m = nano_hexapod.kinematics.J*Gp_m;
    -Gpl_m.OutputName  = {'El1', 'El2', 'El3', 'El4', 'El5', 'El6'};
    +  Gpl_m = nano_hexapod.kinematics.J*Gp_m;
    +  Gpl_m.OutputName  = {'El1', 'El2', 'El3', 'El4', 'El5', 'El6'};
     
    -
    +

    There are two zeros with positive real part for the plant in the y direction at about 100Hz. This is problematic as it limits the bandwidth to be less than \(\approx 50\ \text{Hz}\). @@ -919,7 +923,7 @@ If we make a “rigid” 50kg paylaod, the positive zero disappears.

    -
    +

    voice_coil_variability_mass_primary_plant.png

    Figure 19: Dynamics of the Primary plant when using a 50Kg payload (dashed) and when using a 1Kg payload (solid) (png, pdf)

    @@ -933,28 +937,28 @@ We load the primary controller that was design when the payload has a mass of 1K We load the HAC controller design when the payload has a mass of 1Kg.

    -
    load('mat/hac_lac_cascade_vc_controllers.mat', 'Kp')
    -Kp_x = nano_hexapod.kinematics.J'*Kp;
    +
      load('mat/hac_lac_cascade_vc_controllers.mat', 'Kp')
    +  Kp_x = nano_hexapod.kinematics.J'*Kp;
     
    -
    wc = 2*pi*50; % Bandwidth Bandwidth [rad/s]
    +
      wc = 2*pi*50; % Bandwidth Bandwidth [rad/s]
     
    -h = 2; % Lead parameter
    +  h = 2; % Lead parameter
     
    -Kp = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * ...
    -     (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * ...
    -     (s + 2*pi*1)/s * ...
    -     1/(1+s/2/wc); % For Piezo
    +  Kp = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * ...
    +       (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * ...
    +       (s + 2*pi*1)/s * ...
    +       1/(1+s/2/wc); % For Piezo
     
    -% Normalization of the gain of have a loop gain of 1 at frequency wc
    -Kp = Kp.*diag(1./diag(abs(freqresp(Gpx_m*Kp, wc))));
    +  % Normalization of the gain of have a loop gain of 1 at frequency wc
    +  Kp = Kp.*diag(1./diag(abs(freqresp(Gpx_m*Kp, wc))));
     
    -
    +

    voice_coil_variability_mass_primary_lool_gain.png

    Figure 20: Loop Gain of the Primary loop when using a 50Kg payload (dashed) and when using a 1Kg payload (solid) (png, pdf)

    @@ -962,12 +966,12 @@ Kp = Kp.*diag(1./diag(abs(freqresp(Gpx_m*Kp, wc))));
    -
    -

    1.8.5 Simulation

    +
    +

    1.8.5 Simulation

    -
    load('mat/conf_simulink.mat');
    -set_param(conf_simulink, 'StopTime', '2');
    +
      load('mat/conf_simulink.mat');
    +  set_param(conf_simulink, 'StopTime', '2');
     
    @@ -975,18 +979,18 @@ set_param(conf_simulink, 'StopTime', '2'); And we simulate the system.

    -
    sim('nass_model');
    +
      sim('nass_model');
     
    -
    cascade_hac_lac_lorentz_high_mass = simout;
    -save('./mat/cascade_hac_lac.mat', 'cascade_hac_lac_lorentz_high_mass', '-append');
    +
      cascade_hac_lac_lorentz_high_mass = simout;
    +  save('./mat/cascade_hac_lac.mat', 'cascade_hac_lac_lorentz_high_mass', '-append');
     
    -
    load('./mat/experiment_tomography.mat', 'tomo_align_dist');
    +
      load('./mat/experiment_tomography.mat', 'tomo_align_dist');
     
    @@ -994,12 +998,12 @@ save('./mat/cascade_hac_lac.mat', 'cascade_hac_lac_lorentz_high_mass', '-append'
    -
    -

    2 Other analysis

    +
    +

    2 Other analysis

    -
    -

    2.1 Robustness to Payload Variability

    +
    +

    2.1 Robustness to Payload Variability

    • [ ] For 3/masses (1kg, 10kg, 50kg), plot each of the 3 plants
    • @@ -1007,105 +1011,105 @@ save('./mat/cascade_hac_lac.mat', 'cascade_hac_lac_lorentz_high_mass', '-append'
    -
    -

    2.2 Direct HAC control in the task space - \(\bm{K}_\mathcal{X}\)

    +
    +

    2.2 Direct HAC control in the task space - \(\bm{K}_\mathcal{X}\)

    -
    +

    control_architecture_hac_iff_pos_X.png

    Figure 21: Control Architecture containing an IFF controller and a Controller in the task space

    -
    -

    2.2.1 Identification

    +
    +

    2.2.1 Identification

    -
    initializeController('type', 'hac-iff');
    +
      initializeController('type', 'hac-iff');
     
    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller/HAC-IFF/Kx'],  1, 'input');    io_i = io_i + 1; % Control input
    -io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1; % Position Errror
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller/HAC-IFF/Kx'],  1, 'input');    io_i = io_i + 1; % Control input
    +  io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1; % Position Errror
     
    -%% Run the linearization
    -G = linearize(mdl, io, 0);
    -G.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    -G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
    +  %% Run the linearization
    +  G = linearize(mdl, io, 0);
    +  G.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    +  G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
     
    -
    isstable(G)
    -G = -minreal(G);
    -isstable(G)
    +
      isstable(G)
    +  G = -minreal(G);
    +  isstable(G)
     
    -
    load('mat/stages.mat', 'nano_hexapod');
    -Gx = G*inv(nano_hexapod.kinematics.J');
    -Gx.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    +
      load('mat/stages.mat', 'nano_hexapod');
    +  Gx = G*inv(nano_hexapod.kinematics.J');
    +  Gx.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
     
    -Gl = nano_hexapod.kinematics.J*G;
    -Gl.OutputName  = {'El1', 'El2', 'El3', 'El4', 'El5', 'El6'};
    +  Gl = nano_hexapod.kinematics.J*G;
    +  Gl.OutputName  = {'El1', 'El2', 'El3', 'El4', 'El5', 'El6'};
     
    -
    -

    2.2.2 Obtained Plant in the Task Space

    +
    +

    2.2.2 Obtained Plant in the Task Space

    -
    -

    2.2.3 Obtained Plant in the Joint Space

    +
    +

    2.2.3 Obtained Plant in the Joint Space

    -
    -

    2.2.4 Controller Design in the Joint Space

    +
    +

    2.2.4 Controller Design in the Joint Space

    -
    wc = 2*pi*200; % Bandwidth Bandwidth [rad/s]
    +
      wc = 2*pi*200; % Bandwidth Bandwidth [rad/s]
     
    -h = 2; % Lead parameter
    +  h = 2; % Lead parameter
     
    -Kx = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * ... % Lead
    -     (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * ... % Lead
    -     (s + 2*pi*10)/s * ... % Pseudo Integrator
    -     1/(1+s/2/pi/500); % Low pass Filter
    +  Kx = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * ... % Lead
    +       (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * ... % Lead
    +       (s + 2*pi*10)/s * ... % Pseudo Integrator
    +       1/(1+s/2/pi/500); % Low pass Filter
     
    -% 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))));
     
    -
    wc = 2*pi*200; % Bandwidth Bandwidth [rad/s]
    +
      wc = 2*pi*200; % Bandwidth Bandwidth [rad/s]
     
    -h = 2; % Lead parameter
    +  h = 2; % Lead parameter
     
    -Kl = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * ... % Lead
    -     (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * ... % Lead
    -     (s + 2*pi*1)/s * ... % Pseudo Integrator
    -     (s + 2*pi*10)/s * ... % Pseudo Integrator
    -     1/(1+s/2/pi/500); % Low pass Filter
    +  Kl = (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * ... % Lead
    +       (1/h) * (1 + s/wc*h)/(1 + s/wc/h) * ... % Lead
    +       (s + 2*pi*1)/s * ... % Pseudo Integrator
    +       (s + 2*pi*10)/s * ... % Pseudo Integrator
    +       1/(1+s/2/pi/500); % Low pass Filter
     
    -% Normalization of the gain of have a loop gain of 1 at frequency wc
    -Kl = Kl.*diag(1./diag(abs(freqresp(Gl*Kl, wc))));
    +  % Normalization of the gain of have a loop gain of 1 at frequency wc
    +  Kl = Kl.*diag(1./diag(abs(freqresp(Gl*Kl, wc))));
     
    -
    -

    2.3 On the usefulness of the High Authority Control loop / Linearization loop

    +
    +

    2.3 On the usefulness of the High Authority Control loop / Linearization loop

    Let’s see what happens is we omit the HAC loop and we directly try to control the damped plant using the measurement of the sample with respect to the granite \(\bm{\mathcal{X}}\). @@ -1115,170 +1119,170 @@ Let’s see what happens is we omit the HAC loop and we directly try to cont We can do that in two different ways:

      -
    • in the task space as shown in Figure 22
    • -
    • in the space of the legs as shown in Figure 23
    • +
    • in the task space as shown in Figure 22
    • +
    • in the space of the legs as shown in Figure 23
    -
    +

    control_architecture_iff_X.png

    Figure 22: IFF control + primary controller in the task space

    -
    +

    control_architecture_iff_L.png

    Figure 23: HAC-LAC control architecture in the frame of the legs

    -
    -

    2.3.1 Identification

    +
    +

    2.3.1 Identification

    -
    initializeController('type', 'hac-iff');
    +
      initializeController('type', 'hac-iff');
     
    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller/HAC-IFF/Kx'],  1, 'input');    io_i = io_i + 1;
    -io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1; % Position Errror
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller/HAC-IFF/Kx'],  1, 'input');    io_i = io_i + 1;
    +  io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1; % Position Errror
     
    -%% Run the linearization
    -G = linearize(mdl, io, 0);
    -G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    -G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
    +  %% Run the linearization
    +  G = linearize(mdl, io, 0);
    +  G.InputName  = {'F1', 'F2', 'F3', 'F4', 'F5', 'F6'};
    +  G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
     
    -
    isstable(G)
    -G = -minreal(G);
    -isstable(G)
    +
      isstable(G)
    +  G = -minreal(G);
    +  isstable(G)
     
    -
    -

    2.3.2 Plant in the Task space

    +
    +

    2.3.2 Plant in the Task space

    The obtained plant is shown in Figure

    -
    Gx = G*inv(nano_hexapod.kinematics.J');
    +
      Gx = G*inv(nano_hexapod.kinematics.J');
     
    -
    -

    2.3.3 Plant in the Leg’s space

    +
    +

    2.3.3 Plant in the Leg’s space

    -
    Gl = nano_hexapod.kinematics.J*G;
    +
      Gl = nano_hexapod.kinematics.J*G;
     
    -
    -

    2.4 DVF instead of IFF?

    +
    +

    2.4 DVF instead of IFF?

    -
    -

    2.4.1 Initialization and Identification

    +
    +

    2.4.1 Initialization and Identification

    -
    initializeController('type', 'hac-dvf');
    -Kdvf = tf(zeros(6));
    +
      initializeController('type', 'hac-dvf');
    +  Kdvf = tf(zeros(6));
     
    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller'],    1, 'openinput');               io_i = io_i + 1; % Actuator Inputs
    -io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Dnlm');  io_i = io_i + 1; % Displacement Sensors
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller'],    1, 'openinput');               io_i = io_i + 1; % Actuator Inputs
    +  io(io_i) = linio([mdl, '/Micro-Station'], 3, 'openoutput', [], 'Dnlm');  io_i = io_i + 1; % Displacement Sensors
     
    -%% Run the linearization
    -G_dvf = linearize(mdl, io, 0);
    -G_dvf.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    -G_dvf.OutputName = {'Dlm1', 'Dlm2', 'Dlm3', 'Dlm4', 'Dlm5', 'Dlm6'};
    +  %% Run the linearization
    +  G_dvf = linearize(mdl, io, 0);
    +  G_dvf.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    +  G_dvf.OutputName = {'Dlm1', 'Dlm2', 'Dlm3', 'Dlm4', 'Dlm5', 'Dlm6'};
     
    -
    -

    2.4.2 Obtained Plant

    +
    +

    2.4.2 Obtained Plant

    -
    -

    2.4.3 Controller

    +
    +

    2.4.3 Controller

    -
    Kdvf = -850*s/(1+s/2/pi/1000)*eye(6);
    +
      Kdvf = -850*s/(1+s/2/pi/1000)*eye(6);
     
    -
    -

    2.4.4 HAC Identification

    +
    +

    2.4.4 HAC Identification

    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Controller/HAC-DVF/Kx'],  1, 'input');    io_i = io_i + 1; % Control input
    -io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1; % Position Errror
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Controller/HAC-DVF/Kx'],  1, 'input');    io_i = io_i + 1; % Control input
    +  io(io_i) = linio([mdl, '/Tracking Error'], 1, 'output', [], 'En'); io_i = io_i + 1; % Position Errror
     
    -%% Run the linearization
    -G = linearize(mdl, io, 0);
    -G.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    -G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
    +  %% Run the linearization
    +  G = linearize(mdl, io, 0);
    +  G.InputName  = {'Fnl1', 'Fnl2', 'Fnl3', 'Fnl4', 'Fnl5', 'Fnl6'};
    +  G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
     
    -
    isstable(G)
    -G = -minreal(G);
    -isstable(G)
    +
      isstable(G)
    +  G = -minreal(G);
    +  isstable(G)
     
    -
    load('mat/stages.mat', 'nano_hexapod');
    -Gx = G*inv(nano_hexapod.kinematics.J');
    -Gx.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    +
      load('mat/stages.mat', 'nano_hexapod');
    +  Gx = G*inv(nano_hexapod.kinematics.J');
    +  Gx.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
     
    -Gl = nano_hexapod.kinematics.J*G;
    -Gl.OutputName  = {'El1', 'El2', 'El3', 'El4', 'El5', 'El6'};
    +  Gl = nano_hexapod.kinematics.J*G;
    +  Gl.OutputName  = {'El1', 'El2', 'El3', 'El4', 'El5', 'El6'};
     
    -
    -

    2.4.5 Conclusion

    +
    +

    2.4.5 Conclusion

    -
    +

    DVF can be used instead of IFF.

    @@ -1291,7 +1295,7 @@ DVF can be used instead of IFF.

    Author: Dehaeze Thomas

    -

    Created: 2020-05-05 mar. 10:34

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/disturbances.html b/docs/disturbances.html index 944b364..4f517ca 100644 --- a/docs/disturbances.html +++ b/docs/disturbances.html @@ -3,31 +3,36 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Identification of the disturbances - - - - - - - - + + + +

    Identification of the disturbances

    @@ -41,12 +46,12 @@
  • 5. Compute the Power Spectral Density of the disturbance force
  • 6. Noise Budget
  • 7. Save
  • -
  • 8. Time Domain Disturbances
  • -
  • 9. Time Domain Effect of Disturbances +
  • 8. Time Domain Disturbances
  • +
  • 9. Time Domain Effect of Disturbances
  • @@ -58,7 +63,7 @@ The goal here is to extract the Power Spectral Density of the sources of perturb

    -The sources of perturbations are (schematically shown in figure 1): +The sources of perturbations are (schematically shown in figure 1):

    • \(D_w\): Ground Motion
    • @@ -67,11 +72,11 @@ These forces can be due to imperfect guiding for instance.

    -Because we cannot measure directly the perturbation forces, we have the measure the effect of those perturbations on the system (in terms of velocity for instance using geophones, \(D\) on figure 1) and then, using a model, compute the forces that induced such velocity. +Because we cannot measure directly the perturbation forces, we have the measure the effect of those perturbations on the system (in terms of velocity for instance using geophones, \(D\) on figure 1) and then, using a model, compute the forces that induced such velocity.

    -
    +

    uniaxial-model-micro-station.png

    Figure 1: Schematic of the Micro Station and the sources of disturbance

    @@ -82,19 +87,19 @@ Because we cannot measure directly the perturbation forces, we have the measure This file is divided in the following sections:

      -
    • Section 1: the simscape model used here is presented
    • -
    • Section 2: transfer functions from the disturbance forces to the relative velocity of the hexapod with respect to the granite are computed using the Simscape Model representing the experimental setup
    • -
    • Section 3: the bode plot of those transfer functions are shown
    • -
    • Section 4: the measured PSD of the effect of the disturbances are shown
    • -
    • Section 5: from the model and the measured PSD, the PSD of the disturbance forces are computed
    • -
    • Section 6: with the computed PSD, the noise budget of the system is done
    • +
    • Section 1: the simscape model used here is presented
    • +
    • Section 2: transfer functions from the disturbance forces to the relative velocity of the hexapod with respect to the granite are computed using the Simscape Model representing the experimental setup
    • +
    • Section 3: the bode plot of those transfer functions are shown
    • +
    • Section 4: the measured PSD of the effect of the disturbances are shown
    • +
    • Section 5: from the model and the measured PSD, the PSD of the disturbance forces are computed
    • +
    • Section 6: with the computed PSD, the noise budget of the system is done

    1 Simscape Model

    - +

    @@ -111,8 +116,8 @@ Also, we measure the absolute displacement of the granite and of the top platfor We load the configuration and we set a small StopTime.

    -
    load('mat/conf_simulink.mat');
    -set_param(conf_simulink, 'StopTime', '0.5');
    +
      load('mat/conf_simulink.mat');
    +  set_param(conf_simulink, 'StopTime', '0.5');
     
    @@ -121,16 +126,16 @@ We initialize all the stages without the sample nor the nano-hexapod. The obtained system corresponds to the status micro-station when the vibration measurements were conducted.

    -
    initializeGround();
    -initializeGranite('type', 'modal-analysis');
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod('type', 'modal-analysis');
    -initializeAxisc('type', 'none');
    -initializeMirror('type', 'none');
    -initializeNanoHexapod('type', 'none');
    -initializeSample('type', 'none');
    +
      initializeGround();
    +  initializeGranite('type', 'modal-analysis');
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod('type', 'modal-analysis');
    +  initializeAxisc('type', 'none');
    +  initializeMirror('type', 'none');
    +  initializeNanoHexapod('type', 'none');
    +  initializeSample('type', 'none');
     
    @@ -138,7 +143,7 @@ initializeSample('type', 'none'); Open Loop Control.

    -
    initializeController('type', 'open-loop');
    +
      initializeController('type', 'open-loop');
     
    @@ -146,7 +151,7 @@ Open Loop Control. We don’t need gravity here.

    -
    initializeSimscapeConfiguration('gravity', false);
    +
      initializeSimscapeConfiguration('gravity', false);
     
    @@ -154,7 +159,7 @@ We don’t need gravity here. We log the signals.

    -
    initializeLoggingConfiguration('log', 'all');
    +
      initializeLoggingConfiguration('log', 'all');
     
    @@ -164,25 +169,25 @@ We log the signals.

    2 Identification

    - + The transfer functions from the disturbance forces to the relative velocity of the hexapod with respect to the granite are computed using the Simscape Model representing the experimental setup with the code below.

    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Micro-Hexapod
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'Dwz'); io_i = io_i + 1; % Vertical Ground Motion
    -io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'Fty_z'); io_i = io_i + 1; % Parasitic force Ty
    -io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'Frz_z'); io_i = io_i + 1; % Parasitic force Rz
    +  %% Micro-Hexapod
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'Dwz'); io_i = io_i + 1; % Vertical Ground Motion
    +  io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'Fty_z'); io_i = io_i + 1; % Parasitic force Ty
    +  io(io_i) = linio([mdl, '/Disturbances'], 1, 'openinput', [], 'Frz_z'); io_i = io_i + 1; % Parasitic force Rz
     
    -io(io_i) = linio([mdl, '/Micro-Station/Granite/Modal Analysis/accelerometer'], 1, 'openoutput'); io_i = io_i + 1; % Absolute motion - Granite
    -io(io_i) = linio([mdl, '/Micro-Station/Micro Hexapod/Modal Analysis/accelerometer'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Motion - Hexapod
    +  io(io_i) = linio([mdl, '/Micro-Station/Granite/Modal Analysis/accelerometer'], 1, 'openoutput'); io_i = io_i + 1; % Absolute motion - Granite
    +  io(io_i) = linio([mdl, '/Micro-Station/Micro Hexapod/Modal Analysis/accelerometer'],  1, 'openoutput'); io_i = io_i + 1; % Absolute Motion - Hexapod
     
    -% Run the linearization
    -G = linearize(mdl, io, 0);
    +  % Run the linearization
    +  G = linearize(mdl, io, 0);
     
    @@ -190,11 +195,11 @@ G = linearize(mdl, io, 0); We Take only the outputs corresponding to the vertical acceleration.

    -
    G = G([3,9], :);
    +
      G = G([3,9], :);
     
    -% Input/Output names
    -G.InputName  = {'Dw', 'Fty', 'Frz'};
    -G.OutputName = {'Agm', 'Ahm'};
    +  % Input/Output names
    +  G.InputName  = {'Dw', 'Fty', 'Frz'};
    +  G.OutputName = {'Agm', 'Ahm'};
     
    @@ -202,11 +207,11 @@ G.OutputName = {'Agm', 'Ahm'}; We integrate 1 time the output to have the velocity and we substract the absolute velocities to have the relative velocity.

    -
    G = (1/s)*tf([-1, 1])*G;
    +
      G = (1/s)*tf([-1, 1])*G;
     
    -% Input/Output names
    -G.InputName  = {'Dw', 'Fty', 'Frz'};
    -G.OutputName = {'Vm'};
    +  % Input/Output names
    +  G.InputName  = {'Dw', 'Fty', 'Frz'};
    +  G.OutputName = {'Vm'};
     
    @@ -216,19 +221,19 @@ G.OutputName = {'Vm'};

    3 Sensitivity to Disturbances

    - +

    The obtained sensitivity to disturbances are shown bellow:

      -
    • The transfer function from vertical ground motion \(D_w\) to the vertical relative displacement from the micro-hexapod to the granite \(D\) is shown in Figure 2
    • -
    • The sensitive from vertical forces applied in the Translation stage is shown in Figure 3
    • +
    • The transfer function from vertical ground motion \(D_w\) to the vertical relative displacement from the micro-hexapod to the granite \(D\) is shown in Figure 2
    • +
    • The sensitive from vertical forces applied in the Translation stage is shown in Figure 3
    -
    +

    sensitivity_dist_gm.png

    Figure 2: Sensitivity to Ground Motion (png, pdf)

    @@ -236,7 +241,7 @@ The obtained sensitivity to disturbances are shown bellow: -
    +

    sensitivity_dist_fty.png

    Figure 3: Sensitivity to vertical forces applied by the Ty stage (png, pdf)

    @@ -244,7 +249,7 @@ The obtained sensitivity to disturbances are shown bellow: -
    +

    sensitivity_dist_frz.png

    Figure 4: Sensitivity to vertical forces applied by the Rz stage (png, pdf)

    @@ -256,7 +261,7 @@ The obtained sensitivity to disturbances are shown bellow:

    4 Power Spectral Density of the effect of the disturbances

    - +

    @@ -272,10 +277,10 @@ Also, the Ground Motion is measured.

    -
    gm  = load('./mat/psd_gm.mat', 'f', 'psd_gm');
    -rz  = load('./mat/pxsp_r.mat', 'f', 'pxsp_r');
    -tyz = load('./mat/pxz_ty_r.mat', 'f', 'pxz_ty_r');
    -tyx = load('./mat/pxe_ty_r.mat', 'f', 'pxe_ty_r');
    +
      gm  = load('./mat/psd_gm.mat', 'f', 'psd_gm');
    +  rz  = load('./mat/pxsp_r.mat', 'f', 'pxsp_r');
    +  tyz = load('./mat/pxz_ty_r.mat', 'f', 'pxz_ty_r');
    +  tyx = load('./mat/pxe_ty_r.mat', 'f', 'pxe_ty_r');
     
    @@ -283,11 +288,11 @@ tyx = load('./mat/pxe_ty_r.mat', 'f', 'pxe_ty_r'); Because some 50Hz and harmonics were present in the ground motion measurement, we remove these peaks with the following code:

    -
    f0s = [50, 100, 150, 200, 250, 350, 450];
    -for f0 = f0s
    -    i = find(gm.f > f0-0.5 & gm.f < f0+0.5);
    -    gm.psd_gm(i) = linspace(gm.psd_gm(i(1)), gm.psd_gm(i(end)), length(i));
    -end
    +
      f0s = [50, 100, 150, 200, 250, 350, 450];
    +  for f0 = f0s
    +      i = find(gm.f > f0-0.5 & gm.f < f0+0.5);
    +      gm.psd_gm(i) = linspace(gm.psd_gm(i(1)), gm.psd_gm(i(end)), length(i));
    +  end
     
    @@ -295,20 +300,20 @@ end We now compute the relative velocity between the hexapod and the granite due to ground motion.

    -
    gm.psd_rv = gm.psd_gm.*abs(squeeze(freqresp(G('Vm', 'Dw'), gm.f, 'Hz'))).^2;
    +
      gm.psd_rv = gm.psd_gm.*abs(squeeze(freqresp(G('Vm', 'Dw'), gm.f, 'Hz'))).^2;
     

    -The Power Spectral Density of the relative motion and velocity of the hexapod with respect to the granite are shown in figures 5 and 6. +The Power Spectral Density of the relative motion and velocity of the hexapod with respect to the granite are shown in figures 5 and 6.

    -The Cumulative Amplitude Spectrum of the relative motion is shown in figure 7. +The Cumulative Amplitude Spectrum of the relative motion is shown in figure 7.

    -
    +

    dist_effect_relative_velocity.png

    Figure 5: Amplitude Spectral Density of the relative velocity of the hexapod with respect to the granite due to different sources of perturbation (png, pdf)

    @@ -316,22 +321,22 @@ The Cumulative Amplitude Spectrum of the relative motion is shown in figure + -
    +

    dist_effect_relative_motion_cas.png

    Figure 7: Cumulative Amplitude Spectrum of the relative motion due to different sources of perturbation (png, pdf)

    -
    +

    -From Figure 7, we can see that the translation stage and the rotation stage have almost the same effect on the position error. +From Figure 7, we can see that the translation stage and the rotation stage have almost the same effect on the position error. Also, the ground motion has a relatively negligible effect on the position error.

    @@ -343,28 +348,28 @@ Also, the ground motion has a relatively negligible effect on the position error

    5 Compute the Power Spectral Density of the disturbance force

    - +

    -Using the extracted transfer functions from the disturbance force to the relative motion of the hexapod with respect to the granite (section 3) and using the measured PSD of the relative motion (section 4), we can compute the PSD of the disturbance force. +Using the extracted transfer functions from the disturbance force to the relative motion of the hexapod with respect to the granite (section 3) and using the measured PSD of the relative motion (section 4), we can compute the PSD of the disturbance force.

    This is done below.

    -
    rz.psd_f  = rz.pxsp_r./abs(squeeze(freqresp(G('Vm', 'Frz'), rz.f, 'Hz'))).^2;
    -tyz.psd_f = tyz.pxz_ty_r./abs(squeeze(freqresp(G('Vm', 'Fty'), tyz.f, 'Hz'))).^2;
    +
      rz.psd_f  = rz.pxsp_r./abs(squeeze(freqresp(G('Vm', 'Frz'), rz.f, 'Hz'))).^2;
    +  tyz.psd_f = tyz.pxz_ty_r./abs(squeeze(freqresp(G('Vm', 'Fty'), tyz.f, 'Hz'))).^2;
     

    -The obtained amplitude spectral densities of the disturbance forces are shown in Figure 8. +The obtained amplitude spectral densities of the disturbance forces are shown in Figure 8.

    -
    +

    dist_force_psd.png

    Figure 8: Amplitude Spectral Density of the disturbance force (png, pdf)

    @@ -376,7 +381,7 @@ The obtained amplitude spectral densities of the disturbance forces are shown in

    6 Noise Budget

    - +

    @@ -389,18 +394,18 @@ This is done in order to verify that this is coherent with the measurements.

    -The power spectral density of the relative motion is computed below and the result is shown in Figure 9. -We can see that this is exactly the same as the Figure 6. +The power spectral density of the relative motion is computed below and the result is shown in Figure 9. +We can see that this is exactly the same as the Figure 6.

    -
    psd_gm_d = gm.psd_gm.*abs(squeeze(freqresp(G('Vm', 'Dw')/s, gm.f, 'Hz'))).^2;
    -psd_ty_d = tyz.psd_f.*abs(squeeze(freqresp(G('Vm', 'Fty')/s, tyz.f, 'Hz'))).^2;
    -psd_rz_d = rz.psd_f.*abs(squeeze(freqresp(G('Vm', 'Frz')/s, rz.f, 'Hz'))).^2;
    +
      psd_gm_d = gm.psd_gm.*abs(squeeze(freqresp(G('Vm', 'Dw')/s, gm.f, 'Hz'))).^2;
    +  psd_ty_d = tyz.psd_f.*abs(squeeze(freqresp(G('Vm', 'Fty')/s, tyz.f, 'Hz'))).^2;
    +  psd_rz_d = rz.psd_f.*abs(squeeze(freqresp(G('Vm', 'Frz')/s, rz.f, 'Hz'))).^2;
     
    -
    +

    psd_effect_dist_verif.png

    Figure 9: Computed Effect of the disturbances on the relative displacement hexapod/granite (png, pdf)

    @@ -416,38 +421,38 @@ The PSD of the disturbance force are now saved for further analysis.

    -
    dist_f = struct();
    +
      dist_f = struct();
     
    -dist_f.f = gm.f; % Frequency Vector [Hz]
    +  dist_f.f = gm.f; % Frequency Vector [Hz]
     
    -dist_f.psd_gm = gm.psd_gm; % Power Spectral Density of the Ground Motion [m^2/Hz]
    -dist_f.psd_ty = tyz.psd_f; % Power Spectral Density of the force induced by the Ty stage in the Z direction [N^2/Hz]
    -dist_f.psd_rz = rz.psd_f; % Power Spectral Density of the force induced by the Rz stage in the Z direction [N^2/Hz]
    +  dist_f.psd_gm = gm.psd_gm; % Power Spectral Density of the Ground Motion [m^2/Hz]
    +  dist_f.psd_ty = tyz.psd_f; % Power Spectral Density of the force induced by the Ty stage in the Z direction [N^2/Hz]
    +  dist_f.psd_rz = rz.psd_f; % Power Spectral Density of the force induced by the Rz stage in the Z direction [N^2/Hz]
     
    -save('./mat/dist_psd.mat', 'dist_f');
    +  save('./mat/dist_psd.mat', 'dist_f');
     
    -
    -

    8 Time Domain Disturbances

    +
    +

    8 Time Domain Disturbances

    Let’s initialize the time domain disturbances and load them.

    -
    initializeDisturbances();
    -dist = load('nass_disturbances.mat');
    +
      initializeDisturbances();
    +  dist = load('nass_disturbances.mat');
     

    -The time domain disturbance signals are shown in Figure 10. +The time domain disturbance signals are shown in Figure 10.

    -
    +

    disturbances_time_domain.png

    Figure 10: Disturbances in the Time Domain (png, pdf)

    @@ -455,25 +460,25 @@ The time domain disturbance signals are shown in Figure 10
    -
    -

    9 Time Domain Effect of Disturbances

    +
    +

    9 Time Domain Effect of Disturbances

    -
    -

    9.1 Initialization of the Experiment

    +
    +

    9.1 Initialization of the Experiment

    We initialize all the stages with the default parameters.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
     
    @@ -481,37 +486,37 @@ initializeMirror(); The nano-hexapod is a piezoelectric hexapod and the sample has a mass of 50kg.

    -
    initializeNanoHexapod('type', 'rigid');
    -initializeSample('mass', 1);
    +
      initializeNanoHexapod('type', 'rigid');
    +  initializeSample('mass', 1);
     
    -
    initializeReferences();
    -initializeController('type', 'open-loop');
    -initializeSimscapeConfiguration('gravity', false);
    -initializeLoggingConfiguration('log', 'all');
    +
      initializeReferences();
    +  initializeController('type', 'open-loop');
    +  initializeSimscapeConfiguration('gravity', false);
    +  initializeLoggingConfiguration('log', 'all');
     
    -
    load('mat/conf_simulink.mat');
    -set_param(conf_simulink, 'StopTime', '2');
    +
      load('mat/conf_simulink.mat');
    +  set_param(conf_simulink, 'StopTime', '2');
     
    -
    -

    9.2 Simulations

    +
    +

    9.2 Simulations

    No disturbances:

    -
    initializeDisturbances('enable', false);
    -sim('nass_model');
    -sim_no = simout;
    +
      initializeDisturbances('enable', false);
    +  sim('nass_model');
    +  sim_no = simout;
     
    @@ -519,9 +524,9 @@ sim_no = simout; Ground Motion:

    -
    initializeDisturbances('Fty_x', false, 'Fty_z', false, 'Frz_z', false);
    -sim('nass_model');
    -sim_gm = simout;
    +
      initializeDisturbances('Fty_x', false, 'Fty_z', false, 'Frz_z', false);
    +  sim('nass_model');
    +  sim_gm = simout;
     
    @@ -529,9 +534,9 @@ sim_gm = simout; Translation Stage Vibrations:

    -
    initializeDisturbances('Dwx', false, 'Dwy', false, 'Dwz', false, 'Frz_z', false);
    -sim('nass_model');
    -sim_ty = simout;
    +
      initializeDisturbances('Dwx', false, 'Dwy', false, 'Dwz', false, 'Frz_z', false);
    +  sim('nass_model');
    +  sim_ty = simout;
     
    @@ -539,23 +544,23 @@ sim_ty = simout; Rotation Stage Vibrations:

    -
    initializeDisturbances('Dwx', false, 'Dwy', false, 'Dwz', false, 'Fty_x', false, 'Fty_z', false);
    -sim('nass_model');
    -sim_rz = simout;
    +
      initializeDisturbances('Dwx', false, 'Dwy', false, 'Dwz', false, 'Fty_x', false, 'Fty_z', false);
    +  sim('nass_model');
    +  sim_rz = simout;
     
    -
    -

    9.3 Comparison

    +
    +

    9.3 Comparison

    -Let’s now compare the effect of those perturbations on the position error of the sample (Figure 11) +Let’s now compare the effect of those perturbations on the position error of the sample (Figure 11)

    -
    +

    effect_disturbances_position_error.png

    Figure 11: Effect of Perturbations on the position error (png, pdf)

    @@ -566,7 +571,7 @@ Let’s now compare the effect of those perturbations on the position error

    Author: Dehaeze Thomas

    -

    Created: 2020-09-01 mar. 13:48

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/experiments.html b/docs/experiments.html index eb02165..64da8c8 100644 --- a/docs/experiments.html +++ b/docs/experiments.html @@ -1,66 +1,61 @@ - - + Simulation of Scientific Experiments - - - - - - + +

    Simulation of Scientific Experiments

    Table of Contents

    @@ -85,26 +80,26 @@ This has several goals: The document in organized as follow:

      -
    • In section 1 the Simscape model is initialized
    • -
    • In section 2 a tomography experiment is performed where the sample is aligned with the rotation axis. No disturbance is included
    • -
    • In section 3, the same is done but with disturbance included
    • -
    • In section 5 the micro-hexapod translate the sample such that its center of mass is no longer aligned with the rotation axis. No disturbance is included
    • -
    • In section 6, scans with the translation stage are simulated with no perturbation included
    • +
    • In section 1 the Simscape model is initialized
    • +
    • In section 2 a tomography experiment is performed where the sample is aligned with the rotation axis. No disturbance is included
    • +
    • In section 3, the same is done but with disturbance included
    • +
    • In section 5 the micro-hexapod translate the sample such that its center of mass is no longer aligned with the rotation axis. No disturbance is included
    • +
    • In section 6, scans with the translation stage are simulated with no perturbation included
    -
    -

    1 Simscape Model

    +
    +

    1 Simscape Model

    - +

    We load the shared simulink configuration and we set the StopTime.

    -
    load('mat/conf_simulink.mat');
    -set_param(conf_simulink, 'StopTime', '2');
    +
      load('mat/conf_simulink.mat');
    +  set_param(conf_simulink, 'StopTime', '2');
     
    @@ -113,16 +108,16 @@ We first initialize all the stages. The nano-hexapod is considered to be a rigid body.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    -initializeNanoHexapod('type', 'rigid');
    -initializeSample('mass', 1);
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
    +  initializeNanoHexapod('type', 'rigid');
    +  initializeSample('mass', 1);
     
    @@ -130,7 +125,7 @@ initializeSample('mass', 1); No controller is used (Open Loop).

    -
    initializeController('type', 'open-loop');
    +
      initializeController('type', 'open-loop');
     
    @@ -138,7 +133,7 @@ No controller is used (Open Loop). We don’t gravity.

    -
    initializeSimscapeConfiguration('gravity', false);
    +
      initializeSimscapeConfiguration('gravity', false);
     
    @@ -146,38 +141,38 @@ We don’t gravity. We log the signals for further analysis.

    -
    initializeLoggingConfiguration('log', 'all');
    +
      initializeLoggingConfiguration('log', 'all');
     
    -
    -

    2 Tomography Experiment with no disturbances

    +
    +

    2 Tomography Experiment with no disturbances

    - +

    In this section, a tomography experiment is performed with the sample aligned with the rotation axis. No disturbance is included.

    -
    -

    2.1 Simulation Setup

    +
    +

    2.1 Simulation Setup

    And we initialize the disturbances to be equal to zero.

    -
    initializeDisturbances(...
    -    'Dwx', false, ... % Ground Motion - X direction
    -    'Dwy', false, ... % Ground Motion - Y direction
    -    'Dwz', false, ... % Ground Motion - Z direction
    -    'Fty_x', false, ... % Translation Stage - X direction
    -    'Fty_z', false, ... % Translation Stage - Z direction
    -    'Frz_z', false  ... % Spindle - Z direction
    -    );
    +
      initializeDisturbances(...
    +      'Dwx', false, ... % Ground Motion - X direction
    +      'Dwy', false, ... % Ground Motion - Y direction
    +      'Dwz', false, ... % Ground Motion - Z direction
    +      'Fty_x', false, ... % Translation Stage - X direction
    +      'Fty_z', false, ... % Translation Stage - Z direction
    +      'Frz_z', false  ... % Spindle - Z direction
    +      );
     
    @@ -186,7 +181,7 @@ We initialize the reference path for all the stages. All stage is set to its zero position except the Spindle which is rotating at 60rpm.

    -
    initializeReferences('Rz_type', 'rotating', 'Rz_period', 1);
    +
      initializeReferences('Rz_type', 'rotating', 'Rz_period', 1);
     
    @@ -194,7 +189,7 @@ All stage is set to its zero position except the Spindle which is rotating at 60 We simulate the model.

    -
    sim('nass_model');
    +
      sim('nass_model');
     
    @@ -202,23 +197,23 @@ We simulate the model. And we save the obtained data.

    -
    tomo_align_no_dist = simout;
    -save('./mat/experiment_tomography.mat', 'tomo_align_no_dist', '-append');
    +
      tomo_align_no_dist = simout;
    +  save('./mat/experiment_tomography.mat', 'tomo_align_no_dist', '-append');
     
    -
    -

    2.2 Analysis

    +
    +

    2.2 Analysis

    -
    load('./mat/experiment_tomography.mat', 'tomo_align_no_dist');
    +
      load('./mat/experiment_tomography.mat', 'tomo_align_no_dist');
     
    -
    +

    exp_tomo_without_dist.png

    Figure 1: X-Y-Z translation of the sample w.r.t. granite when performing tomography experiment with no disturbances (png, pdf)

    @@ -226,10 +221,10 @@ save('./mat/experiment_tomography.mat', 'tomo_align_no_dist', '-append');
    -
    -

    2.3 Conclusion

    +
    +

    2.3 Conclusion

    -
    +

    When everything is aligned, the resulting error motion is very small (nm range) and is quite negligible with respect to the error when disturbances are included. This residual error motion probably comes from a small misalignment somewhere. @@ -240,32 +235,32 @@ This residual error motion probably comes from a small misalignment somewhere.

    -
    -

    3 Tomography Experiment with included perturbations

    +
    +

    3 Tomography Experiment with included perturbations

    - +

    In this section, we also perform a tomography experiment with the sample’s center of mass aligned with the rotation axis. However this time, we include perturbations such as ground motion and stage vibrations.

    -
    -

    3.1 Simulation Setup

    +
    +

    3.1 Simulation Setup

    We now activate the disturbances.

    -
    initializeDisturbances(...
    -    'Dwx', true, ... % Ground Motion - X direction
    -    'Dwy', true, ... % Ground Motion - Y direction
    -    'Dwz', true, ... % Ground Motion - Z direction
    -    'Fty_x', false, ... % Translation Stage - X direction
    -    'Fty_z', false, ... % Translation Stage - Z direction
    -    'Frz_z', true  ... % Spindle - Z direction
    -    );
    +
      initializeDisturbances(...
    +      'Dwx', true, ... % Ground Motion - X direction
    +      'Dwy', true, ... % Ground Motion - Y direction
    +      'Dwz', true, ... % Ground Motion - Z direction
    +      'Fty_x', false, ... % Translation Stage - X direction
    +      'Fty_z', false, ... % Translation Stage - Z direction
    +      'Frz_z', true  ... % Spindle - Z direction
    +      );
     
    @@ -274,7 +269,7 @@ We initialize the reference path for all the stages. All stage is set to its zero position except the Spindle which is rotating at 60rpm.

    -
    initializeReferences('Rz_type', 'rotating', 'Rz_period', 1);
    +
      initializeReferences('Rz_type', 'rotating', 'Rz_period', 1);
     
    @@ -282,7 +277,7 @@ All stage is set to its zero position except the Spindle which is rotating at 60 We simulate the model.

    -
    sim('nass_model');
    +
      sim('nass_model');
     
    @@ -290,23 +285,23 @@ We simulate the model. And we save the obtained data.

    -
    tomo_align_dist = simout;
    -save('./mat/experiment_tomography.mat', 'tomo_align_dist', '-append');
    +
      tomo_align_dist = simout;
    +  save('./mat/experiment_tomography.mat', 'tomo_align_dist', '-append');
     
    -
    -

    3.2 Analysis

    +
    +

    3.2 Analysis

    -
    load('./mat/experiment_tomography.mat', 'tomo_align_dist', 'tomo_align_no_dist');
    +
      load('./mat/experiment_tomography.mat', 'tomo_align_dist', 'tomo_align_no_dist');
     
    -
    +

    exp_tomo_dist.png

    Figure 2: X-Y-Z translations and rotations of the sample w.r.t. the granite when performing tomography experiment with disturbances (png, pdf)

    @@ -314,10 +309,10 @@ save('./mat/experiment_tomography.mat', 'tomo_align_dist', '-append');
    -
    -

    3.3 Conclusion

    +
    +

    3.3 Conclusion

    -
    +

    Here, no vibration is included in the X and Y directions.

    @@ -327,32 +322,32 @@ Here, no vibration is included in the X and Y directions.
    -
    -

    4 Tomography Experiment with Ty raster scans

    +
    +

    4 Tomography Experiment with Ty raster scans

    - +

    In this section, we also perform a tomography experiment with scans of the Translation stage. All the perturbations are included.

    -
    -

    4.1 Simulation Setup

    +
    +

    4.1 Simulation Setup

    We now activate the disturbances.

    -
    initializeDisturbances(...
    -    'Dwx', true, ... % Ground Motion - X direction
    -    'Dwy', true, ... % Ground Motion - Y direction
    -    'Dwz', true, ... % Ground Motion - Z direction
    -    'Fty_x', true, ... % Translation Stage - X direction
    -    'Fty_z', true, ... % Translation Stage - Z direction
    -    'Frz_z', true  ... % Spindle - Z direction
    -    );
    +
      initializeDisturbances(...
    +      'Dwx', true, ... % Ground Motion - X direction
    +      'Dwy', true, ... % Ground Motion - Y direction
    +      'Dwz', true, ... % Ground Motion - Z direction
    +      'Fty_x', true, ... % Translation Stage - X direction
    +      'Fty_z', true, ... % Translation Stage - Z direction
    +      'Frz_z', true  ... % Spindle - Z direction
    +      );
     
    @@ -362,7 +357,7 @@ The Spindle which is rotating at 60rpm and the translation stage not moving as i However, vibrations of the Ty stage are included.

    -
    initializeReferences('Rz_type', 'rotating', 'Rz_period', 1);
    +
      initializeReferences('Rz_type', 'rotating', 'Rz_period', 1);
     
    @@ -370,7 +365,7 @@ However, vibrations of the Ty stage are included. We simulate the model.

    -
    sim('nass_model');
    +
      sim('nass_model');
     
    @@ -378,23 +373,23 @@ We simulate the model. And we save the obtained data.

    -
    scans_rz_align_dist = simout;
    -save('./mat/experiment_tomography.mat', 'scans_rz_align_dist', '-append');
    +
      scans_rz_align_dist = simout;
    +  save('./mat/experiment_tomography.mat', 'scans_rz_align_dist', '-append');
     
    -
    -

    4.2 Analysis

    +
    +

    4.2 Analysis

    -
    load('./mat/experiment_tomography.mat', 'scans_rz_align_dist');
    +
      load('./mat/experiment_tomography.mat', 'scans_rz_align_dist');
     
    -
    +

    exp_scans_rz_dist.png

    Figure 3: X-Y-Z translations and rotations of the sample w.r.t. the granite when performing tomography experiment and scans with the translation stage at the same time

    @@ -402,16 +397,16 @@ save('./mat/experiment_tomography.mat', 'scans_rz_align_dist', '-append');
    -
    -

    4.3 Conclusion

    +
    +

    4.3 Conclusion

    -
    -

    5 Tomography when the micro-hexapod is not centered

    +
    +

    5 Tomography when the micro-hexapod is not centered

    - +

    In this section, the sample’s center of mass is not aligned with the rotation axis anymore. @@ -422,14 +417,14 @@ This is due to the fact that the micro-hexapod has performed some displacement. No disturbances are included.

    -
    -

    5.1 Simulation Setup

    +
    +

    5.1 Simulation Setup

    We first set the wanted translation of the Micro Hexapod.

    -
    P_micro_hexapod = [0.01; 0; 0]; % [m]
    +
      P_micro_hexapod = [0.01; 0; 0]; % [m]
     
    @@ -437,7 +432,7 @@ We first set the wanted translation of the Micro Hexapod. We initialize the reference path.

    -
    initializeReferences('Dh_pos', [P_micro_hexapod; 0; 0; 0], 'Rz_type', 'rotating', 'Rz_period', 1);
    +
      initializeReferences('Dh_pos', [P_micro_hexapod; 0; 0; 0], 'Rz_type', 'rotating', 'Rz_period', 1);
     
    @@ -445,7 +440,7 @@ We initialize the reference path. We initialize the stages.

    -
    initializeMicroHexapod('AP', P_micro_hexapod);
    +
      initializeMicroHexapod('AP', P_micro_hexapod);
     
    @@ -453,14 +448,14 @@ We initialize the stages. And we initialize the disturbances to zero.

    -
    initializeDisturbances(...
    -    'Dwx', false, ... % Ground Motion - X direction
    -    'Dwy', false, ... % Ground Motion - Y direction
    -    'Dwz', false, ... % Ground Motion - Z direction
    -    'Fty_x', false, ... % Translation Stage - X direction
    -    'Fty_z', false, ... % Translation Stage - Z direction
    -    'Frz_z', false  ... % Spindle - Z direction
    -    );
    +
      initializeDisturbances(...
    +      'Dwx', false, ... % Ground Motion - X direction
    +      'Dwy', false, ... % Ground Motion - Y direction
    +      'Dwz', false, ... % Ground Motion - Z direction
    +      'Fty_x', false, ... % Translation Stage - X direction
    +      'Fty_z', false, ... % Translation Stage - Z direction
    +      'Frz_z', false  ... % Spindle - Z direction
    +      );
     
    @@ -468,7 +463,7 @@ And we initialize the disturbances to zero. We simulate the model.

    -
    sim('nass_model');
    +
      sim('nass_model');
     
    @@ -476,23 +471,23 @@ We simulate the model. And we save the obtained data.

    -
    tomo_not_align = simout;
    -save('./mat/experiment_tomography.mat', 'tomo_not_align', '-append');
    +
      tomo_not_align = simout;
    +  save('./mat/experiment_tomography.mat', 'tomo_not_align', '-append');
     
    -
    -

    5.2 Analysis

    +
    +

    5.2 Analysis

    -
    load('./mat/experiment_tomography.mat', 'tomo_not_align', 'tomo_align_no_dist');
    +
      load('./mat/experiment_tomography.mat', 'tomo_not_align', 'tomo_align_no_dist');
     
    -
    +

    exp_tomo_offset.png

    Figure 4: X-Y-Z translation of the sample w.r.t. granite when performing tomography experiment with no disturbances (png, pdf)

    @@ -500,10 +495,10 @@ save('./mat/experiment_tomography.mat', 'tomo_not_align', '-append');
    -
    -

    5.3 Conclusion

    +
    +

    5.3 Conclusion

    -
    +

    The main motion error are 1Hz X-Y translations and constant Ry error. This is mainly due to finite stiffness of the elements. @@ -514,33 +509,33 @@ This is mainly due to finite stiffness of the elements.

    -
    -

    6 Raster Scans with the translation stage

    +
    +

    6 Raster Scans with the translation stage

    - +

    In this section, scans with the translation stage are performed.

    -
    -

    6.1 Simulation Setup

    +
    +

    6.1 Simulation Setup

    We initialize the stages.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    -initializeNanoHexapod('type', 'rigid');
    -initializeSample('mass', 1);
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
    +  initializeNanoHexapod('type', 'rigid');
    +  initializeSample('mass', 1);
     
    @@ -548,14 +543,14 @@ initializeSample('mass', 1); And we initialize the disturbances to zero.

    -
    initializeDisturbances(...
    -    'Dwx', false, ... % Ground Motion - X direction
    -    'Dwy', false, ... % Ground Motion - Y direction
    -    'Dwz', false, ... % Ground Motion - Z direction
    -    'Fty_x', false, ... % Translation Stage - X direction
    -    'Fty_z', false, ... % Translation Stage - Z direction
    -    'Frz_z', false  ... % Spindle - Z direction
    -    );
    +
      initializeDisturbances(...
    +      'Dwx', false, ... % Ground Motion - X direction
    +      'Dwy', false, ... % Ground Motion - Y direction
    +      'Dwz', false, ... % Ground Motion - Z direction
    +      'Fty_x', false, ... % Translation Stage - X direction
    +      'Fty_z', false, ... % Translation Stage - Z direction
    +      'Frz_z', false  ... % Spindle - Z direction
    +      );
     
    @@ -563,7 +558,7 @@ And we initialize the disturbances to zero. We set the reference path to be a triangular signal for the Translation Stage.

    -
    initializeReferences('Dy_type', 'triangular', 'Dy_amplitude', 10e-3, 'Dy_period', 1);
    +
      initializeReferences('Dy_type', 'triangular', 'Dy_amplitude', 10e-3, 'Dy_period', 1);
     
    @@ -571,7 +566,7 @@ We set the reference path to be a triangular signal for the Translation Stage. We simulate the model.

    -
    sim('nass_model');
    +
      sim('nass_model');
     
    @@ -579,8 +574,8 @@ We simulate the model. And we save the obtained data.

    -
    ty_scan_triangle = simout;
    -save('./mat/experiment_tomography.mat', 'ty_scan_triangle', '-append');
    +
      ty_scan_triangle = simout;
    +  save('./mat/experiment_tomography.mat', 'ty_scan_triangle', '-append');
     
    @@ -588,7 +583,7 @@ save('./mat/experiment_tomography.mat', 'ty_scan_triangle', '-append'); We now set the reference path to be a sinusoidal signal for the Translation Stage.

    -
    initializeReferences('Dy_type', 'sinusoidal', 'Dy_amplitude', 10e-3, 'Dy_period', 1);
    +
      initializeReferences('Dy_type', 'sinusoidal', 'Dy_amplitude', 10e-3, 'Dy_period', 1);
     
    @@ -596,7 +591,7 @@ We now set the reference path to be a sinusoidal signal for the Translation Stag We simulate the model.

    -
    sim('nass_model');
    +
      sim('nass_model');
     
    @@ -604,23 +599,23 @@ We simulate the model. And we save the obtained data.

    -
    ty_scan_sinus = simout;
    -save('./mat/experiment_tomography.mat', 'ty_scan_sinus', '-append');
    +
      ty_scan_sinus = simout;
    +  save('./mat/experiment_tomography.mat', 'ty_scan_sinus', '-append');
     
    -
    -

    6.2 Analysis

    +
    +

    6.2 Analysis

    -
    load('./mat/experiment_tomography.mat', 'ty_scan_triangle', 'ty_scan_sinus');
    +
      load('./mat/experiment_tomography.mat', 'ty_scan_triangle', 'ty_scan_sinus');
     
    -
    +

    exp_ty_scan.png

    Figure 5: X-Y-Z translation of the sample w.r.t. granite when performing tomography experiment with no disturbances (png, pdf)

    @@ -628,10 +623,10 @@ save('./mat/experiment_tomography.mat', 'ty_scan_sinus', '-append');
    -
    -

    6.3 Conclusion

    +
    +

    6.3 Conclusion

    -
    +

    Scans with the translation stage induces some errors in the Y direction and Rx translations.

    @@ -648,7 +643,7 @@ Thus, this should be preferred.

    Author: Dehaeze Thomas

    -

    Created: 2020-05-05 mar. 10:34

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/flexible_joints_study.html b/docs/flexible_joints_study.html index 3eccd2c..d04b365 100644 --- a/docs/flexible_joints_study.html +++ b/docs/flexible_joints_study.html @@ -3,81 +3,86 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Study of the Flexible Joints - - - - - - - - + + + +

    Study of the Flexible Joints

    Table of Contents

    @@ -93,40 +98,40 @@ Ideally, we want the x and y rotations to be free and all the translations to be However, this is never the case and be have to consider:

      -
    • Finite bending stiffnesses (Section 1)
    • -
    • Axial stiffness in the direction of the legs (Section 2)
    • +
    • Finite bending stiffnesses (Section 1)
    • +
    • Axial stiffness in the direction of the legs (Section 2)

    -This may impose some limitations, also, the goal is to specify the required joints stiffnesses (summarized in Section 3). +This may impose some limitations, also, the goal is to specify the required joints stiffnesses (summarized in Section 3).

    -
    -

    1 Bending and Torsional Stiffness

    +
    +

    1 Bending and Torsional Stiffness

    - +

    In this section, we wish to study the effect of the rotation flexibility of the nano-hexapod joints.

    -
    -

    1.1 Initialization

    +
    +

    1.1 Initialization

    Let’s initialize all the stages with default parameters.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
     
    @@ -134,15 +139,15 @@ initializeMirror(); Let’s consider the heaviest mass which should we the most problematic with it comes to the flexible joints.

    -
    initializeSample('mass', 50, 'freq', 200*ones(6,1));
    -initializeReferences('Rz_type', 'rotating-not-filtered', 'Rz_period', 60);
    +
      initializeSample('mass', 50, 'freq', 200*ones(6,1));
    +  initializeReferences('Rz_type', 'rotating-not-filtered', 'Rz_period', 60);
     
    -
    -

    1.2 Realistic Bending Stiffness Values

    +
    +

    1.2 Realistic Bending Stiffness Values

    Let’s compare the ideal case (zero stiffness in rotation and infinite stiffness in translation) with a more realistic case: @@ -153,10 +158,10 @@ Let’s compare the ideal case (zero stiffness in rotation and infinite stif

    -
    Kf_M = 15*ones(6,1);
    -Kf_F = 15*ones(6,1);
    -Kt_M = 20*ones(6,1);
    -Kt_F = 20*ones(6,1);
    +
      Kf_M = 15*ones(6,1);
    +  Kf_F = 15*ones(6,1);
    +  Kt_M = 20*ones(6,1);
    +  Kt_F = 20*ones(6,1);
     
    @@ -164,8 +169,8 @@ Kt_F = 20*ones(6,1); The stiffness and damping of the nano-hexapod’s legs are:

    -
    k_opt = 1e5; % [N/m]
    -c_opt = 2e2; % [N/(m/s)]
    +
      k_opt = 1e5; % [N/m]
    +  c_opt = 2e2; % [N/(m/s)]
     
    @@ -174,20 +179,20 @@ This corresponds to the optimal identified stiffness.

    -
    -

    1.2.1 Direct Velocity Feedback

    +
    +

    1.2.1 Direct Velocity Feedback

    We identify the dynamics from actuators force \(\tau_i\) to relative motion sensors \(d\mathcal{L}_i\) with and without considering the flexible joint stiffness.

    -The obtained dynamics are shown in Figure 1. +The obtained dynamics are shown in Figure 1. It is shown that the adding of stiffness for the flexible joints does increase a little bit the frequencies of the mass suspension modes. It stiffen the structure.

    -
    +

    flex_joint_rot_dvf.png

    Figure 1: Dynamics from actuators force \(\tau_i\) to relative motion sensors \(d\mathcal{L}_i\) with (blue) and without (red) considering the flexible joint stiffness

    @@ -195,20 +200,20 @@ It is shown that the adding of stiffness for the flexible joints does increase a
    -
    -

    1.2.2 Primary Plant

    +
    +

    1.2.2 Primary Plant

    Let’s now identify the dynamics from \(\bm{\tau}^\prime\) to \(\bm{\epsilon}_{\mathcal{X}_n}\) (for the primary controller designed in the frame of the legs).

    -The dynamics is compare with and without the joint flexibility in Figure 2. +The dynamics is compare with and without the joint flexibility in Figure 2. The plant dynamics is not found to be changing significantly.

    -
    +

    flex_joints_rot_primary_plant_L.png

    Figure 2: Dynamics from \(\bm{\tau}^\prime_i\) to \(\bm{\epsilon}_{\mathcal{X}_n,i}\) with perfect joints and with flexible joints

    @@ -216,10 +221,10 @@ The plant dynamics is not found to be changing significantly.
    -
    -

    1.2.3 Conclusion

    +
    +

    1.2.3 Conclusion

    -
    +

    Considering realistic flexible joint bending stiffness for the nano-hexapod does not seems to impose any limitation on the DVF control nor on the primary control.

    @@ -233,8 +238,8 @@ It only increases a little bit the suspension modes of the sample on top of the
    -
    -

    1.3 Parametric Study

    +
    +

    1.3 Parametric Study

    We wish now to see what is the impact of the rotation stiffness of the flexible joints on the dynamics. @@ -245,7 +250,7 @@ This will help to determine the requirements on the joint’s stiffness. Let’s consider the following bending stiffness of the flexible joints:

    -
    Ks = [1, 5, 10, 50, 100]; % [Nm/rad]
    +
      Ks = [1, 5, 10, 50, 100]; % [Nm/rad]
     
    @@ -254,15 +259,15 @@ We also consider here a nano-hexapod with the identified optimal actuator stiffn

    -
    -

    1.3.1 Direct Velocity Feedback

    +
    +

    1.3.1 Direct Velocity Feedback

    -The dynamics from the actuators to the relative displacement sensor in each leg is identified and shown in Figure 3. +The dynamics from the actuators to the relative displacement sensor in each leg is identified and shown in Figure 3.

    -The corresponding Root Locus plot is shown in Figure 4. +The corresponding Root Locus plot is shown in Figure 4.

    @@ -270,14 +275,14 @@ It is shown that the bending stiffness of the flexible joints does indeed change

    -
    +

    flex_joints_rot_study_dvf.png

    Figure 3: Dynamics from \(\tau_i\) to \(d\mathcal{L}_i\) for all the considered Rotation Stiffnesses

    -
    +

    flex_joints_rot_study_dvf_root_locus.png

    Figure 4: Root Locus for all the considered Rotation Stiffnesses

    @@ -285,11 +290,11 @@ It is shown that the bending stiffness of the flexible joints does indeed change
    -
    -

    1.3.2 Primary Control

    +
    +

    1.3.2 Primary Control

    -The dynamics from \(\bm{\tau}^\prime\) to \(\bm{\epsilon}_{\mathcal{X}_n}\) (for the primary controller designed in the frame of the legs) is shown in Figure 5. +The dynamics from \(\bm{\tau}^\prime\) to \(\bm{\epsilon}_{\mathcal{X}_n}\) (for the primary controller designed in the frame of the legs) is shown in Figure 5.

    @@ -297,7 +302,7 @@ It is shown that the bending stiffness of the flexible joints have very little i

    -
    +

    flex_joints_rot_study_primary_plant.png

    Figure 5: Diagonal elements of the transfer function matrix from \(\bm{\tau}^\prime\) to \(\bm{\epsilon}_{\mathcal{X}_n}\) for the considered bending stiffnesses

    @@ -305,10 +310,10 @@ It is shown that the bending stiffness of the flexible joints have very little i
    -
    -

    1.3.3 Conclusion

    +
    +

    1.3.3 Conclusion

    -
    +

    The bending stiffness of the flexible joint does not significantly change the dynamics.

    @@ -319,19 +324,19 @@ The bending stiffness of the flexible joint does not significantly change the dy
    -
    -

    2 Axial Stiffness

    +
    +

    2 Axial Stiffness

    - +

    Let’s know consider a flexibility in translation of the flexible joint, in the axis of the legs.

    -
    -

    2.1 Realistic Translation Stiffness Values

    +
    +

    2.1 Realistic Translation Stiffness Values

    We choose realistic values of the axial stiffness of the joints: @@ -339,29 +344,29 @@ We choose realistic values of the axial stiffness of the joints:

    -
    Ka_F = 60e6*ones(6,1); % [N/m]
    -Ka_M = 60e6*ones(6,1); % [N/m]
    -Ca_F = 1*ones(6,1); % [N/(m/s)]
    -Ca_M = 1*ones(6,1); % [N/(m/s)]
    +
      Ka_F = 60e6*ones(6,1); % [N/m]
    +  Ka_M = 60e6*ones(6,1); % [N/m]
    +  Ca_F = 1*ones(6,1); % [N/(m/s)]
    +  Ca_M = 1*ones(6,1); % [N/(m/s)]
     
    -
    -

    2.1.1 Initialization

    +
    +

    2.1.1 Initialization

    Let’s initialize all the stages with default parameters.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
     
    @@ -369,26 +374,26 @@ initializeMirror(); Let’s consider the heaviest mass which should we the most problematic with it comes to the flexible joints.

    -
    initializeSample('mass', 50, 'freq', 200*ones(6,1));
    -initializeReferences('Rz_type', 'rotating-not-filtered', 'Rz_period', 60);
    +
      initializeSample('mass', 50, 'freq', 200*ones(6,1));
    +  initializeReferences('Rz_type', 'rotating-not-filtered', 'Rz_period', 60);
     
    -
    -

    2.1.2 Direct Velocity Feedback

    +
    +

    2.1.2 Direct Velocity Feedback

    The dynamics from actuators force \(\tau_i\) to relative motion sensors \(d\mathcal{L}_i\) with and without considering the flexible joint stiffness are identified.

    -The obtained dynamics are shown in Figure 6. +The obtained dynamics are shown in Figure 6.

    -
    +

    flex_joint_trans_dvf.png

    Figure 6: Dynamics from actuators force \(\tau_i\) to relative motion sensors \(d\mathcal{L}_i\) with (blue) and without (red) considering the flexible joint axis stiffness

    @@ -396,11 +401,11 @@ The obtained dynamics are shown in Figure 6.
    -
    -

    2.1.3 Primary Plant

    +
    +

    2.1.3 Primary Plant

    -
    Kdvf = 5e3*s/(1+s/2/pi/1e3)*eye(6);
    +
      Kdvf = 5e3*s/(1+s/2/pi/1e3)*eye(6);
     
    @@ -409,11 +414,11 @@ Let’s now identify the dynamics from \(\bm{\tau}^\prime\) to \(\bm{\epsilo

    -The dynamics is compare with and without the joint flexibility in Figure 7. +The dynamics is compare with and without the joint flexibility in Figure 7.

    -
    +

    flex_joints_trans_primary_plant_L.png

    Figure 7: Dynamics from \(\bm{\tau}^\prime_i\) to \(\bm{\epsilon}_{\mathcal{X}_n,i}\) with infinite axis stiffnes (solid) and with realistic axial stiffness (dashed)

    @@ -421,10 +426,10 @@ The dynamics is compare with and without the joint flexibility in Figure
    -
    -

    2.1.4 Conclusion

    +
    +

    2.1.4 Conclusion

    -
    +

    For the realistic value of the flexible joint axial stiffness, the dynamics is not much impact, and this should not be a problem for control.

    @@ -434,8 +439,8 @@ For the realistic value of the flexible joint axial stiffness, the dynamics is n
    -
    -

    2.2 Parametric study

    +
    +

    2.2 Parametric study

    We wish now to see what is the impact of the axial stiffness of the flexible joints on the dynamics. @@ -445,7 +450,7 @@ We wish now to see what is the impact of the axial stiffness of the flexi Let’s consider the following values for the axial stiffness:

    -
    Kas = [1e4, 1e5, 1e6, 1e7, 1e8, 1e9]; % [N/m]
    +
      Kas = [1e4, 1e5, 1e6, 1e7, 1e8, 1e9]; % [N/m]
     
    @@ -454,11 +459,11 @@ We also consider here a nano-hexapod with the identified optimal actuator stiffn

    -
    -

    2.2.1 Direct Velocity Feedback

    +
    +

    2.2.1 Direct Velocity Feedback

    -The dynamics from the actuators to the relative displacement sensor in each leg is identified and shown in Figure 8. +The dynamics from the actuators to the relative displacement sensor in each leg is identified and shown in Figure 8.

    @@ -470,26 +475,26 @@ If the axial stiffness of the flexible joints is \(K_a > 10^7\,[N/m]\) (here \(1

    -This is more clear by looking at the root locus (Figures 9 and 10). +This is more clear by looking at the root locus (Figures 9 and 10). It can be seen that very little active damping can be achieve for axial stiffnesses below \(10^7\,[N/m]\).

    -
    +

    flex_joints_trans_study_dvf.png

    Figure 8: Dynamics from \(\tau_i\) to \(d\mathcal{L}_i\) for all the considered axis Stiffnesses

    -
    +

    flex_joints_trans_study_dvf_root_locus.png

    Figure 9: Root Locus for all the considered axial Stiffnesses

    -
    +

    flex_joints_trans_study_root_locus_unzoom.png

    Figure 10: Root Locus (unzoom) for all the considered axial Stiffnesses

    @@ -497,15 +502,15 @@ It can be seen that very little active damping can be achieve for axial stiffnes
    -
    -

    2.2.2 Primary Control

    +
    +

    2.2.2 Primary Control

    -The dynamics from \(\bm{\tau}^\prime\) to \(\bm{\epsilon}_{\mathcal{X}_n}\) (for the primary controller designed in the frame of the legs) is shown in Figure 11. +The dynamics from \(\bm{\tau}^\prime\) to \(\bm{\epsilon}_{\mathcal{X}_n}\) (for the primary controller designed in the frame of the legs) is shown in Figure 11.

    -
    +

    flex_joints_trans_study_primary_plant.png

    Figure 11: Diagonal elements of the transfer function matrix from \(\bm{\tau}^\prime\) to \(\bm{\epsilon}_{\mathcal{X}_n}\) for the considered axial stiffnesses

    @@ -514,10 +519,10 @@ The dynamics from \(\bm{\tau}^\prime\) to \(\bm{\epsilon}_{\mathcal{X}_n}\) (for
    -
    -

    2.3 Conclusion

    +
    +

    2.3 Conclusion

    -
    +

    The axial stiffness of the flexible joints should be maximized.

    @@ -539,14 +544,14 @@ We may interpolate the results and say that the axial joint stiffness should be
    -
    -

    3 Conclusion

    +
    +

    3 Conclusion

    - +

    -
    +

    In this study we considered the bending, torsional and axial stiffnesses of the flexible joints used for the nano-hexapod.

    @@ -583,26 +588,26 @@ As there is generally a trade-off between bending stiffness and axial stiffness,
    -
    -

    4 Designed Flexible Joints

    +
    +

    4 Designed Flexible Joints

    -
    -

    4.1 Initialization

    +
    +

    4.1 Initialization

    Let’s initialize all the stages with default parameters.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc('type', 'none');
    -initializeMirror('type', 'none');
    -initializeMirror();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc('type', 'none');
    +  initializeMirror('type', 'none');
    +  initializeMirror();
     
    @@ -610,51 +615,51 @@ initializeMirror(); Let’s consider the heaviest mass which should we the most problematic with it comes to the flexible joints.

    -
    initializeSample('mass', 50, 'freq', 200*ones(6,1));
    -initializeReferences('Rz_type', 'rotating-not-filtered', 'Rz_period', 60);
    +
      initializeSample('mass', 50, 'freq', 200*ones(6,1));
    +  initializeReferences('Rz_type', 'rotating-not-filtered', 'Rz_period', 60);
     
    -
    flex_joint = load('./mat/flexor_025.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K');
    -apa = load('./mat/APA300ML_simplified_model.mat');
    +
      flex_joint = load('./mat/flexor_025.mat', 'int_xyz', 'int_i', 'n_xyz', 'n_i', 'nodes', 'M', 'K');
    +  apa = load('./mat/APA300ML_simplified_model.mat');
     
    -
    initializeNanoHexapod('actuator', 'amplified', ...
    -                      'ke', apa.ke, 'ka', apa.ka, 'k1', apa.k1, 'c1', apa.c1, 'F_gain', apa.F_gain, ...
    -                      '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', 'spherical_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));
    +
      initializeNanoHexapod('actuator', 'amplified', ...
    +                        'ke', apa.ke, 'ka', apa.ka, 'k1', apa.k1, 'c1', apa.c1, 'F_gain', apa.F_gain, ...
    +                        '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', 'spherical_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));
     
    -
    initializeNanoHexapod();
    +
      initializeNanoHexapod();
     
    -
    -

    4.2 Direct Velocity Feedback

    +
    +

    4.2 Direct Velocity Feedback

    -
    -

    4.3 Integral Force Feedback

    +
    +

    4.3 Integral Force Feedback

    Author: Dehaeze Thomas

    -

    Created: 2020-11-03 mar. 09:45

    +

    Created: 2021-02-20 sam. 23:09

    diff --git a/docs/functions.html b/docs/functions.html index 1c07990..7d7fcb1 100644 --- a/docs/functions.html +++ b/docs/functions.html @@ -1,359 +1,354 @@ - - + Matlab Functions used for the NASS Project - - - - - - + +

    Matlab Functions used for the NASS Project

    -
    -

    1 describeNassSetup

    +
    +

    1 describeNassSetup

    - +

    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [] = describeNassSetup()
    -% describeNassSetup -
    -%
    -% Syntax: [] = describeNassSetup()
    -%
    -% Inputs:
    -%    -  -
    -%
    -% Outputs:
    -%    -  -
    +
      function [] = describeNassSetup()
    +  % describeNassSetup -
    +  %
    +  % Syntax: [] = describeNassSetup()
    +  %
    +  % Inputs:
    +  %    -  -
    +  %
    +  % Outputs:
    +  %    -  -
     
    -
    -

    Simscape Configuration

    -
    +
    +

    Simscape Configuration

    +
    -
    load('./mat/conf_simscape.mat', 'conf_simscape');
    +
      load('./mat/conf_simscape.mat', 'conf_simscape');
     
    -
    fprintf('Simscape Configuration:\n');
    +
      fprintf('Simscape Configuration:\n');
     
    -if conf_simscape.type == 1
    -    fprintf('- Gravity is included\n');
    -else
    -    fprintf('- Gravity is not included\n');
    -end
    +  if conf_simscape.type == 1
    +      fprintf('- Gravity is included\n');
    +  else
    +      fprintf('- Gravity is not included\n');
    +  end
     
    -fprintf('\n');
    +  fprintf('\n');
     
    -
    -

    Disturbances

    -
    +
    +

    Disturbances

    +
    -
    load('./mat/nass_disturbances.mat', 'args');
    +
      load('./mat/nass_disturbances.mat', 'args');
     
    -
    fprintf('Disturbances:\n');
    -if ~args.enable
    -    fprintf('- No disturbance is included\n');
    -else
    -    if args.Dwx && args.Dwy && args.Dwz
    -        fprintf('- Ground motion\n');
    -    end
    -    if args.Fty_x && args.Fty_z
    -        fprintf('- Vibrations of the Translation Stage\n');
    -    end
    -    if args.Frz_z
    -        fprintf('- Vibrations of the Spindle\n');
    -    end
    -end
    -fprintf('\n');
    +
      fprintf('Disturbances:\n');
    +  if ~args.enable
    +      fprintf('- No disturbance is included\n');
    +  else
    +      if args.Dwx && args.Dwy && args.Dwz
    +          fprintf('- Ground motion\n');
    +      end
    +      if args.Fty_x && args.Fty_z
    +          fprintf('- Vibrations of the Translation Stage\n');
    +      end
    +      if args.Frz_z
    +          fprintf('- Vibrations of the Spindle\n');
    +      end
    +  end
    +  fprintf('\n');
     
    -
    -

    References

    -
    +
    +

    References

    +
    -
    load('./mat/nass_references.mat', 'args');
    +
      load('./mat/nass_references.mat', 'args');
     
    -
    fprintf('Reference Tracking:\n');
    -fprintf('- Translation Stage:\n');
    -switch args.Dy_type
    -  case 'constant'
    -    fprintf('  - Constant Position\n');
    -    fprintf('  - Dy = %.0f [mm]\n', args.Dy_amplitude*1e3);
    -  case 'triangular'
    -    fprintf('  - Triangular Path\n');
    -    fprintf('  - Amplitude = %.0f [mm]\n', args.Dy_amplitude*1e3);
    -    fprintf('  - Period = %.0f [s]\n', args.Dy_period);
    -  case 'sinusoidal'
    -    fprintf('  - Sinusoidal Path\n');
    -    fprintf('  - Amplitude = %.0f [mm]\n', args.Dy_amplitude*1e3);
    -    fprintf('  - Period = %.0f [s]\n', args.Dy_period);
    -end
    +
      fprintf('Reference Tracking:\n');
    +  fprintf('- Translation Stage:\n');
    +  switch args.Dy_type
    +    case 'constant'
    +      fprintf('  - Constant Position\n');
    +      fprintf('  - Dy = %.0f [mm]\n', args.Dy_amplitude*1e3);
    +    case 'triangular'
    +      fprintf('  - Triangular Path\n');
    +      fprintf('  - Amplitude = %.0f [mm]\n', args.Dy_amplitude*1e3);
    +      fprintf('  - Period = %.0f [s]\n', args.Dy_period);
    +    case 'sinusoidal'
    +      fprintf('  - Sinusoidal Path\n');
    +      fprintf('  - Amplitude = %.0f [mm]\n', args.Dy_amplitude*1e3);
    +      fprintf('  - Period = %.0f [s]\n', args.Dy_period);
    +  end
     
    -fprintf('- Tilt Stage:\n');
    -switch args.Ry_type
    -  case 'constant'
    -    fprintf('  - Constant Position\n');
    -    fprintf('  - Ry = %.0f [mm]\n', args.Ry_amplitude*1e3);
    -  case 'triangular'
    -    fprintf('  - Triangular Path\n');
    -    fprintf('  - Amplitude = %.0f [mm]\n', args.Ry_amplitude*1e3);
    -    fprintf('  - Period = %.0f [s]\n', args.Ry_period);
    -  case 'sinusoidal'
    -    fprintf('  - Sinusoidal Path\n');
    -    fprintf('  - Amplitude = %.0f [mm]\n', args.Ry_amplitude*1e3);
    -    fprintf('  - Period = %.0f [s]\n', args.Ry_period);
    -end
    +  fprintf('- Tilt Stage:\n');
    +  switch args.Ry_type
    +    case 'constant'
    +      fprintf('  - Constant Position\n');
    +      fprintf('  - Ry = %.0f [mm]\n', args.Ry_amplitude*1e3);
    +    case 'triangular'
    +      fprintf('  - Triangular Path\n');
    +      fprintf('  - Amplitude = %.0f [mm]\n', args.Ry_amplitude*1e3);
    +      fprintf('  - Period = %.0f [s]\n', args.Ry_period);
    +    case 'sinusoidal'
    +      fprintf('  - Sinusoidal Path\n');
    +      fprintf('  - Amplitude = %.0f [mm]\n', args.Ry_amplitude*1e3);
    +      fprintf('  - Period = %.0f [s]\n', args.Ry_period);
    +  end
     
    -fprintf('- Spindle:\n');
    -switch args.Rz_type
    -  case 'constant'
    -    fprintf('  - Constant Position\n');
    -    fprintf('  - Rz = %.0f [deg]\n', 180/pi*args.Rz_amplitude);
    -  case { 'rotating', 'rotating-not-filtered' }
    -    fprintf('  - Rotating\n');
    -    fprintf('  - Speed = %.0f [rpm]\n', 60/args.Rz_period);
    -end
    +  fprintf('- Spindle:\n');
    +  switch args.Rz_type
    +    case 'constant'
    +      fprintf('  - Constant Position\n');
    +      fprintf('  - Rz = %.0f [deg]\n', 180/pi*args.Rz_amplitude);
    +    case { 'rotating', 'rotating-not-filtered' }
    +      fprintf('  - Rotating\n');
    +      fprintf('  - Speed = %.0f [rpm]\n', 60/args.Rz_period);
    +  end
     
     
    -fprintf('- Micro Hexapod:\n');
    -switch args.Dh_type
    -  case 'constant'
    -    fprintf('  - Constant Position\n');
    -    fprintf('  - Dh = %.0f, %.0f, %.0f [mm]\n',  args.Dh_pos(1), args.Dh_pos(2), args.Dh_pos(3));
    -    fprintf('  - Rh = %.0f, %.0f, %.0f [deg]\n', args.Dh_pos(4), args.Dh_pos(5), args.Dh_pos(6));
    -end
    +  fprintf('- Micro Hexapod:\n');
    +  switch args.Dh_type
    +    case 'constant'
    +      fprintf('  - Constant Position\n');
    +      fprintf('  - Dh = %.0f, %.0f, %.0f [mm]\n',  args.Dh_pos(1), args.Dh_pos(2), args.Dh_pos(3));
    +      fprintf('  - Rh = %.0f, %.0f, %.0f [deg]\n', args.Dh_pos(4), args.Dh_pos(5), args.Dh_pos(6));
    +  end
     
    -fprintf('\n');
    +  fprintf('\n');
     
    -
    -

    Controller

    -
    +
    +

    Controller

    +
    -
    load('./mat/controller.mat', 'controller');
    +
      load('./mat/controller.mat', 'controller');
     
    -
    fprintf('Controller:\n');
    -fprintf('- %s\n', controller.name);
    -fprintf('\n');
    +
      fprintf('Controller:\n');
    +  fprintf('- %s\n', controller.name);
    +  fprintf('\n');
     
    -
    -

    Micro-Station

    -
    +
    +

    Micro-Station

    +
    -
    load('./mat/stages.mat', 'ground', 'granite', 'ty', 'ry', 'rz', 'micro_hexapod', 'axisc');
    +
      load('./mat/stages.mat', 'ground', 'granite', 'ty', 'ry', 'rz', 'micro_hexapod', 'axisc');
     
    -
    fprintf('Micro Station:\n');
    +
      fprintf('Micro Station:\n');
     
    -if granite.type == 1 && ...
    -        ty.type == 1 && ...
    -        ry.type == 1 && ...
    -        rz.type == 1 && ...
    -        micro_hexapod.type == 1;
    -    fprintf('- All stages are rigid\n');
    -elseif granite.type == 2 && ...
    -        ty.type == 2 && ...
    -        ry.type == 2 && ...
    -        rz.type == 2 && ...
    -        micro_hexapod.type == 2;
    -    fprintf('- All stages are flexible\n');
    -else
    -    if granite.type == 1 || granite.type == 4
    -        fprintf('- Granite is rigid\n');
    -    else
    -        fprintf('- Granite is flexible\n');
    -    end
    -    if ty.type == 1 || ty.type == 4
    -        fprintf('- Translation Stage is rigid\n');
    -    else
    -        fprintf('- Translation Stage is flexible\n');
    -    end
    -    if ry.type == 1 || ry.type == 4
    -        fprintf('- Tilt Stage is rigid\n');
    -    else
    -        fprintf('- Tilt Stage is flexible\n');
    -    end
    -    if rz.type == 1 || rz.type == 4
    -        fprintf('- Spindle is rigid\n');
    -    else
    -        fprintf('- Spindle is flexible\n');
    -    end
    -    if micro_hexapod.type == 1 || micro_hexapod.type == 4
    -        fprintf('- Micro Hexapod is rigid\n');
    -    else
    -        fprintf('- Micro Hexapod is flexible\n');
    -    end
    +  if granite.type == 1 && ...
    +          ty.type == 1 && ...
    +          ry.type == 1 && ...
    +          rz.type == 1 && ...
    +          micro_hexapod.type == 1;
    +      fprintf('- All stages are rigid\n');
    +  elseif granite.type == 2 && ...
    +          ty.type == 2 && ...
    +          ry.type == 2 && ...
    +          rz.type == 2 && ...
    +          micro_hexapod.type == 2;
    +      fprintf('- All stages are flexible\n');
    +  else
    +      if granite.type == 1 || granite.type == 4
    +          fprintf('- Granite is rigid\n');
    +      else
    +          fprintf('- Granite is flexible\n');
    +      end
    +      if ty.type == 1 || ty.type == 4
    +          fprintf('- Translation Stage is rigid\n');
    +      else
    +          fprintf('- Translation Stage is flexible\n');
    +      end
    +      if ry.type == 1 || ry.type == 4
    +          fprintf('- Tilt Stage is rigid\n');
    +      else
    +          fprintf('- Tilt Stage is flexible\n');
    +      end
    +      if rz.type == 1 || rz.type == 4
    +          fprintf('- Spindle is rigid\n');
    +      else
    +          fprintf('- Spindle is flexible\n');
    +      end
    +      if micro_hexapod.type == 1 || micro_hexapod.type == 4
    +          fprintf('- Micro Hexapod is rigid\n');
    +      else
    +          fprintf('- Micro Hexapod is flexible\n');
    +      end
     
    -end
    +  end
     
    -fprintf('\n');
    +  fprintf('\n');
     
    -
    -

    Metrology

    -
    +
    +

    Metrology

    +
    -
    load('./mat/stages.mat', 'mirror');
    +
      load('./mat/stages.mat', 'mirror');
     
    -
    fprintf('Reference Mirror:\n');
    +
      fprintf('Reference Mirror:\n');
     
    -if mirror.type == 2;
    -    fprintf('- flexible fixation\n');
    -    fprintf('- w = %.0f [Hz]\n', mirror.freq(1));
    -else
    -    fprintf('- rigidly attached to the nano-hexapod\n');
    -end
    -fprintf('- m = %.0f [kg]\n', mirror.mass);
    -fprintf('\n');
    +  if mirror.type == 2;
    +      fprintf('- flexible fixation\n');
    +      fprintf('- w = %.0f [Hz]\n', mirror.freq(1));
    +  else
    +      fprintf('- rigidly attached to the nano-hexapod\n');
    +  end
    +  fprintf('- m = %.0f [kg]\n', mirror.mass);
    +  fprintf('\n');
     
    -
    -

    Nano Hexapod

    -
    +
    +

    Nano Hexapod

    +
    -
    load('./mat/stages.mat', 'nano_hexapod');
    +
      load('./mat/stages.mat', 'nano_hexapod');
     
    -
    fprintf('Nano Hexapod:\n');
    +
      fprintf('Nano Hexapod:\n');
     
    -if nano_hexapod.type == 0;
    -    fprintf('- no included\n');
    -elseif nano_hexapod.type == 1 || nano_hexapod.type == 3;
    -    fprintf('- rigid\n');
    -elseif nano_hexapod.type == 2;
    -    fprintf('- flexible\n');
    -    fprintf('- Ki = %.0g [N/m]\n', nano_hexapod.actuators.K(1));
    -end
    +  if nano_hexapod.type == 0;
    +      fprintf('- no included\n');
    +  elseif nano_hexapod.type == 1 || nano_hexapod.type == 3;
    +      fprintf('- rigid\n');
    +  elseif nano_hexapod.type == 2;
    +      fprintf('- flexible\n');
    +      fprintf('- Ki = %.0g [N/m]\n', nano_hexapod.actuators.K(1));
    +  end
     
    -fprintf('\n');
    +  fprintf('\n');
     
    -
    -

    Sample

    -
    +
    +

    Sample

    +
    -
    load('./mat/stages.mat', 'sample');
    +
      load('./mat/stages.mat', 'sample');
     
    -
    fprintf('Sample:\n');
    +
      fprintf('Sample:\n');
     
    -if sample.type == 0;
    -    fprintf('- no included\n');
    -elseif sample.type == 1 || sample.type == 3;
    -    fprintf('- rigid\n');
    -    fprintf('- mass = %.0f [kg]\n', sample.mass);
    -    fprintf('- moment of inertia = %.2f, %.2f, %.2f [kg m2]\n', sample.inertia(1), sample.inertia(2), sample.inertia(3));
    -elseif sample.type == 2;
    -    fprintf('- flexible\n');
    -    fprintf('- mass = %.0f [kg]\n', sample.mass);
    -    fprintf('- moment of inertia = %.2f, %.2f, %.2f [kg m2]\n', sample.inertia(1), sample.inertia(2), sample.inertia(3));
    -    % fprintf('- Kt = %.0g, %.0g, %.0g [N/m]\n', sample.K(1), sample.K(2), sample.K(3));
    -    % fprintf('- Kr = %.0g, %.0g, %.0g [Nm/rad]\n', sample.K(4), sample.K(5), sample.K(6));
    -    fprintf('- wt(x,y,z) = %.0f, %.0f, %.0f [Hz]\n', 1/2/pi*sqrt(sample.K(1)/sample.mass), 1/2/pi*sqrt(sample.K(1)/sample.mass), 1/2/pi*sqrt(sample.K(1)/sample.mass));
    -    fprintf('- wr(x,y,z) = %.0f, %.0f, %.0f [Hz]\n', 1/2/pi*sqrt(sample.K(4)/sample.inertia(1)), 1/2/pi*sqrt(sample.K(5)/sample.inertia(2)), 1/2/pi*sqrt(sample.K(6)/sample.inertia(3)));
    -end
    -fprintf('\n');
    +  if sample.type == 0;
    +      fprintf('- no included\n');
    +  elseif sample.type == 1 || sample.type == 3;
    +      fprintf('- rigid\n');
    +      fprintf('- mass = %.0f [kg]\n', sample.mass);
    +      fprintf('- moment of inertia = %.2f, %.2f, %.2f [kg m2]\n', sample.inertia(1), sample.inertia(2), sample.inertia(3));
    +  elseif sample.type == 2;
    +      fprintf('- flexible\n');
    +      fprintf('- mass = %.0f [kg]\n', sample.mass);
    +      fprintf('- moment of inertia = %.2f, %.2f, %.2f [kg m2]\n', sample.inertia(1), sample.inertia(2), sample.inertia(3));
    +      % fprintf('- Kt = %.0g, %.0g, %.0g [N/m]\n', sample.K(1), sample.K(2), sample.K(3));
    +      % fprintf('- Kr = %.0g, %.0g, %.0g [Nm/rad]\n', sample.K(4), sample.K(5), sample.K(6));
    +      fprintf('- wt(x,y,z) = %.0f, %.0f, %.0f [Hz]\n', 1/2/pi*sqrt(sample.K(1)/sample.mass), 1/2/pi*sqrt(sample.K(1)/sample.mass), 1/2/pi*sqrt(sample.K(1)/sample.mass));
    +      fprintf('- wr(x,y,z) = %.0f, %.0f, %.0f [Hz]\n', 1/2/pi*sqrt(sample.K(4)/sample.inertia(1)), 1/2/pi*sqrt(sample.K(5)/sample.inertia(2)), 1/2/pi*sqrt(sample.K(6)/sample.inertia(3)));
    +  end
    +  fprintf('\n');
     
    -
    -

    2 computeReferencePose

    +
    +

    2 computeReferencePose

    - +

    @@ -361,93 +356,93 @@ This Matlab function is accessible here

    -
    function [WTr] = computeReferencePose(Dy, Ry, Rz, Dh, Dn)
    -% computeReferencePose - Compute the homogeneous transformation matrix corresponding to the wanted pose of the sample
    -%
    -% Syntax: [WTr] = computeReferencePose(Dy, Ry, Rz, Dh, Dn)
    -%
    -% Inputs:
    -%    - Dy - Reference of the Translation Stage [m]
    -%    - Ry - Reference of the Tilt Stage [rad]
    -%    - Rz - Reference of the Spindle [rad]
    -%    - Dh - Reference of the Micro Hexapod (Pitch, Roll, Yaw angles) [m, m, m, rad, rad, rad]
    -%    - Dn - Reference of the Nano Hexapod [m, m, m, rad, rad, rad]
    -%
    -% Outputs:
    -%    - WTr -
    +
      function [WTr] = computeReferencePose(Dy, Ry, Rz, Dh, Dn)
    +  % computeReferencePose - Compute the homogeneous transformation matrix corresponding to the wanted pose of the sample
    +  %
    +  % Syntax: [WTr] = computeReferencePose(Dy, Ry, Rz, Dh, Dn)
    +  %
    +  % Inputs:
    +  %    - Dy - Reference of the Translation Stage [m]
    +  %    - Ry - Reference of the Tilt Stage [rad]
    +  %    - Rz - Reference of the Spindle [rad]
    +  %    - Dh - Reference of the Micro Hexapod (Pitch, Roll, Yaw angles) [m, m, m, rad, rad, rad]
    +  %    - Dn - Reference of the Nano Hexapod [m, m, m, rad, rad, rad]
    +  %
    +  % Outputs:
    +  %    - WTr -
     
    -  %% Translation Stage
    -  Rty = [1 0 0 0;
    -         0 1 0 Dy;
    -         0 0 1 0;
    -         0 0 0 1];
    +    %% Translation Stage
    +    Rty = [1 0 0 0;
    +           0 1 0 Dy;
    +           0 0 1 0;
    +           0 0 0 1];
     
    -  %% Tilt Stage - Pure rotating aligned with Ob
    -  Rry = [ cos(Ry) 0 sin(Ry) 0;
    -          0       1 0       0;
    -         -sin(Ry) 0 cos(Ry) 0;
    -          0       0 0       1];
    +    %% Tilt Stage - Pure rotating aligned with Ob
    +    Rry = [ cos(Ry) 0 sin(Ry) 0;
    +            0       1 0       0;
    +           -sin(Ry) 0 cos(Ry) 0;
    +            0       0 0       1];
     
    -  %% Spindle - Rotation along the Z axis
    -  Rrz = [cos(Rz) -sin(Rz) 0 0 ;
    -         sin(Rz)  cos(Rz) 0 0 ;
    -         0        0       1 0 ;
    -         0        0       0 1 ];
    +    %% Spindle - Rotation along the Z axis
    +    Rrz = [cos(Rz) -sin(Rz) 0 0 ;
    +           sin(Rz)  cos(Rz) 0 0 ;
    +           0        0       1 0 ;
    +           0        0       0 1 ];
     
     
    -  %% Micro-Hexapod
    -  Rhx = [1 0           0;
    -         0 cos(Dh(4)) -sin(Dh(4));
    -         0 sin(Dh(4))  cos(Dh(4))];
    +    %% Micro-Hexapod
    +    Rhx = [1 0           0;
    +           0 cos(Dh(4)) -sin(Dh(4));
    +           0 sin(Dh(4))  cos(Dh(4))];
     
    -  Rhy = [ cos(Dh(5)) 0 sin(Dh(5));
    -         0           1 0;
    -         -sin(Dh(5)) 0 cos(Dh(5))];
    +    Rhy = [ cos(Dh(5)) 0 sin(Dh(5));
    +           0           1 0;
    +           -sin(Dh(5)) 0 cos(Dh(5))];
     
    -  Rhz = [cos(Dh(6)) -sin(Dh(6)) 0;
    -         sin(Dh(6))  cos(Dh(6)) 0;
    -         0           0          1];
    +    Rhz = [cos(Dh(6)) -sin(Dh(6)) 0;
    +           sin(Dh(6))  cos(Dh(6)) 0;
    +           0           0          1];
     
    -  Rh = [1 0 0 Dh(1) ;
    -        0 1 0 Dh(2) ;
    -        0 0 1 Dh(3) ;
    -        0 0 0 1 ];
    +    Rh = [1 0 0 Dh(1) ;
    +          0 1 0 Dh(2) ;
    +          0 0 1 Dh(3) ;
    +          0 0 0 1 ];
     
    -  Rh(1:3, 1:3) = Rhz*Rhy*Rhx;
    +    Rh(1:3, 1:3) = Rhz*Rhy*Rhx;
     
    -  %% Nano-Hexapod
    -  Rnx = [1 0           0;
    -         0 cos(Dn(4)) -sin(Dn(4));
    -         0 sin(Dn(4))  cos(Dn(4))];
    +    %% Nano-Hexapod
    +    Rnx = [1 0           0;
    +           0 cos(Dn(4)) -sin(Dn(4));
    +           0 sin(Dn(4))  cos(Dn(4))];
     
    -  Rny = [ cos(Dn(5)) 0 sin(Dn(5));
    -         0           1 0;
    -         -sin(Dn(5)) 0 cos(Dn(5))];
    +    Rny = [ cos(Dn(5)) 0 sin(Dn(5));
    +           0           1 0;
    +           -sin(Dn(5)) 0 cos(Dn(5))];
     
    -  Rnz = [cos(Dn(6)) -sin(Dn(6)) 0;
    -         sin(Dn(6))  cos(Dn(6)) 0;
    -         0           0          1];
    +    Rnz = [cos(Dn(6)) -sin(Dn(6)) 0;
    +           sin(Dn(6))  cos(Dn(6)) 0;
    +           0           0          1];
     
    -  Rn = [1 0 0 Dn(1) ;
    -        0 1 0 Dn(2) ;
    -        0 0 1 Dn(3) ;
    -        0 0 0 1 ];
    +    Rn = [1 0 0 Dn(1) ;
    +          0 1 0 Dn(2) ;
    +          0 0 1 Dn(3) ;
    +          0 0 0 1 ];
     
    -  Rn(1:3, 1:3) = Rnz*Rny*Rnx;
    +    Rn(1:3, 1:3) = Rnz*Rny*Rnx;
     
    -  %% Total Homogeneous transformation
    -  WTr = Rty*Rry*Rrz*Rh*Rn;
    -end
    +    %% Total Homogeneous transformation
    +    WTr = Rty*Rry*Rrz*Rh*Rn;
    +  end
     
    -
    -

    3 Compute the Sample Position Error w.r.t. the NASS

    +

    Author: Dehaeze Thomas

    -

    Created: 2020-05-05 mar. 10:33

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/identification.html b/docs/identification.html index 992646f..e5f2ab4 100644 --- a/docs/identification.html +++ b/docs/identification.html @@ -3,53 +3,58 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Identification - - - - - - - - + + + +

    Identification

    @@ -70,8 +75,8 @@ We can then compare the measured Frequency Response Functions with the identifie Finally, this should help to tune the parameters of the model such that the dynamics is closer to the measured FRF.

    -
    -

    1 Some notes about the Simscape Model

    +
    +

    1 Some notes about the Simscape Model

    The Simscape Model of the micro-station consists of several solid bodies: @@ -97,18 +102,18 @@ Some of the springs and dampers values can be estimated from the joints/stages s

    -
    -

    2 Compare with measurements at the CoM of each element

    +
    +

    2 Compare with measurements at the CoM of each element

    -
    -

    2.1 Prepare the Simulation

    +
    +

    2.1 Prepare the Simulation

    We load the configuration.

    -
    load('mat/conf_simulink.mat');
    +
      load('mat/conf_simulink.mat');
     
    @@ -116,7 +121,7 @@ We load the configuration. We set a small StopTime.

    -
    set_param(conf_simulink, 'StopTime', '0.5');
    +
      set_param(conf_simulink, 'StopTime', '0.5');
     
    @@ -124,46 +129,46 @@ We set a small StopTime. We initialize all the stages.

    -
    initializeGround(      'type', 'rigid');
    -initializeGranite(     'type', 'modal-analysis');
    -initializeTy(          'type', 'modal-analysis');
    -initializeRy(          'type', 'modal-analysis');
    -initializeRz(          'type', 'modal-analysis');
    -initializeMicroHexapod('type', 'modal-analysis');
    -initializeAxisc(       'type', 'flexible');
    +
      initializeGround(      'type', 'rigid');
    +  initializeGranite(     'type', 'modal-analysis');
    +  initializeTy(          'type', 'modal-analysis');
    +  initializeRy(          'type', 'modal-analysis');
    +  initializeRz(          'type', 'modal-analysis');
    +  initializeMicroHexapod('type', 'modal-analysis');
    +  initializeAxisc(       'type', 'flexible');
     
    -initializeMirror(      'type', 'none');
    -initializeNanoHexapod( 'type', 'none');
    -initializeSample(      'type', 'none');
    +  initializeMirror(      'type', 'none');
    +  initializeNanoHexapod( 'type', 'none');
    +  initializeSample(      'type', 'none');
     
    -initializeController(  'type', 'open-loop');
    +  initializeController(  'type', 'open-loop');
     
    -initializeLoggingConfiguration('log', 'none');
    +  initializeLoggingConfiguration('log', 'none');
     
    -initializeReferences();
    -initializeDisturbances('enable', false);
    +  initializeReferences();
    +  initializeDisturbances('enable', false);
     
    -
    -

    2.2 Estimate the position of the CoM of each solid and compare with the one took for the Measurement Analysis

    +
    +

    2.2 Estimate the position of the CoM of each solid and compare with the one took for the Measurement Analysis

    Thanks to the Inertia Sensor simscape block, it is possible to estimate the position of the Center of Mass of a solid body with respect to a defined frame.

    -
    sim('nass_model')
    +
      sim('nass_model')
     

    -The results are shown in the table 1. +The results are shown in the table 1.

    -
    +
    @@ -226,10 +231,10 @@ The results are shown in the table 1.
    Table 1: Center of Mass of each solid body as defined in Simscape

    -We can compare the obtained center of mass (table 1) with the one used for the Modal Analysis shown in table 2. +We can compare the obtained center of mass (table 1) with the one used for the Modal Analysis shown in table 2.

    - +
    @@ -303,8 +308,8 @@ However, in SolidWorks, this has probably not be included with the top granite. -
    -

    2.3 Create a frame at the CoM of each solid body

    +
    +

    2.3 Create a frame at the CoM of each solid body

    Now we use one inertiasensor block connected on each solid body that measured the center of mass of this solid with respect to the same connected frame. @@ -315,12 +320,12 @@ We do that in order to position an accelerometer on the Simscape model at this p

    -
    open('identification/matlab/sim_micro_station_com_estimation.slx')
    +
      open('identification/matlab/sim_micro_station_com_estimation.slx')
     
    -
    sim('sim_micro_station_com_estimation')
    +
      sim('sim_micro_station_com_estimation')
     
    @@ -390,14 +395,14 @@ We do that in order to position an accelerometer on the Simscape model at this p We now same this for further use:

    -
    granite_bot_com = granite_bot_com.Data(end, :)';
    -granite_top_com = granite_top_com.Data(end, :)';
    -ty_com = ty_com.Data(end, :)';
    -ry_com = ry_com.Data(end, :)';
    -rz_com = rz_com.Data(end, :)';
    -hexa_com = hexa_com.Data(end, :)';
    +
      granite_bot_com = granite_bot_com.Data(end, :)';
    +  granite_top_com = granite_top_com.Data(end, :)';
    +  ty_com = ty_com.Data(end, :)';
    +  ry_com = ry_com.Data(end, :)';
    +  rz_com = rz_com.Data(end, :)';
    +  hexa_com = hexa_com.Data(end, :)';
     
    -save('./mat/solids_com.mat', 'granite_bot_com', 'granite_top_com', 'ty_com', 'ry_com', 'rz_com', 'hexa_com');
    +  save('./mat/solids_com.mat', 'granite_bot_com', 'granite_top_com', 'ty_com', 'ry_com', 'rz_com', 'hexa_com');
     
    @@ -407,20 +412,20 @@ Then, we use the obtained results to add a rigidTransform block in
    -
    -

    2.4 Identification of the dynamics of the Simscape Model

    +
    +

    2.4 Identification of the dynamics of the Simscape Model

    We now use a new Simscape Model where 6DoF inertial sensors are located at the Center of Mass of each solid body.

    -
    % load('mat/solids_com.mat', 'granite_bot_com', 'granite_top_com', 'ty_com', 'ry_com', 'rz_com', 'hexa_com');
    +
      % load('mat/solids_com.mat', 'granite_bot_com', 'granite_top_com', 'ty_com', 'ry_com', 'rz_com', 'hexa_com');
     
    -
    open('nass_model.slx')
    +
      open('nass_model.slx')
     
    @@ -428,35 +433,35 @@ We now use a new Simscape Model where 6DoF inertial sensors are located at the C We use the linearize function in order to estimate the dynamics from forces applied on the Translation stage at the same position used for the real modal analysis to the inertial sensors.

    -
    %% Options for Linearized
    -options = linearizeOptions;
    -options.SampleTime = 0;
    +
      %% Options for Linearized
    +  options = linearizeOptions;
    +  options.SampleTime = 0;
     
    -%% Name of the Simulink File
    -mdl = 'nass_model';
    +  %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Micro-Station/Translation Stage/Modal Analysis/F_hammer'],          1, 'openinput');  io_i = io_i + 1;
    -io(io_i) = linio([mdl, '/Micro-Station/Granite/Modal Analysis/accelerometer'],               1, 'openoutput'); io_i = io_i + 1;
    -io(io_i) = linio([mdl, '/Micro-Station/Translation Stage/Modal Analysis/accelerometer'],     1, 'openoutput'); io_i = io_i + 1;
    -io(io_i) = linio([mdl, '/Micro-Station/Tilt Stage/Modal Analysis/accelerometer'],            1, 'openoutput'); io_i = io_i + 1;
    -io(io_i) = linio([mdl, '/Micro-Station/Spindle/Modal Analysis/accelerometer'],               1, 'openoutput'); io_i = io_i + 1;
    -io(io_i) = linio([mdl, '/Micro-Station/Micro Hexapod/Modal Analysis/accelerometer'],         1, 'openoutput'); io_i = io_i + 1;
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Micro-Station/Translation Stage/Modal Analysis/F_hammer'],          1, 'openinput');  io_i = io_i + 1;
    +  io(io_i) = linio([mdl, '/Micro-Station/Granite/Modal Analysis/accelerometer'],               1, 'openoutput'); io_i = io_i + 1;
    +  io(io_i) = linio([mdl, '/Micro-Station/Translation Stage/Modal Analysis/accelerometer'],     1, 'openoutput'); io_i = io_i + 1;
    +  io(io_i) = linio([mdl, '/Micro-Station/Tilt Stage/Modal Analysis/accelerometer'],            1, 'openoutput'); io_i = io_i + 1;
    +  io(io_i) = linio([mdl, '/Micro-Station/Spindle/Modal Analysis/accelerometer'],               1, 'openoutput'); io_i = io_i + 1;
    +  io(io_i) = linio([mdl, '/Micro-Station/Micro Hexapod/Modal Analysis/accelerometer'],         1, 'openoutput'); io_i = io_i + 1;
     
    -
    % Run the linearization
    -G_ms = linearize(mdl, io, 0);
    +
      % Run the linearization
    +  G_ms = linearize(mdl, io, 0);
     
    -%% Input/Output definition
    -G_ms.InputName  = {'Fx', 'Fy', 'Fz'};
    -G_ms.OutputName = {'gtop_x', 'gtop_y', 'gtop_z', 'gtop_rx', 'gtop_ry', 'gtop_rz', ...
    -                   'ty_x', 'ty_y', 'ty_z', 'ty_rx', 'ty_ry', 'ty_rz', ...
    -                   'ry_x', 'ry_y', 'ry_z', 'ry_rx', 'ry_ry', 'ry_rz', ...
    -                   'rz_x', 'rz_y', 'rz_z', 'rz_rx', 'rz_ry', 'rz_rz', ...
    -                   'hexa_x', 'hexa_y', 'hexa_z', 'hexa_rx', 'hexa_ry', 'hexa_rz'};
    +  %% Input/Output definition
    +  G_ms.InputName  = {'Fx', 'Fy', 'Fz'};
    +  G_ms.OutputName = {'gtop_x', 'gtop_y', 'gtop_z', 'gtop_rx', 'gtop_ry', 'gtop_rz', ...
    +                     'ty_x', 'ty_y', 'ty_z', 'ty_rx', 'ty_ry', 'ty_rz', ...
    +                     'ry_x', 'ry_y', 'ry_z', 'ry_rx', 'ry_ry', 'ry_rz', ...
    +                     'rz_x', 'rz_y', 'rz_z', 'rz_rx', 'rz_ry', 'rz_rz', ...
    +                     'hexa_x', 'hexa_y', 'hexa_z', 'hexa_rx', 'hexa_ry', 'hexa_rz'};
     
    @@ -465,22 +470,22 @@ The output of G_ms is the acceleration of each solid body. In order to obtain a displacement, we divide the obtained transfer function by \(1/s^{2}\);

    -
    G_ms = G_ms/s^2;
    +
      G_ms = G_ms/s^2;
     
    -
    -

    2.5 Compare with measurements

    +
    +

    2.5 Compare with measurements

    We now load the Frequency Response Functions measurements during the Modal Analysis (accessible here).

    -
    load('../meas/modal-analysis/mat/frf_coh_matrices.mat', 'freqs');
    -load('../meas/modal-analysis/mat/frf_com.mat', 'FRFs_CoM');
    +
      load('../meas/modal-analysis/mat/frf_coh_matrices.mat', 'freqs');
    +  load('../meas/modal-analysis/mat/frf_com.mat', 'FRFs_CoM');
     
    @@ -489,7 +494,7 @@ We then compare the measurements with the identified transfer functions using th

    -
    +

    identification_comp_bot_stages.png

    Figure 1: caption (png, pdf)

    @@ -497,7 +502,7 @@ We then compare the measurements with the identified transfer functions using th -
    +

    identification_comp_mid_stages.png

    Figure 2: caption (png, pdf)

    @@ -505,7 +510,7 @@ We then compare the measurements with the identified transfer functions using th -
    +

    identification_comp_top_stages.png

    Figure 3: caption (png, pdf)

    @@ -515,23 +520,23 @@ We then compare the measurements with the identified transfer functions using th
    -
    -

    3 Obtained Compliance of the Micro-Station

    +
    +

    3 Obtained Compliance of the Micro-Station

    -
    -

    3.1 Initialization

    +
    +

    3.1 Initialization

    We initialize all the stages with the default parameters.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod('type', 'compliance');
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod('type', 'compliance');
     
    @@ -539,19 +544,19 @@ initializeMicroHexapod('type', 'compliance'); We put nothing on top of the micro-hexapod.

    -
    initializeAxisc('type', 'none');
    -initializeMirror('type', 'none');
    -initializeNanoHexapod('type', 'none');
    -initializeSample('type', 'none');
    +
      initializeAxisc('type', 'none');
    +  initializeMirror('type', 'none');
    +  initializeNanoHexapod('type', 'none');
    +  initializeSample('type', 'none');
     
    -
    initializeReferences();
    -initializeDisturbances();
    -initializeController();
    -initializeSimscapeConfiguration();
    -initializeLoggingConfiguration();
    +
      initializeReferences();
    +  initializeDisturbances();
    +  initializeController();
    +  initializeSimscapeConfiguration();
    +  initializeLoggingConfiguration();
     
    @@ -560,31 +565,31 @@ And we identify the dynamics from forces/torques applied on the micro-hexapod to

    -The obtained compliance is shown in Figure 4. +The obtained compliance is shown in Figure 4.

    -
    %% Name of the Simulink File
    -mdl = 'nass_model';
    +
      %% Name of the Simulink File
    +  mdl = 'nass_model';
     
    -%% Input/Output definition
    -clear io; io_i = 1;
    -io(io_i) = linio([mdl, '/Micro-Station/Micro Hexapod/Compliance/Fm'], 1, 'openinput');       io_i = io_i + 1; % Direct Forces/Torques applied on the micro-hexapod top platform
    -io(io_i) = linio([mdl, '/Micro-Station/Micro Hexapod/Compliance/Dm'], 1, 'output'); io_i = io_i + 1; % Absolute displacement of the top platform
    +  %% Input/Output definition
    +  clear io; io_i = 1;
    +  io(io_i) = linio([mdl, '/Micro-Station/Micro Hexapod/Compliance/Fm'], 1, 'openinput');       io_i = io_i + 1; % Direct Forces/Torques applied on the micro-hexapod top platform
    +  io(io_i) = linio([mdl, '/Micro-Station/Micro Hexapod/Compliance/Dm'], 1, 'output'); io_i = io_i + 1; % Absolute displacement of the top platform
     
    -%% Run the linearization
    -Gm = linearize(mdl, io, 0);
    -Gm.InputName  = {'Fmx', 'Fmy', 'Fmz', 'Mmx', 'Mmy', 'Mmz'};
    -Gm.OutputName = {'Dx', 'Dy', 'Dz', 'Drx', 'Dry', 'Drz'};
    +  %% Run the linearization
    +  Gm = linearize(mdl, io, 0);
    +  Gm.InputName  = {'Fmx', 'Fmy', 'Fmz', 'Mmx', 'Mmy', 'Mmz'};
    +  Gm.OutputName = {'Dx', 'Dy', 'Dz', 'Drx', 'Dry', 'Drz'};
     
    -
    save('../meas/micro-station-compliance/mat/model.mat', 'Gm');
    +
      save('../meas/micro-station-compliance/mat/model.mat', 'Gm');
     
    -
    +

    compliance_micro_station.png

    Figure 4: Obtained compliance of the Micro-Station (png, pdf)

    @@ -593,10 +598,10 @@ Gm.OutputName = {'Dx', 'Dy', 'Dz', 'Drx', 'Dry', 'Drz'};
    -
    -

    4 Conclusion

    +
    +

    4 Conclusion

    -
    +

    For such a complex system, we believe that the Simscape Model represents the dynamics of the system with enough fidelity.

    @@ -607,7 +612,7 @@ For such a complex system, we believe that the Simscape Model represents the dyn

    Author: Dehaeze Thomas

    -

    Created: 2020-09-01 mar. 13:47

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/index.html b/docs/index.html index 8789986..796ca60 100644 --- a/docs/index.html +++ b/docs/index.html @@ -3,47 +3,43 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Simscape Model of the Nano-Active-Stabilization-System - - - - - - + +

    Simscape Model of the Nano-Active-Stabilization-System

    Table of Contents

    @@ -51,8 +47,8 @@ Here are links to the documents related to the Simscape model of the Nano-Active-Stabilization-System.

    -
    -

    1 Simulink Project (link)

    +
    +

    1 Simulink Project (link)

    The project is managed with a Simulink Project. @@ -61,8 +57,8 @@ Such project is briefly presented here.

    -
    -

    2 Simscape Model (link)

    +
    +

    2 Simscape Model (link)

    The model of the NASS is based on Simulink and Simscape Multi-Body. @@ -71,8 +67,8 @@ Such toolbox is presented here.

    -
    -

    3 Simscape Subsystems (link)

    +
    +

    3 Simscape Subsystems (link)

    The model is decomposed of multiple subsystems. @@ -86,8 +82,8 @@ All these subsystems are described here

    -
    -

    4 Kinematics of the Station (link)

    +
    +

    4 Kinematics of the Station (link)

    First, we consider perfectly rigid elements and joints and we just study the kinematic of the station. @@ -97,8 +93,8 @@ This is detailed here.

    -
    -

    5 Computation of the positioning error of the Sample (link)

    +
    +

    5 Computation of the positioning error of the Sample (link)

    From the measurement of the position of the sample with respect to the granite and from the wanted position of each stage, we can compute the positioning error of the sample with respect to the nano-hexapod. @@ -107,8 +103,8 @@ This is done here.

    -
    -

    6 Tuning of the Dynamics of the Simscape model (link)

    +
    +

    6 Tuning of the Dynamics of the Simscape model (link)

    From dynamical measurements perform on the real positioning station, we tune the parameters of the simscape model to have similar dynamics. @@ -120,8 +116,8 @@ This is explained here.

    -
    -

    7 Compensating Gravity forces to start simulation at steady state (link)

    +
    +

    7 Compensating Gravity forces to start simulation at steady state (link)

    When gravity is included in the model, the simulation does not start at steady state. @@ -137,8 +133,8 @@ A technique is described in this document in order to compensate the gravity for

    -
    -

    8 Disturbances (link)

    +
    +

    8 Disturbances (link)

    The effect of disturbances on the position of the micro-station have been measured. @@ -160,8 +156,8 @@ Some numerical analysis of such forces are done -

    9 Simulation of Experiment (link)

    +
    +

    9 Simulation of Experiment (link)

    Now that the dynamics of the Model have been tuned and the Disturbances have included, we can simulate experiments. @@ -173,8 +169,8 @@ Experiments are simulated and the results are presented -

    10 Effect of support’s compliance on the plant dynamics (link)

    +
    +

    10 Effect of support’s compliance on the plant dynamics (link)

    In this document, is studied how uncertainty on the micro-station compliance will affect the uncertainty of the isolation platform to be designed. @@ -182,8 +178,8 @@ In this document, is studied how uncertainty on the micro-station compliance wil

    -
    -

    11 Effect of the payload’s “impedance” on the plant dynamics (link)

    +
    +

    11 Effect of the payload’s “impedance” on the plant dynamics (link)

    The payload mass, stiffness and damping properties will influence the dynamics of the isolation platform. @@ -192,8 +188,8 @@ This effect is studied, and conclusions on what characteristics of the isolation

    -
    -

    12 Effect of Experimental conditions on the plant dynamics (link)

    +
    +

    12 Effect of Experimental conditions on the plant dynamics (link)

    In this document, the effect of all the experimental conditions (rotation speed, sample mass, …) on the plant dynamics are studied. @@ -202,12 +198,12 @@ Conclusion are drawn about what experimental conditions are critical on the vari

    -
    -

    13 Optimal Stiffness of the nano-hexapod to reduce plant uncertainty (link)

    +
    +

    13 Optimal Stiffness of the nano-hexapod to reduce plant uncertainty (link)

    -
    -

    14 Effect of flexible joints on the plant dynamics (link)

    +
    +

    14 Effect of flexible joints on the plant dynamics (link)

    In this document is studied how the flexible joint stiffnesses (in flexion, torsion and compression) is affecting the plant dynamics. @@ -216,8 +212,8 @@ Conclusion are drawn on the required stiffness properties of the flexible joints

    -
    -

    15 Dynamic Noise Budgeting (link)

    +
    +

    15 Dynamic Noise Budgeting (link)

    The maximum allowed noise of the sensors in the system are estimated using a Dynamic Noise Budgeting. @@ -225,8 +221,8 @@ The maximum allowed noise of the sensors in the system are estimated using a Dyn

    -
    -

    16 Active Damping Techniques on the full Simscape Model (link)

    +
    +

    16 Active Damping Techniques on the full Simscape Model (link)

    Active damping techniques are applied to the full Simscape model. @@ -234,8 +230,8 @@ Active damping techniques are applied to the full Simscape model.

    -
    -

    17 Control of the Nano-Active-Stabilization-System (link)

    +
    +

    17 Control of the Nano-Active-Stabilization-System (link)

    In this file are gathered all studies about the control the Nano-Active-Stabilization-System. @@ -243,8 +239,8 @@ In this file are gathered all studies about the control the Nano-Active-Stabiliz

    -
    -

    18 Useful Matlab Functions (link)

    +
    +

    18 Useful Matlab Functions (link)

    Many matlab functions are shared among all the files of the projects. @@ -258,7 +254,7 @@ These functions are all defined here.

    Author: Dehaeze Thomas

    -

    Created: 2020-07-31 ven. 18:00

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/kinematics.html b/docs/kinematics.html index df67c88..cdebb8e 100644 --- a/docs/kinematics.html +++ b/docs/kinematics.html @@ -1,50 +1,54 @@ - - + Kinematics of the station - - - - - - - - + + + +

    Kinematics of the station

    Table of Contents

      -
    • 1. Micro Hexapod +
    • 1. Micro Hexapod
        -
      • 1.1. How the Symetrie Hexapod is controlled on the micro station
      • -
      • 1.2. Control of the Micro-Hexapod using Simscape +
      • 1.1. How the Symetrie Hexapod is controlled on the micro station
      • +
      • 1.2. Control of the Micro-Hexapod using Simscape @@ -59,12 +63,12 @@ In this document, we discuss the way the motion of each stage is defined.

        -
        -

        1 Micro Hexapod

        +
        +

        1 Micro Hexapod

        -
        -

        1.1 How the Symetrie Hexapod is controlled on the micro station

        +
        +

        1.1 How the Symetrie Hexapod is controlled on the micro station

        For the Micro-Hexapod, the convention for the angles are defined in MAN_A_Software API_4.0.150918_EN.pdf on page 13 (section 2.4 - Rotation Vectors): @@ -112,8 +116,8 @@ Thus, it does the translations and then the rotation around the new translated f

        -
        -

        1.2 Control of the Micro-Hexapod using Simscape

        +
        +

        1.2 Control of the Micro-Hexapod using Simscape

        We can think of two main ways to position the Micro-Hexapod using Simscape. @@ -130,15 +134,15 @@ This require a little bit more of mathematical derivations but this is the chose

        -
        -

        1.2.1 Using Bushing Joint

        +
        +

        1.2.1 Using Bushing Joint

        -In the documentation of the Bushing Joint (doc "Bushing Joint") that is used to position the Hexapods, it is mention that the following frame is positioned with respect to the base frame in a way shown in figure 1. +In the documentation of the Bushing Joint (doc "Bushing Joint") that is used to position the Hexapods, it is mention that the following frame is positioned with respect to the base frame in a way shown in figure 1.

        -
        +

        bushing_joint_transform.png

        Figure 1: Joint Transformation Sequence for the Bushing Joint

        @@ -156,8 +160,8 @@ However, the Bushing Joint makes rotations around mobiles axes (X, Y’ and
        -
        -

        1.2.2 Using Inverse Kinematics and Leg Actuators

        +
        +

        1.2.2 Using Inverse Kinematics and Leg Actuators

        Here, we can use the Inverse Kinematic of the Hexapod to determine the length of each leg in order to obtain some defined translation and rotation of the mobile platform. @@ -183,8 +187,8 @@ Thus, for this simulation, we remove the gravity.

        -
        -
        1.2.2.1 Theory
        +
        +
        1.2.2.1 Theory

        For inverse kinematic analysis, it is assumed that the position \({}^A\bm{P}\) and orientation of the moving platform \({}^A\bm{R}_B\) are given and the problem is to obtain the joint variables, namely, \(\bm{L} = [l_1, l_2, \dots, l_6]^T\). @@ -219,14 +223,14 @@ Otherwise, when the limbs’ lengths derived yield complex numbers, then the

        -
        -
        1.2.2.2 Matlab Implementation
        +
        +
        1.2.2.2 Matlab Implementation

        We open the Simulink file.

        -
        open('nass_model.slx')
        +
          open('nass_model.slx')
         
        @@ -234,8 +238,8 @@ We open the Simulink file. We load the configuration and set a small StopTime.

        -
        load('mat/conf_simulink.mat');
        -set_param(conf_simulink, 'StopTime', '0.1');
        +
          load('mat/conf_simulink.mat');
        +  set_param(conf_simulink, 'StopTime', '0.1');
         
        @@ -243,40 +247,40 @@ We load the configuration and set a small StopTime. We define the wanted position/orientation of the Hexapod under study.

        -
        tx = 0.05; % [rad]
        -ty = 0.1; % [rad]
        -tz = 0.02; % [rad]
        +
          tx = 0.05; % [rad]
        +  ty = 0.1; % [rad]
        +  tz = 0.02; % [rad]
         
        -Rx = [1 0        0;
        -      0 cos(tx) -sin(tx);
        -      0 sin(tx)  cos(tx)];
        +  Rx = [1 0        0;
        +        0 cos(tx) -sin(tx);
        +        0 sin(tx)  cos(tx)];
         
        -Ry = [ cos(ty) 0 sin(ty);
        -      0        1 0;
        -      -sin(ty) 0 cos(ty)];
        +  Ry = [ cos(ty) 0 sin(ty);
        +        0        1 0;
        +        -sin(ty) 0 cos(ty)];
         
        -Rz = [cos(tz) -sin(tz) 0;
        -      sin(tz)  cos(tz) 0;
        -      0        0       1];
        +  Rz = [cos(tz) -sin(tz) 0;
        +        sin(tz)  cos(tz) 0;
        +        0        0       1];
         
        -ARB = Rz*Ry*Rx;
        -AP = [0.1; 0.005; 0.01]; % [m]
        +  ARB = Rz*Ry*Rx;
        +  AP = [0.1; 0.005; 0.01]; % [m]
         
        -
        initializeSimscapeConfiguration('gravity', false);
        -initializeGround('type', 'none');
        -initializeGranite('type', 'none');
        -initializeTy('type', 'none');
        -initializeRy('type', 'none');
        -initializeRz('type', 'none');
        -initializeMicroHexapod('type', 'rigid', 'AP', AP, 'ARB', ARB);
        -initializeAxisc('type', 'none');
        -initializeMirror('type', 'none');
        -initializeNanoHexapod('type', 'none');
        -initializeSample('type', 'none');
        -initializeLoggingConfiguration('log', 'all');
        +
          initializeSimscapeConfiguration('gravity', false);
        +  initializeGround('type', 'none');
        +  initializeGranite('type', 'none');
        +  initializeTy('type', 'none');
        +  initializeRy('type', 'none');
        +  initializeRz('type', 'none');
        +  initializeMicroHexapod('type', 'rigid', 'AP', AP, 'ARB', ARB);
        +  initializeAxisc('type', 'none');
        +  initializeMirror('type', 'none');
        +  initializeNanoHexapod('type', 'none');
        +  initializeSample('type', 'none');
        +  initializeLoggingConfiguration('log', 'all');
         
        @@ -284,7 +288,7 @@ initializeLoggingConfiguration('log',
        -
        sim('nass_model');
        +
          sim('nass_model');
         
        @@ -292,7 +296,7 @@ We run the simulation. And we verify that we indeed succeed to go to the wanted position.

        -
        [simout.Dhm.x.Data(end) ; simout.Dhm.y.Data(end) ; simout.Dhm.z.Data(end)] - AP
        +
          [simout.Dhm.x.Data(end) ; simout.Dhm.y.Data(end) ; simout.Dhm.z.Data(end)] - AP
         
        @@ -318,7 +322,7 @@ And we verify that we indeed succeed to go to the wanted position.
    Table 2: Estimated Center of Mass of each solid body using Solidworks
    -
    simout.Dhm.R.Data(:, :, end)-ARB
    +
      simout.Dhm.R.Data(:, :, end)-ARB
     
    @@ -360,7 +364,7 @@ And we verify that we indeed succeed to go to the wanted position.

    Author: Dehaeze Thomas

    -

    Created: 2020-04-17 ven. 09:35

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/metrology_frame.html b/docs/metrology_frame.html index 4a01e75..94a47ed 100644 --- a/docs/metrology_frame.html +++ b/docs/metrology_frame.html @@ -1,55 +1,59 @@ - - + Study of the Metrology Frame - - - - - - - - + + + +

    Study of the Metrology Frame

    -
    -

    1 Flexibility of the reference mirror

    +
    +

    1 Flexibility of the reference mirror

    In this section we wish to see how a flexibility between the nano-hexapod’s top platform and the reference mirror will change the plant dynamics and limits the performance. @@ -64,21 +68,21 @@ We will compare the two dynamics and conclude.

    -
    -

    1.1 Initialization

    +
    +

    1.1 Initialization

    We initialize all the stages with the default parameters.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeNanoHexapod();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeNanoHexapod();
     
    @@ -86,33 +90,33 @@ initializeNanoHexapod(); We first consider a rigid Sample to simplify the analysis.

    -
    initializeSample('type', 'rigid');
    +
      initializeSample('type', 'rigid');
     
    -
    -

    1.2 Rigid fixation between the metrology frame and the nano-hexapod

    +
    +

    1.2 Rigid fixation between the metrology frame and the nano-hexapod

    Let’s first consider a rigid reference mirror and we identify the dynamics of the system.

    -
    initializeMirror('type', 'rigid');
    +
      initializeMirror('type', 'rigid');
     
    -
    -

    1.3 Flexible fixation between the metrology frame and the nano-hexapod

    +
    +

    1.3 Flexible fixation between the metrology frame and the nano-hexapod

    We now initialize a reference mirror with a main resonance frequency at \(200\ [Hz]\).

    -
    initializeMirror('type', 'flexible', 'freq', 200*ones(6,1));
    +
      initializeMirror('type', 'flexible', 'freq', 200*ones(6,1));
     
    @@ -121,15 +125,15 @@ And we re identify the plant dynamics.

    -
    -

    1.4 Comparison

    +
    +

    1.4 Comparison

    -The obtained transfer functions from \(\mathcal{F}_z\) to \(\mathcal{X}_z\) when considering a rigid reference mirror and a flexible one are shown in Figure 1. +The obtained transfer functions from \(\mathcal{F}_z\) to \(\mathcal{X}_z\) when considering a rigid reference mirror and a flexible one are shown in Figure 1.

    -
    +

    effect_mirror_flexibility_fz_dz.png

    Figure 1: Effect of the mirror flexibility on the transfer function from \(\mathcal{F}_z\) to \(\mathcal{X}_z\)

    @@ -137,10 +141,10 @@ The obtained transfer functions from \(\mathcal{F}_z\) to \(\mathcal{X}_z\) when
    -
    -

    1.5 Conclusion

    +
    +

    1.5 Conclusion

    -
    +

    A flexibility between the nano-hexapod top platform and the reference mirror will appear in the plant as two complex conjugate poles at the frequency of the resonance of the mirror on top of the nano-hexapod. This induces 180 degrees of phase drop on the plant and will limit the attainable controller bandwidth. @@ -158,7 +162,7 @@ Thus, care should be taken when designing the fixation of the reference mirror o

    Author: Dehaeze Thomas

    -

    Created: 2020-05-05 mar. 10:33

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/motion_force_requirements.html b/docs/motion_force_requirements.html index af3d598..aef2a8b 100644 --- a/docs/motion_force_requirements.html +++ b/docs/motion_force_requirements.html @@ -1,51 +1,55 @@ - - + Motion and Force Requirements for the Nano-Hexapod - - - - - - - - + + + +

    Motion and Force Requirements for the Nano-Hexapod

    -
    -

    1 Soft Hexapod

    +
    +

    1 Soft Hexapod

    As the nano-hexapod is in series with the other stages, it must apply all the force required to move the sample. @@ -76,8 +80,8 @@ Then from the Newton’s second law: \(m \vec{a} = \sum \vec{F}\) we can com

    -
    -

    1.1 Example

    +
    +

    1.1 Example

    The wanted motion is: @@ -121,11 +125,11 @@ And the norm of the force is: For a Light sample:

    -
    m = 30;
    -d = 10e-3;
    -w = 2*pi;
    -F = m*d*w^2;
    -ans = F
    +
      m = 30;
    +  d = 10e-3;
    +  w = 2*pi;
    +  F = m*d*w^2;
    +  ans = F
     
    @@ -138,11 +142,11 @@ F = m*d*w
    -
    m = 80;
    -d = 10e-3;
    -w = 2*pi/60;
    -F = m*d*w^2
    -ans = F
    +
      m = 80;
    +  d = 10e-3;
    +  w = 2*pi/60;
    +  F = m*d*w^2
    +  ans = F
     
    @@ -155,7 +159,7 @@ F = m*d*w

    Author: Dehaeze Thomas

    -

    Created: 2020-04-17 ven. 09:35

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/noise_budgeting.html b/docs/noise_budgeting.html index 082d58a..c6e7bb4 100644 --- a/docs/noise_budgeting.html +++ b/docs/noise_budgeting.html @@ -3,77 +3,82 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Noise Budgeting - - - - - - - - + + + +

    Noise Budgeting

    -
    -

    1 Maximum Noise of the Relative Motion Sensors

    +
    +

    1 Maximum Noise of the Relative Motion Sensors

    -
    -

    1.1 Initialization

    +
    +

    1.1 Initialization

    -
    open('nass_model.slx');
    +
      open('nass_model.slx');
     
    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
     
    -initializeSimscapeConfiguration();
    -initializeDisturbances('enable', false);
    -initializeLoggingConfiguration('log', 'none');
    +  initializeSimscapeConfiguration();
    +  initializeDisturbances('enable', false);
    +  initializeLoggingConfiguration('log', 'none');
     
    -initializeController('type', 'hac-dvf');
    +  initializeController('type', 'hac-dvf');
     
    @@ -81,61 +86,61 @@ initializeController('type', 'hac-dvf'); We set the stiffness of the payload fixation:

    -
    Kp = 1e8; % [N/m]
    +
      Kp = 1e8; % [N/m]
     
    -
    initializeNanoHexapod('k', 1e5, 'c', 2e2);
    -
    -Ms = 50;
    -initializeSample('mass', Ms, 'freq', sqrt(Kp/Ms)/2/pi*ones(6,1));
    +
      initializeNanoHexapod('k', 1e5, 'c', 2e2);
    + 
    +  Ms = 50;
    +  initializeSample('mass', Ms, 'freq', sqrt(Kp/Ms)/2/pi*ones(6,1));
     
    -
    initializeReferences('Rz_type', 'rotating-not-filtered', 'Rz_period', Ms);
    +
      initializeReferences('Rz_type', 'rotating-not-filtered', 'Rz_period', Ms);
     
    -
    -

    1.2 Control System

    +
    +

    1.2 Control System

    -
    Kdvf = 5e3*s/(1+s/2/pi/1e3)*eye(6);
    +
      Kdvf = 5e3*s/(1+s/2/pi/1e3)*eye(6);
     
    -
    h = 2.0;
    -Kl = 2e7 * eye(6) * ...
    -     1/h*(s/(2*pi*100/h) + 1)/(s/(2*pi*100*h) + 1) * ...
    -     1/h*(s/(2*pi*200/h) + 1)/(s/(2*pi*200*h) + 1) * ...
    -     (s/2/pi/10 + 1)/(s/2/pi/10) * ...
    -     1/(1 + s/2/pi/300);
    +
      h = 2.0;
    +  Kl = 2e7 * eye(6) * ...
    +       1/h*(s/(2*pi*100/h) + 1)/(s/(2*pi*100*h) + 1) * ...
    +       1/h*(s/(2*pi*200/h) + 1)/(s/(2*pi*200*h) + 1) * ...
    +       (s/2/pi/10 + 1)/(s/2/pi/10) * ...
    +       1/(1 + s/2/pi/300);
     
    -
    load('mat/stages.mat', 'nano_hexapod');
    -K = Kl*nano_hexapod.kinematics.J*diag([1, 1, 1, 1, 1, 0]);
    +
      load('mat/stages.mat', 'nano_hexapod');
    +  K = Kl*nano_hexapod.kinematics.J*diag([1, 1, 1, 1, 1, 0]);
     
    -
    %% Run the linearization
    -G = linearize(mdl, io);
    -G.InputName  = {'ndL1', 'ndL2', 'ndL3', 'ndL4', 'ndL5', 'ndL6'};
    -G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
    +
      %% Run the linearization
    +  G = linearize(mdl, io);
    +  G.InputName  = {'ndL1', 'ndL2', 'ndL3', 'ndL4', 'ndL5', 'ndL6'};
    +  G.OutputName = {'Ex', 'Ey', 'Ez', 'Erx', 'Ery', 'Erz'};
     
    -
    -

    1.3 Maximum induced vibration’s ASD

    +
    +

    1.3 Maximum induced vibration’s ASD

    Required maximum induced ASD of the sample’s vibration due to the relative motion sensor noise. @@ -143,16 +148,16 @@ Required maximum induced ASD of the sample’s vibration due to the relative

    -
    Gamma_x = [(1e-9)/(1 + s/2/pi/100); % Dx
    -           (1e-9)/(1 + s/2/pi/100); % Dy
    -           (1e-9)/(1 + s/2/pi/100); % Dz
    -           (2e-8)/(1 + s/2/pi/100); % Rx
    -           (2e-8)/(1 + s/2/pi/100)]; % Ry
    +
      Gamma_x = [(1e-9)/(1 + s/2/pi/100); % Dx
    +             (1e-9)/(1 + s/2/pi/100); % Dy
    +             (1e-9)/(1 + s/2/pi/100); % Dz
    +             (2e-8)/(1 + s/2/pi/100); % Rx
    +             (2e-8)/(1 + s/2/pi/100)]; % Ry
     
    -
    freqs = logspace(0, 3, 1000);
    +
      freqs = logspace(0, 3, 1000);
     
    @@ -203,8 +208,8 @@ Corresponding RMS value in [nm rms, nrad rms]
    -
    -

    1.4 Computation of the maximum relative motion sensor noise

    +
    +

    1.4 Computation of the maximum relative motion sensor noise

    Let’s note \(G\) the transfer function from the 6 sensor noise \(n\) to the 5dof pose error \(x\). @@ -225,15 +230,15 @@ We then have an upper bound of the sensor noise for each of the considered motio

    -
    Gamma_ndL = zeros(5, length(freqs));
    -for in = 1:5
    -  Gamma_ndL(in, :) = abs(squeeze(freqresp(Gamma_x(in), freqs, 'Hz')))./sqrt(sum(abs(squeeze(freqresp(G(in, :), freqs, 'Hz'))).^2))';
    -end
    +
      Gamma_ndL = zeros(5, length(freqs));
    +  for in = 1:5
    +    Gamma_ndL(in, :) = abs(squeeze(freqresp(Gamma_x(in), freqs, 'Hz')))./sqrt(sum(abs(squeeze(freqresp(G(in, :), freqs, 'Hz'))).^2))';
    +  end
     
    -
    +

    noise_budget_ndL_max_asd.png

    Figure 1: Maximum estimated ASD of the relative motion sensor noise

    @@ -246,7 +251,7 @@ Then, the motion error due to sensor noise should be bellow the one specified.

    -
    Gamma_ndL_max = min(Gamma_ndL(1:5, :));
    +
      Gamma_ndL_max = min(Gamma_ndL(1:5, :));
     
    @@ -254,12 +259,12 @@ Then, the motion error due to sensor noise should be bellow the one specified. Let’s take a sensor with a white noise up to 1kHz that is bellow the specified one:

    -
    Gamma_ndL_ex = abs(squeeze(freqresp(min(Gamma_ndL_max)/(1 + s/2/pi/1e3), freqs, 'Hz')));
    +
      Gamma_ndL_ex = abs(squeeze(freqresp(min(Gamma_ndL_max)/(1 + s/2/pi/1e3), freqs, 'Hz')));
     
    -
    +

    relative_motion_sensor_noise_ASD_example.png

    Figure 2: Requirement maximum ASD of the sensor noise + example of a sensor validating the requirements

    @@ -269,7 +274,7 @@ Let’s take a sensor with a white noise up to 1kHz that is bellow the speci The corresponding RMS value of the sensor noise taken as an example is [nm RMS]:

    -
    1e9*sqrt(trapz(freqs, Gamma_ndL_max.^2))
    +
      1e9*sqrt(trapz(freqs, Gamma_ndL_max.^2))
     
    @@ -279,8 +284,8 @@ The corresponding RMS value of the sensor noise taken as an example is [nm RMS]:
    -
    -

    1.5 Verification of the induced motion error

    +
    +

    1.5 Verification of the induced motion error

    Verify that by taking the sensor noise, we have to wanted displacement error @@ -289,11 +294,11 @@ From the sensor noise PSD \(\Gamma_n(\omega)\), we can estimate the obtained dis

    -
    Gamma_xest = zeros(5, length(freqs));
    +
      Gamma_xest = zeros(5, length(freqs));
     
    -for in = 1:5
    -    Gamma_xest(in, :) = sqrt(sum(abs(squeeze(freqresp(G(in, :), freqs, 'Hz'))).^2.*Gamma_ndL_max.^2));
    -end
    +  for in = 1:5
    +      Gamma_xest(in, :) = sqrt(sum(abs(squeeze(freqresp(G(in, :), freqs, 'Hz'))).^2.*Gamma_ndL_max.^2));
    +  end
     
    @@ -352,7 +357,7 @@ end

    Author: Dehaeze Thomas

    -

    Created: 2020-09-01 mar. 13:47

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/optimal_stiffness_control.html b/docs/optimal_stiffness_control.html index 24f72b6..eabe83e 100644 --- a/docs/optimal_stiffness_control.html +++ b/docs/optimal_stiffness_control.html @@ -3,121 +3,126 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Control of the NASS with optimal stiffness - - - - - - - - + + + +

    Control of the NASS with optimal stiffness

    Table of Contents

    -
    -

    1 Low Authority Control - Decentralized Direct Velocity Feedback

    +
    +

    1 Low Authority Control - Decentralized Direct Velocity Feedback

    - +

    -
    +

    control_architecture_dvf.png

    Figure 1: Low Authority Control: Decentralized Direct Velocity Feedback

    -
    -

    1.1 Initialization

    +
    +

    1.1 Initialization

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
     
    -initializeSimscapeConfiguration();
    -initializeDisturbances('enable', false);
    -initializeLoggingConfiguration('log', 'none');
    +  initializeSimscapeConfiguration();
    +  initializeDisturbances('enable', false);
    +  initializeLoggingConfiguration('log', 'none');
     
    -initializeController('type', 'hac-dvf');
    +  initializeController('type', 'hac-dvf');
     
    @@ -125,18 +130,18 @@ initializeController('type', 'hac-dvf'); We set the stiffness of the payload fixation:

    -
    Kp = 1e8; % [N/m]
    +
      Kp = 1e8; % [N/m]
     
    -
    -

    1.2 Identification

    +
    +

    1.2 Identification

    -
    K = tf(zeros(6));
    -Kdvf = tf(zeros(6));
    +
      K = tf(zeros(6));
    +  Kdvf = tf(zeros(6));
     
    @@ -144,7 +149,7 @@ Kdvf = tf(zeros(6)); We identify the system for the following payload masses:

    -
    Ms = [1, 10, 50];
    +
      Ms = [1, 10, 50];
     
    @@ -152,36 +157,36 @@ We identify the system for the following payload masses: The nano-hexapod has the following leg’s stiffness and damping.

    -
    initializeNanoHexapod('k', 1e5, 'c', 2e2);
    +
      initializeNanoHexapod('k', 1e5, 'c', 2e2);
     
    -
    -

    1.3 Controller Design

    +
    +

    1.3 Controller Design

    -The obtain dynamics from actuators forces \(\tau_i\) to the relative motion of the legs \(d\mathcal{L}_i\) is shown in Figure 2 for the three considered payload masses. +The obtain dynamics from actuators forces \(\tau_i\) to the relative motion of the legs \(d\mathcal{L}_i\) is shown in Figure 2 for the three considered payload masses.

    -The Root Locus is shown in Figure 3 and wee see that we have unconditional stability. +The Root Locus is shown in Figure 3 and wee see that we have unconditional stability.

    -In order to choose the gain such that we obtain good damping for all the three payload masses, we plot the damping ration of the modes as a function of the gain for all three payload masses in Figure 4. +In order to choose the gain such that we obtain good damping for all the three payload masses, we plot the damping ration of the modes as a function of the gain for all three payload masses in Figure 4.

    -
    +

    opt_stiff_dvf_plant.png

    Figure 2: Dynamics for the Direct Velocity Feedback active damping for three payload masses

    -
    +

    opt_stiff_dvf_root_locus.png

    Figure 3: Root Locus for the DVF control for three payload masses

    @@ -191,7 +196,7 @@ In order to choose the gain such that we obtain good damping for all the three p Damping as function of the gain

    -
    +

    opt_stiff_dvf_damping_gain.png

    Figure 4: Damping ratio of the poles as a function of the DVF gain

    @@ -201,14 +206,14 @@ Damping as function of the gain Finally, we use the following controller for the Decentralized Direct Velocity Feedback:

    -
    Kdvf = 5e3*s/(1+s/2/pi/1e3)*eye(6);
    +
      Kdvf = 5e3*s/(1+s/2/pi/1e3)*eye(6);
     
    -
    -

    1.4 Effect of the Low Authority Control on the Primary Plant

    +
    +

    1.4 Effect of the Low Authority Control on the Primary Plant

    Let’s identify the dynamics from actuator forces \(\bm{\tau}\) to displacement as measured by the metrology \(\bm{\mathcal{X}}\): @@ -220,10 +225,10 @@ We do so both when the DVF is applied and when it is not applied.

    Then, we compute the transfer function from forces applied by the actuators \(\bm{\mathcal{F}}\) to the measured position error in the frame of the nano-hexapod \(\bm{\epsilon}_{\mathcal{X}_n}\): \[ \bm{G}_\mathcal{X}(s) = \frac{\bm{\epsilon}_{\mathcal{X}_n}}{\bm{\mathcal{F}}} = \bm{G}(s) \bm{J}^{-T} \] -The obtained dynamics is shown in Figure 5. +The obtained dynamics is shown in Figure 5.

    -
    +

    A zero with a positive real part is introduced in the transfer function from \(\mathcal{F}_y\) to \(\mathcal{X}_y\) after Decentralized Direct Velocity Feedback is applied.

    @@ -233,23 +238,23 @@ A zero with a positive real part is introduced in the transfer function from \(\

    And we compute the transfer function from actuator forces \(\bm{\tau}\) to position error of each leg \(\bm{\epsilon}_\mathcal{L}\): \[ \bm{G}_\mathcal{L} = \frac{\bm{\epsilon}_\mathcal{L}}{\bm{\tau}} = \bm{J} \bm{G}(s) \] -The obtained dynamics is shown in Figure 6. +The obtained dynamics is shown in Figure 6.

    -
    +

    opt_stiff_primary_plant_damped_X.png

    Figure 5: Primary plant in the task space with (dashed) and without (solid) Direct Velocity Feedback

    -
    +

    opt_stiff_primary_plant_damped_L.png

    Figure 6: Primary plant in the space of the legs with (dashed) and without (solid) Direct Velocity Feedback

    -The coupling (off diagonal elements) of \(\bm{G}_\mathcal{X}\) are shown in Figure 7 both when DVF is applied and when it is not. +The coupling (off diagonal elements) of \(\bm{G}_\mathcal{X}\) are shown in Figure 7 both when DVF is applied and when it is not.

    @@ -258,25 +263,25 @@ The coupling does not change a lot with DVF.

    -The coupling in the space of the legs \(\bm{G}_\mathcal{L}\) are shown in Figure 8. +The coupling in the space of the legs \(\bm{G}_\mathcal{L}\) are shown in Figure 8.

    -
    +

    -The magnitude of the coupling between \(\tau_i\) and \(d\mathcal{L}_j\) (Figure 8) around the resonance of the nano-hexapod (where the coupling is the highest) is considerably reduced when DVF is applied. +The magnitude of the coupling between \(\tau_i\) and \(d\mathcal{L}_j\) (Figure 8) around the resonance of the nano-hexapod (where the coupling is the highest) is considerably reduced when DVF is applied.

    -
    +

    opt_stiff_primary_plant_damped_coupling_X.png

    Figure 7: Coupling in the primary plant in the task with (dashed) and without (solid) Direct Velocity Feedback

    -
    +

    opt_stiff_primary_plant_damped_coupling_L.png

    Figure 8: Coupling in the primary plant in the space of the legs with (dashed) and without (solid) Direct Velocity Feedback

    @@ -284,8 +289,8 @@ The magnitude of the coupling between \(\tau_i\) and \(d\mathcal{L}_j\) (Figure
    -
    -

    1.5 Effect of the Low Authority Control on the Sensibility to Disturbances

    +
    +

    1.5 Effect of the Low Authority Control on the Sensibility to Disturbances

    We may now see how Decentralized Direct Velocity Feedback changes the sensibility to disturbances, namely: @@ -307,15 +312,15 @@ To simplify the analysis, we here only consider the vertical direction, thus, we

    -The norm of these transfer functions are shown in Figure 9. +The norm of these transfer functions are shown in Figure 9.

    -
    +

    opt_stiff_sensibility_dist_dvf.png

    Figure 9: Norm of the transfer function from vertical disturbances to vertical position error with (dashed) and without (solid) Direct Velocity Feedback applied

    -
    +

    Decentralized Direct Velocity Feedback is shown to increase the effect of stages vibrations at high frequency and to reduce the effect of ground motion and direct forces at low frequency.

    @@ -324,10 +329,10 @@ Decentralized Direct Velocity Feedback is shown to increase the effect of stages
    -
    -

    1.6 Conclusion

    +
    +

    1.6 Conclusion

    -
    +

    @@ -337,14 +342,14 @@ Decentralized Direct Velocity Feedback is shown to increase the effect of stages
    -
    -

    2 Primary Control in the leg space

    +
    +

    2 Primary Control in the leg space

    - +

    -In this section we implement the control architecture shown in Figure 10 consisting of: +In this section we implement the control architecture shown in Figure 10 consisting of:

    -
    -

    2.1 Plant in the leg space

    +
    +

    2.1 Plant in the leg space

    We now look at the transfer function matrix from \(\bm{\tau}^\prime\) to \(\bm{\epsilon}_{\mathcal{X}_n}\) for the design of \(\bm{K}_\mathcal{L}\).

    -The diagonal elements of the transfer function matrix from \(\bm{\tau}^\prime\) to \(\bm{\epsilon}_{\mathcal{X}_n}\) for the three considered masses are shown in Figure 11. +The diagonal elements of the transfer function matrix from \(\bm{\tau}^\prime\) to \(\bm{\epsilon}_{\mathcal{X}_n}\) for the three considered masses are shown in Figure 11.

    @@ -378,7 +383,7 @@ The plant dynamics below \(100\ [Hz]\) is only slightly dependent on the payload

    -
    +

    opt_stiff_primary_plant_L.png

    Figure 11: Diagonal elements of the transfer function matrix from \(\bm{\tau}^\prime\) to \(\bm{\epsilon}_{\mathcal{X}_n}\) for the three considered masses

    @@ -387,8 +392,8 @@ The plant dynamics below \(100\ [Hz]\) is only slightly dependent on the payload
    -
    -

    2.2 Control in the leg space

    +
    +

    2.2 Control in the leg space

    We design a diagonal controller with all the same diagonal elements. @@ -414,21 +419,21 @@ The design controller is as follows:

    -The loop gain is shown in Figure 12. +The loop gain is shown in Figure 12.

    -
    h = 2.0;
    -Kl = 2e7 * eye(6) * ...
    -     1/h*(s/(2*pi*100/h) + 1)/(s/(2*pi*100*h) + 1) * ...
    -     1/h*(s/(2*pi*200/h) + 1)/(s/(2*pi*200*h) + 1) * ...
    -     (s/2/pi/10 + 1)/(s/2/pi/10) * ...
    -     1/(1 + s/2/pi/300);
    +
      h = 2.0;
    +  Kl = 2e7 * eye(6) * ...
    +       1/h*(s/(2*pi*100/h) + 1)/(s/(2*pi*100*h) + 1) * ...
    +       1/h*(s/(2*pi*200/h) + 1)/(s/(2*pi*200*h) + 1) * ...
    +       (s/2/pi/10 + 1)/(s/2/pi/10) * ...
    +       1/(1 + s/2/pi/300);
     
    -
    +

    opt_stiff_primary_loop_gain_L.png

    Figure 12: Loop gain for the primary plant

    @@ -438,25 +443,25 @@ Kl = 2e7 * eye(6) * ... Finally, we include the Jacobian in the control and we ignore the measurement of the vertical rotation as for the real system.

    -
    load('mat/stages.mat', 'nano_hexapod');
    -K = Kl*nano_hexapod.kinematics.J*diag([1, 1, 1, 1, 1, 0]);
    +
      load('mat/stages.mat', 'nano_hexapod');
    +  K = Kl*nano_hexapod.kinematics.J*diag([1, 1, 1, 1, 1, 0]);
     
    -
    -

    2.3 Sensibility to Disturbances and Noise Budget

    +
    +

    2.3 Sensibility to Disturbances and Noise Budget

    We identify the transfer function from disturbances to the position error of the sample when the HAC-LAC control is applied.

    -We compare the norm of these transfer function for the vertical direction when no control is applied and when HAC-LAC control is applied: Figure 13. +We compare the norm of these transfer function for the vertical direction when no control is applied and when HAC-LAC control is applied: Figure 13.

    -
    +

    opt_stiff_primary_control_L_senbility_dist.png

    Figure 13: Sensibility to disturbances when the HAC-LAC control is applied

    @@ -465,27 +470,27 @@ We compare the norm of these transfer function for the vertical direction when n Then, we load the Power Spectral Density of the perturbations and we look at the obtained PSD of the displacement error in the vertical direction due to the disturbances:

      -
    • Figure 14: Amplitude Spectral Density of the vertical position error due to both the vertical ground motion and the vertical vibrations of the spindle
    • -
    • Figure 15: Comparison of the Amplitude Spectral Density of the vertical position error in Open Loop and with the HAC-DVF Control
    • -
    • Figure 16: Comparison of the Cumulative Amplitude Spectrum of the vertical position error in Open Loop and with the HAC-DVF Control
    • +
    • Figure 14: Amplitude Spectral Density of the vertical position error due to both the vertical ground motion and the vertical vibrations of the spindle
    • +
    • Figure 15: Comparison of the Amplitude Spectral Density of the vertical position error in Open Loop and with the HAC-DVF Control
    • +
    • Figure 16: Comparison of the Cumulative Amplitude Spectrum of the vertical position error in Open Loop and with the HAC-DVF Control
    -
    +

    opt_stiff_primary_control_L_psd_dist.png

    Figure 14: Amplitude Spectral Density of the vertical position error of the sample when the HAC-DVF control is applied due to both the ground motion and spindle vibrations

    -
    +

    opt_stiff_primary_control_L_psd_tot.png

    Figure 15: Amplitude Spectral Density of the vertical position error of the sample in Open-Loop and when the HAC-DVF control is applied

    -
    +

    opt_stiff_primary_control_L_cas_tot.png

    Figure 16: Cumulative Amplitude Spectrum of the vertical position error of the sample in Open-Loop and when the HAC-DVF control is applied

    @@ -493,17 +498,17 @@ Then, we load the Power Spectral Density of the perturbations and we look at the
    -
    -

    2.4 Simulations of Tomography Experiment

    +
    +

    2.4 Simulations of Tomography Experiment

    Let’s now simulate a tomography experiment. To do so, we include all disturbances except vibrations of the translation stage.

    -
    initializeDisturbances();
    -initializeSimscapeConfiguration('gravity', false);
    -initializeLoggingConfiguration('log', 'all');
    +
      initializeDisturbances();
    +  initializeSimscapeConfiguration('gravity', false);
    +  initializeLoggingConfiguration('log', 'all');
     
    @@ -512,40 +517,40 @@ And we run the simulation for all three payload Masses.

    -
    -

    2.5 Results

    +
    +

    2.5 Results

    Let’s now see how this controller performs.

    -First, we compute the Power Spectral Density of the sample’s position error and we compare it with the open loop case in Figure 17. +First, we compute the Power Spectral Density of the sample’s position error and we compare it with the open loop case in Figure 17.

    -Similarly, the Cumulative Amplitude Spectrum is shown in Figure 18. +Similarly, the Cumulative Amplitude Spectrum is shown in Figure 18.

    -Finally, the time domain position error signals are shown in Figure 19. +Finally, the time domain position error signals are shown in Figure 19.

    -
    +

    opt_stiff_hac_dvf_L_psd_disp_error.png

    Figure 17: Amplitude Spectral Density of the position error in Open Loop and with the HAC-LAC controller

    -
    +

    opt_stiff_hac_dvf_L_cas_disp_error.png

    Figure 18: Cumulative Amplitude Spectrum of the position error in Open Loop and with the HAC-LAC controller

    -
    +

    opt_stiff_hac_dvf_L_pos_error.png

    Figure 19: Position Error of the sample during a tomography experiment when no control is applied and with the HAC-DVF control architecture

    @@ -553,18 +558,18 @@ Finally, the time domain position error signals are shown in Figure -

    2.6 Actuator Stroke and Forces

    +
    +

    2.6 Actuator Stroke and Forces

    -
    +

    opt_stiff_hac_dvf_L_act_force.png

    Figure 20: Force applied by the actuator during the simulation

    -
    +

    opt_stiff_hac_dvf_L_act_stroke.png

    Figure 21: Leg’s stroke during the simulation

    @@ -572,10 +577,10 @@ Finally, the time domain position error signals are shown in Figure
    -

    2.7 Conclusion

    +
    +

    2.7 Conclusion

    -
    +

    @@ -585,16 +590,16 @@ Finally, the time domain position error signals are shown in Figure
    -

    3 Further More complex simulations

    +
    +

    3 Further More complex simulations

    -
    -

    3.1 Simulation with Micro-Hexapod Offset

    +
    +

    3.1 Simulation with Micro-Hexapod Offset

    -
    -

    3.1.1 Simulation

    +
    +

    3.1.1 Simulation

    The micro-hexapod is inducing a 10mm offset of the sample center of mass with the rotation axis. @@ -602,43 +607,43 @@ A tomography experiment is then simulated.

    -
    initializeDisturbances();
    -initializeSimscapeConfiguration('gravity', false);
    -initializeLoggingConfiguration('log', 'all');
    +
      initializeDisturbances();
    +  initializeSimscapeConfiguration('gravity', false);
    +  initializeLoggingConfiguration('log', 'all');
     
    -initializeSample('mass', 1, 'freq', 200);
    -initializeMicroHexapod('AP', [10e-3 0 0]);
    -initializeReferences('Rz_type', 'rotating', 'Rz_period', 1, ...
    -                     'Dh_pos', [10e-3; 0; 0; 0; 0; 0]);
    +  initializeSample('mass', 1, 'freq', 200);
    +  initializeMicroHexapod('AP', [10e-3 0 0]);
    +  initializeReferences('Rz_type', 'rotating', 'Rz_period', 1, ...
    +                       'Dh_pos', [10e-3; 0; 0; 0; 0; 0]);
     
    -
    load('mat/conf_simulink.mat');
    -set_param(conf_simulink, 'StopTime', '3');
    -sim('nass_model');
    +
      load('mat/conf_simulink.mat');
    +  set_param(conf_simulink, 'StopTime', '3');
    +  sim('nass_model');
     
    -
    -

    3.1.2 Results

    +
    +

    3.1.2 Results

    -
    +

    opt_stiff_hac_dvf_Dh_offset_disp_error.png

    -
    +

    opt_stiff_hac_dvf_Dh_offset_F.png

    -
    +

    opt_stiff_hac_dvf_Dh_offset_dL.png

    @@ -646,12 +651,12 @@ sim('nass_model');
    -
    -

    3.2 Simultaneous Translation scans and Spindle’s rotation

    +
    +

    3.2 Simultaneous Translation scans and Spindle’s rotation

    -
    -

    3.2.1 Simulation

    +
    +

    3.2.1 Simulation

    A simulation is now performed with translation scans and spindle rotation at the same time. @@ -662,35 +667,35 @@ The sample has a mass of 1kg, the spindle rotation speed is 60rpm and the transl

    -
    initializeDisturbances();
    -initializeSimscapeConfiguration('gravity', false);
    -initializeLoggingConfiguration('log', 'all');
    +
      initializeDisturbances();
    +  initializeSimscapeConfiguration('gravity', false);
    +  initializeLoggingConfiguration('log', 'all');
     
    -initializeSample('mass', 1, 'freq', 200);
    -initializeReferences('Rz_type', 'rotating', 'Rz_period', 1, ...
    -                     'Dy_type', 'triangular', 'Dy_amplitude', 5e-3, 'Dy_period', 4);
    +  initializeSample('mass', 1, 'freq', 200);
    +  initializeReferences('Rz_type', 'rotating', 'Rz_period', 1, ...
    +                       'Dy_type', 'triangular', 'Dy_amplitude', 5e-3, 'Dy_period', 4);
     
    -
    -

    3.2.2 Results

    +
    +

    3.2.2 Results

    -
    +

    opt_stiff_hac_dvf_Dy_scans_disp_error.png

    -
    +

    opt_stiff_hac_dvf_Dy_scans_F.png

    -
    +

    opt_stiff_hac_dvf_Dy_scans_dL.png

    @@ -699,14 +704,14 @@ initializeReferences('Rz_type', 'rotating', 'Rz_period', 1, ...
    -
    -

    4 Primary Control in the task space

    +
    +

    4 Primary Control in the task space

    - +

    -In this section, the control architecture shown in Figure 28 is applied and consists of: +In this section, the control architecture shown in Figure 28 is applied and consists of:

    • an inner Low Authority Control loop consisting of a decentralized direct velocity control controller
    • @@ -714,14 +719,14 @@ In this section, the control architecture shown in Figure
    -
    +

    control_architecture_hac_dvf_pos_X.png

    Figure 28: HAC-LAC architecture

    -
    -

    4.1 Plant in the task space

    +
    +

    4.1 Plant in the task space

    Let’s look \(\bm{G}_\mathcal{X}(s)\). @@ -729,62 +734,62 @@ Let’s look \(\bm{G}_\mathcal{X}(s)\).

    -
    -

    4.2 Control in the task space

    +
    +

    4.2 Control in the task space

    -
    Kx = tf(zeros(6));
    +
      Kx = tf(zeros(6));
     
    -h = 2.5;
    -Kx(1,1) = 3e7 * ...
    -          1/h*(s/(2*pi*100/h) + 1)/(s/(2*pi*100*h) + 1) * ...
    -          (s/2/pi/1 + 1)/(s/2/pi/1);
    +  h = 2.5;
    +  Kx(1,1) = 3e7 * ...
    +            1/h*(s/(2*pi*100/h) + 1)/(s/(2*pi*100*h) + 1) * ...
    +            (s/2/pi/1 + 1)/(s/2/pi/1);
     
    -Kx(2,2) = Kx(1,1);
    +  Kx(2,2) = Kx(1,1);
     
    -h = 2.5;
    -Kx(3,3) = 3e7 * ...
    -          1/h*(s/(2*pi*100/h) + 1)/(s/(2*pi*100*h) + 1) * ...
    -          (s/2/pi/1 + 1)/(s/2/pi/1);
    +  h = 2.5;
    +  Kx(3,3) = 3e7 * ...
    +            1/h*(s/(2*pi*100/h) + 1)/(s/(2*pi*100*h) + 1) * ...
    +            (s/2/pi/1 + 1)/(s/2/pi/1);
     
    -
    h = 1.5;
    -Kx(4,4) = 5e5 * ...
    -          1/h*(s/(2*pi*100/h) + 1)/(s/(2*pi*100*h) + 1) * ...
    -          (s/2/pi/1 + 1)/(s/2/pi/1);
    +
      h = 1.5;
    +  Kx(4,4) = 5e5 * ...
    +            1/h*(s/(2*pi*100/h) + 1)/(s/(2*pi*100*h) + 1) * ...
    +            (s/2/pi/1 + 1)/(s/2/pi/1);
     
    -Kx(5,5) = Kx(4,4);
    +  Kx(5,5) = Kx(4,4);
     
    -h = 1.5;
    -Kx(6,6) = 5e4 * ...
    -          1/h*(s/(2*pi*30/h) + 1)/(s/(2*pi*30*h) + 1) * ...
    -          (s/2/pi/1 + 1)/(s/2/pi/1);
    +  h = 1.5;
    +  Kx(6,6) = 5e4 * ...
    +            1/h*(s/(2*pi*30/h) + 1)/(s/(2*pi*30*h) + 1) * ...
    +            (s/2/pi/1 + 1)/(s/2/pi/1);
     
    -
    -

    4.2.1 Stability

    +
    +

    4.2.1 Stability

    -
    for i = 1:length(Ms)
    -    isstable(feedback(Gm_x{i}*Kx, eye(6), -1))
    -end
    +
      for i = 1:length(Ms)
    +      isstable(feedback(Gm_x{i}*Kx, eye(6), -1))
    +  end
     
    -
    -

    4.3 Simulation

    +
    +

    4.3 Simulation

    -
    -

    4.4 Conclusion

    +
    +

    4.4 Conclusion

    -
    +

    @@ -796,7 +801,7 @@ end

    Author: Dehaeze Thomas

    -

    Created: 2020-05-20 mer. 16:41

    +

    Created: 2021-02-20 sam. 23:09

    diff --git a/docs/optimal_stiffness_disturbances.html b/docs/optimal_stiffness_disturbances.html index d3cdc59..b37be84 100644 --- a/docs/optimal_stiffness_disturbances.html +++ b/docs/optimal_stiffness_disturbances.html @@ -1,79 +1,83 @@ - - + Determination of the optimal nano-hexapod’s stiffness for reducing the effect of disturbances - - - - - - - - + + + +

    Determination of the optimal nano-hexapod’s stiffness for reducing the effect of disturbances

    Table of Contents

    @@ -86,18 +90,18 @@ In this document is studied how the stiffness of the nano-hexapod will impact th It is divided in the following sections:

      -
    • Section 1: the disturbances are listed and their Power Spectral Densities (PSD) are shown
    • -
    • Section 2: the transfer functions from disturbances to the position error of the sample are computed for a wide range of nano-hexapod stiffnesses
    • -
    • Section 3:
    • -
    • Section 4: from both the PSD of the disturbances and the transfer function from disturbances to sample’s position errors, we compute the resulting PSD and Cumulative Amplitude Spectrum (CAS)
    • -
    • Section 5: from a simplistic model is computed the required control bandwidth to reduce the position error to acceptable values
    • +
    • Section 1: the disturbances are listed and their Power Spectral Densities (PSD) are shown
    • +
    • Section 2: the transfer functions from disturbances to the position error of the sample are computed for a wide range of nano-hexapod stiffnesses
    • +
    • Section 3:
    • +
    • Section 4: from both the PSD of the disturbances and the transfer function from disturbances to sample’s position errors, we compute the resulting PSD and Cumulative Amplitude Spectrum (CAS)
    • +
    • Section 5: from a simplistic model is computed the required control bandwidth to reduce the position error to acceptable values
    -
    -

    1 Disturbances

    +
    +

    1 Disturbances

    - +

    The main disturbances considered here are: @@ -113,7 +117,7 @@ The main disturbances considered here are: The level of these disturbances has been identified form experiments which are detailed in this document.

    -The measured Amplitude Spectral Densities (ASD) of these forces are shown in Figures 1 and 2. +The measured Amplitude Spectral Densities (ASD) of these forces are shown in Figures 1 and 2.

    @@ -121,14 +125,14 @@ In this study, the expected frequency content of the direct forces applied to th

    -
    +

    opt_stiff_dist_gm.png

    Figure 1: Amplitude Spectral Density of the Ground Displacement (png, pdf)

    -
    +

    opt_stiff_dist_fty_frz.png

    Figure 2: Amplitude Spectral Density of the “parasitic” forces comming from the Translation stage and the spindle (png, pdf)

    @@ -136,32 +140,32 @@ In this study, the expected frequency content of the direct forces applied to th
    -
    -

    2 Effect of disturbances on the position error

    +
    +

    2 Effect of disturbances on the position error

    - +

    In this section, we use the Simscape model to identify the transfer function from disturbances to the position error of the sample. We do that for a wide range of nano-hexapod stiffnesses and we compare the obtained results.

    -
    -

    2.1 Initialization

    +
    +

    2.1 Initialization

    We initialize all the stages with the default parameters.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
     
    @@ -169,7 +173,7 @@ initializeMirror(); We use a sample mass of 10kg.

    -
    initializeSample('mass', 10);
    +
      initializeSample('mass', 10);
     
    @@ -177,17 +181,17 @@ We use a sample mass of 10kg. We include gravity, and we use no controller.

    -
    initializeSimscapeConfiguration('gravity', true);
    -initializeController();
    -initializeDisturbances('enable', false);
    -initializeLoggingConfiguration('log', 'none');
    +
      initializeSimscapeConfiguration('gravity', true);
    +  initializeController();
    +  initializeDisturbances('enable', false);
    +  initializeLoggingConfiguration('log', 'none');
     
    -
    -

    2.2 Identification

    +
    +

    2.2 Identification

    The considered inputs are: @@ -210,40 +214,40 @@ The outputs are Ex, Ey, Ez, Erx

    -
    Ks = logspace(3,9,7); % [N/m]
    +
      Ks = logspace(3,9,7); % [N/m]
     
    -
    -

    2.3 Sensitivity to Stages vibration (Filtering)

    +
    +

    2.3 Sensitivity to Stages vibration (Filtering)

    The sensitivity the stage vibrations are displayed:

      -
    • Figure 3: sensitivity to vertical spindle vibrations
    • -
    • Figure 4: sensitivity to vertical translation stage vibrations
    • -
    • Figure 5: sensitivity to horizontal (x) translation stage vibrations
    • +
    • Figure 3: sensitivity to vertical spindle vibrations
    • +
    • Figure 4: sensitivity to vertical translation stage vibrations
    • +
    • Figure 5: sensitivity to horizontal (x) translation stage vibrations
    -
    +

    opt_stiff_sensitivity_Frz.png

    Figure 3: Sensitivity to Spindle vertical motion error (\(F_{rz}\)) to the vertical error position of the sample (\(E_z\)) (png, pdf)

    -
    +

    opt_stiff_sensitivity_Fty_z.png

    Figure 4: Sensitivity to Translation stage vertical motion error (\(F_{ty,z}\)) to the vertical error position of the sample (\(E_z\)) (png, pdf)

    -
    +

    opt_stiff_sensitivity_Fty_x.png

    Figure 5: Sensitivity to Translation stage \(x\) motion error (\(F_{ty,x}\)) to the error position of the sample in the \(x\) direction (\(E_x\)) (png, pdf)

    @@ -251,15 +255,15 @@ The sensitivity the stage vibrations are displayed:
    -
    -

    2.4 Effect of Ground motion (Transmissibility).

    +
    +

    2.4 Effect of Ground motion (Transmissibility).

    -The effect of Ground motion on the position error of the sample is shown in Figure 6. +The effect of Ground motion on the position error of the sample is shown in Figure 6.

    -
    +

    opt_stiff_sensitivity_Dw.png

    Figure 6: Sensitivity to Ground motion (\(D_{w}\)) to the position error of the sample (\(E_y\) and \(E_z\)) (png, pdf)

    @@ -267,15 +271,15 @@ The effect of Ground motion on the position error of the sample is shown in Figu
    -
    -

    2.5 Direct Forces (Compliance).

    +
    +

    2.5 Direct Forces (Compliance).

    -The effect of direct forces/torques applied on the sample (cable forces for instance) on the position error of the sample is shown in Figure 7. +The effect of direct forces/torques applied on the sample (cable forces for instance) on the position error of the sample is shown in Figure 7.

    -
    +

    opt_stiff_sensitivity_Fd.png

    Figure 7: Sensitivity to Direct forces and torques applied to the sample (\(F_d\), \(M_d\)) to the position error of the sample (png, pdf)

    @@ -283,16 +287,16 @@ The effect of direct forces/torques applied on the sample (cable forces for inst
    -
    -

    2.6 Conclusion

    +
    +

    2.6 Conclusion

    -
    +

    Reducing the nano-hexapod stiffness generally lowers the sensitivity to stages vibration but increases the sensitivity to ground motion and direct forces.

    -In order to conclude on the optimal stiffness that will yield the smallest sample vibration, one has to include the level of disturbances. This is done in Section 4. +In order to conclude on the optimal stiffness that will yield the smallest sample vibration, one has to include the level of disturbances. This is done in Section 4.

    @@ -300,38 +304,38 @@ In order to conclude on the optimal stiffness that will yield the smallest sampl
    -
    -

    3 Effect of granite stiffness

    +
    +

    3 Effect of granite stiffness

    - +

    In this section, we wish to see if a soft granite suspension could help in reducing the effect of disturbances on the position error of the sample.

    -
    -

    3.1 Analytical Analysis

    +
    +

    3.1 Analytical Analysis

    -
    -

    3.1.1 Simple mass-spring-damper model

    +
    +

    3.1.1 Simple mass-spring-damper model

    -Let’s consider the system shown in Figure 8 consisting of two stacked mass-spring-damper systems. +Let’s consider the system shown in Figure 8 consisting of two stacked mass-spring-damper systems. The bottom one represents the granite, and the top one all the positioning stages. We want the smallest stage “deformation” \(d = x^\prime - x\) due to ground motion \(w\).

    -
    +

    2dof_system_granite_stiffness.png

    Figure 8: Mass Spring Damper system consisting of a granite and a positioning stage

    -If we write the equation of motion of the system in Figure 8, we obtain: +If we write the equation of motion of the system in Figure 8, we obtain:

    \begin{align} m^\prime s^2 x^\prime &= (c^\prime s + k^\prime) (x - x^\prime) \\ @@ -347,8 +351,8 @@ If we note \(d = x^\prime - x\), we obtain:
    -
    -

    3.1.2 General Case

    +
    +

    3.1.2 General Case

    Let’s now considering a general positioning stage defined by: @@ -359,7 +363,7 @@ Let’s now considering a general positioning stage defined by: -

    +

    general_system_granite_stiffness.png

    Figure 9: Mass Spring Damper representing the granite and a general representation of positioning stages

    @@ -380,7 +384,7 @@ where:
  • \(F\) is the force applied by the position stages on the granite mass
  • -
    +

    We can express \(d\) as a function of \(w\):

    @@ -416,47 +420,47 @@ which is the same as the previously derived equation.
    -
    -

    3.2 Soft Granite

    +
    +

    3.2 Soft Granite

    Let’s initialize a soft granite and see how the sensitivity to disturbances will change.

    -
    initializeGranite('K', 5e5*ones(3,1), 'C', 5e3*ones(3,1));
    +
      initializeGranite('K', 5e5*ones(3,1), 'C', 5e3*ones(3,1));
     
    -
    -

    3.3 Effect of the Granite transfer function

    +
    +

    3.3 Effect of the Granite transfer function

    -From Figure 10, we can see that having a “soft” granite suspension greatly lowers the sensitivity to ground motion. +From Figure 10, we can see that having a “soft” granite suspension greatly lowers the sensitivity to ground motion. The sensitivity is indeed lowered starting from the resonance of the granite on its soft suspension (few Hz here).

    -From Figures 11 and 12, we see that the change of granite suspension does not change a lot the sensitivity to both direct forces and stage vibrations. +From Figures 11 and 12, we see that the change of granite suspension does not change a lot the sensitivity to both direct forces and stage vibrations.

    -
    +

    opt_stiff_soft_granite_Dw.png

    Figure 10: Change of sensibility to Ground motion when using a stiff Granite (solid curves) and a soft Granite (dashed curves) (png, pdf)

    -
    +

    opt_stiff_soft_granite_Frz.png

    Figure 11: Change of sensibility to Spindle vibrations when using a stiff Granite (solid curves) and a soft Granite (dashed curves) (png, pdf)

    -
    +

    opt_stiff_soft_granite_Fd.png

    Figure 12: Change of sensibility to direct forces when using a stiff Granite (solid curves) and a soft Granite (dashed curves) (png, pdf)

    @@ -464,10 +468,10 @@ From Figures 11 and 12, we s
    -
    -

    3.4 Conclusion

    +
    +

    3.4 Conclusion

    -
    +

    Having a soft granite suspension greatly decreases the sensitivity the ground motion. Also, it does not affect much the sensitivity to stage vibration and direct forces. @@ -479,29 +483,29 @@ Thus the level of sample vibration can be reduced by using a soft granite suspen

    -
    -

    4 Open Loop Budget Error

    +
    +

    4 Open Loop Budget Error

    - +

    -Now that the frequency content of disturbances have been estimated (Section 1) and the transfer functions from disturbances to the position error of the sample have been identified (Section 2), we can compute the level of sample vibration due to the disturbances. +Now that the frequency content of disturbances have been estimated (Section 1) and the transfer functions from disturbances to the position error of the sample have been identified (Section 2), we can compute the level of sample vibration due to the disturbances.

    We then can conclude and the nano-hexapod stiffness that will lower the sample position error.

    -
    -

    4.1 Noise Budgeting - Theory

    +
    +

    4.1 Noise Budgeting - Theory

    -Let’s consider Figure 13 there \(G_d(s)\) is the transfer function from a signal \(d\) (the perturbation) to a signal \(y\) (the sample’s position error). +Let’s consider Figure 13 there \(G_d(s)\) is the transfer function from a signal \(d\) (the perturbation) to a signal \(y\) (the sample’s position error).

    -
    +

    psd_change_tf.png

    Figure 13: Signal \(d\) going through and LTI transfer function \(G_d(s)\) to give a signal \(y\)

    @@ -515,7 +519,7 @@ We can compute the Power Spectral Density (PSD) of signal \(y\) from the PSD of \end{equation}

    -If we now consider multiple disturbances \(d_1, \dots, d_n\) as shown in Figure 14, we have that: +If we now consider multiple disturbances \(d_1, \dots, d_n\) as shown in Figure 14, we have that:

    \begin{equation} S_{y}(\omega) = \left|G_{d_1}(j\omega)\right|^2 S_{d_1}(\omega) + \dots + \left|G_{d_n}(j\omega)\right|^2 S_{d_n}(\omega) \label{eq:sum_psd} @@ -527,7 +531,7 @@ Sometimes, we prefer to compute the Amplitude Spectral Density (ASD) whic

    -
    +

    psd_change_tf_multiple_pert.png

    Figure 14: Block diagram showing and output \(y\) resulting from the addition of multiple perturbations \(d_i\)

    @@ -554,8 +558,8 @@ The CAS evaluation for all frequency corresponds to the rms value of the conside
    -
    -

    4.2 Power Spectral Densities

    +
    +

    4.2 Power Spectral Densities

    We compute the effect of perturbations on the motion error thanks to Eq. \eqref{eq:psd_transfer_function}. @@ -565,29 +569,29 @@ We compute the effect of perturbations on the motion error thanks to Eq. \eqref{ The result is shown in:

      -
    • Figure 15: PSD of the vertical sample’s motion error due to vertical ground motion
    • -
    • Figure 16: PSD of the vertical sample’s motion error due to vertical vibrations of the Spindle
    • +
    • Figure 15: PSD of the vertical sample’s motion error due to vertical ground motion
    • +
    • Figure 16: PSD of the vertical sample’s motion error due to vertical vibrations of the Spindle
    -
    +

    opt_stiff_psd_dz_gm.png

    Figure 15: Amplitude Spectral Density of the Sample vertical position error due to Ground motion for multiple nano-hexapod stiffnesses (png, pdf)

    -
    +

    opt_stiff_psd_dz_rz.png

    Figure 16: Amplitude Spectral Density of the Sample vertical position error due to Vertical vibration of the Spindle for multiple nano-hexapod stiffnesses (png, pdf)

    -We compute the effect of all perturbations on the vertical position error using Eq. \eqref{eq:sum_psd} and the resulting PSD is shown in Figure 17. +We compute the effect of all perturbations on the vertical position error using Eq. \eqref{eq:sum_psd} and the resulting PSD is shown in Figure 17.

    -
    +

    opt_stiff_psd_dz_tot.png

    Figure 17: Amplitude Spectral Density of the Sample vertical position error due to all considered perturbations for multiple nano-hexapod stiffnesses (png, pdf)

    @@ -595,16 +599,16 @@ We compute the effect of all perturbations on the vertical position error using
    -
    -

    4.3 Cumulative Amplitude Spectrum

    +
    +

    4.3 Cumulative Amplitude Spectrum

    Similarly, the Cumulative Amplitude Spectrum of the sample vibrations are shown:

      -
    • Figure 18: due to vertical ground motion
    • -
    • Figure 19: due to vertical vibrations of the Spindle
    • -
    • Figure 20: due to all considered perturbations
    • +
    • Figure 18: due to vertical ground motion
    • +
    • Figure 19: due to vertical vibrations of the Spindle
    • +
    • Figure 20: due to all considered perturbations

    @@ -612,21 +616,21 @@ The black dashed line corresponds to the performance objective of a sample vibra

    -
    +

    opt_stiff_cas_dz_gm.png

    Figure 18: Cumulative Amplitude Spectrum of the Sample vertical position error due to Ground motion for multiple nano-hexapod stiffnesses (png, pdf)

    -
    +

    opt_stiff_cas_dz_rz.png

    Figure 19: Cumulative Amplitude Spectrum of the Sample vertical position error due to Vertical vibration of the Spindle for multiple nano-hexapod stiffnesses (png, pdf)

    -
    +

    opt_stiff_cas_dz_tot.png

    Figure 20: Cumulative Amplitude Spectrum of the Sample vertical position error due to all considered perturbations for multiple nano-hexapod stiffnesses (png, pdf)

    @@ -634,12 +638,12 @@ The black dashed line corresponds to the performance objective of a sample vibra
    -
    -

    4.4 Conclusion

    +
    +

    4.4 Conclusion

    -
    +

    -From Figure 20, we can see that a soft nano-hexapod \(k<10^6\ [N/m]\) significantly reduces the effect of perturbations from 20Hz to 300Hz. +From Figure 20, we can see that a soft nano-hexapod \(k<10^6\ [N/m]\) significantly reduces the effect of perturbations from 20Hz to 300Hz.

    @@ -647,25 +651,25 @@ From Figure 20, we can see that a soft nano-hexapod \(
    -
    -

    5 Closed Loop Budget Error

    +
    +

    5 Closed Loop Budget Error

    - +

    From the total open-loop power spectral density of the sample’s motion error, we can estimate what is the required control bandwidth for the sample’s motion error to be reduced down to \(10nm\).

    -
    -

    5.1 Approximation of the effect of feedback on the motion error

    +
    +

    5.1 Approximation of the effect of feedback on the motion error

    -Let’s consider Figure 21 where a controller \(K\) is used to reduce the effect of the disturbance \(d\) on the position error \(y\). +Let’s consider Figure 21 where a controller \(K\) is used to reduce the effect of the disturbance \(d\) on the position error \(y\).

    -
    +

    effect_feedback_disturbance_diagram.png

    Figure 21: Feedback System

    @@ -678,7 +682,7 @@ The reduction of the impact of \(d\) on \(y\) thanks to feedback is described by \frac{y}{d} = \frac{G_d}{1 + KG} \end{equation}

    -The transfer functions corresponding to \(G_d\) are those identified in Section 2. +The transfer functions corresponding to \(G_d\) are those identified in Section 2.

    @@ -702,43 +706,43 @@ This will help to determine what is the approximate control bandwidth required s
    -
    -

    5.2 Reduction thanks to feedback - Required bandwidth

    +
    +

    5.2 Reduction thanks to feedback - Required bandwidth

    Let’s first see how does the Cumulative Amplitude Spectrum of the sample’s motion error is modified by the control.

    -In Figure 22 is shown the Cumulative Amplitude Spectrum of the sample’s motion error in Open-Loop and in Closed Loop for several control bandwidth (from 1Hz to 200Hz) and 4 different nano-hexapod stiffnesses. +In Figure 22 is shown the Cumulative Amplitude Spectrum of the sample’s motion error in Open-Loop and in Closed Loop for several control bandwidth (from 1Hz to 200Hz) and 4 different nano-hexapod stiffnesses. The controller used in this simulation is \(K_1\). The loop gain is then a pure integrator.

    -In Figure 23 is shown the expected RMS value of the sample’s position error as a function of the control bandwidth, both for \(K_1\) (left plot) and \(K_2\) (right plot). +In Figure 23 is shown the expected RMS value of the sample’s position error as a function of the control bandwidth, both for \(K_1\) (left plot) and \(K_2\) (right plot). As expected, it is shown that \(K_2\) performs better than \(K_1\). This Figure tells us how much control bandwidth is required to attain a certain level of performance, and that for all the considered nano-hexapod stiffnesses.

    -The obtained required bandwidth (approximate upper and lower bounds) to obtained a sample’s motion error less than 10nm rms are gathered in Table 1. +The obtained required bandwidth (approximate upper and lower bounds) to obtained a sample’s motion error less than 10nm rms are gathered in Table 1.

    -
    +

    opt_stiff_cas_closed_loop.png

    Figure 22: Cumulative Amplitude Spectrum of the sample’s motion error in Open-Loop and in Closed Loop for several control bandwidth and 4 different nano-hexapod stiffnesses (png, pdf)

    -
    +

    opt_stiff_req_bandwidth_K1_K2.png

    Figure 23: Expected RMS value of the sample’s motion error \(E_z\) as a function of the control bandwidth when using \(K_1\) and \(K_2\) (png, pdf)

    - +
    @@ -798,12 +802,12 @@ The obtained required bandwidth (approximate upper and lower bounds) to obtained -
    -

    6 Conclusion

    +
    +

    6 Conclusion

    -
    +

    -From Figure 23 and Table 1, we can clearly see three different results depending on the nano-hexapod stiffness: +From Figure 23 and Table 1, we can clearly see three different results depending on the nano-hexapod stiffness:

    • For a soft nano-hexapod (\(k < 10^4\ [N/m]\)), the required bandwidth is \(\omega_c \approx 50-100\ Hz\)
    • @@ -817,7 +821,7 @@ From Figure 23 and Table 1,

    Author: Dehaeze Thomas

    -

    Created: 2020-04-17 ven. 09:35

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/positioning_error.html b/docs/positioning_error.html index dbc464b..b43c616 100644 --- a/docs/positioning_error.html +++ b/docs/positioning_error.html @@ -1,54 +1,58 @@ - - + Computation of the Positioning Error with respect to the nano-hexapod - - - - - - - - + + + +

    Computation of the Positioning Error with respect to the nano-hexapod

    Table of Contents

    -The global measurement and control schematic is shown in figure 1. +The global measurement and control schematic is shown in figure 1.

    -
    +

    control-schematic-nass.png

    Figure 1: Global Control Schematic for the Station

    @@ -82,25 +86,25 @@ Also, all the stages can be perfectly positioned.

    -First, in section 1, is explained how the measurement of the position of the sample with respect to the granite is performed (using Simscape blocs). +First, in section 1, is explained how the measurement of the position of the sample with respect to the granite is performed (using Simscape blocs).

    -In section 2, we verify that the function developed to compute the wanted pose (translation and orientation) of the sample with respect to the granite can be determined from the wanted position of each stage (translation stage, tilt stage, spindle and micro-hexapod). This corresponds to the bloc “Compute Wanted Sample Position w.r.t. Granite” in figure 1. +In section 2, we verify that the function developed to compute the wanted pose (translation and orientation) of the sample with respect to the granite can be determined from the wanted position of each stage (translation stage, tilt stage, spindle and micro-hexapod). This corresponds to the bloc “Compute Wanted Sample Position w.r.t. Granite” in figure 1. To do so, we impose a perfect displacement and all the stage, we perfectly measure the position of the sample with respect to the granite, and we verify that this measured position corresponds to the computed wanted pose of the sample.

    -Then, in section 3, we introduce some positioning error in the micro-station’s stages. -The positioning error of the sample expressed with respect to the granite frame (the one measured) is expressed in a frame connected to the NASS top platform (corresponding to the green bloc “Compute Sample Position Error w.r.t. NASS” in figure 1). +Then, in section 3, we introduce some positioning error in the micro-station’s stages. +The positioning error of the sample expressed with respect to the granite frame (the one measured) is expressed in a frame connected to the NASS top platform (corresponding to the green bloc “Compute Sample Position Error w.r.t. NASS” in figure 1). Then, we move the NASS such that it compensate for the positioning error that are expressed in the frame of the NASS, and we verify that the positioning error of the sample is well compensated.

    -
    -

    1 How do we measure the position of the sample with respect to the granite

    +
    +

    1 How do we measure the position of the sample with respect to the granite

    - + A transform sensor block gives the translation and orientation of the follower frame with respect to the base frame.

    @@ -126,25 +130,25 @@ We can then determine extract other orientation conventions such that Euler angl
    -
    -

    2 Verify that the function to compute the reference pose is correct

    +
    +

    2 Verify that the function to compute the reference pose is correct

    - +

    The goal here is to perfectly move the station and verify that there is no mismatch between the metrology measurement and the computation of the reference pose.

    -
    -

    2.1 Prepare the Simulation

    +
    +

    2.1 Prepare the Simulation

    We set a small StopTime.

    -
    load('mat/conf_simulink.mat');
    -set_param(conf_simulink, 'StopTime', '0.5');
    +
      load('mat/conf_simulink.mat');
    +  set_param(conf_simulink, 'StopTime', '0.5');
     
    @@ -152,16 +156,16 @@ We set a small StopTime. We initialize all the stages.

    -
    initializeGround('type', 'rigid');
    -initializeGranite('type', 'rigid');
    -initializeTy('type', 'rigid');
    -initializeRy('type', 'rigid');
    -initializeRz('type', 'rigid');
    -initializeMicroHexapod('type', 'rigid');
    -initializeAxisc('type', 'rigid');
    -initializeMirror('type', 'rigid');
    -initializeNanoHexapod('type', 'rigid', 'actuator', 'piezo');
    -initializeSample('type', 'rigid', 'mass', 50);
    +
      initializeGround('type', 'rigid');
    +  initializeGranite('type', 'rigid');
    +  initializeTy('type', 'rigid');
    +  initializeRy('type', 'rigid');
    +  initializeRz('type', 'rigid');
    +  initializeMicroHexapod('type', 'rigid');
    +  initializeAxisc('type', 'rigid');
    +  initializeMirror('type', 'rigid');
    +  initializeNanoHexapod('type', 'rigid', 'actuator', 'piezo');
    +  initializeSample('type', 'rigid', 'mass', 50);
     
    @@ -169,8 +173,8 @@ initializeSample('type', -
    initializeSimscapeConfiguration('gravity', false);
    -initializeDisturbances('enable', false);
    +
      initializeSimscapeConfiguration('gravity', false);
    +  initializeDisturbances('enable', false);
     
    @@ -178,24 +182,24 @@ initializeDisturbances('enable', -
    initializeReferences(...
    -    'Ts',           1e-3, ...       % Sampling Frequency [s]
    -    'Dy_type',      'constant', ... % Either "constant" / "triangular" / "sinusoidal"
    -    'Dy_amplitude', 5e-3, ...          % Amplitude of the displacement [m]
    -    'Dy_period',    1, ...          % Period of the displacement [s]
    -    'Ry_type',      'constant', ... % Either "constant" / "triangular" / "sinusoidal"
    -    'Ry_amplitude', -1*pi/180, ...          % Amplitude [rad]
    -    'Ry_period',    10, ...         % Period of the displacement [s]
    -    'Rz_type',      'constant', ... % Either "constant" / "rotating"
    -    'Rz_amplitude', -135*pi/180, ...          % Initial angle [rad]
    -    'Rz_period',    1, ...          % Period of the rotating [s]
    -    'Dh_type',      'constant', ... % For now, only constant is implemented
    -    'Dh_pos',       [0.01; 0.02; -0.03; -3*pi/180; 1*pi/180; 3*pi/180], ...  % Initial position [m,m,m,rad,rad,rad] of the top platform
    -    'Rm_type',      'constant', ... % For now, only constant is implemented
    -    'Rm_pos',       [0, pi]', ...   % Initial position of the two masses
    -    'Dn_type',      'constant', ... % For now, only constant is implemented
    -    'Dn_pos',       [1e-3; 2e-3; 3e-3; 1*pi/180; 0; 1*pi/180] ...  % Initial position [m,m,m,rad,rad,rad] of the top platform
    -    );
    +
      initializeReferences(...
    +      'Ts',           1e-3, ...       % Sampling Frequency [s]
    +      'Dy_type',      'constant', ... % Either "constant" / "triangular" / "sinusoidal"
    +      'Dy_amplitude', 5e-3, ...          % Amplitude of the displacement [m]
    +      'Dy_period',    1, ...          % Period of the displacement [s]
    +      'Ry_type',      'constant', ... % Either "constant" / "triangular" / "sinusoidal"
    +      'Ry_amplitude', -1*pi/180, ...          % Amplitude [rad]
    +      'Ry_period',    10, ...         % Period of the displacement [s]
    +      'Rz_type',      'constant', ... % Either "constant" / "rotating"
    +      'Rz_amplitude', -135*pi/180, ...          % Initial angle [rad]
    +      'Rz_period',    1, ...          % Period of the rotating [s]
    +      'Dh_type',      'constant', ... % For now, only constant is implemented
    +      'Dh_pos',       [0.01; 0.02; -0.03; -3*pi/180; 1*pi/180; 3*pi/180], ...  % Initial position [m,m,m,rad,rad,rad] of the top platform
    +      'Rm_type',      'constant', ... % For now, only constant is implemented
    +      'Rm_pos',       [0, pi]', ...   % Initial position of the two masses
    +      'Dn_type',      'constant', ... % For now, only constant is implemented
    +      'Dn_pos',       [1e-3; 2e-3; 3e-3; 1*pi/180; 0; 1*pi/180] ...  % Initial position [m,m,m,rad,rad,rad] of the top platform
    +      );
     
    @@ -203,12 +207,12 @@ We setup the reference path to be constant. No position error for now (perfect positioning).

    -
    Dye = 0; % [m]
    -Rye = 0; % [rad]
    -Rze = 0; % [rad]
    -Dhe = zeros(6,1); % [m,m,m,rad,rad,rad]
    -Dhle = zeros(6,1); % [m,m,m,m,m,m]
    -Dne = zeros(6,1); % [m,m,m,rad,rad,rad]
    +
      Dye = 0; % [m]
    +  Rye = 0; % [rad]
    +  Rze = 0; % [rad]
    +  Dhe = zeros(6,1); % [m,m,m,rad,rad,rad]
    +  Dhle = zeros(6,1); % [m,m,m,m,m,m]
    +  Dne = zeros(6,1); % [m,m,m,rad,rad,rad]
     
    @@ -216,7 +220,7 @@ Dne = zeros(6,1); % [m,m,m,rad,rad,rad] We want to log the signals

    -
    initializeLoggingConfiguration('log', 'all');
    +
      initializeLoggingConfiguration('log', 'all');
     
    @@ -224,14 +228,14 @@ We want to log the signals And we run the simulation.

    -
    sim('nass_model');
    +
      sim('nass_model');
     
    -
    -

    2.2 Verify that the pose of the sample is the same as the computed one

    +
    +

    2.2 Verify that the pose of the sample is the same as the computed one

    Let’s denote: @@ -254,11 +258,11 @@ We have then computed: We load the reference and we compute the desired trajectory of the sample in the form of an homogeneous transformation matrix \({}^W\bm{T}_R\).

    -
    n = length(simout.r.Dy.Time);
    -WTr = zeros(4, 4, n);
    -for i = 1:n
    -  WTr(:, :, i) = computeReferencePose(simout.r.Dy.Data(i), simout.r.Ry.Data(i), simout.r.Rz.Data(i), simout.r.Dh.Data(i,:), simout.r.Dn.Data(i,:));
    -end
    +
      n = length(simout.r.Dy.Time);
    +  WTr = zeros(4, 4, n);
    +  for i = 1:n
    +    WTr(:, :, i) = computeReferencePose(simout.r.Dy.Data(i), simout.r.Ry.Data(i), simout.r.Rz.Data(i), simout.r.Dh.Data(i,:), simout.r.Dn.Data(i,:));
    +  end
     
    @@ -267,11 +271,11 @@ As the displacement is perfect, we also measure in simulation the pose of the sa From that we can compute the homogeneous transformation matrix \({}^W\bm{T}_M\).

    -
    n = length(simout.y.R.Time);
    -WTm = zeros(4, 4, n);
    -WTm(1:3, 1:3, :) = simout.y.R.Data;
    -WTm(1:3, 4, :) = [simout.y.x.Data' ; simout.y.y.Data' ; simout.y.z.Data'];
    -WTm(4, 4, :) = 1;
    +
      n = length(simout.y.R.Time);
    +  WTm = zeros(4, 4, n);
    +  WTm(1:3, 1:3, :) = simout.y.R.Data;
    +  WTm(1:3, 4, :) = [simout.y.x.Data' ; simout.y.y.Data' ; simout.y.z.Data'];
    +  WTm(4, 4, :) = 1;
     
    @@ -287,12 +291,12 @@ Or are least:

    -
    WTr(1:3, 4, end)-WTm(1:3, 4, end)
    -WTr(1:3, 1:3, end)'*WTm(1:3, 1:3, end)-eye(3)
    +
      WTr(1:3, 4, end)-WTm(1:3, 4, end)
    +  WTr(1:3, 1:3, end)'*WTm(1:3, 1:3, end)-eye(3)
     
    -
    +
     WTr(1:3, 4, end)-WTm(1:3, 4, end)
     ans =
           8.53830894875784e-15
    @@ -307,10 +311,10 @@ ans =
     
    -
    -

    2.3 Conclusion

    +
    +

    2.3 Conclusion

    -
    +

    We are able to compute the wanted position and orientation of the sample. Both the measurement and the theory gives the same result. @@ -321,11 +325,11 @@ Both the measurement and the theory gives the same result.

    -
    -

    3 Verify that the function to convert the position error in the frame fixed to the nano-hexapod is working

    +
    +

    3 Verify that the function to convert the position error in the frame fixed to the nano-hexapod is working

    - +

    We now introduce some positioning error in the stage. @@ -336,15 +340,15 @@ This will induce a global positioning error of the sample with respect to the de We want to verify that we are able to measure this positioning error and convert it in the frame attached to the Nano-hexapod.

    -
    -

    3.1 Prepare the Simulation

    +
    +

    3.1 Prepare the Simulation

    We set a small StopTime.

    -
    load('mat/conf_simulink.mat');
    -set_param(conf_simulink, 'StopTime', '0.5');
    +
      load('mat/conf_simulink.mat');
    +  set_param(conf_simulink, 'StopTime', '0.5');
     
    @@ -352,16 +356,16 @@ We set a small StopTime. We initialize all the stages.

    -
    initializeGround('type', 'rigid');
    -initializeGranite('type', 'rigid');
    -initializeTy('type', 'rigid');
    -initializeRy('type', 'rigid');
    -initializeRz('type', 'rigid');
    -initializeMicroHexapod('type', 'rigid');
    -initializeAxisc('type', 'rigid');
    -initializeMirror('type', 'rigid');
    -initializeNanoHexapod('type', 'rigid', 'actuator', 'piezo');
    -initializeSample('type', 'rigid', 'mass', 50);
    +
      initializeGround('type', 'rigid');
    +  initializeGranite('type', 'rigid');
    +  initializeTy('type', 'rigid');
    +  initializeRy('type', 'rigid');
    +  initializeRz('type', 'rigid');
    +  initializeMicroHexapod('type', 'rigid');
    +  initializeAxisc('type', 'rigid');
    +  initializeMirror('type', 'rigid');
    +  initializeNanoHexapod('type', 'rigid', 'actuator', 'piezo');
    +  initializeSample('type', 'rigid', 'mass', 50);
     
    @@ -369,8 +373,8 @@ initializeSample('type', -
    initializeSimscapeConfiguration('gravity', false);
    -initializeDisturbances('enable', false);
    +
      initializeSimscapeConfiguration('gravity', false);
    +  initializeDisturbances('enable', false);
     
    @@ -378,21 +382,21 @@ initializeDisturbances('enable', -
    initializeReferences(...
    -    'Ts',           1e-3, ...       % Sampling Frequency [s]
    -    'Dy_type',      'constant', ... % Either "constant" / "triangular" / "sinusoidal"
    -    'Dy_amplitude', 0, ...          % Amplitude of the displacement [m]
    -    'Ry_type',      'constant', ... % Either "constant" / "triangular" / "sinusoidal"
    -    'Ry_amplitude', 0, ...          % Amplitude [rad]
    -    'Rz_type',      'constant', ... % Either "constant" / "rotating"
    -    'Rz_amplitude', 0*pi/180, ...          % Initial angle [rad]
    -    'Dh_type',      'constant', ... % For now, only constant is implemented
    -    'Dh_pos',       [0; 0; 0; 0; 0; 0],  ...  % Initial position [m,m,m,rad,rad,rad] of the top platform
    -    'Rm_type',      'constant', ... % For now, only constant is implemented
    -    'Rm_pos',       [0, pi]', ...   % Initial position of the two masses
    -    'Dn_type',      'constant', ... % For now, only constant is implemented
    -    'Dn_pos',       [0; 0; 0; 0; 0; 0]  ...  % Initial position [m,m,m,rad,rad,rad] of the top platform
    -    );
    +
      initializeReferences(...
    +      'Ts',           1e-3, ...       % Sampling Frequency [s]
    +      'Dy_type',      'constant', ... % Either "constant" / "triangular" / "sinusoidal"
    +      'Dy_amplitude', 0, ...          % Amplitude of the displacement [m]
    +      'Ry_type',      'constant', ... % Either "constant" / "triangular" / "sinusoidal"
    +      'Ry_amplitude', 0, ...          % Amplitude [rad]
    +      'Rz_type',      'constant', ... % Either "constant" / "rotating"
    +      'Rz_amplitude', 0*pi/180, ...          % Initial angle [rad]
    +      'Dh_type',      'constant', ... % For now, only constant is implemented
    +      'Dh_pos',       [0; 0; 0; 0; 0; 0],  ...  % Initial position [m,m,m,rad,rad,rad] of the top platform
    +      'Rm_type',      'constant', ... % For now, only constant is implemented
    +      'Rm_pos',       [0, pi]', ...   % Initial position of the two masses
    +      'Dn_type',      'constant', ... % For now, only constant is implemented
    +      'Dn_pos',       [0; 0; 0; 0; 0; 0]  ...  % Initial position [m,m,m,rad,rad,rad] of the top platform
    +      );
     
    @@ -400,10 +404,10 @@ We setup the reference path to be constant. Now we introduce some positioning error.

    -
    Dye = 1e-6; % [m]
    -Rye = 2e-4; % [rad]
    -Rze = 1e-5; % [rad]
    -initializePosError('error', true, 'Dy', Dye, 'Ry', Rye, 'Rz', Rze);
    +
      Dye = 1e-6; % [m]
    +  Rye = 2e-4; % [rad]
    +  Rze = 1e-5; % [rad]
    +  initializePosError('error', true, 'Dy', Dye, 'Ry', Rye, 'Rz', Rze);
     
    @@ -411,14 +415,14 @@ initializePosError('error', -
    sim('nass_model');
    +
      sim('nass_model');
     
    -
    -

    3.2 Compute the wanted pose of the sample in the NASS Base from the metrology and the reference

    +
    +

    3.2 Compute the wanted pose of the sample in the NASS Base from the metrology and the reference

    Now that we have introduced some positioning error, the computed wanted pose and the measured pose will not be the same. @@ -444,11 +448,11 @@ The top platform of the nano-hexapod is considered to be rigidly connected to th We load the reference and we compute the desired trajectory of the sample in the form of an homogeneous transformation matrix \({}^W\bm{T}_R\).

    -
    n = length(simout.r.Dy.Time);
    -WTr = zeros(4, 4, n);
    -for i = 1:n
    -  WTr(:, :, i) = computeReferencePose(simout.r.Dy.Data(i), simout.r.Ry.Data(i), simout.r.Rz.Data(i), simout.r.Dh.Data(i,:), simout.r.Dn.Data(i,:));
    -end
    +
      n = length(simout.r.Dy.Time);
    +  WTr = zeros(4, 4, n);
    +  for i = 1:n
    +    WTr(:, :, i) = computeReferencePose(simout.r.Dy.Data(i), simout.r.Ry.Data(i), simout.r.Rz.Data(i), simout.r.Dh.Data(i,:), simout.r.Dn.Data(i,:));
    +  end
     
    @@ -457,11 +461,11 @@ We also measure in simulation the pose of the sample with respect to the granite From that we can compute the homogeneous transformation matrix \({}^W\bm{T}_M\).

    -
    n = length(simout.y.R.Time);
    -WTm = zeros(4, 4, n);
    -WTm(1:3, 1:3, :) = simout.y.R.Data;
    -WTm(1:3, 4, :) = [simout.y.x.Data' ; simout.y.y.Data' ; simout.y.z.Data'];
    -WTm(4, 4, :) = 1;
    +
      n = length(simout.y.R.Time);
    +  WTm = zeros(4, 4, n);
    +  WTm(1:3, 1:3, :) = simout.y.R.Data;
    +  WTm(1:3, 4, :) = [simout.y.x.Data' ; simout.y.y.Data' ; simout.y.z.Data'];
    +  WTm(4, 4, :) = 1;
     
    @@ -483,10 +487,10 @@ The inverse of the transformation matrix can be obtain by (it is less com Finally, we compute \({}^M\bm{T}_R\).

    -
    MTr = zeros(4, 4, n);
    -for i = 1:n
    -  MTr(:, :, i) = [WTm(1:3,1:3,i)', -WTm(1:3,1:3,i)'*WTm(1:3,4,i) ; 0 0 0 1]*WTr(:,:,i);
    -end
    +
      MTr = zeros(4, 4, n);
    +  for i = 1:n
    +    MTr(:, :, i) = [WTm(1:3,1:3,i)', -WTm(1:3,1:3,i)'*WTm(1:3,4,i) ; 0 0 0 1]*WTr(:,:,i);
    +  end
     
    @@ -494,18 +498,18 @@ Finally, we compute \({}^M\bm{T}_R\). Verify that the pose error corresponds to the positioning error of the stages.

    -
    MTr(1:3, 1:3, end)
    -Rx = [1 0       0;
    -      0 cos(Erx) -sin(Erx);
    -      0 sin(Erx)  cos(Erx)];
    +
      MTr(1:3, 1:3, end)
    +  Rx = [1 0       0;
    +        0 cos(Erx) -sin(Erx);
    +        0 sin(Erx)  cos(Erx)];
     
    -Ry = [ cos(Ery) 0 sin(Ery);
    -      0      1 0;
    -      -sin(Ery) 0 cos(Ery)];
    +  Ry = [ cos(Ery) 0 sin(Ery);
    +        0      1 0;
    +        -sin(Ery) 0 cos(Ery)];
     
    -Rz = [cos(Erz) -sin(Erz) 0;
    -      sin(Erz)  cos(Erz) 0;
    -      0       0      1];
    +  Rz = [cos(Erz) -sin(Erz) 0;
    +        sin(Erz)  cos(Erz) 0;
    +        0       0      1];
     
    @@ -553,28 +557,28 @@ Rz = [cos(Erz) -sin(Erz) 0;
    -
    -

    3.3 Verify that be imposing the error motion on the nano-hexapod, we indeed have zero error at the end

    +
    +

    3.3 Verify that be imposing the error motion on the nano-hexapod, we indeed have zero error at the end

    We now keep the wanted pose but we impose a displacement of the nano hexapod corresponding to the measured position error.

    -
    initializeReferences(...
    -    'Ts',           1e-3, ...       % Sampling Frequency [s]
    -    'Dy_type',      'constant', ... % Either "constant" / "triangular" / "sinusoidal"
    -    'Dy_amplitude', 0, ...          % Amplitude of the displacement [m]
    -    'Ry_type',      'constant', ... % Either "constant" / "triangular" / "sinusoidal"
    -    'Ry_amplitude', 0, ...          % Amplitude [rad]
    -    'Rz_type',      'constant', ... % Either "constant" / "rotating"
    -    'Rz_amplitude', 0*pi/180, ...          % Initial angle [rad]
    -    'Dh_type',      'constant', ... % For now, only constant is implemented
    -    'Dh_pos',       [0; 0; 0; 0; 0; 0],  ...  % Initial position [m,m,m,rad,rad,rad] of the top platform
    -    'Rm_type',      'constant', ... % For now, only constant is implemented
    -    'Rm_pos',       [0, pi]', ...   % Initial position of the two masses
    -    'Dn_type',      'constant', ... % For now, only constant is implemented
    -    'Dn_pos',       [Edx; Edy; Edz; Erx; Ery; Erz] ...  % Initial position [m,m,m,rad,rad,rad] of the top platform
    -    );
    +
      initializeReferences(...
    +      'Ts',           1e-3, ...       % Sampling Frequency [s]
    +      'Dy_type',      'constant', ... % Either "constant" / "triangular" / "sinusoidal"
    +      'Dy_amplitude', 0, ...          % Amplitude of the displacement [m]
    +      'Ry_type',      'constant', ... % Either "constant" / "triangular" / "sinusoidal"
    +      'Ry_amplitude', 0, ...          % Amplitude [rad]
    +      'Rz_type',      'constant', ... % Either "constant" / "rotating"
    +      'Rz_amplitude', 0*pi/180, ...          % Initial angle [rad]
    +      'Dh_type',      'constant', ... % For now, only constant is implemented
    +      'Dh_pos',       [0; 0; 0; 0; 0; 0],  ...  % Initial position [m,m,m,rad,rad,rad] of the top platform
    +      'Rm_type',      'constant', ... % For now, only constant is implemented
    +      'Rm_pos',       [0, pi]', ...   % Initial position of the two masses
    +      'Dn_type',      'constant', ... % For now, only constant is implemented
    +      'Dn_pos',       [Edx; Edy; Edz; Erx; Ery; Erz] ...  % Initial position [m,m,m,rad,rad,rad] of the top platform
    +      );
     
    @@ -582,7 +586,7 @@ We now keep the wanted pose but we impose a displacement of the nano hexapod cor And we run the simulation.

    -
    sim('nass_model');
    +
      sim('nass_model');
     
    @@ -595,11 +599,11 @@ As the displacement is perfect, we also measure in simulation the pose of the sa From that we can compute the homogeneous transformation matrix \({}^W\bm{T}_M\).

    -
    n = length(simout.y.R.Time);
    -WTm = zeros(4, 4, n);
    -WTm(1:3, 1:3, :) = simout.y.R.Data;
    -WTm(1:3, 4, :) = [simout.y.x.Data' ; simout.y.y.Data' ; simout.y.z.Data'];
    -WTm(4, 4, :) = 1;
    +
      n = length(simout.y.R.Time);
    +  WTm = zeros(4, 4, n);
    +  WTm(1:3, 1:3, :) = simout.y.R.Data;
    +  WTm(1:3, 4, :) = [simout.y.x.Data' ; simout.y.y.Data' ; simout.y.z.Data'];
    +  WTm(4, 4, :) = 1;
     
    @@ -607,10 +611,10 @@ WTm(4, 4, :) = 1; Finally, we compute \({}^M\bm{T}_R\).

    -
    MTr = zeros(4, 4, n);
    -for i = 1:n
    -  MTr(:, :, i) = [WTm(1:3,1:3,i)', -WTm(1:3,1:3,i)'*WTm(1:3,4,i) ; 0 0 0 1]*WTr(:,:,i);
    -end
    +
      MTr = zeros(4, 4, n);
    +  for i = 1:n
    +    MTr(:, :, i) = [WTm(1:3,1:3,i)', -WTm(1:3,1:3,i)'*WTm(1:3,4,i) ; 0 0 0 1]*WTr(:,:,i);
    +  end
     
    @@ -661,10 +665,10 @@ Verify that the pose error is small.
    -
    -

    3.4 Conclusion

    +
    +

    3.4 Conclusion

    -
    +

    Indeed, we are able to convert the position error in the frame of the NASS and then compensate these errors with the NASS.

    @@ -676,7 +680,7 @@ Indeed, we are able to convert the position error in the frame of the NASS and t

    Author: Dehaeze Thomas

    -

    Created: 2020-04-17 ven. 09:35

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/simscape.html b/docs/simscape.html index 9e1374f..2f57fe4 100644 --- a/docs/simscape.html +++ b/docs/simscape.html @@ -1,37 +1,32 @@ - - + Simscape Model - - - - - - + +

    Simscape Model

    @@ -44,8 +39,8 @@ A simscape model per Simscape Multibody permits to model multibody systems using blocks representing bodies, joints, constraints, force elements, and sensors.

    -
    -

    1 Solid bodies

    +
    +

    1 Solid bodies

    Each solid body is represented by a solid block. @@ -54,8 +49,8 @@ The geometry of the solid body can be imported using a step file. T

    -
    -

    2 Frames

    +
    +

    2 Frames

    Frames are very important in simscape multibody, they defined where the forces are applied, where the joints are located and where the measurements are made. @@ -67,8 +62,8 @@ They can be defined from the solid body geometry, or using the -

    3 Joints

    +
    Table 1: Approximate required control bandwidth such that the motion error is below \(10nm\)
    +
    @@ -211,7 +206,7 @@ Joint blocks are assortments of joint primitives:
  • Constant Velocity: Allows rotation at constant velocity between intersection through arbitrarily aligned shafts: CV
  • -
    Table 1: Degrees of freedom associated with each joint
    +
    @@ -503,8 +498,8 @@ Composite Force/Torque sensing: -
    -

    4 Measurements

    +
    +

    4 Measurements

    A transform sensor block measures the spatial relationship between two frames: the base B and the follower F. @@ -528,8 +523,8 @@ If we want to simulate an inertial sensor, we just have to choose B

    -
    -

    5 Excitation

    +
    +

    5 Excitation

    We can apply external forces to the model by using an external force and torque block. @@ -543,7 +538,7 @@ Internal force, acting reciprocally between base and following origins is implem

    Author: Dehaeze Thomas

    -

    Created: 2020-04-17 ven. 09:35

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/simscape_subsystems.html b/docs/simscape_subsystems.html index 02e8983..814a0bd 100644 --- a/docs/simscape_subsystems.html +++ b/docs/simscape_subsystems.html @@ -3,231 +3,227 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Subsystems used for the Simscape Models - - - - - - + +

    Subsystems used for the Simscape Models

    Table of Contents

    -The full Simscape Model is represented in Figure 1. +The full Simscape Model is represented in Figure 1.

    -
    +

    simscape_picture.png

    Figure 1: Screenshot of the Multi-Body Model representation

    @@ -246,161 +242,161 @@ Each stage is configured (geometry, mass properties, dynamic properties … These functions are defined below.

    -
    -

    1 Simscape Configuration

    +
    +

    1 Simscape Configuration

    - +

    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [] = initializeSimscapeConfiguration(args)
    +
      function [] = initializeSimscapeConfiguration(args)
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -  args.gravity logical {mustBeNumericOrLogical} = true
    -end
    +
      arguments
    +    args.gravity logical {mustBeNumericOrLogical} = true
    +  end
     
    -
    -

    Structure initialization

    -
    +
    +

    Structure initialization

    +
    -
    conf_simscape = struct();
    +
      conf_simscape = struct();
     
    -
    -

    Add Type

    -
    +
    +

    Add Type

    +
    -
    if args.gravity
    -  conf_simscape.type = 1;
    -else
    -  conf_simscape.type = 2;
    -end
    +
      if args.gravity
    +    conf_simscape.type = 1;
    +  else
    +    conf_simscape.type = 2;
    +  end
     
    -
    -

    Save the Structure

    -
    +
    +

    Save the Structure

    +
    -
    save('./mat/conf_simscape.mat', 'conf_simscape');
    +
      save('./mat/conf_simscape.mat', 'conf_simscape');
     
    -
    -

    2 Logging Configuration

    +
    +

    2 Logging Configuration

    - +

    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [] = initializeLoggingConfiguration(args)
    +
      function [] = initializeLoggingConfiguration(args)
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -  args.log      char   {mustBeMember(args.log,{'none', 'all', 'forces'})} = 'none'
    -  args.Ts (1,1) double {mustBeNumeric, mustBePositive} = 1e-3
    -end
    +
      arguments
    +    args.log      char   {mustBeMember(args.log,{'none', 'all', 'forces'})} = 'none'
    +    args.Ts (1,1) double {mustBeNumeric, mustBePositive} = 1e-3
    +  end
     
    -
    -

    Structure initialization

    -
    +
    +

    Structure initialization

    +
    -
    conf_log = struct();
    +
      conf_log = struct();
     
    -
    -

    Add Type

    -
    +
    +

    Add Type

    +
    -
    switch args.log
    -  case 'none'
    -    conf_log.type = 0;
    -  case 'all'
    -    conf_log.type = 1;
    -  case 'forces'
    -    conf_log.type = 2;
    -end
    +
      switch args.log
    +    case 'none'
    +      conf_log.type = 0;
    +    case 'all'
    +      conf_log.type = 1;
    +    case 'forces'
    +      conf_log.type = 2;
    +  end
     
    -
    -

    Sampling Time

    -
    +
    +

    Sampling Time

    +
    -
    conf_log.Ts = args.Ts;
    +
      conf_log.Ts = args.Ts;
     
    -
    -

    Save the Structure

    -
    +
    +

    Save the Structure

    +
    -
    save('./mat/conf_log.mat', 'conf_log');
    +
      save('./mat/conf_log.mat', 'conf_log');
     
    -
    -

    3 Ground

    +
    +

    3 Ground

    - +

    -
    -

    Simscape Model

    -
    +
    +

    Simscape Model

    +

    The model of the Ground is composed of:

    @@ -410,14 +406,14 @@ The model of the Ground is composed of: -
    +

    simscape_model_ground.png

    Figure 2: Simscape model for the Ground

    -
    +

    simscape_picture_ground.png

    Figure 3: Simscape picture for the Ground

    @@ -425,106 +421,106 @@ The model of the Ground is composed of:
    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [ground] = initializeGround(args)
    +
      function [ground] = initializeGround(args)
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -  args.type char {mustBeMember(args.type,{'none', 'rigid'})} = 'rigid'
    -  args.rot_point (3,1) double {mustBeNumeric} = zeros(3,1) % Rotation point for the ground motion [m]
    -end
    +
      arguments
    +    args.type char {mustBeMember(args.type,{'none', 'rigid'})} = 'rigid'
    +    args.rot_point (3,1) double {mustBeNumeric} = zeros(3,1) % Rotation point for the ground motion [m]
    +  end
     
    -
    -

    Structure initialization

    -
    +
    +

    Structure initialization

    +

    First, we initialize the granite structure.

    -
    ground = struct();
    +
      ground = struct();
     
    -
    -

    Add Type

    -
    +
    +

    Add Type

    +
    -
    switch args.type
    -  case 'none'
    -    ground.type = 0;
    -  case 'rigid'
    -    ground.type = 1;
    -end
    +
      switch args.type
    +    case 'none'
    +      ground.type = 0;
    +    case 'rigid'
    +      ground.type = 1;
    +  end
     
    -
    -

    Ground Solid properties

    -
    +
    +

    Ground Solid properties

    +

    We set the shape and density of the ground solid element.

    -
    ground.shape   = [2, 2, 0.5]; % [m]
    -ground.density = 2800;        % [kg/m3]
    +
      ground.shape   = [2, 2, 0.5]; % [m]
    +  ground.density = 2800;        % [kg/m3]
     
    -
    -

    Rotation Point

    -
    +
    +

    Rotation Point

    +
    -
    ground.rot_point = args.rot_point;
    +
      ground.rot_point = args.rot_point;
     
    -
    -

    Save the Structure

    -
    +
    +

    Save the Structure

    +

    The ground structure is saved.

    -
    save('./mat/stages.mat', 'ground', '-append');
    +
      save('./mat/stages.mat', 'ground', '-append');
     
    -
    -

    4 Granite

    +
    +

    4 Granite

    - +

    -
    -

    Simscape Model

    -
    +
    +

    Simscape Model

    +

    The Simscape model of the granite is composed of:

    @@ -538,14 +534,14 @@ The output sample_pos corresponds to the impact point of the X-ray.

    -
    +

    simscape_model_granite.png

    Figure 4: Simscape model for the Granite

    -
    +

    simscape_picture_granite.png

    Figure 5: Simscape picture for the Granite

    @@ -553,79 +549,79 @@ The output sample_pos corresponds to the impact point of the X-ray.
    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [granite] = initializeGranite(args)
    +
      function [granite] = initializeGranite(args)
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -  args.type          char    {mustBeMember(args.type,{'rigid', 'flexible', 'none', 'modal-analysis', 'init'})} = 'flexible'
    -  args.Foffset       logical {mustBeNumericOrLogical} = false
    -  args.density (1,1) double {mustBeNumeric, mustBeNonnegative} = 2800 % Density [kg/m3]
    -  args.K  (3,1) double {mustBeNumeric, mustBeNonnegative} = [4e9; 3e8; 8e8] % [N/m]
    -  args.C  (3,1) double {mustBeNumeric, mustBeNonnegative} = [4.0e5; 1.1e5; 9.0e5] % [N/(m/s)]
    -  args.x0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the X direction [m]
    -  args.y0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the Y direction [m]
    -  args.z0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the Z direction [m]
    -  args.sample_pos (1,1) double {mustBeNumeric} = 0.8 % Height of the measurment point [m]
    -end
    +
      arguments
    +    args.type          char    {mustBeMember(args.type,{'rigid', 'flexible', 'none', 'modal-analysis', 'init'})} = 'flexible'
    +    args.Foffset       logical {mustBeNumericOrLogical} = false
    +    args.density (1,1) double {mustBeNumeric, mustBeNonnegative} = 2800 % Density [kg/m3]
    +    args.K  (3,1) double {mustBeNumeric, mustBeNonnegative} = [4e9; 3e8; 8e8] % [N/m]
    +    args.C  (3,1) double {mustBeNumeric, mustBeNonnegative} = [4.0e5; 1.1e5; 9.0e5] % [N/(m/s)]
    +    args.x0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the X direction [m]
    +    args.y0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the Y direction [m]
    +    args.z0 (1,1) double {mustBeNumeric} = 0 % Rest position of the Joint in the Z direction [m]
    +    args.sample_pos (1,1) double {mustBeNumeric} = 0.8 % Height of the measurment point [m]
    +  end
     
    -
    -

    Structure initialization

    -
    +
    +

    Structure initialization

    +

    First, we initialize the granite structure.

    -
    granite = struct();
    +
      granite = struct();
     
    -
    -

    Add Granite Type

    -
    +
    +

    Add Granite Type

    +
    -
    switch args.type
    -  case 'none'
    -    granite.type = 0;
    -  case 'rigid'
    -    granite.type = 1;
    -  case 'flexible'
    -    granite.type = 2;
    -  case 'modal-analysis'
    -    granite.type = 3;
    -  case 'init'
    -    granite.type = 4;
    -end
    +
      switch args.type
    +    case 'none'
    +      granite.type = 0;
    +    case 'rigid'
    +      granite.type = 1;
    +    case 'flexible'
    +      granite.type = 2;
    +    case 'modal-analysis'
    +      granite.type = 3;
    +    case 'init'
    +      granite.type = 4;
    +  end
     
    -
    -

    Material and Geometry

    -
    +
    +

    Material and Geometry

    +

    Properties of the Material and link to the geometry of the granite.

    -
    granite.density = args.density; % [kg/m3]
    -granite.STEP    = './STEPS/granite/granite.STEP';
    +
      granite.density = args.density; % [kg/m3]
    +  granite.STEP    = './STEPS/granite/granite.STEP';
     
    @@ -633,63 +629,63 @@ granite.STEP = './STEPS/granite/granite.STEP' Z-offset for the initial position of the sample with respect to the granite top surface.

    -
    granite.sample_pos = args.sample_pos; % [m]
    +
      granite.sample_pos = args.sample_pos; % [m]
     
    -
    -

    Stiffness and Damping properties

    -
    +
    +

    Stiffness and Damping properties

    +
    -
    granite.K = args.K; % [N/m]
    -granite.C = args.C; % [N/(m/s)]
    +
      granite.K = args.K; % [N/m]
    +  granite.C = args.C; % [N/(m/s)]
     
    -
    -

    Equilibrium position of the each joint.

    -
    +
    +

    Equilibrium position of the each joint.

    +
    -
    if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
    -  load('mat/Foffset.mat', 'Fgm');
    -  granite.Deq = -Fgm'./granite.K;
    -else
    -  granite.Deq = zeros(6,1);
    -end
    +
      if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
    +    load('mat/Foffset.mat', 'Fgm');
    +    granite.Deq = -Fgm'./granite.K;
    +  else
    +    granite.Deq = zeros(6,1);
    +  end
     
    -
    -

    Save the Structure

    -
    +
    +

    Save the Structure

    +

    The granite structure is saved.

    -
    save('./mat/stages.mat', 'granite', '-append');
    +
      save('./mat/stages.mat', 'granite', '-append');
     
    -
    -

    5 Translation Stage

    +
    +

    5 Translation Stage

    - +

    -
    -

    Simscape Model

    -
    +
    +

    Simscape Model

    +

    The Simscape model of the Translation stage consist of:

    @@ -704,14 +700,14 @@ It is used to impose the motion in the Y direction -
    +

    simscape_model_ty.png

    Figure 6: Simscape model for the Translation Stage

    -
    +

    simscape_picture_ty.png

    Figure 7: Simscape picture for the Translation Stage

    @@ -719,161 +715,161 @@ It is used to impose the motion in the Y direction
    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [ty] = initializeTy(args)
    +
      function [ty] = initializeTy(args)
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -  args.type      char   {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible'
    -  args.Foffset logical {mustBeNumericOrLogical} = false
    -end
    +
      arguments
    +    args.type      char   {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible'
    +    args.Foffset logical {mustBeNumericOrLogical} = false
    +  end
     
    -
    -

    Structure initialization

    -
    +
    +

    Structure initialization

    +

    First, we initialize the ty structure.

    -
    ty = struct();
    +
      ty = struct();
     
    -
    -

    Add Translation Stage Type

    -
    +
    +

    Add Translation Stage Type

    +
    -
    switch args.type
    -  case 'none'
    -    ty.type = 0;
    -  case 'rigid'
    -    ty.type = 1;
    -  case 'flexible'
    -    ty.type = 2;
    -  case 'modal-analysis'
    -    ty.type = 3;
    -  case 'init'
    -    ty.type = 4;
    -end
    +
      switch args.type
    +    case 'none'
    +      ty.type = 0;
    +    case 'rigid'
    +      ty.type = 1;
    +    case 'flexible'
    +      ty.type = 2;
    +    case 'modal-analysis'
    +      ty.type = 3;
    +    case 'init'
    +      ty.type = 4;
    +  end
     
    -
    -

    Material and Geometry

    -
    +
    +

    Material and Geometry

    +

    Define the density of the materials as well as the geometry (STEP files).

    -
    % Ty Granite frame
    -ty.granite_frame.density = 7800; % [kg/m3] => 43kg
    -ty.granite_frame.STEP    = './STEPS/Ty/Ty_Granite_Frame.STEP';
    +
      % Ty Granite frame
    +  ty.granite_frame.density = 7800; % [kg/m3] => 43kg
    +  ty.granite_frame.STEP    = './STEPS/Ty/Ty_Granite_Frame.STEP';
     
    -% Guide Translation Ty
    -ty.guide.density         = 7800; % [kg/m3] => 76kg
    -ty.guide.STEP            = './STEPS/ty/Ty_Guide.STEP';
    +  % Guide Translation Ty
    +  ty.guide.density         = 7800; % [kg/m3] => 76kg
    +  ty.guide.STEP            = './STEPS/ty/Ty_Guide.STEP';
     
    -% Ty - Guide_Translation12
    -ty.guide12.density       = 7800; % [kg/m3]
    -ty.guide12.STEP          = './STEPS/Ty/Ty_Guide_12.STEP';
    +  % Ty - Guide_Translation12
    +  ty.guide12.density       = 7800; % [kg/m3]
    +  ty.guide12.STEP          = './STEPS/Ty/Ty_Guide_12.STEP';
     
    -% Ty - Guide_Translation11
    -ty.guide11.density       = 7800; % [kg/m3]
    -ty.guide11.STEP          = './STEPS/ty/Ty_Guide_11.STEP';
    +  % Ty - Guide_Translation11
    +  ty.guide11.density       = 7800; % [kg/m3]
    +  ty.guide11.STEP          = './STEPS/ty/Ty_Guide_11.STEP';
     
    -% Ty - Guide_Translation22
    -ty.guide22.density       = 7800; % [kg/m3]
    -ty.guide22.STEP          = './STEPS/ty/Ty_Guide_22.STEP';
    +  % Ty - Guide_Translation22
    +  ty.guide22.density       = 7800; % [kg/m3]
    +  ty.guide22.STEP          = './STEPS/ty/Ty_Guide_22.STEP';
     
    -% Ty - Guide_Translation21
    -ty.guide21.density       = 7800; % [kg/m3]
    -ty.guide21.STEP          = './STEPS/Ty/Ty_Guide_21.STEP';
    +  % Ty - Guide_Translation21
    +  ty.guide21.density       = 7800; % [kg/m3]
    +  ty.guide21.STEP          = './STEPS/Ty/Ty_Guide_21.STEP';
     
    -% Ty - Plateau translation
    -ty.frame.density         = 7800; % [kg/m3]
    -ty.frame.STEP            = './STEPS/ty/Ty_Stage.STEP';
    +  % Ty - Plateau translation
    +  ty.frame.density         = 7800; % [kg/m3]
    +  ty.frame.STEP            = './STEPS/ty/Ty_Stage.STEP';
     
    -% Ty Stator Part
    -ty.stator.density        = 5400; % [kg/m3]
    -ty.stator.STEP           = './STEPS/ty/Ty_Motor_Stator.STEP';
    +  % Ty Stator Part
    +  ty.stator.density        = 5400; % [kg/m3]
    +  ty.stator.STEP           = './STEPS/ty/Ty_Motor_Stator.STEP';
     
    -% Ty Rotor Part
    -ty.rotor.density         = 5400; % [kg/m3]
    -ty.rotor.STEP            = './STEPS/ty/Ty_Motor_Rotor.STEP';
    +  % Ty Rotor Part
    +  ty.rotor.density         = 5400; % [kg/m3]
    +  ty.rotor.STEP            = './STEPS/ty/Ty_Motor_Rotor.STEP';
     
    -
    -

    Stiffness and Damping properties

    -
    +
    +

    Stiffness and Damping properties

    +
    -
    ty.K = [2e8; 1e8; 2e8; 6e7; 9e7; 6e7]; % [N/m, N*m/rad]
    -ty.C = [8e4; 5e4; 8e4; 2e4; 3e4; 2e4]; % [N/(m/s), N*m/(rad/s)]
    +
      ty.K = [2e8; 1e8; 2e8; 6e7; 9e7; 6e7]; % [N/m, N*m/rad]
    +  ty.C = [8e4; 5e4; 8e4; 2e4; 3e4; 2e4]; % [N/(m/s), N*m/(rad/s)]
     
    -
    -

    Equilibrium position of the each joint.

    -
    +
    +

    Equilibrium position of the each joint.

    +
    -
    if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
    -  load('mat/Foffset.mat', 'Ftym');
    -  ty.Deq = -Ftym'./ty.K;
    -else
    -  ty.Deq = zeros(6,1);
    -end
    +
      if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
    +    load('mat/Foffset.mat', 'Ftym');
    +    ty.Deq = -Ftym'./ty.K;
    +  else
    +    ty.Deq = zeros(6,1);
    +  end
     
    -
    -

    Save the Structure

    -
    +
    +

    Save the Structure

    +

    The ty structure is saved.

    -
    save('./mat/stages.mat', 'ty', '-append');
    +
      save('./mat/stages.mat', 'ty', '-append');
     
    -
    -

    6 Tilt Stage

    +
    +

    6 Tilt Stage

    - +

    -
    -

    Simscape Model

    -
    +
    +

    Simscape Model

    +

    The Simscape model of the Tilt stage is composed of:

    @@ -888,14 +884,14 @@ The Ry motion is imposed by the input. -
    +

    simscape_model_ry.png

    Figure 8: Simscape model for the Tilt Stage

    -
    +

    simscape_picture_ry.png

    Figure 9: Simscape picture for the Tilt Stage

    @@ -903,87 +899,87 @@ The Ry motion is imposed by the input.
    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [ry] = initializeRy(args)
    +
      function [ry] = initializeRy(args)
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -  args.type          char    {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible'
    -  args.Foffset       logical {mustBeNumericOrLogical} = false
    -  args.Ry_init (1,1) double  {mustBeNumeric} = 0
    -end
    +
      arguments
    +    args.type          char    {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible'
    +    args.Foffset       logical {mustBeNumericOrLogical} = false
    +    args.Ry_init (1,1) double  {mustBeNumeric} = 0
    +  end
     
    -
    -

    Structure initialization

    -
    +
    +

    Structure initialization

    +

    First, we initialize the ry structure.

    -
    ry = struct();
    +
      ry = struct();
     
    -
    -

    Add Tilt Type

    -
    +
    +

    Add Tilt Type

    +
    -
    switch args.type
    -  case 'none'
    -    ry.type = 0;
    -  case 'rigid'
    -    ry.type = 1;
    -  case 'flexible'
    -    ry.type = 2;
    -  case 'modal-analysis'
    -    ry.type = 3;
    -  case 'init'
    -    ry.type = 4;
    -end
    +
      switch args.type
    +    case 'none'
    +      ry.type = 0;
    +    case 'rigid'
    +      ry.type = 1;
    +    case 'flexible'
    +      ry.type = 2;
    +    case 'modal-analysis'
    +      ry.type = 3;
    +    case 'init'
    +      ry.type = 4;
    +  end
     
    -
    -

    Material and Geometry

    -
    +
    +

    Material and Geometry

    +

    Properties of the Material and link to the geometry of the Tilt stage.

    -
    % Ry - Guide for the tilt stage
    -ry.guide.density = 7800; % [kg/m3]
    -ry.guide.STEP    = './STEPS/ry/Tilt_Guide.STEP';
    +
      % Ry - Guide for the tilt stage
    +  ry.guide.density = 7800; % [kg/m3]
    +  ry.guide.STEP    = './STEPS/ry/Tilt_Guide.STEP';
     
    -% Ry - Rotor of the motor
    -ry.rotor.density = 2400; % [kg/m3]
    -ry.rotor.STEP    = './STEPS/ry/Tilt_Motor_Axis.STEP';
    +  % Ry - Rotor of the motor
    +  ry.rotor.density = 2400; % [kg/m3]
    +  ry.rotor.STEP    = './STEPS/ry/Tilt_Motor_Axis.STEP';
     
    -% Ry - Motor
    -ry.motor.density = 3200; % [kg/m3]
    -ry.motor.STEP    = './STEPS/ry/Tilt_Motor.STEP';
    +  % Ry - Motor
    +  ry.motor.density = 3200; % [kg/m3]
    +  ry.motor.STEP    = './STEPS/ry/Tilt_Motor.STEP';
     
    -% Ry - Plateau Tilt
    -ry.stage.density = 7800; % [kg/m3]
    -ry.stage.STEP    = './STEPS/ry/Tilt_Stage.STEP';
    +  % Ry - Plateau Tilt
    +  ry.stage.density = 7800; % [kg/m3]
    +  ry.stage.STEP    = './STEPS/ry/Tilt_Stage.STEP';
     
    @@ -991,68 +987,68 @@ ry.stage.STEP = './STEPS/ry/Tilt_Stage.STEP'; Z-Offset so that the center of rotation matches the sample center;

    -
    ry.z_offset = 0.58178; % [m]
    +
      ry.z_offset = 0.58178; % [m]
     
    -
    ry.Ry_init = args.Ry_init; % [rad]
    +
      ry.Ry_init = args.Ry_init; % [rad]
     
    -
    -

    Stiffness and Damping properties

    -
    +
    +

    Stiffness and Damping properties

    +
    -
    ry.K = [3.8e8; 4e8; 3.8e8; 1.2e8; 6e4; 1.2e8];
    -ry.C = [1e5;   1e5; 1e5;   3e4;   1e3; 3e4];
    +
      ry.K = [3.8e8; 4e8; 3.8e8; 1.2e8; 6e4; 1.2e8];
    +  ry.C = [1e5;   1e5; 1e5;   3e4;   1e3; 3e4];
     
    -
    -

    Equilibrium position of the each joint.

    -
    +
    +

    Equilibrium position of the each joint.

    +
    -
    if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
    -  load('mat/Foffset.mat', 'Fym');
    -  ry.Deq = -Fym'./ry.K;
    -else
    -  ry.Deq = zeros(6,1);
    -end
    +
      if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
    +    load('mat/Foffset.mat', 'Fym');
    +    ry.Deq = -Fym'./ry.K;
    +  else
    +    ry.Deq = zeros(6,1);
    +  end
     
    -
    -

    Save the Structure

    -
    +
    +

    Save the Structure

    +

    The ry structure is saved.

    -
    save('./mat/stages.mat', 'ry', '-append');
    +
      save('./mat/stages.mat', 'ry', '-append');
     
    -
    -

    7 Spindle

    +
    +

    7 Spindle

    - +

    -
    -

    Simscape Model

    -
    +
    +

    Simscape Model

    +

    The Simscape model of the Spindle is composed of:

    @@ -1063,14 +1059,14 @@ The Simscape model of the Spindle is composed of: -
    +

    simscape_model_rz.png

    Figure 10: Simscape model for the Spindle

    -
    +

    simscape_picture_rz.png

    Figure 11: Simscape picture for the Spindle

    @@ -1078,146 +1074,146 @@ The Simscape model of the Spindle is composed of:
    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [rz] = initializeRz(args)
    +
      function [rz] = initializeRz(args)
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -  args.type    char    {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible'
    -  args.Foffset logical {mustBeNumericOrLogical} = false
    -end
    +
      arguments
    +    args.type    char    {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init'})} = 'flexible'
    +    args.Foffset logical {mustBeNumericOrLogical} = false
    +  end
     
    -
    -

    Structure initialization

    -
    +
    +

    Structure initialization

    +

    First, we initialize the rz structure.

    -
    rz = struct();
    +
      rz = struct();
     
    -
    -

    Add Spindle Type

    -
    +
    +

    Add Spindle Type

    +
    -
    switch args.type
    -  case 'none'
    -    rz.type = 0;
    -  case 'rigid'
    -    rz.type = 1;
    -  case 'flexible'
    -    rz.type = 2;
    -  case 'modal-analysis'
    -    rz.type = 3;
    -  case 'init'
    -    rz.type = 4;
    -end
    +
      switch args.type
    +    case 'none'
    +      rz.type = 0;
    +    case 'rigid'
    +      rz.type = 1;
    +    case 'flexible'
    +      rz.type = 2;
    +    case 'modal-analysis'
    +      rz.type = 3;
    +    case 'init'
    +      rz.type = 4;
    +  end
     
    -
    -

    Material and Geometry

    -
    +
    +

    Material and Geometry

    +

    Properties of the Material and link to the geometry of the spindle.

    -
    % Spindle - Slip Ring
    -rz.slipring.density = 7800; % [kg/m3]
    -rz.slipring.STEP    = './STEPS/rz/Spindle_Slip_Ring.STEP';
    +
      % Spindle - Slip Ring
    +  rz.slipring.density = 7800; % [kg/m3]
    +  rz.slipring.STEP    = './STEPS/rz/Spindle_Slip_Ring.STEP';
     
    -% Spindle - Rotor
    -rz.rotor.density    = 7800; % [kg/m3]
    -rz.rotor.STEP       = './STEPS/rz/Spindle_Rotor.STEP';
    +  % Spindle - Rotor
    +  rz.rotor.density    = 7800; % [kg/m3]
    +  rz.rotor.STEP       = './STEPS/rz/Spindle_Rotor.STEP';
     
    -% Spindle - Stator
    -rz.stator.density   = 7800; % [kg/m3]
    -rz.stator.STEP      = './STEPS/rz/Spindle_Stator.STEP';
    +  % Spindle - Stator
    +  rz.stator.density   = 7800; % [kg/m3]
    +  rz.stator.STEP      = './STEPS/rz/Spindle_Stator.STEP';
     
    -
    -

    Stiffness and Damping properties

    -
    +
    +

    Stiffness and Damping properties

    +
    -
    rz.K = [7e8; 7e8; 2e9; 1e7; 1e7; 1e7];
    -rz.C = [4e4; 4e4; 7e4; 1e4; 1e4; 1e4];
    +
      rz.K = [7e8; 7e8; 2e9; 1e7; 1e7; 1e7];
    +  rz.C = [4e4; 4e4; 7e4; 1e4; 1e4; 1e4];
     
    -
    -

    Equilibrium position of the each joint.

    -
    +
    +

    Equilibrium position of the each joint.

    +
    -
    if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
    -  load('mat/Foffset.mat', 'Fzm');
    -  rz.Deq = -Fzm'./rz.K;
    -else
    -  rz.Deq = zeros(6,1);
    -end
    +
      if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
    +    load('mat/Foffset.mat', 'Fzm');
    +    rz.Deq = -Fzm'./rz.K;
    +  else
    +    rz.Deq = zeros(6,1);
    +  end
     
    -
    -

    Save the Structure

    -
    +
    +

    Save the Structure

    +

    The rz structure is saved.

    -
    save('./mat/stages.mat', 'rz', '-append');
    +
      save('./mat/stages.mat', 'rz', '-append');
     
    -
    -

    8 Micro Hexapod

    +
    +

    8 Micro Hexapod

    - +

    -
    -

    Simscape Model

    -
    +
    +

    Simscape Model

    +
    -
    +

    simscape_model_micro_hexapod.png

    Figure 12: Simscape model for the Micro-Hexapod

    -
    +

    simscape_picture_micro_hexapod.png

    Figure 13: Simscape picture for the Micro-Hexapod

    @@ -1225,120 +1221,120 @@ The rz structure is saved.
    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [micro_hexapod] = initializeMicroHexapod(args)
    +
      function [micro_hexapod] = initializeMicroHexapod(args)
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    args.type      char   {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init', 'compliance'})} = 'flexible'
    -    % initializeFramesPositions
    -    args.H    (1,1) double {mustBeNumeric, mustBePositive} = 350e-3
    -    args.MO_B (1,1) double {mustBeNumeric} = 270e-3
    -    % generateGeneralConfiguration
    -    args.FH  (1,1) double {mustBeNumeric, mustBePositive} = 50e-3
    -    args.FR  (1,1) double {mustBeNumeric, mustBePositive} = 175.5e-3
    -    args.FTh (6,1) double {mustBeNumeric} = [-10, 10, 120-10, 120+10, 240-10, 240+10]*(pi/180)
    -    args.MH  (1,1) double {mustBeNumeric, mustBePositive} = 45e-3
    -    args.MR  (1,1) double {mustBeNumeric, mustBePositive} = 118e-3
    -    args.MTh (6,1) double {mustBeNumeric} = [-60+10, 60-10, 60+10, 180-10, 180+10, -60-10]*(pi/180)
    -    % initializeStrutDynamics
    -    args.Ki (6,1) double {mustBeNumeric, mustBeNonnegative} = 2e7*ones(6,1)
    -    args.Ci (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.4e3*ones(6,1)
    -    % initializeCylindricalPlatforms
    -    args.Fpm (1,1) double {mustBeNumeric, mustBePositive} = 10
    -    args.Fph (1,1) double {mustBeNumeric, mustBePositive} = 26e-3
    -    args.Fpr (1,1) double {mustBeNumeric, mustBePositive} = 207.5e-3
    -    args.Mpm (1,1) double {mustBeNumeric, mustBePositive} = 10
    -    args.Mph (1,1) double {mustBeNumeric, mustBePositive} = 26e-3
    -    args.Mpr (1,1) double {mustBeNumeric, mustBePositive} = 150e-3
    -    % initializeCylindricalStruts
    -    args.Fsm (1,1) double {mustBeNumeric, mustBePositive} = 1
    -    args.Fsh (1,1) double {mustBeNumeric, mustBePositive} = 100e-3
    -    args.Fsr (1,1) double {mustBeNumeric, mustBePositive} = 25e-3
    -    args.Msm (1,1) double {mustBeNumeric, mustBePositive} = 1
    -    args.Msh (1,1) double {mustBeNumeric, mustBePositive} = 100e-3
    -    args.Msr (1,1) double {mustBeNumeric, mustBePositive} = 25e-3
    -    % inverseKinematics
    -    args.AP  (3,1) double {mustBeNumeric} = zeros(3,1)
    -    args.ARB (3,3) double {mustBeNumeric} = eye(3)
    -    % Force that stiffness of each joint should apply at t=0
    -    args.Foffset      logical {mustBeNumericOrLogical} = false
    -end
    +
      arguments
    +      args.type      char   {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'modal-analysis', 'init', 'compliance'})} = 'flexible'
    +      % initializeFramesPositions
    +      args.H    (1,1) double {mustBeNumeric, mustBePositive} = 350e-3
    +      args.MO_B (1,1) double {mustBeNumeric} = 270e-3
    +      % generateGeneralConfiguration
    +      args.FH  (1,1) double {mustBeNumeric, mustBePositive} = 50e-3
    +      args.FR  (1,1) double {mustBeNumeric, mustBePositive} = 175.5e-3
    +      args.FTh (6,1) double {mustBeNumeric} = [-10, 10, 120-10, 120+10, 240-10, 240+10]*(pi/180)
    +      args.MH  (1,1) double {mustBeNumeric, mustBePositive} = 45e-3
    +      args.MR  (1,1) double {mustBeNumeric, mustBePositive} = 118e-3
    +      args.MTh (6,1) double {mustBeNumeric} = [-60+10, 60-10, 60+10, 180-10, 180+10, -60-10]*(pi/180)
    +      % initializeStrutDynamics
    +      args.Ki (6,1) double {mustBeNumeric, mustBeNonnegative} = 2e7*ones(6,1)
    +      args.Ci (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.4e3*ones(6,1)
    +      % initializeCylindricalPlatforms
    +      args.Fpm (1,1) double {mustBeNumeric, mustBePositive} = 10
    +      args.Fph (1,1) double {mustBeNumeric, mustBePositive} = 26e-3
    +      args.Fpr (1,1) double {mustBeNumeric, mustBePositive} = 207.5e-3
    +      args.Mpm (1,1) double {mustBeNumeric, mustBePositive} = 10
    +      args.Mph (1,1) double {mustBeNumeric, mustBePositive} = 26e-3
    +      args.Mpr (1,1) double {mustBeNumeric, mustBePositive} = 150e-3
    +      % initializeCylindricalStruts
    +      args.Fsm (1,1) double {mustBeNumeric, mustBePositive} = 1
    +      args.Fsh (1,1) double {mustBeNumeric, mustBePositive} = 100e-3
    +      args.Fsr (1,1) double {mustBeNumeric, mustBePositive} = 25e-3
    +      args.Msm (1,1) double {mustBeNumeric, mustBePositive} = 1
    +      args.Msh (1,1) double {mustBeNumeric, mustBePositive} = 100e-3
    +      args.Msr (1,1) double {mustBeNumeric, mustBePositive} = 25e-3
    +      % inverseKinematics
    +      args.AP  (3,1) double {mustBeNumeric} = zeros(3,1)
    +      args.ARB (3,3) double {mustBeNumeric} = eye(3)
    +      % Force that stiffness of each joint should apply at t=0
    +      args.Foffset      logical {mustBeNumericOrLogical} = false
    +  end
     
    -
    -

    Function content

    -
    +
    +

    Function content

    +
    -
    stewart = initializeStewartPlatform();
    +
      stewart = initializeStewartPlatform();
     
    -stewart = initializeFramesPositions(stewart, ...
    -                                    'H', args.H, ...
    -                                    'MO_B', args.MO_B);
    +  stewart = initializeFramesPositions(stewart, ...
    +                                      'H', args.H, ...
    +                                      'MO_B', args.MO_B);
     
    -stewart = generateGeneralConfiguration(stewart, ...
    -                                       'FH', args.FH, ...
    -                                       'FR', args.FR, ...
    -                                       'FTh', args.FTh, ...
    -                                       'MH', args.MH, ...
    -                                       'MR', args.MR, ...
    -                                       'MTh', args.MTh);
    +  stewart = generateGeneralConfiguration(stewart, ...
    +                                         'FH', args.FH, ...
    +                                         'FR', args.FR, ...
    +                                         'FTh', args.FTh, ...
    +                                         'MH', args.MH, ...
    +                                         'MR', args.MR, ...
    +                                         'MTh', args.MTh);
     
    -stewart = computeJointsPose(stewart);
    +  stewart = computeJointsPose(stewart);
     
    -
    stewart = initializeStrutDynamics(stewart, ...
    -                                  'K', args.Ki, ...
    -                                  'C', args.Ci);
    +
      stewart = initializeStrutDynamics(stewart, ...
    +                                    'K', args.Ki, ...
    +                                    'C', args.Ci);
     
    -stewart = initializeJointDynamics(stewart, ...
    -                                  'type_F', 'universal_p', ...
    -                                  'type_M', 'spherical_p');
    +  stewart = initializeJointDynamics(stewart, ...
    +                                    'type_F', 'universal_p', ...
    +                                    'type_M', 'spherical_p');
     
    -
    stewart = initializeCylindricalPlatforms(stewart, ...
    -                                         'Fpm', args.Fpm, ...
    -                                         'Fph', args.Fph, ...
    -                                         'Fpr', args.Fpr, ...
    -                                         'Mpm', args.Mpm, ...
    -                                         'Mph', args.Mph, ...
    -                                         'Mpr', args.Mpr);
    +
      stewart = initializeCylindricalPlatforms(stewart, ...
    +                                           'Fpm', args.Fpm, ...
    +                                           'Fph', args.Fph, ...
    +                                           'Fpr', args.Fpr, ...
    +                                           'Mpm', args.Mpm, ...
    +                                           'Mph', args.Mph, ...
    +                                           'Mpr', args.Mpr);
     
    -stewart = initializeCylindricalStruts(stewart, ...
    -                                      'Fsm', args.Fsm, ...
    -                                      'Fsh', args.Fsh, ...
    -                                      'Fsr', args.Fsr, ...
    -                                      'Msm', args.Msm, ...
    -                                      'Msh', args.Msh, ...
    -                                      'Msr', args.Msr);
    +  stewart = initializeCylindricalStruts(stewart, ...
    +                                        'Fsm', args.Fsm, ...
    +                                        'Fsh', args.Fsh, ...
    +                                        'Fsr', args.Fsr, ...
    +                                        'Msm', args.Msm, ...
    +                                        'Msh', args.Msh, ...
    +                                        'Msr', args.Msr);
     
    -stewart = computeJacobian(stewart);
    +  stewart = computeJacobian(stewart);
     
    -stewart = initializeStewartPose(stewart, ...
    -                              'AP', args.AP, ...
    -                              'ARB', args.ARB);
    +  stewart = initializeStewartPose(stewart, ...
    +                                'AP', args.AP, ...
    +                                'ARB', args.ARB);
     
    -
    stewart = initializeInertialSensor(stewart, 'type', 'none');
    +
      stewart = initializeInertialSensor(stewart, 'type', 'none');
     
    @@ -1346,66 +1342,66 @@ stewart = initializeStewartPose(stewart, ... Equilibrium position of the each joint.

    -
    if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
    -  load('mat/Foffset.mat', 'Fhm');
    -  stewart.actuators.dLeq = -Fhm'./args.Ki;
    -else
    -  stewart.actuators.dLeq = zeros(6,1);
    -end
    +
      if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
    +    load('mat/Foffset.mat', 'Fhm');
    +    stewart.actuators.dLeq = -Fhm'./args.Ki;
    +  else
    +    stewart.actuators.dLeq = zeros(6,1);
    +  end
     
    -
    -

    Add Type

    -
    +
    +

    Add Type

    +
    -
    switch args.type
    -  case 'none'
    -    stewart.type = 0;
    -  case 'rigid'
    -    stewart.type = 1;
    -  case 'flexible'
    -    stewart.type = 2;
    -  case 'modal-analysis'
    -    stewart.type = 3;
    -  case 'init'
    -    stewart.type = 4;
    -  case 'compliance'
    -    stewart.type = 5;
    -end
    +
      switch args.type
    +    case 'none'
    +      stewart.type = 0;
    +    case 'rigid'
    +      stewart.type = 1;
    +    case 'flexible'
    +      stewart.type = 2;
    +    case 'modal-analysis'
    +      stewart.type = 3;
    +    case 'init'
    +      stewart.type = 4;
    +    case 'compliance'
    +      stewart.type = 5;
    +  end
     
    -
    -

    Save the Structure

    -
    +
    +

    Save the Structure

    +

    The micro_hexapod structure is saved.

    -
    micro_hexapod = stewart;
    -save('./mat/stages.mat', 'micro_hexapod', '-append');
    +
      micro_hexapod = stewart;
    +  save('./mat/stages.mat', 'micro_hexapod', '-append');
     
    -
    -

    9 Center of gravity compensation

    +
    +

    9 Center of gravity compensation

    - +

    -
    -

    Simscape Model

    -
    +
    +

    Simscape Model

    +

    The Simscape model of the Center of gravity compensator is composed of:

    @@ -1415,14 +1411,14 @@ The Simscape model of the Center of gravity compensator is composed of: -
    +

    simscape_model_axisc.png

    Figure 14: Simscape model for the Center of Mass compensation system

    -
    +

    simscape_picture_axisc.png

    Figure 15: Simscape picture for the Center of Mass compensation system

    @@ -1430,124 +1426,124 @@ The Simscape model of the Center of gravity compensator is composed of:
    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [axisc] = initializeAxisc(args)
    +
      function [axisc] = initializeAxisc(args)
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -  args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible'})} = 'flexible'
    -end
    +
      arguments
    +    args.type char {mustBeMember(args.type,{'none', 'rigid', 'flexible'})} = 'flexible'
    +  end
     
    -
    -

    Structure initialization

    -
    +
    +

    Structure initialization

    +

    First, we initialize the axisc structure.

    -
    axisc = struct();
    +
      axisc = struct();
     
    -
    -

    Add Type

    -
    +
    +

    Add Type

    +
    -
    switch args.type
    -  case 'none'
    -    axisc.type = 0;
    -  case 'rigid'
    -    axisc.type = 1;
    -  case 'flexible'
    -    axisc.type = 2;
    -end
    +
      switch args.type
    +    case 'none'
    +      axisc.type = 0;
    +    case 'rigid'
    +      axisc.type = 1;
    +    case 'flexible'
    +      axisc.type = 2;
    +  end
     
    -
    -

    Material and Geometry

    -
    +
    +

    Material and Geometry

    +

    Properties of the Material and link to the geometry files.

    -
    % Structure
    -axisc.structure.density = 3400; % [kg/m3]
    -axisc.structure.STEP    = './STEPS/axisc/axisc_structure.STEP';
    +
      % Structure
    +  axisc.structure.density = 3400; % [kg/m3]
    +  axisc.structure.STEP    = './STEPS/axisc/axisc_structure.STEP';
     
    -% Wheel
    -axisc.wheel.density     = 2700; % [kg/m3]
    -axisc.wheel.STEP        = './STEPS/axisc/axisc_wheel.STEP';
    +  % Wheel
    +  axisc.wheel.density     = 2700; % [kg/m3]
    +  axisc.wheel.STEP        = './STEPS/axisc/axisc_wheel.STEP';
     
    -% Mass
    -axisc.mass.density      = 7800; % [kg/m3]
    -axisc.mass.STEP         = './STEPS/axisc/axisc_mass.STEP';
    +  % Mass
    +  axisc.mass.density      = 7800; % [kg/m3]
    +  axisc.mass.STEP         = './STEPS/axisc/axisc_mass.STEP';
     
    -% Gear
    -axisc.gear.density      = 7800; % [kg/m3]
    -axisc.gear.STEP         = './STEPS/axisc/axisc_gear.STEP';
    +  % Gear
    +  axisc.gear.density      = 7800; % [kg/m3]
    +  axisc.gear.STEP         = './STEPS/axisc/axisc_gear.STEP';
     
    -
    -

    Save the Structure

    -
    +
    +

    Save the Structure

    +

    The axisc structure is saved.

    -
    save('./mat/stages.mat', 'axisc', '-append');
    +
      save('./mat/stages.mat', 'axisc', '-append');
     
    -
    -

    10 Mirror

    +
    +

    10 Mirror

    - +

    -
    -

    Simscape Model

    -
    +
    +

    Simscape Model

    +

    The Simscape Model of the mirror is just a solid body. The output mirror_center corresponds to the center of the Sphere and is the point of measurement for the metrology

    -
    +

    simscape_model_mirror.png

    Figure 16: Simscape model for the Mirror

    -
    +

    simscape_picture_mirror.png

    Figure 17: Simscape picture for the Mirror

    @@ -1555,128 +1551,128 @@ The output mirror_center corresponds to the center of the Sphere an
    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [] = initializeMirror(args)
    +
      function [] = initializeMirror(args)
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    args.type        char   {mustBeMember(args.type,{'none', 'rigid', 'flexible'})} = 'rigid'
    -    args.shape       char   {mustBeMember(args.shape,{'spherical', 'conical'})} = 'spherical'
    -    args.angle (1,1) double {mustBeNumeric, mustBePositive} = 45 % [deg]
    -    args.mass  (1,1) double {mustBeNumeric, mustBePositive} = 10 % [kg]
    -    args.freq  (6,1) double {mustBeNumeric, mustBeNonnegative} = 200*ones(6,1) % [Hz]
    -end
    +
      arguments
    +      args.type        char   {mustBeMember(args.type,{'none', 'rigid', 'flexible'})} = 'rigid'
    +      args.shape       char   {mustBeMember(args.shape,{'spherical', 'conical'})} = 'spherical'
    +      args.angle (1,1) double {mustBeNumeric, mustBePositive} = 45 % [deg]
    +      args.mass  (1,1) double {mustBeNumeric, mustBePositive} = 10 % [kg]
    +      args.freq  (6,1) double {mustBeNumeric, mustBeNonnegative} = 200*ones(6,1) % [Hz]
    +  end
     
    -
    -

    Structure initialization

    -
    +
    +

    Structure initialization

    +

    First, we initialize the mirror structure.

    -
    mirror = struct();
    +
      mirror = struct();
     
    -
    -

    Add Mirror Type

    -
    +
    +

    Add Mirror Type

    +
    -
    switch args.type
    -  case 'none'
    -    mirror.type = 0;
    -  case 'rigid'
    -    mirror.type = 1;
    -  case 'flexible'
    -    mirror.type = 2;
    -end
    +
      switch args.type
    +    case 'none'
    +      mirror.type = 0;
    +    case 'rigid'
    +      mirror.type = 1;
    +    case 'flexible'
    +      mirror.type = 2;
    +  end
     
    -
    -

    Mass and Inertia

    -
    +
    +

    Mass and Inertia

    +
    -
    mirror.mass = args.mass;
    -mirror.freq = args.freq;
    +
      mirror.mass = args.mass;
    +  mirror.freq = args.freq;
     
    -
    -

    Stiffness and Damping properties

    -
    +
    +

    Stiffness and Damping properties

    +
    -
    mirror.K = zeros(6,1);
    -mirror.K(1:3) = mirror.mass * (2*pi*mirror.freq(1:3)).^2;
    +
      mirror.K = zeros(6,1);
    +  mirror.K(1:3) = mirror.mass * (2*pi*mirror.freq(1:3)).^2;
     
    -mirror.C = zeros(6,1);
    -mirror.C(1:3) = 0.2 * sqrt(mirror.K(1:3).*mirror.mass);
    +  mirror.C = zeros(6,1);
    +  mirror.C(1:3) = 0.2 * sqrt(mirror.K(1:3).*mirror.mass);
     
    -
    -

    Equilibrium position of the each joint.

    -
    +
    +

    Equilibrium position of the each joint.

    +
    -
    mirror.Deq = zeros(6,1);
    +
      mirror.Deq = zeros(6,1);
     
    -
    -

    Geometry

    -
    +
    +

    Geometry

    +

    We define the geometrical values.

    -
    mirror.h = 0.05; % Height of the mirror [m]
    +
      mirror.h = 0.05; % Height of the mirror [m]
     
    -mirror.thickness = 0.02; % Thickness of the plate supporting the sample [m]
    +  mirror.thickness = 0.02; % Thickness of the plate supporting the sample [m]
     
    -mirror.hole_rad = 0.125; % radius of the hole in the mirror [m]
    +  mirror.hole_rad = 0.125; % radius of the hole in the mirror [m]
     
    -mirror.support_rad = 0.1; % radius of the support plate [m]
    +  mirror.support_rad = 0.1; % radius of the support plate [m]
     
    -% point of interest offset in z (above the top surfave) [m]
    -switch args.type
    -  case 'none'
    -    mirror.jacobian = 0.205;
    -  case 'rigid'
    -    mirror.jacobian = 0.205 - mirror.h;
    -  case 'flexible'
    -    mirror.jacobian = 0.205 - mirror.h;
    -end
    +  % point of interest offset in z (above the top surfave) [m]
    +  switch args.type
    +    case 'none'
    +      mirror.jacobian = 0.205;
    +    case 'rigid'
    +      mirror.jacobian = 0.205 - mirror.h;
    +    case 'flexible'
    +      mirror.jacobian = 0.205 - mirror.h;
    +  end
     
    -mirror.rad = 0.180; % radius of the mirror (at the bottom surface) [m]
    +  mirror.rad = 0.180; % radius of the mirror (at the bottom surface) [m]
     
    -
    mirror.cone_length = mirror.rad*tand(args.angle)+mirror.h+mirror.jacobian; % Distance from Apex point of the cone to jacobian point
    +
      mirror.cone_length = mirror.rad*tand(args.angle)+mirror.h+mirror.jacobian; % Distance from Apex point of the cone to jacobian point
     
    @@ -1685,12 +1681,12 @@ Now we define the Shape of the mirror. We first start with the internal part.

    -
    mirror.shape = [...
    -    mirror.support_rad+5e-3 mirror.h-mirror.thickness
    -    mirror.hole_rad mirror.h-mirror.thickness; ...
    -    mirror.hole_rad 0; ...
    -    mirror.rad 0 ...
    -];
    +
      mirror.shape = [...
    +      mirror.support_rad+5e-3 mirror.h-mirror.thickness
    +      mirror.hole_rad mirror.h-mirror.thickness; ...
    +      mirror.hole_rad 0; ...
    +      mirror.rad 0 ...
    +  ];
     
    @@ -1698,17 +1694,17 @@ We first start with the internal part. Then, we define the reflective used part of the mirror.

    -
    if strcmp(args.shape, 'spherical')
    -    mirror.sphere_radius = sqrt((mirror.jacobian+mirror.h)^2+mirror.rad^2); % Radius of the sphere [mm]
    +
      if strcmp(args.shape, 'spherical')
    +      mirror.sphere_radius = sqrt((mirror.jacobian+mirror.h)^2+mirror.rad^2); % Radius of the sphere [mm]
     
    -    for z = linspace(0, mirror.h, 101)
    -        mirror.shape = [mirror.shape; sqrt(mirror.sphere_radius^2-(z-mirror.jacobian-mirror.h)^2) z];
    -    end
    -elseif strcmp(args.shape, 'conical')
    -    mirror.shape = [mirror.shape; mirror.rad+mirror.h/tand(args.angle) mirror.h];
    -else
    -    error('Shape should be either conical or spherical');
    -end
    +      for z = linspace(0, mirror.h, 101)
    +          mirror.shape = [mirror.shape; sqrt(mirror.sphere_radius^2-(z-mirror.jacobian-mirror.h)^2) z];
    +      end
    +  elseif strcmp(args.shape, 'conical')
    +      mirror.shape = [mirror.shape; mirror.rad+mirror.h/tand(args.angle) mirror.h];
    +  else
    +      error('Shape should be either conical or spherical');
    +  end
     
    @@ -1716,46 +1712,46 @@ Then, we define the reflective used part of the mirror. Finally, we close the shape.

    -
    mirror.shape = [mirror.shape; mirror.support_rad+5e-3 mirror.h];
    +
      mirror.shape = [mirror.shape; mirror.support_rad+5e-3 mirror.h];
     
    -
    -

    Save the Structure

    -
    +
    +

    Save the Structure

    +

    The mirror structure is saved.

    -
    save('./mat/stages.mat', 'mirror', '-append');
    +
      save('./mat/stages.mat', 'mirror', '-append');
     
    -
    -

    11 Nano Hexapod

    +
    +

    11 Nano Hexapod

    - +

    -
    -

    Simscape Model

    -
    +
    +

    Simscape Model

    +
    -
    +

    simscape_model_nano_hexapod.png

    Figure 18: Simscape model for the Nano Hexapod

    -
    +

    simscape_picture_nano_hexapod.png

    Figure 19: Simscape picture for the Nano Hexapod

    @@ -1763,159 +1759,159 @@ The mirror structure is saved.
    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [nano_hexapod] = initializeNanoHexapod(args)
    +
      function [nano_hexapod] = initializeNanoHexapod(args)
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    args.type      char   {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'init'})} = 'flexible'
    -    % initializeFramesPositions
    -    args.H    (1,1) double {mustBeNumeric, mustBePositive} = 95e-3
    -    args.MO_B (1,1) double {mustBeNumeric} = 170e-3
    -    % generateGeneralConfiguration
    -    args.FH  (1,1) double {mustBeNumeric, mustBePositive} = 15e-3
    -    args.FR  (1,1) double {mustBeNumeric, mustBePositive} = 100e-3
    -    args.FTh (6,1) double {mustBeNumeric} = [-10, 10, 120-10, 120+10, 240-10, 240+10]*(pi/180)
    -    args.MH  (1,1) double {mustBeNumeric, mustBePositive} = 15e-3
    -    args.MR  (1,1) double {mustBeNumeric, mustBePositive} = 90e-3
    -    args.MTh (6,1) double {mustBeNumeric} = [-60+10, 60-10, 60+10, 180-10, 180+10, -60-10]*(pi/180)
    -    % initializeStrutDynamics
    -    args.actuator  char   {mustBeMember(args.actuator,{'piezo', 'lorentz', 'amplified'})} = 'piezo'
    -    args.k1  (1,1) double {mustBeNumeric} = 1e6
    -    args.ke  (1,1) double {mustBeNumeric} = 5e6
    -    args.ka  (1,1) double {mustBeNumeric} = 60e6
    -    args.c1  (1,1) double {mustBeNumeric} = 10
    -    args.F_gain  (1,1) double {mustBeNumeric} = 1
    -    args.k   (1,1) double {mustBeNumeric} = -1
    -    args.c   (1,1) double {mustBeNumeric} = -1
    -    % initializeJointDynamics
    -    args.type_F     char   {mustBeMember(args.type_F,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof', 'spherical_3dof', 'flexible'})} = 'universal'
    -    args.type_M     char   {mustBeMember(args.type_M,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof', 'spherical_3dof', 'flexible'})} = 'spherical'
    -    args.Ka_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.2e8*ones(6,1)
    -    args.Ca_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
    -    args.Kr_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.1e7*ones(6,1)
    -    args.Cr_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
    -    args.Kf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1)
    -    args.Cf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
    -    args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1)
    -    args.Ct_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
    -    args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1)
    -    args.Cf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
    -    args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1)
    -    args.Ct_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
    -    args.Ka_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.2e8*ones(6,1)
    -    args.Ca_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
    -    args.Kr_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.1e7*ones(6,1)
    -    args.Cr_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
    -    % initializeCylindricalPlatforms
    -    args.Fpm (1,1) double {mustBeNumeric, mustBePositive} = 1
    -    args.Fph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3
    -    args.Fpr (1,1) double {mustBeNumeric, mustBePositive} = 150e-3
    -    args.Mpm (1,1) double {mustBeNumeric, mustBePositive} = 1
    -    args.Mph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3
    -    args.Mpr (1,1) double {mustBeNumeric, mustBePositive} = 120e-3
    -    % initializeCylindricalStruts
    -    args.Fsm (1,1) double {mustBeNumeric, mustBePositive} = 0.1
    -    args.Fsh (1,1) double {mustBeNumeric, mustBePositive} = 50e-3
    -    args.Fsr (1,1) double {mustBeNumeric, mustBePositive} = 5e-3
    -    args.Msm (1,1) double {mustBeNumeric, mustBePositive} = 0.1
    -    args.Msh (1,1) double {mustBeNumeric, mustBePositive} = 50e-3
    -    args.Msr (1,1) double {mustBeNumeric, mustBePositive} = 5e-3
    -    % inverseKinematics
    -    args.AP  (3,1) double {mustBeNumeric} = zeros(3,1)
    -    args.ARB (3,3) double {mustBeNumeric} = eye(3)
    -    % Equilibrium position of each leg
    -    args.dLeq (6,1) double {mustBeNumeric} = zeros(6,1)
    -    % Force that stiffness of each joint should apply at t=0
    -    args.Foffset      logical {mustBeNumericOrLogical} = false
    -end
    +
      arguments
    +      args.type      char   {mustBeMember(args.type,{'none', 'rigid', 'flexible', 'init'})} = 'flexible'
    +      % initializeFramesPositions
    +      args.H    (1,1) double {mustBeNumeric, mustBePositive} = 95e-3
    +      args.MO_B (1,1) double {mustBeNumeric} = 170e-3
    +      % generateGeneralConfiguration
    +      args.FH  (1,1) double {mustBeNumeric, mustBePositive} = 15e-3
    +      args.FR  (1,1) double {mustBeNumeric, mustBePositive} = 100e-3
    +      args.FTh (6,1) double {mustBeNumeric} = [-10, 10, 120-10, 120+10, 240-10, 240+10]*(pi/180)
    +      args.MH  (1,1) double {mustBeNumeric, mustBePositive} = 15e-3
    +      args.MR  (1,1) double {mustBeNumeric, mustBePositive} = 90e-3
    +      args.MTh (6,1) double {mustBeNumeric} = [-60+10, 60-10, 60+10, 180-10, 180+10, -60-10]*(pi/180)
    +      % initializeStrutDynamics
    +      args.actuator  char   {mustBeMember(args.actuator,{'piezo', 'lorentz', 'amplified'})} = 'piezo'
    +      args.k1  (1,1) double {mustBeNumeric} = 1e6
    +      args.ke  (1,1) double {mustBeNumeric} = 5e6
    +      args.ka  (1,1) double {mustBeNumeric} = 60e6
    +      args.c1  (1,1) double {mustBeNumeric} = 10
    +      args.F_gain  (1,1) double {mustBeNumeric} = 1
    +      args.k   (1,1) double {mustBeNumeric} = -1
    +      args.c   (1,1) double {mustBeNumeric} = -1
    +      % initializeJointDynamics
    +      args.type_F     char   {mustBeMember(args.type_F,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof', 'spherical_3dof', 'flexible'})} = 'universal'
    +      args.type_M     char   {mustBeMember(args.type_M,{'universal', 'spherical', 'universal_p', 'spherical_p', 'universal_3dof', 'spherical_3dof', 'flexible'})} = 'spherical'
    +      args.Ka_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.2e8*ones(6,1)
    +      args.Ca_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
    +      args.Kr_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.1e7*ones(6,1)
    +      args.Cr_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
    +      args.Kf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1)
    +      args.Cf_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
    +      args.Kt_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1)
    +      args.Ct_M (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
    +      args.Kf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 33*ones(6,1)
    +      args.Cf_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-4*ones(6,1)
    +      args.Kt_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 236*ones(6,1)
    +      args.Ct_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e-3*ones(6,1)
    +      args.Ka_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.2e8*ones(6,1)
    +      args.Ca_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
    +      args.Kr_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1.1e7*ones(6,1)
    +      args.Cr_F (6,1) double {mustBeNumeric, mustBeNonnegative} = 1e1*ones(6,1)
    +      % initializeCylindricalPlatforms
    +      args.Fpm (1,1) double {mustBeNumeric, mustBePositive} = 1
    +      args.Fph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3
    +      args.Fpr (1,1) double {mustBeNumeric, mustBePositive} = 150e-3
    +      args.Mpm (1,1) double {mustBeNumeric, mustBePositive} = 1
    +      args.Mph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3
    +      args.Mpr (1,1) double {mustBeNumeric, mustBePositive} = 120e-3
    +      % initializeCylindricalStruts
    +      args.Fsm (1,1) double {mustBeNumeric, mustBePositive} = 0.1
    +      args.Fsh (1,1) double {mustBeNumeric, mustBePositive} = 50e-3
    +      args.Fsr (1,1) double {mustBeNumeric, mustBePositive} = 5e-3
    +      args.Msm (1,1) double {mustBeNumeric, mustBePositive} = 0.1
    +      args.Msh (1,1) double {mustBeNumeric, mustBePositive} = 50e-3
    +      args.Msr (1,1) double {mustBeNumeric, mustBePositive} = 5e-3
    +      % inverseKinematics
    +      args.AP  (3,1) double {mustBeNumeric} = zeros(3,1)
    +      args.ARB (3,3) double {mustBeNumeric} = eye(3)
    +      % Equilibrium position of each leg
    +      args.dLeq (6,1) double {mustBeNumeric} = zeros(6,1)
    +      % Force that stiffness of each joint should apply at t=0
    +      args.Foffset      logical {mustBeNumericOrLogical} = false
    +  end
     
    -
    -

    Function content

    -
    +
    +

    Function content

    +
    -
    stewart = initializeStewartPlatform();
    +
      stewart = initializeStewartPlatform();
     
    -stewart = initializeFramesPositions(stewart, 'H', args.H, 'MO_B', args.MO_B);
    +  stewart = initializeFramesPositions(stewart, 'H', args.H, 'MO_B', args.MO_B);
     
    -stewart = generateGeneralConfiguration(stewart, 'FH', args.FH, 'FR', args.FR, 'FTh', args.FTh, 'MH', args.MH, 'MR', args.MR, 'MTh', args.MTh);
    +  stewart = generateGeneralConfiguration(stewart, 'FH', args.FH, 'FR', args.FR, 'FTh', args.FTh, 'MH', args.MH, 'MR', args.MR, 'MTh', args.MTh);
     
    -stewart = computeJointsPose(stewart);
    +  stewart = computeJointsPose(stewart);
     
    -
    if args.k > 0 && args.c > 0
    -    stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', args.k*ones(6,1), 'C', args.c*ones(6,1));
    -elseif args.k > 0
    -    stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', args.k*ones(6,1), 'C', 1.5*sqrt(args.k)*ones(6,1));
    -elseif strcmp(args.actuator, 'piezo')
    -    stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', 1e7*ones(6,1), 'C', 1e2*ones(6,1));
    -elseif strcmp(args.actuator, 'lorentz')
    -    stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', 1e4*ones(6,1), 'C', 1e2*ones(6,1));
    -elseif strcmp(args.actuator, 'amplified')
    -    stewart = initializeStrutDynamics(stewart, 'type', 'amplified', ...
    -                                      'k1', args.k1*ones(6,1), ...
    -                                      'c1', args.c1*ones(6,1), ...
    -                                      'ka', args.ka*ones(6,1), ...
    -                                      'ke', args.ke*ones(6,1), ...
    -                                      'F_gain', args.F_gain*ones(6,1));
    -else
    -    error('args.actuator should be piezo, lorentz or amplified');
    -end
    +
      if args.k > 0 && args.c > 0
    +      stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', args.k*ones(6,1), 'C', args.c*ones(6,1));
    +  elseif args.k > 0
    +      stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', args.k*ones(6,1), 'C', 1.5*sqrt(args.k)*ones(6,1));
    +  elseif strcmp(args.actuator, 'piezo')
    +      stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', 1e7*ones(6,1), 'C', 1e2*ones(6,1));
    +  elseif strcmp(args.actuator, 'lorentz')
    +      stewart = initializeStrutDynamics(stewart, 'type', 'classical', 'K', 1e4*ones(6,1), 'C', 1e2*ones(6,1));
    +  elseif strcmp(args.actuator, 'amplified')
    +      stewart = initializeStrutDynamics(stewart, 'type', 'amplified', ...
    +                                        'k1', args.k1*ones(6,1), ...
    +                                        'c1', args.c1*ones(6,1), ...
    +                                        'ka', args.ka*ones(6,1), ...
    +                                        'ke', args.ke*ones(6,1), ...
    +                                        'F_gain', args.F_gain*ones(6,1));
    +  else
    +      error('args.actuator should be piezo, lorentz or amplified');
    +  end
     
    -
    stewart = initializeJointDynamics(stewart, ...
    -                                  'type_F', args.type_F, ...
    -                                  'type_M', args.type_M, ...
    -                                  'Kf_M', args.Kf_M, ...
    -                                  'Cf_M', args.Cf_M, ...
    -                                  'Kt_M', args.Kt_M, ...
    -                                  'Ct_M', args.Ct_M, ...
    -                                  'Kf_F', args.Kf_F, ...
    -                                  'Cf_F', args.Cf_F, ...
    -                                  'Kt_F', args.Kt_F, ...
    -                                  'Ct_F', args.Ct_F, ...
    -                                  'Ka_F', args.Ka_F, ...
    -                                  'Ca_F', args.Ca_F, ...
    -                                  'Kr_F', args.Kr_F, ...
    -                                  'Cr_F', args.Cr_F, ...
    -                                  'Ka_M', args.Ka_M, ...
    -                                  'Ca_M', args.Ca_M, ...
    -                                  'Kr_M', args.Kr_M, ...
    -                                  'Cr_M', args.Cr_M);
    +
      stewart = initializeJointDynamics(stewart, ...
    +                                    'type_F', args.type_F, ...
    +                                    'type_M', args.type_M, ...
    +                                    'Kf_M', args.Kf_M, ...
    +                                    'Cf_M', args.Cf_M, ...
    +                                    'Kt_M', args.Kt_M, ...
    +                                    'Ct_M', args.Ct_M, ...
    +                                    'Kf_F', args.Kf_F, ...
    +                                    'Cf_F', args.Cf_F, ...
    +                                    'Kt_F', args.Kt_F, ...
    +                                    'Ct_F', args.Ct_F, ...
    +                                    'Ka_F', args.Ka_F, ...
    +                                    'Ca_F', args.Ca_F, ...
    +                                    'Kr_F', args.Kr_F, ...
    +                                    'Cr_F', args.Cr_F, ...
    +                                    'Ka_M', args.Ka_M, ...
    +                                    'Ca_M', args.Ca_M, ...
    +                                    'Kr_M', args.Kr_M, ...
    +                                    'Cr_M', args.Cr_M);
     
    -
    stewart = initializeCylindricalPlatforms(stewart, 'Fpm', args.Fpm, 'Fph', args.Fph, 'Fpr', args.Fpr, 'Mpm', args.Mpm, 'Mph', args.Mph, 'Mpr', args.Mpr);
    +
      stewart = initializeCylindricalPlatforms(stewart, 'Fpm', args.Fpm, 'Fph', args.Fph, 'Fpr', args.Fpr, 'Mpm', args.Mpm, 'Mph', args.Mph, 'Mpr', args.Mpr);
     
    -stewart = initializeCylindricalStruts(stewart, 'Fsm', args.Fsm, 'Fsh', args.Fsh, 'Fsr', args.Fsr, 'Msm', args.Msm, 'Msh', args.Msh, 'Msr', args.Msr);
    +  stewart = initializeCylindricalStruts(stewart, 'Fsm', args.Fsm, 'Fsh', args.Fsh, 'Fsr', args.Fsr, 'Msm', args.Msm, 'Msh', args.Msh, 'Msr', args.Msr);
     
    -stewart = computeJacobian(stewart);
    +  stewart = computeJacobian(stewart);
     
    -stewart = initializeStewartPose(stewart, 'AP', args.AP, 'ARB', args.ARB);
    +  stewart = initializeStewartPose(stewart, 'AP', args.AP, 'ARB', args.ARB);
     
    -
    stewart = initializeInertialSensor(stewart, 'type', 'accelerometer');
    +
      stewart = initializeInertialSensor(stewart, 'type', 'accelerometer');
     
    @@ -1924,59 +1920,59 @@ Equilibrium position of the each joint.

    -if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
    -  load('mat/Foffset.mat', 'Fnm');
    -  stewart.actuators.dLeq = -Fnm'./stewart.Ki;
    -else
    -  stewart.actuators.dLeq = args.dLeq;
    -end
    +  if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
    +    load('mat/Foffset.mat', 'Fnm');
    +    stewart.actuators.dLeq = -Fnm'./stewart.Ki;
    +  else
    +    stewart.actuators.dLeq = args.dLeq;
    +  end
     
    -
    -

    Add Type

    -
    +
    +

    Add Type

    +
    -
    switch args.type
    -  case 'none'
    -    stewart.type = 0;
    -  case 'rigid'
    -    stewart.type = 1;
    -  case 'flexible'
    -    stewart.type = 2;
    -  case 'init'
    -    stewart.type = 4;
    -end
    +
      switch args.type
    +    case 'none'
    +      stewart.type = 0;
    +    case 'rigid'
    +      stewart.type = 1;
    +    case 'flexible'
    +      stewart.type = 2;
    +    case 'init'
    +      stewart.type = 4;
    +  end
     
    -
    -

    Save the Structure

    -
    +
    +

    Save the Structure

    +
    -
    nano_hexapod = stewart;
    -save('./mat/stages.mat', 'nano_hexapod', '-append');
    +
      nano_hexapod = stewart;
    +  save('./mat/stages.mat', 'nano_hexapod', '-append');
     
    -
    -

    12 Sample

    +
    +

    12 Sample

    - +

    -
    -

    Simscape Model

    -
    +
    +

    Simscape Model

    +

    The Simscape model of the sample environment is composed of:

    @@ -1989,14 +1985,14 @@ This could be the case for cable forces for instance. -
    +

    simscape_model_sample.png

    Figure 20: Simscape model for the Sample

    -
    +

    simscape_picture_sample.png

    Figure 21: Simscape picture for the Sample

    @@ -2004,100 +2000,100 @@ This could be the case for cable forces for instance.
    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [sample] = initializeSample(args)
    +
      function [sample] = initializeSample(args)
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -  args.type         char    {mustBeMember(args.type,{'rigid', 'flexible', 'none', 'init'})} = 'flexible'
    -  args.radius (1,1) double  {mustBeNumeric, mustBePositive} = 0.1 % [m]
    -  args.height (1,1) double  {mustBeNumeric, mustBePositive} = 0.3 % [m]
    -  args.mass   (1,1) double  {mustBeNumeric, mustBePositive} = 50 % [kg]
    -  args.freq   (6,1) double  {mustBeNumeric, mustBePositive} = 100*ones(6,1) % [Hz]
    -  args.offset (1,1) double  {mustBeNumeric} = 0 % [m]
    -  args.Foffset      logical {mustBeNumericOrLogical} = false
    -end
    +
      arguments
    +    args.type         char    {mustBeMember(args.type,{'rigid', 'flexible', 'none', 'init'})} = 'flexible'
    +    args.radius (1,1) double  {mustBeNumeric, mustBePositive} = 0.1 % [m]
    +    args.height (1,1) double  {mustBeNumeric, mustBePositive} = 0.3 % [m]
    +    args.mass   (1,1) double  {mustBeNumeric, mustBePositive} = 50 % [kg]
    +    args.freq   (6,1) double  {mustBeNumeric, mustBePositive} = 100*ones(6,1) % [Hz]
    +    args.offset (1,1) double  {mustBeNumeric} = 0 % [m]
    +    args.Foffset      logical {mustBeNumericOrLogical} = false
    +  end
     
    -
    -

    Structure initialization

    -
    +
    +

    Structure initialization

    +

    First, we initialize the sample structure.

    -
    sample = struct();
    +
      sample = struct();
     
    -
    -

    Add Sample Type

    -
    +
    +

    Add Sample Type

    +
    -
    switch args.type
    -  case 'none'
    -    sample.type = 0;
    -  case 'rigid'
    -    sample.type = 1;
    -  case 'flexible'
    -    sample.type = 2;
    -  case 'init'
    -    sample.type = 3;
    -end
    +
      switch args.type
    +    case 'none'
    +      sample.type = 0;
    +    case 'rigid'
    +      sample.type = 1;
    +    case 'flexible'
    +      sample.type = 2;
    +    case 'init'
    +      sample.type = 3;
    +  end
     
    -
    -

    Material and Geometry

    -
    +
    +

    Material and Geometry

    +

    We define the geometrical parameters of the sample as well as its mass and position.

    -
    sample.radius = args.radius; % [m]
    -sample.height = args.height; % [m]
    -sample.mass   = args.mass; % [kg]
    -sample.offset = args.offset; % [m]
    +
      sample.radius = args.radius; % [m]
    +  sample.height = args.height; % [m]
    +  sample.mass   = args.mass; % [kg]
    +  sample.offset = args.offset; % [m]
     
    -
    -

    Compute the Inertia

    -
    +
    +

    Compute the Inertia

    +
    -
    sample.inertia = [1/12 * sample.mass * (3*sample.radius^2 + sample.height^2); ...
    -                  1/12 * sample.mass * (3*sample.radius^2 + sample.height^2); ...
    -                  1/2  * sample.mass * sample.radius^2];
    +
      sample.inertia = [1/12 * sample.mass * (3*sample.radius^2 + sample.height^2); ...
    +                    1/12 * sample.mass * (3*sample.radius^2 + sample.height^2); ...
    +                    1/2  * sample.mass * sample.radius^2];
     
    -
    -

    Stiffness and Damping properties

    -
    +
    +

    Stiffness and Damping properties

    +
    -
    sample.K = zeros(6, 1);
    -sample.C = zeros(6, 1);
    +
      sample.K = zeros(6, 1);
    +  sample.C = zeros(6, 1);
     
    @@ -2105,8 +2101,8 @@ sample.C = zeros(6, 1); Translation Stiffness and Damping:

    -
    sample.K(1:3) = sample.mass .* (2*pi * args.freq(1:3)).^2; % [N/m]
    -sample.C(1:3) = 0.1 * sqrt(sample.K(1:3)*sample.mass); % [N/(m/s)]
    +
      sample.K(1:3) = sample.mass .* (2*pi * args.freq(1:3)).^2; % [N/m]
    +  sample.C(1:3) = 0.1 * sqrt(sample.K(1:3)*sample.mass); % [N/(m/s)]
     
    @@ -2114,514 +2110,514 @@ sample.C(1:3) = 0.1 *
    -
    sample.K(4:6) = sample.inertia .* (2*pi * args.freq(4:6)).^2; % [N/m]
    -sample.C(4:6) = 0.1 * sqrt(sample.K(4:6).*sample.inertia); % [N/(m/s)]
    +
      sample.K(4:6) = sample.inertia .* (2*pi * args.freq(4:6)).^2; % [N/m]
    +  sample.C(4:6) = 0.1 * sqrt(sample.K(4:6).*sample.inertia); % [N/(m/s)]
     
    -
    -

    Equilibrium position of the each joint.

    -
    +
    +

    Equilibrium position of the each joint.

    +
    -
    if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
    -  load('mat/Foffset.mat', 'Fsm');
    -  sample.Deq = -Fsm'./sample.K;
    -else
    -  sample.Deq = zeros(6,1);
    -end
    +
      if args.Foffset && ~strcmp(args.type, 'none') && ~strcmp(args.type, 'rigid') && ~strcmp(args.type, 'init')
    +    load('mat/Foffset.mat', 'Fsm');
    +    sample.Deq = -Fsm'./sample.K;
    +  else
    +    sample.Deq = zeros(6,1);
    +  end
     
    -
    -

    Save the Structure

    -
    +
    +

    Save the Structure

    +

    The sample structure is saved.

    -
    save('./mat/stages.mat', 'sample', '-append');
    +
      save('./mat/stages.mat', 'sample', '-append');
     
    -
    -

    13 Initialize Controller

    +
    +

    13 Initialize Controller

    - +

    -
    -

    Function Declaration and Documentation

    -
    +
    +

    Function Declaration and Documentation

    +
    -
    function [] = initializeController(args)
    +
      function [] = initializeController(args)
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -  args.type char {mustBeMember(args.type,{'open-loop', 'iff', 'dvf', 'hac-dvf', 'ref-track-L', 'ref-track-iff-L', 'cascade-hac-lac', 'hac-iff', 'stabilizing'})} = 'open-loop'
    -end
    +
      arguments
    +    args.type char {mustBeMember(args.type,{'open-loop', 'iff', 'dvf', 'hac-dvf', 'ref-track-L', 'ref-track-iff-L', 'cascade-hac-lac', 'hac-iff', 'stabilizing'})} = 'open-loop'
    +  end
     
    -
    -

    Structure initialization

    -
    +
    +

    Structure initialization

    +

    First, we initialize the controller structure.

    -
    controller = struct();
    +
      controller = struct();
     
    -
    -

    Controller Type

    -
    +
    +

    Controller Type

    +
    -
    switch args.type
    -  case 'open-loop'
    -    controller.type = 1;
    -    controller.name = 'Open-Loop';
    -  case 'dvf'
    -    controller.type = 2;
    -    controller.name = 'Decentralized Direct Velocity Feedback';
    -  case 'iff'
    -    controller.type = 3;
    -    controller.name = 'Decentralized Integral Force Feedback';
    -  case 'hac-dvf'
    -    controller.type = 4;
    -    controller.name = 'HAC-DVF';
    -  case 'ref-track-L'
    -    controller.type = 5;
    -    controller.name = 'Reference Tracking in the frame of the legs';
    -  case 'ref-track-iff-L'
    -    controller.type = 6;
    -    controller.name = 'Reference Tracking in the frame of the legs + IFF';
    -  case 'cascade-hac-lac'
    -    controller.type = 7;
    -    controller.name = 'Cascade Control + HAC-LAC';
    -  case 'hac-iff'
    -    controller.type = 8;
    -    controller.name = 'HAC-IFF';
    -  case 'stabilizing'
    -    controller.type = 9;
    -    controller.name = 'Stabilizing Controller';
    -end
    +
      switch args.type
    +    case 'open-loop'
    +      controller.type = 1;
    +      controller.name = 'Open-Loop';
    +    case 'dvf'
    +      controller.type = 2;
    +      controller.name = 'Decentralized Direct Velocity Feedback';
    +    case 'iff'
    +      controller.type = 3;
    +      controller.name = 'Decentralized Integral Force Feedback';
    +    case 'hac-dvf'
    +      controller.type = 4;
    +      controller.name = 'HAC-DVF';
    +    case 'ref-track-L'
    +      controller.type = 5;
    +      controller.name = 'Reference Tracking in the frame of the legs';
    +    case 'ref-track-iff-L'
    +      controller.type = 6;
    +      controller.name = 'Reference Tracking in the frame of the legs + IFF';
    +    case 'cascade-hac-lac'
    +      controller.type = 7;
    +      controller.name = 'Cascade Control + HAC-LAC';
    +    case 'hac-iff'
    +      controller.type = 8;
    +      controller.name = 'HAC-IFF';
    +    case 'stabilizing'
    +      controller.type = 9;
    +      controller.name = 'Stabilizing Controller';
    +  end
     
    -
    -

    Save the Structure

    -
    +
    +

    Save the Structure

    +

    The controller structure is saved.

    -
    save('./mat/controller.mat', 'controller');
    +
      save('./mat/controller.mat', 'controller');
     
    -
    -

    14 Generate Reference Signals

    +
    +

    14 Generate Reference Signals

    - +

    -
    -

    Function Declaration and Documentation

    -
    +
    +

    Function Declaration and Documentation

    +
    -
    function [ref] = initializeReferences(args)
    +
      function [ref] = initializeReferences(args)
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    % Sampling Frequency [s]
    -    args.Ts           (1,1) double {mustBeNumeric, mustBePositive} = 1e-3
    -    % Maximum simulation time [s]
    -    args.Tmax         (1,1) double {mustBeNumeric, mustBePositive} = 100
    -    % Either "constant" / "triangular" / "sinusoidal"
    -    args.Dy_type      char {mustBeMember(args.Dy_type,{'constant', 'triangular', 'sinusoidal'})} = 'constant'
    -    % Amplitude of the displacement [m]
    -    args.Dy_amplitude (1,1) double {mustBeNumeric} = 0
    -    % Period of the displacement [s]
    -    args.Dy_period    (1,1) double {mustBeNumeric, mustBePositive} = 1
    -    % Either "constant" / "triangular" / "sinusoidal"
    -    args.Ry_type      char {mustBeMember(args.Ry_type,{'constant', 'triangular', 'sinusoidal'})} = 'constant'
    -    % Amplitude [rad]
    -    args.Ry_amplitude (1,1) double {mustBeNumeric} = 0
    -    % Period of the displacement [s]
    -    args.Ry_period    (1,1) double {mustBeNumeric, mustBePositive} = 1
    -    % Either "constant" / "rotating"
    -    args.Rz_type      char {mustBeMember(args.Rz_type,{'constant', 'rotating', 'rotating-not-filtered'})} = 'constant'
    -    % Initial angle [rad]
    -    args.Rz_amplitude (1,1) double {mustBeNumeric} = 0
    -    % Period of the rotating [s]
    -    args.Rz_period    (1,1) double {mustBeNumeric, mustBePositive} = 1
    -    % For now, only constant is implemented
    -    args.Dh_type      char {mustBeMember(args.Dh_type,{'constant'})} = 'constant'
    -    % Initial position [m,m,m,rad,rad,rad] of the top platform (Pitch-Roll-Yaw Euler angles)
    -    args.Dh_pos       (6,1) double {mustBeNumeric} = zeros(6, 1), ...
    -    % For now, only constant is implemented
    -    args.Rm_type      char {mustBeMember(args.Rm_type,{'constant'})} = 'constant'
    -    % Initial position of the two masses
    -    args.Rm_pos       (2,1) double {mustBeNumeric} = [0; pi]
    -    % For now, only constant is implemented
    -    args.Dn_type      char {mustBeMember(args.Dn_type,{'constant'})} = 'constant'
    -    % Initial position [m,m,m,rad,rad,rad] of the top platform
    -    args.Dn_pos       (6,1) double {mustBeNumeric} = zeros(6,1)
    -end
    +
      arguments
    +      % Sampling Frequency [s]
    +      args.Ts           (1,1) double {mustBeNumeric, mustBePositive} = 1e-3
    +      % Maximum simulation time [s]
    +      args.Tmax         (1,1) double {mustBeNumeric, mustBePositive} = 100
    +      % Either "constant" / "triangular" / "sinusoidal"
    +      args.Dy_type      char {mustBeMember(args.Dy_type,{'constant', 'triangular', 'sinusoidal'})} = 'constant'
    +      % Amplitude of the displacement [m]
    +      args.Dy_amplitude (1,1) double {mustBeNumeric} = 0
    +      % Period of the displacement [s]
    +      args.Dy_period    (1,1) double {mustBeNumeric, mustBePositive} = 1
    +      % Either "constant" / "triangular" / "sinusoidal"
    +      args.Ry_type      char {mustBeMember(args.Ry_type,{'constant', 'triangular', 'sinusoidal'})} = 'constant'
    +      % Amplitude [rad]
    +      args.Ry_amplitude (1,1) double {mustBeNumeric} = 0
    +      % Period of the displacement [s]
    +      args.Ry_period    (1,1) double {mustBeNumeric, mustBePositive} = 1
    +      % Either "constant" / "rotating"
    +      args.Rz_type      char {mustBeMember(args.Rz_type,{'constant', 'rotating', 'rotating-not-filtered'})} = 'constant'
    +      % Initial angle [rad]
    +      args.Rz_amplitude (1,1) double {mustBeNumeric} = 0
    +      % Period of the rotating [s]
    +      args.Rz_period    (1,1) double {mustBeNumeric, mustBePositive} = 1
    +      % For now, only constant is implemented
    +      args.Dh_type      char {mustBeMember(args.Dh_type,{'constant'})} = 'constant'
    +      % Initial position [m,m,m,rad,rad,rad] of the top platform (Pitch-Roll-Yaw Euler angles)
    +      args.Dh_pos       (6,1) double {mustBeNumeric} = zeros(6, 1), ...
    +      % For now, only constant is implemented
    +      args.Rm_type      char {mustBeMember(args.Rm_type,{'constant'})} = 'constant'
    +      % Initial position of the two masses
    +      args.Rm_pos       (2,1) double {mustBeNumeric} = [0; pi]
    +      % For now, only constant is implemented
    +      args.Dn_type      char {mustBeMember(args.Dn_type,{'constant'})} = 'constant'
    +      % Initial position [m,m,m,rad,rad,rad] of the top platform
    +      args.Dn_pos       (6,1) double {mustBeNumeric} = zeros(6,1)
    +  end
     
    -
    -

    Initialize Parameters

    -
    +
    +

    Initialize Parameters

    +
    -
    %% Set Sampling Time
    -Ts = args.Ts;
    -Tmax = args.Tmax;
    +
      %% Set Sampling Time
    +  Ts = args.Ts;
    +  Tmax = args.Tmax;
     
    -%% Low Pass Filter to filter out the references
    -s = zpk('s');
    -w0 = 2*pi*10;
    -xi = 1;
    -H_lpf = 1/(1 + 2*xi/w0*s + s^2/w0^2);
    +  %% Low Pass Filter to filter out the references
    +  s = zpk('s');
    +  w0 = 2*pi*10;
    +  xi = 1;
    +  H_lpf = 1/(1 + 2*xi/w0*s + s^2/w0^2);
     
    -
    -

    Translation Stage

    -
    +
    +

    Translation Stage

    +
    -
    %% Translation stage - Dy
    -t = 0:Ts:Tmax; % Time Vector [s]
    -Dy   = zeros(length(t), 1);
    -Dyd  = zeros(length(t), 1);
    -Dydd = zeros(length(t), 1);
    -switch args.Dy_type
    -  case 'constant'
    -    Dy(:)   = args.Dy_amplitude;
    -    Dyd(:)  = 0;
    -    Dydd(:) = 0;
    -  case 'triangular'
    -    % This is done to unsure that we start with no displacement
    -    Dy_raw = args.Dy_amplitude*sawtooth(2*pi*t/args.Dy_period,1/2);
    -    i0 = find(t>=args.Dy_period/4,1);
    -    Dy(1:end-i0+1) = Dy_raw(i0:end);
    -    Dy(end-i0+2:end) = Dy_raw(end); % we fix the last value
    +
      %% Translation stage - Dy
    +  t = 0:Ts:Tmax; % Time Vector [s]
    +  Dy   = zeros(length(t), 1);
    +  Dyd  = zeros(length(t), 1);
    +  Dydd = zeros(length(t), 1);
    +  switch args.Dy_type
    +    case 'constant'
    +      Dy(:)   = args.Dy_amplitude;
    +      Dyd(:)  = 0;
    +      Dydd(:) = 0;
    +    case 'triangular'
    +      % This is done to unsure that we start with no displacement
    +      Dy_raw = args.Dy_amplitude*sawtooth(2*pi*t/args.Dy_period,1/2);
    +      i0 = find(t>=args.Dy_period/4,1);
    +      Dy(1:end-i0+1) = Dy_raw(i0:end);
    +      Dy(end-i0+2:end) = Dy_raw(end); % we fix the last value
     
    -    % The signal is filtered out
    -    Dy   = lsim(H_lpf,     Dy, t);
    -    Dyd  = lsim(H_lpf*s,   Dy, t);
    -    Dydd = lsim(H_lpf*s^2, Dy, t);
    -  case 'sinusoidal'
    -    Dy(:) = args.Dy_amplitude*sin(2*pi/args.Dy_period*t);
    -    Dyd   = args.Dy_amplitude*2*pi/args.Dy_period*cos(2*pi/args.Dy_period*t);
    -    Dydd  = -args.Dy_amplitude*(2*pi/args.Dy_period)^2*sin(2*pi/args.Dy_period*t);
    -  otherwise
    -    warning('Dy_type is not set correctly');
    -end
    +      % The signal is filtered out
    +      Dy   = lsim(H_lpf,     Dy, t);
    +      Dyd  = lsim(H_lpf*s,   Dy, t);
    +      Dydd = lsim(H_lpf*s^2, Dy, t);
    +    case 'sinusoidal'
    +      Dy(:) = args.Dy_amplitude*sin(2*pi/args.Dy_period*t);
    +      Dyd   = args.Dy_amplitude*2*pi/args.Dy_period*cos(2*pi/args.Dy_period*t);
    +      Dydd  = -args.Dy_amplitude*(2*pi/args.Dy_period)^2*sin(2*pi/args.Dy_period*t);
    +    otherwise
    +      warning('Dy_type is not set correctly');
    +  end
     
    -Dy = struct('time', t, 'signals', struct('values', Dy), 'deriv', Dyd, 'dderiv', Dydd);
    +  Dy = struct('time', t, 'signals', struct('values', Dy), 'deriv', Dyd, 'dderiv', Dydd);
     
    -
    -

    Tilt Stage

    -
    +
    +

    Tilt Stage

    +
    -
    %% Tilt Stage - Ry
    -t = 0:Ts:Tmax; % Time Vector [s]
    -Ry   = zeros(length(t), 1);
    -Ryd  = zeros(length(t), 1);
    -Rydd = zeros(length(t), 1);
    +
      %% Tilt Stage - Ry
    +  t = 0:Ts:Tmax; % Time Vector [s]
    +  Ry   = zeros(length(t), 1);
    +  Ryd  = zeros(length(t), 1);
    +  Rydd = zeros(length(t), 1);
     
    -switch args.Ry_type
    -  case 'constant'
    -    Ry(:) = args.Ry_amplitude;
    -    Ryd(:)   = 0;
    -    Rydd(:)  = 0;
    -  case 'triangular'
    -    Ry_raw = args.Ry_amplitude*sawtooth(2*pi*t/args.Ry_period,1/2);
    -    i0 = find(t>=args.Ry_period/4,1);
    -    Ry(1:end-i0+1) = Ry_raw(i0:end);
    -    Ry(end-i0+2:end) = Ry_raw(end); % we fix the last value
    +  switch args.Ry_type
    +    case 'constant'
    +      Ry(:) = args.Ry_amplitude;
    +      Ryd(:)   = 0;
    +      Rydd(:)  = 0;
    +    case 'triangular'
    +      Ry_raw = args.Ry_amplitude*sawtooth(2*pi*t/args.Ry_period,1/2);
    +      i0 = find(t>=args.Ry_period/4,1);
    +      Ry(1:end-i0+1) = Ry_raw(i0:end);
    +      Ry(end-i0+2:end) = Ry_raw(end); % we fix the last value
     
    -    % The signal is filtered out
    -    Ry   = lsim(H_lpf,     Ry, t);
    -    Ryd  = lsim(H_lpf*s,   Ry, t);
    -    Rydd = lsim(H_lpf*s^2, Ry, t);
    -  case 'sinusoidal'
    -    Ry(:) = args.Ry_amplitude*sin(2*pi/args.Ry_period*t);
    +      % The signal is filtered out
    +      Ry   = lsim(H_lpf,     Ry, t);
    +      Ryd  = lsim(H_lpf*s,   Ry, t);
    +      Rydd = lsim(H_lpf*s^2, Ry, t);
    +    case 'sinusoidal'
    +      Ry(:) = args.Ry_amplitude*sin(2*pi/args.Ry_period*t);
     
    -    Ryd  = args.Ry_amplitude*2*pi/args.Ry_period*cos(2*pi/args.Ry_period*t);
    -    Rydd = -args.Ry_amplitude*(2*pi/args.Ry_period)^2*sin(2*pi/args.Ry_period*t);
    -  otherwise
    -    warning('Ry_type is not set correctly');
    -end
    +      Ryd  = args.Ry_amplitude*2*pi/args.Ry_period*cos(2*pi/args.Ry_period*t);
    +      Rydd = -args.Ry_amplitude*(2*pi/args.Ry_period)^2*sin(2*pi/args.Ry_period*t);
    +    otherwise
    +      warning('Ry_type is not set correctly');
    +  end
     
    -Ry = struct('time', t, 'signals', struct('values', Ry), 'deriv', Ryd, 'dderiv', Rydd);
    +  Ry = struct('time', t, 'signals', struct('values', Ry), 'deriv', Ryd, 'dderiv', Rydd);
     
    -
    -

    Spindle

    -
    +
    +

    Spindle

    +
    -
    %% Spindle - Rz
    -t = 0:Ts:Tmax; % Time Vector [s]
    -Rz   = zeros(length(t), 1);
    -Rzd  = zeros(length(t), 1);
    -Rzdd = zeros(length(t), 1);
    +
      %% Spindle - Rz
    +  t = 0:Ts:Tmax; % Time Vector [s]
    +  Rz   = zeros(length(t), 1);
    +  Rzd  = zeros(length(t), 1);
    +  Rzdd = zeros(length(t), 1);
     
    -switch args.Rz_type
    -  case 'constant'
    -    Rz(:)   = args.Rz_amplitude;
    -    Rzd(:)  = 0;
    -    Rzdd(:) = 0;
    -  case 'rotating-not-filtered'
    -    Rz(:) = 2*pi/args.Rz_period*t;
    +  switch args.Rz_type
    +    case 'constant'
    +      Rz(:)   = args.Rz_amplitude;
    +      Rzd(:)  = 0;
    +      Rzdd(:) = 0;
    +    case 'rotating-not-filtered'
    +      Rz(:) = 2*pi/args.Rz_period*t;
     
    -    % The signal is filtered out
    -    Rz(:)   = 2*pi/args.Rz_period*t;
    -    Rzd(:)  = 2*pi/args.Rz_period;
    -    Rzdd(:) = 0;
    +      % The signal is filtered out
    +      Rz(:)   = 2*pi/args.Rz_period*t;
    +      Rzd(:)  = 2*pi/args.Rz_period;
    +      Rzdd(:) = 0;
     
    -    % We add the angle offset
    -    Rz = Rz + args.Rz_amplitude;
    +      % We add the angle offset
    +      Rz = Rz + args.Rz_amplitude;
     
    -  case 'rotating'
    -    Rz(:) = 2*pi/args.Rz_period*t;
    +    case 'rotating'
    +      Rz(:) = 2*pi/args.Rz_period*t;
     
    -    % The signal is filtered out
    -    Rz   = lsim(H_lpf,     Rz, t);
    -    Rzd  = lsim(H_lpf*s,   Rz, t);
    -    Rzdd = lsim(H_lpf*s^2, Rz, t);
    +      % The signal is filtered out
    +      Rz   = lsim(H_lpf,     Rz, t);
    +      Rzd  = lsim(H_lpf*s,   Rz, t);
    +      Rzdd = lsim(H_lpf*s^2, Rz, t);
     
    -    % We add the angle offset
    -    Rz = Rz + args.Rz_amplitude;
    -  otherwise
    -    warning('Rz_type is not set correctly');
    -end
    +      % We add the angle offset
    +      Rz = Rz + args.Rz_amplitude;
    +    otherwise
    +      warning('Rz_type is not set correctly');
    +  end
     
    -Rz = struct('time', t, 'signals', struct('values', Rz), 'deriv', Rzd, 'dderiv', Rzdd);
    +  Rz = struct('time', t, 'signals', struct('values', Rz), 'deriv', Rzd, 'dderiv', Rzdd);
     
    -
    -

    Micro Hexapod

    -
    +
    +

    Micro Hexapod

    +
    -
    %% Micro-Hexapod
    -t = [0, Ts];
    -Dh = zeros(length(t), 6);
    -Dhl = zeros(length(t), 6);
    +
      %% Micro-Hexapod
    +  t = [0, Ts];
    +  Dh = zeros(length(t), 6);
    +  Dhl = zeros(length(t), 6);
     
    -switch args.Dh_type
    -  case 'constant'
    -    Dh = [args.Dh_pos, args.Dh_pos];
    +  switch args.Dh_type
    +    case 'constant'
    +      Dh = [args.Dh_pos, args.Dh_pos];
     
    -    load('mat/stages.mat', 'micro_hexapod');
    +      load('mat/stages.mat', 'micro_hexapod');
     
    -    AP = [args.Dh_pos(1) ; args.Dh_pos(2) ; args.Dh_pos(3)];
    +      AP = [args.Dh_pos(1) ; args.Dh_pos(2) ; args.Dh_pos(3)];
     
    -    tx = args.Dh_pos(4);
    -    ty = args.Dh_pos(5);
    -    tz = args.Dh_pos(6);
    +      tx = args.Dh_pos(4);
    +      ty = args.Dh_pos(5);
    +      tz = args.Dh_pos(6);
     
    -    ARB = [cos(tz) -sin(tz) 0;
    -           sin(tz)  cos(tz) 0;
    -           0        0       1]*...
    -          [ cos(ty) 0 sin(ty);
    -            0       1 0;
    -           -sin(ty) 0 cos(ty)]*...
    -          [1 0        0;
    -           0 cos(tx) -sin(tx);
    -           0 sin(tx)  cos(tx)];
    +      ARB = [cos(tz) -sin(tz) 0;
    +             sin(tz)  cos(tz) 0;
    +             0        0       1]*...
    +            [ cos(ty) 0 sin(ty);
    +              0       1 0;
    +             -sin(ty) 0 cos(ty)]*...
    +            [1 0        0;
    +             0 cos(tx) -sin(tx);
    +             0 sin(tx)  cos(tx)];
     
    -    [~, Dhl] = inverseKinematics(micro_hexapod, 'AP', AP, 'ARB', ARB);
    -    Dhl = [Dhl, Dhl];
    -  otherwise
    -    warning('Dh_type is not set correctly');
    -end
    +      [~, Dhl] = inverseKinematics(micro_hexapod, 'AP', AP, 'ARB', ARB);
    +      Dhl = [Dhl, Dhl];
    +    otherwise
    +      warning('Dh_type is not set correctly');
    +  end
     
    -Dh = struct('time', t, 'signals', struct('values', Dh));
    -Dhl = struct('time', t, 'signals', struct('values', Dhl));
    +  Dh = struct('time', t, 'signals', struct('values', Dh));
    +  Dhl = struct('time', t, 'signals', struct('values', Dhl));
     
    -
    -

    Axis Compensation

    -
    +
    +

    Axis Compensation

    +
    -
    %% Axis Compensation - Rm
    -t = [0, Ts];
    +
      %% Axis Compensation - Rm
    +  t = [0, Ts];
     
    -Rm = [args.Rm_pos, args.Rm_pos];
    -Rm = struct('time', t, 'signals', struct('values', Rm));
    +  Rm = [args.Rm_pos, args.Rm_pos];
    +  Rm = struct('time', t, 'signals', struct('values', Rm));
     
    -
    -

    Nano Hexapod

    -
    +
    +

    Nano Hexapod

    +
    -
    %% Nano-Hexapod
    -t = [0, Ts];
    -Dn = zeros(length(t), 6);
    +
      %% Nano-Hexapod
    +  t = [0, Ts];
    +  Dn = zeros(length(t), 6);
     
    -switch args.Dn_type
    -  case 'constant'
    -    Dn = [args.Dn_pos, args.Dn_pos];
    +  switch args.Dn_type
    +    case 'constant'
    +      Dn = [args.Dn_pos, args.Dn_pos];
     
    -    load('mat/stages.mat', 'nano_hexapod');
    +      load('mat/stages.mat', 'nano_hexapod');
     
    -    AP = [args.Dn_pos(1) ; args.Dn_pos(2) ; args.Dn_pos(3)];
    +      AP = [args.Dn_pos(1) ; args.Dn_pos(2) ; args.Dn_pos(3)];
     
    -    tx = args.Dn_pos(4);
    -    ty = args.Dn_pos(5);
    -    tz = args.Dn_pos(6);
    +      tx = args.Dn_pos(4);
    +      ty = args.Dn_pos(5);
    +      tz = args.Dn_pos(6);
     
    -    ARB = [cos(tz) -sin(tz) 0;
    -           sin(tz)  cos(tz) 0;
    -           0        0       1]*...
    -          [ cos(ty) 0 sin(ty);
    -            0       1 0;
    -           -sin(ty) 0 cos(ty)]*...
    -          [1 0        0;
    -           0 cos(tx) -sin(tx);
    -           0 sin(tx)  cos(tx)];
    +      ARB = [cos(tz) -sin(tz) 0;
    +             sin(tz)  cos(tz) 0;
    +             0        0       1]*...
    +            [ cos(ty) 0 sin(ty);
    +              0       1 0;
    +             -sin(ty) 0 cos(ty)]*...
    +            [1 0        0;
    +             0 cos(tx) -sin(tx);
    +             0 sin(tx)  cos(tx)];
     
    -    [~, Dnl] = inverseKinematics(nano_hexapod, 'AP', AP, 'ARB', ARB);
    -    Dnl = [Dnl, Dnl];
    -  otherwise
    -    warning('Dn_type is not set correctly');
    -end
    +      [~, Dnl] = inverseKinematics(nano_hexapod, 'AP', AP, 'ARB', ARB);
    +      Dnl = [Dnl, Dnl];
    +    otherwise
    +      warning('Dn_type is not set correctly');
    +  end
     
    -Dn = struct('time', t, 'signals', struct('values', Dn));
    -Dnl = struct('time', t, 'signals', struct('values', Dnl));
    +  Dn = struct('time', t, 'signals', struct('values', Dn));
    +  Dnl = struct('time', t, 'signals', struct('values', Dnl));
     
    -
    -

    Save

    -
    +
    +

    Save

    +
    -
        %% Save
    -    save('./mat/nass_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'Rm', 'Dn', 'Dnl', 'args', 'Ts');
    -end
    +
          %% Save
    +      save('./mat/nass_references.mat', 'Dy', 'Ry', 'Rz', 'Dh', 'Dhl', 'Rm', 'Dn', 'Dnl', 'args', 'Ts');
    +  end
     
    -
    -

    15 Initialize Disturbances

    +
    +

    15 Initialize Disturbances

    - +

    -
    -

    Function Declaration and Documentation

    -
    +
    +

    Function Declaration and Documentation

    +
    -
    function [] = initializeDisturbances(args)
    -% initializeDisturbances - Initialize the disturbances
    -%
    -% Syntax: [] = initializeDisturbances(args)
    -%
    -% Inputs:
    -%    - args -
    +
      function [] = initializeDisturbances(args)
    +  % initializeDisturbances - Initialize the disturbances
    +  %
    +  % Syntax: [] = initializeDisturbances(args)
    +  %
    +  % Inputs:
    +  %    - args -
     
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    % Global parameter to enable or disable the disturbances
    -    args.enable logical {mustBeNumericOrLogical} = true
    -    % Ground Motion - X direction
    -    args.Dwx logical {mustBeNumericOrLogical} = true
    -    % Ground Motion - Y direction
    -    args.Dwy logical {mustBeNumericOrLogical} = true
    -    % Ground Motion - Z direction
    -    args.Dwz logical {mustBeNumericOrLogical} = true
    -    % Translation Stage - X direction
    -    args.Fty_x logical {mustBeNumericOrLogical} = true
    -    % Translation Stage - Z direction
    -    args.Fty_z logical {mustBeNumericOrLogical} = true
    -    % Spindle - Z direction
    -    args.Frz_z logical {mustBeNumericOrLogical} = true
    -end
    +
      arguments
    +      % Global parameter to enable or disable the disturbances
    +      args.enable logical {mustBeNumericOrLogical} = true
    +      % Ground Motion - X direction
    +      args.Dwx logical {mustBeNumericOrLogical} = true
    +      % Ground Motion - Y direction
    +      args.Dwy logical {mustBeNumericOrLogical} = true
    +      % Ground Motion - Z direction
    +      args.Dwz logical {mustBeNumericOrLogical} = true
    +      % Translation Stage - X direction
    +      args.Fty_x logical {mustBeNumericOrLogical} = true
    +      % Translation Stage - Z direction
    +      args.Fty_z logical {mustBeNumericOrLogical} = true
    +      % Spindle - Z direction
    +      args.Frz_z logical {mustBeNumericOrLogical} = true
    +  end
     
    -
    -

    Load Data

    -
    +
    +

    Load Data

    +
    -
    load('./mat/dist_psd.mat', 'dist_f');
    +
      load('./mat/dist_psd.mat', 'dist_f');
     
    @@ -2630,337 +2626,337 @@ We remove the first frequency point that usually is very large.

    -
    -

    Parameters

    -
    +
    +

    Parameters

    +

    We define some parameters that will be used in the algorithm.

    -
    Fs = 2*dist_f.f(end);      % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz]
    -N  = 2*length(dist_f.f);   % Number of Samples match the one of the wanted PSD
    -T0 = N/Fs;                 % Signal Duration [s]
    -df = 1/T0;                 % Frequency resolution of the DFT [Hz]
    -                           % Also equal to (dist_f.f(2)-dist_f.f(1))
    -t = linspace(0, T0, N+1)'; % Time Vector [s]
    -Ts = 1/Fs;                 % Sampling Time [s]
    +
      Fs = 2*dist_f.f(end);      % Sampling Frequency of data is twice the maximum frequency of the PSD vector [Hz]
    +  N  = 2*length(dist_f.f);   % Number of Samples match the one of the wanted PSD
    +  T0 = N/Fs;                 % Signal Duration [s]
    +  df = 1/T0;                 % Frequency resolution of the DFT [Hz]
    +                             % Also equal to (dist_f.f(2)-dist_f.f(1))
    +  t = linspace(0, T0, N+1)'; % Time Vector [s]
    +  Ts = 1/Fs;                 % Sampling Time [s]
     
    -
    -

    Ground Motion

    -
    +
    +

    Ground Motion

    +
    -
    phi = dist_f.psd_gm;
    -C = zeros(N/2,1);
    -for i = 1:N/2
    -  C(i) = sqrt(phi(i)*df);
    -end
    -
    -
    - -
    -
    if args.Dwx && args.enable
    -  rng(111);
    -  theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
    -  Cx = [0 ; C.*complex(cos(theta),sin(theta))];
    -  Cx = [Cx; flipud(conj(Cx(2:end)))];;
    -  Dwx = N/sqrt(2)*ifft(Cx); % Ground Motion - x direction [m]
    -else
    -  Dwx = zeros(length(t), 1);
    -end
    -
    -
    - -
    -
    if args.Dwy && args.enable
    -  rng(112);
    -  theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
    -  Cx = [0 ; C.*complex(cos(theta),sin(theta))];
    -  Cx = [Cx; flipud(conj(Cx(2:end)))];;
    -  Dwy = N/sqrt(2)*ifft(Cx); % Ground Motion - y direction [m]
    -else
    -  Dwy = zeros(length(t), 1);
    -end
    -
    -
    - -
    -
    if args.Dwy && args.enable
    -  rng(113);
    -  theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
    -  Cx = [0 ; C.*complex(cos(theta),sin(theta))];
    -  Cx = [Cx; flipud(conj(Cx(2:end)))];;
    -  Dwz = N/sqrt(2)*ifft(Cx); % Ground Motion - z direction [m]
    -else
    -  Dwz = zeros(length(t), 1);
    -end
    -
    -
    -
    -
    - -
    -

    Translation Stage - X direction

    -
    -
    -
    if args.Fty_x && args.enable
    -  phi = dist_f.psd_ty; % TODO - we take here the vertical direction which is wrong but approximate
    +
      phi = dist_f.psd_gm;
       C = zeros(N/2,1);
       for i = 1:N/2
         C(i) = sqrt(phi(i)*df);
       end
    -  rng(121);
    -  theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
    -  Cx = [0 ; C.*complex(cos(theta),sin(theta))];
    -  Cx = [Cx; flipud(conj(Cx(2:end)))];;
    -  u = N/sqrt(2)*ifft(Cx); % Disturbance Force Ty x [N]
    -  Fty_x = u;
    -else
    -  Fty_x = zeros(length(t), 1);
    -end
     
    -
    -
    -
    -

    Translation Stage - Z direction

    -
    -
    if args.Fty_z && args.enable
    -  phi = dist_f.psd_ty;
    -  C = zeros(N/2,1);
    -  for i = 1:N/2
    -    C(i) = sqrt(phi(i)*df);
    +
      if args.Dwx && args.enable
    +    rng(111);
    +    theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
    +    Cx = [0 ; C.*complex(cos(theta),sin(theta))];
    +    Cx = [Cx; flipud(conj(Cx(2:end)))];;
    +    Dwx = N/sqrt(2)*ifft(Cx); % Ground Motion - x direction [m]
    +  else
    +    Dwx = zeros(length(t), 1);
       end
    -  rng(122);
    -  theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
    -  Cx = [0 ; C.*complex(cos(theta),sin(theta))];
    -  Cx = [Cx; flipud(conj(Cx(2:end)))];;
    -  u = N/sqrt(2)*ifft(Cx); % Disturbance Force Ty z [N]
    -  Fty_z = u;
    -else
    -  Fty_z = zeros(length(t), 1);
    -end
     
    -
    -
    -
    -

    Spindle - Z direction

    -
    -
    if args.Frz_z && args.enable
    -  phi = dist_f.psd_rz;
    -  C = zeros(N/2,1);
    -  for i = 1:N/2
    -    C(i) = sqrt(phi(i)*df);
    +
      if args.Dwy && args.enable
    +    rng(112);
    +    theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
    +    Cx = [0 ; C.*complex(cos(theta),sin(theta))];
    +    Cx = [Cx; flipud(conj(Cx(2:end)))];;
    +    Dwy = N/sqrt(2)*ifft(Cx); % Ground Motion - y direction [m]
    +  else
    +    Dwy = zeros(length(t), 1);
       end
    -  rng(131);
    -  theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
    -  Cx = [0 ; C.*complex(cos(theta),sin(theta))];
    -  Cx = [Cx; flipud(conj(Cx(2:end)))];;
    -  u = N/sqrt(2)*ifft(Cx); % Disturbance Force Rz z [N]
    -  Frz_z = u;
    -else
    -  Frz_z = zeros(length(t), 1);
    -end
     
    -
    -
    -
    -

    Direct Forces

    -
    -
    u = zeros(length(t), 6);
    -Fd = u;
    +
      if args.Dwy && args.enable
    +    rng(113);
    +    theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
    +    Cx = [0 ; C.*complex(cos(theta),sin(theta))];
    +    Cx = [Cx; flipud(conj(Cx(2:end)))];;
    +    Dwz = N/sqrt(2)*ifft(Cx); % Ground Motion - z direction [m]
    +  else
    +    Dwz = zeros(length(t), 1);
    +  end
     
    -
    -

    Set initial value to zero

    -
    +
    +

    Translation Stage - X direction

    +
    -
    Dwx    = Dwx   - Dwx(1);
    -Dwy    = Dwy   - Dwy(1);
    -Dwz    = Dwz   - Dwz(1);
    -Fty_x  = Fty_x - Fty_x(1);
    -Fty_z  = Fty_z - Fty_z(1);
    -Frz_z  = Frz_z - Frz_z(1);
    +
      if args.Fty_x && args.enable
    +    phi = dist_f.psd_ty; % TODO - we take here the vertical direction which is wrong but approximate
    +    C = zeros(N/2,1);
    +    for i = 1:N/2
    +      C(i) = sqrt(phi(i)*df);
    +    end
    +    rng(121);
    +    theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
    +    Cx = [0 ; C.*complex(cos(theta),sin(theta))];
    +    Cx = [Cx; flipud(conj(Cx(2:end)))];;
    +    u = N/sqrt(2)*ifft(Cx); % Disturbance Force Ty x [N]
    +    Fty_x = u;
    +  else
    +    Fty_x = zeros(length(t), 1);
    +  end
     
    -
    -

    Save

    -
    +
    +

    Translation Stage - Z direction

    +
    -
    save('./mat/nass_disturbances.mat', 'Dwx', 'Dwy', 'Dwz', 'Fty_x', 'Fty_z', 'Frz_z', 'Fd', 'Ts', 't', 'args');
    +
      if args.Fty_z && args.enable
    +    phi = dist_f.psd_ty;
    +    C = zeros(N/2,1);
    +    for i = 1:N/2
    +      C(i) = sqrt(phi(i)*df);
    +    end
    +    rng(122);
    +    theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
    +    Cx = [0 ; C.*complex(cos(theta),sin(theta))];
    +    Cx = [Cx; flipud(conj(Cx(2:end)))];;
    +    u = N/sqrt(2)*ifft(Cx); % Disturbance Force Ty z [N]
    +    Fty_z = u;
    +  else
    +    Fty_z = zeros(length(t), 1);
    +  end
    +
    +
    +
    +
    + +
    +

    Spindle - Z direction

    +
    +
    +
      if args.Frz_z && args.enable
    +    phi = dist_f.psd_rz;
    +    C = zeros(N/2,1);
    +    for i = 1:N/2
    +      C(i) = sqrt(phi(i)*df);
    +    end
    +    rng(131);
    +    theta = 2*pi*rand(N/2,1); % Generate random phase [rad]
    +    Cx = [0 ; C.*complex(cos(theta),sin(theta))];
    +    Cx = [Cx; flipud(conj(Cx(2:end)))];;
    +    u = N/sqrt(2)*ifft(Cx); % Disturbance Force Rz z [N]
    +    Frz_z = u;
    +  else
    +    Frz_z = zeros(length(t), 1);
    +  end
    +
    +
    +
    +
    + +
    +

    Direct Forces

    +
    +
    +
      u = zeros(length(t), 6);
    +  Fd = u;
    +
    +
    +
    +
    + +
    +

    Set initial value to zero

    +
    +
    +
      Dwx    = Dwx   - Dwx(1);
    +  Dwy    = Dwy   - Dwy(1);
    +  Dwz    = Dwz   - Dwz(1);
    +  Fty_x  = Fty_x - Fty_x(1);
    +  Fty_z  = Fty_z - Fty_z(1);
    +  Frz_z  = Frz_z - Frz_z(1);
    +
    +
    +
    +
    + +
    +

    Save

    +
    +
    +
      save('./mat/nass_disturbances.mat', 'Dwx', 'Dwy', 'Dwz', 'Fty_x', 'Fty_z', 'Frz_z', 'Fd', 'Ts', 't', 'args');
     
    -
    -

    16 Initialize Position Errors

    +
    +

    16 Initialize Position Errors

    - +

    -
    -

    Function Declaration and Documentation

    -
    +
    +

    Function Declaration and Documentation

    +
    -
    function [] = initializePosError(args)
    -% initializePosError - Initialize the position errors
    -%
    -% Syntax: [] = initializePosError(args)
    -%
    -% Inputs:
    -%    - args -
    +
      function [] = initializePosError(args)
    +  % initializePosError - Initialize the position errors
    +  %
    +  % Syntax: [] = initializePosError(args)
    +  %
    +  % Inputs:
    +  %    - args -
     
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    args.error    logical {mustBeNumericOrLogical} = false
    -    args.Dy (1,1) double  {mustBeNumeric} = 0 % [m]
    -    args.Ry (1,1) double  {mustBeNumeric} = 0 % [m]
    -    args.Rz (1,1) double  {mustBeNumeric} = 0 % [m]
    -end
    +
      arguments
    +      args.error    logical {mustBeNumericOrLogical} = false
    +      args.Dy (1,1) double  {mustBeNumeric} = 0 % [m]
    +      args.Ry (1,1) double  {mustBeNumeric} = 0 % [m]
    +      args.Rz (1,1) double  {mustBeNumeric} = 0 % [m]
    +  end
     
    -
    -

    Structure initialization

    -
    +
    +

    Structure initialization

    +

    First, we initialize the pos_error structure.

    -
    pos_error = struct();
    +
      pos_error = struct();
     
    -
    -

    Type

    -
    +
    +

    Type

    +
    -
    if args.error
    -  pos_error.type = 1;
    -else
    -  pos_error.type = 0;
    -end
    +
      if args.error
    +    pos_error.type = 1;
    +  else
    +    pos_error.type = 0;
    +  end
     
    -
    -

    Position Errors

    -
    +
    +

    Position Errors

    +
    -
    pos_error.Dy = args.Dy;
    -pos_error.Ry = args.Ry;
    -pos_error.Rz = args.Rz;
    +
      pos_error.Dy = args.Dy;
    +  pos_error.Ry = args.Ry;
    +  pos_error.Rz = args.Rz;
     
    -
    -

    Save

    -
    +
    +

    Save

    +
    -
    save('./mat/pos_error.mat', 'pos_error');
    +
      save('./mat/pos_error.mat', 'pos_error');
     
    -
    -

    17 Z-Axis Geophone

    +
    +

    17 Z-Axis Geophone

    - +

    -
    function [geophone] = initializeZAxisGeophone(args)
    -    arguments
    -        args.mass (1,1) double {mustBeNumeric, mustBePositive} = 1e-3 % [kg]
    -        args.freq (1,1) double {mustBeNumeric, mustBePositive} = 1    % [Hz]
    -    end
    +
      function [geophone] = initializeZAxisGeophone(args)
    +      arguments
    +          args.mass (1,1) double {mustBeNumeric, mustBePositive} = 1e-3 % [kg]
    +          args.freq (1,1) double {mustBeNumeric, mustBePositive} = 1    % [Hz]
    +      end
     
    -    %%
    -    geophone.m = args.mass;
    +      %%
    +      geophone.m = args.mass;
     
    -    %% The Stiffness is set to have the damping resonance frequency
    -    geophone.k = geophone.m * (2*pi*args.freq)^2;
    +      %% The Stiffness is set to have the damping resonance frequency
    +      geophone.k = geophone.m * (2*pi*args.freq)^2;
     
    -    %% We set the damping value to have critical damping
    -    geophone.c = 2*sqrt(geophone.m * geophone.k);
    +      %% We set the damping value to have critical damping
    +      geophone.c = 2*sqrt(geophone.m * geophone.k);
     
    -    %% Save
    -    save('./mat/geophone_z_axis.mat', 'geophone');
    -end
    +      %% Save
    +      save('./mat/geophone_z_axis.mat', 'geophone');
    +  end
     
    -
    -

    18 Z-Axis Accelerometer

    +
    +

    18 Z-Axis Accelerometer

    - +

    -
    function [accelerometer] = initializeZAxisAccelerometer(args)
    -    arguments
    -        args.mass (1,1) double {mustBeNumeric, mustBePositive} = 1e-3 % [kg]
    -        args.freq (1,1) double {mustBeNumeric, mustBePositive} = 5e3  % [Hz]
    -    end
    +
      function [accelerometer] = initializeZAxisAccelerometer(args)
    +      arguments
    +          args.mass (1,1) double {mustBeNumeric, mustBePositive} = 1e-3 % [kg]
    +          args.freq (1,1) double {mustBeNumeric, mustBePositive} = 5e3  % [Hz]
    +      end
     
    -    %%
    -    accelerometer.m = args.mass;
    +      %%
    +      accelerometer.m = args.mass;
     
    -    %% The Stiffness is set to have the damping resonance frequency
    -    accelerometer.k = accelerometer.m * (2*pi*args.freq)^2;
    +      %% The Stiffness is set to have the damping resonance frequency
    +      accelerometer.k = accelerometer.m * (2*pi*args.freq)^2;
     
    -    %% We set the damping value to have critical damping
    -    accelerometer.c = 2*sqrt(accelerometer.m * accelerometer.k);
    +      %% We set the damping value to have critical damping
    +      accelerometer.c = 2*sqrt(accelerometer.m * accelerometer.k);
     
    -    %% Gain correction of the accelerometer to have a unity gain until the resonance
    -    accelerometer.gain = -accelerometer.k/accelerometer.m;
    +      %% Gain correction of the accelerometer to have a unity gain until the resonance
    +      accelerometer.gain = -accelerometer.k/accelerometer.m;
     
    -    %% Save
    -    save('./mat/accelerometer_z_axis.mat', 'accelerometer');
    -end
    +      %% Save
    +      save('./mat/accelerometer_z_axis.mat', 'accelerometer');
    +  end
     
    @@ -2968,7 +2964,7 @@ pos_error.Rz = args.Rz;

    Author: Dehaeze Thomas

    -

    Created: 2020-11-03 mar. 09:45

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/simulink_project.html b/docs/simulink_project.html index 7d38d87..fb5e6d8 100644 --- a/docs/simulink_project.html +++ b/docs/simulink_project.html @@ -1,26 +1,21 @@ - - + Simulink Project for the NASS - - - - - - + +

    Simulink Project for the NASS

    @@ -50,7 +45,7 @@ The project can be opened using the simulinkproject function:

    -
    simulinkproject('./');
    +
      simulinkproject('./');
     
    @@ -59,19 +54,19 @@ When the project opens, a startup script is ran. The startup script is defined below and is exported to the project_startup.m script.

    -
    project = simulinkproject;
    -projectRoot = project.RootFolder;
    +
      project = simulinkproject;
    +  projectRoot = project.RootFolder;
     
    -myCacheFolder = fullfile(projectRoot, '.SimulinkCache');
    -myCodeFolder = fullfile(projectRoot, '.SimulinkCode');
    +  myCacheFolder = fullfile(projectRoot, '.SimulinkCache');
    +  myCodeFolder = fullfile(projectRoot, '.SimulinkCode');
     
    -Simulink.fileGenControl('set',...
    -    'CacheFolder', myCacheFolder,...
    -    'CodeGenFolder', myCodeFolder,...
    -    'createDir', true);
    +  Simulink.fileGenControl('set',...
    +      'CacheFolder', myCacheFolder,...
    +      'CodeGenFolder', myCodeFolder,...
    +      'createDir', true);
     
    -%% Load the Simscape Configuration
    -load('mat/conf_simulink.mat');
    +  %% Load the Simscape Configuration
    +  load('mat/conf_simulink.mat');
     
    @@ -79,7 +74,7 @@ load('mat/conf_simulink.mat'); When the project closes, it runs the project_shutdown.m script defined below.

    -
    Simulink.fileGenControl('reset');
    +
      Simulink.fileGenControl('reset');
     
    @@ -89,7 +84,7 @@ The project also permits to automatically add defined folder to the path when th

    Author: Dehaeze Thomas

    -

    Created: 2020-04-17 ven. 09:36

    +

    Created: 2021-02-20 sam. 23:09

    diff --git a/docs/stewart_platform.html b/docs/stewart_platform.html index 9faff69..21ed6ce 100644 --- a/docs/stewart_platform.html +++ b/docs/stewart_platform.html @@ -3,184 +3,189 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Stewart Platform - Simscape Model - - - - - - - - + + + +

    Stewart Platform - Simscape Model

    Table of Contents

    @@ -253,11 +258,11 @@ For Simscape, we need:
  • The position of the frame \(\{B\}\) with respect to the frame \(\{M\}\): \({}^{M}\bm{O}_{B}\)
  • -
    -

    1 initializeStewartPlatform: Initialize the Stewart Platform structure

    +
    +

    1 initializeStewartPlatform: Initialize the Stewart Platform structure

    - +

    @@ -265,11 +270,11 @@ This Matlab function is accessible

    -
    -

    Documentation

    -
    +
    +

    Documentation

    +
    - -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [stewart] = initializeStewartPlatform()
    -% initializeStewartPlatform - Initialize the stewart structure
    -%
    -% Syntax: [stewart] = initializeStewartPlatform(args)
    -%
    -% Outputs:
    -%    - stewart - A structure with the following sub-structures:
    -%      - platform_F -
    -%      - platform_M -
    -%      - joints_F   -
    -%      - joints_M   -
    -%      - struts_F   -
    -%      - struts_M   -
    -%      - actuators  -
    -%      - geometry   -
    -%      - properties -
    +
      function [stewart] = initializeStewartPlatform()
    +  % initializeStewartPlatform - Initialize the stewart structure
    +  %
    +  % Syntax: [stewart] = initializeStewartPlatform(args)
    +  %
    +  % Outputs:
    +  %    - stewart - A structure with the following sub-structures:
    +  %      - platform_F -
    +  %      - platform_M -
    +  %      - joints_F   -
    +  %      - joints_M   -
    +  %      - struts_F   -
    +  %      - struts_M   -
    +  %      - actuators  -
    +  %      - geometry   -
    +  %      - properties -
     
    -
    -

    Initialize the Stewart structure

    -
    +
    +

    Initialize the Stewart structure

    +
    -
    stewart = struct();
    -stewart.platform_F = struct();
    -stewart.platform_M = struct();
    -stewart.joints_F   = struct();
    -stewart.joints_M   = struct();
    -stewart.struts_F   = struct();
    -stewart.struts_M   = struct();
    -stewart.actuators  = struct();
    -stewart.sensors    = struct();
    -stewart.sensors.inertial = struct();
    -stewart.sensors.force    = struct();
    -stewart.sensors.relative = struct();
    -stewart.geometry   = struct();
    -stewart.kinematics = struct();
    +
      stewart = struct();
    +  stewart.platform_F = struct();
    +  stewart.platform_M = struct();
    +  stewart.joints_F   = struct();
    +  stewart.joints_M   = struct();
    +  stewart.struts_F   = struct();
    +  stewart.struts_M   = struct();
    +  stewart.actuators  = struct();
    +  stewart.sensors    = struct();
    +  stewart.sensors.inertial = struct();
    +  stewart.sensors.force    = struct();
    +  stewart.sensors.relative = struct();
    +  stewart.geometry   = struct();
    +  stewart.kinematics = struct();
     
    -
    -

    2 initializeFramesPositions: Initialize the positions of frames {A}, {B}, {F} and {M}

    +
    +

    2 initializeFramesPositions: Initialize the positions of frames {A}, {B}, {F} and {M}

    - +

    @@ -338,11 +343,11 @@ This Matlab function is accessible

    -
    -

    Documentation

    -
    +
    +

    Documentation

    +
    - -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [stewart] = initializeFramesPositions(stewart, args)
    -% initializeFramesPositions - Initialize the positions of frames {A}, {B}, {F} and {M}
    -%
    -% Syntax: [stewart] = initializeFramesPositions(stewart, args)
    -%
    -% Inputs:
    -%    - args - Can have the following fields:
    -%        - H    [1x1] - Total Height of the Stewart Platform (height from {F} to {M}) [m]
    -%        - MO_B [1x1] - Height of the frame {B} with respect to {M} [m]
    -%
    -% Outputs:
    -%    - stewart - A structure with the following fields:
    -%        - geometry.H      [1x1] - Total Height of the Stewart Platform [m]
    -%        - geometry.FO_M   [3x1] - Position of {M} with respect to {F} [m]
    -%        - platform_M.MO_B [3x1] - Position of {B} with respect to {M} [m]
    -%        - platform_F.FO_A [3x1] - Position of {A} with respect to {F} [m]
    +
      function [stewart] = initializeFramesPositions(stewart, args)
    +  % initializeFramesPositions - Initialize the positions of frames {A}, {B}, {F} and {M}
    +  %
    +  % Syntax: [stewart] = initializeFramesPositions(stewart, args)
    +  %
    +  % Inputs:
    +  %    - args - Can have the following fields:
    +  %        - H    [1x1] - Total Height of the Stewart Platform (height from {F} to {M}) [m]
    +  %        - MO_B [1x1] - Height of the frame {B} with respect to {M} [m]
    +  %
    +  % Outputs:
    +  %    - stewart - A structure with the following fields:
    +  %        - geometry.H      [1x1] - Total Height of the Stewart Platform [m]
    +  %        - geometry.FO_M   [3x1] - Position of {M} with respect to {F} [m]
    +  %        - platform_M.MO_B [3x1] - Position of {B} with respect to {M} [m]
    +  %        - platform_F.FO_A [3x1] - Position of {A} with respect to {F} [m]
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    stewart
    -    args.H    (1,1) double {mustBeNumeric, mustBePositive} = 90e-3
    -    args.MO_B (1,1) double {mustBeNumeric} = 50e-3
    -end
    +
      arguments
    +      stewart
    +      args.H    (1,1) double {mustBeNumeric, mustBePositive} = 90e-3
    +      args.MO_B (1,1) double {mustBeNumeric} = 50e-3
    +  end
     
    -
    -

    Compute the position of each frame

    -
    +
    +

    Compute the position of each frame

    +
    -
    H = args.H; % Total Height of the Stewart Platform [m]
    +
      H = args.H; % Total Height of the Stewart Platform [m]
     
    -FO_M = [0; 0; H]; % Position of {M} with respect to {F} [m]
    +  FO_M = [0; 0; H]; % Position of {M} with respect to {F} [m]
     
    -MO_B = [0; 0; args.MO_B]; % Position of {B} with respect to {M} [m]
    +  MO_B = [0; 0; args.MO_B]; % Position of {B} with respect to {M} [m]
     
    -FO_A = MO_B + FO_M; % Position of {A} with respect to {F} [m]
    +  FO_A = MO_B + FO_M; % Position of {A} with respect to {F} [m]
     
    -
    -

    Populate the stewart structure

    -
    +
    +

    Populate the stewart structure

    +
    -
    stewart.geometry.H      = H;
    -stewart.geometry.FO_M   = FO_M;
    -stewart.platform_M.MO_B = MO_B;
    -stewart.platform_F.FO_A = FO_A;
    +
      stewart.geometry.H      = H;
    +  stewart.geometry.FO_M   = FO_M;
    +  stewart.platform_M.MO_B = MO_B;
    +  stewart.platform_F.FO_A = FO_A;
     
    -
    -

    3 generateGeneralConfiguration: Generate a Very General Configuration

    +
    +

    3 generateGeneralConfiguration: Generate a Very General Configuration

    - +

    @@ -431,16 +436,16 @@ This Matlab function is accessible -

    Documentation

    -
    +
    +

    Documentation

    +

    Joints are positions on a circle centered with the Z axis of {F} and {M} and at a chosen distance from {F} and {M}. -The radius of the circles can be chosen as well as the angles where the joints are located (see Figure 3). +The radius of the circles can be chosen as well as the angles where the joints are located (see Figure 3).

    -
    +

    stewart_bottom_plate.png

    Figure 3: Position of the joints

    @@ -448,87 +453,87 @@ The radius of the circles can be chosen as well as the angles where the joints a
    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [stewart] = generateGeneralConfiguration(stewart, args)
    -% generateGeneralConfiguration - Generate a Very General Configuration
    -%
    -% Syntax: [stewart] = generateGeneralConfiguration(stewart, args)
    -%
    -% Inputs:
    -%    - args - Can have the following fields:
    -%        - FH  [1x1] - Height of the position of the fixed joints with respect to the frame {F} [m]
    -%        - FR  [1x1] - Radius of the position of the fixed joints in the X-Y [m]
    -%        - FTh [6x1] - Angles of the fixed joints in the X-Y plane with respect to the X axis [rad]
    -%        - MH  [1x1] - Height of the position of the mobile joints with respect to the frame {M} [m]
    -%        - FR  [1x1] - Radius of the position of the mobile joints in the X-Y [m]
    -%        - MTh [6x1] - Angles of the mobile joints in the X-Y plane with respect to the X axis [rad]
    -%
    -% 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] = generateGeneralConfiguration(stewart, args)
    +  % generateGeneralConfiguration - Generate a Very General Configuration
    +  %
    +  % Syntax: [stewart] = generateGeneralConfiguration(stewart, args)
    +  %
    +  % Inputs:
    +  %    - args - Can have the following fields:
    +  %        - FH  [1x1] - Height of the position of the fixed joints with respect to the frame {F} [m]
    +  %        - FR  [1x1] - Radius of the position of the fixed joints in the X-Y [m]
    +  %        - FTh [6x1] - Angles of the fixed joints in the X-Y plane with respect to the X axis [rad]
    +  %        - MH  [1x1] - Height of the position of the mobile joints with respect to the frame {M} [m]
    +  %        - FR  [1x1] - Radius of the position of the mobile joints in the X-Y [m]
    +  %        - MTh [6x1] - Angles of the mobile joints in the X-Y plane with respect to the X axis [rad]
    +  %
    +  % 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}
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    stewart
    -    args.FH  (1,1) double {mustBeNumeric, mustBePositive} = 15e-3
    -    args.FR  (1,1) double {mustBeNumeric, mustBePositive} = 115e-3;
    -    args.FTh (6,1) double {mustBeNumeric} = [-10, 10, 120-10, 120+10, 240-10, 240+10]*(pi/180);
    -    args.MH  (1,1) double {mustBeNumeric, mustBePositive} = 15e-3
    -    args.MR  (1,1) double {mustBeNumeric, mustBePositive} = 90e-3;
    -    args.MTh (6,1) double {mustBeNumeric} = [-60+10, 60-10, 60+10, 180-10, 180+10, -60-10]*(pi/180);
    -end
    +
      arguments
    +      stewart
    +      args.FH  (1,1) double {mustBeNumeric, mustBePositive} = 15e-3
    +      args.FR  (1,1) double {mustBeNumeric, mustBePositive} = 115e-3;
    +      args.FTh (6,1) double {mustBeNumeric} = [-10, 10, 120-10, 120+10, 240-10, 240+10]*(pi/180);
    +      args.MH  (1,1) double {mustBeNumeric, mustBePositive} = 15e-3
    +      args.MR  (1,1) double {mustBeNumeric, mustBePositive} = 90e-3;
    +      args.MTh (6,1) double {mustBeNumeric} = [-60+10, 60-10, 60+10, 180-10, 180+10, -60-10]*(pi/180);
    +  end
     
    -
    -

    Compute the pose

    -
    +
    +

    Compute the pose

    +
    -
    Fa = zeros(3,6);
    -Mb = zeros(3,6);
    +
      Fa = zeros(3,6);
    +  Mb = zeros(3,6);
     
    -
    for i = 1:6
    -  Fa(:,i) = [args.FR*cos(args.FTh(i)); args.FR*sin(args.FTh(i));  args.FH];
    -  Mb(:,i) = [args.MR*cos(args.MTh(i)); args.MR*sin(args.MTh(i)); -args.MH];
    -end
    +
      for i = 1:6
    +    Fa(:,i) = [args.FR*cos(args.FTh(i)); args.FR*sin(args.FTh(i));  args.FH];
    +    Mb(:,i) = [args.MR*cos(args.MTh(i)); args.MR*sin(args.MTh(i)); -args.MH];
    +  end
     
    -
    -

    Populate the stewart structure

    -
    +
    +

    Populate the stewart structure

    +
    -
    stewart.platform_F.Fa = Fa;
    -stewart.platform_M.Mb = Mb;
    +
      stewart.platform_F.Fa = Fa;
    +  stewart.platform_M.Mb = Mb;
     
    -
    -

    4 computeJointsPose: Compute the Pose of the Joints

    +
    +

    4 computeJointsPose: Compute the Pose of the Joints

    - +

    @@ -536,11 +541,11 @@ This Matlab function is accessible here

    -
    -

    Documentation

    -
    +
    +

    Documentation

    +
    -
    +

    stewart-struts.png

    Figure 4: Position and orientation of the struts

    @@ -548,142 +553,142 @@ This Matlab function is accessible here
    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [stewart] = computeJointsPose(stewart)
    -% computeJointsPose -
    -%
    -% Syntax: [stewart] = computeJointsPose(stewart)
    -%
    -% Inputs:
    -%    - stewart - A structure with the following 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}
    -%        - platform_F.FO_A [3x1] - Position of {A} with respect to {F}
    -%        - platform_M.MO_B [3x1] - Position of {B} with respect to {M}
    -%        - geometry.FO_M   [3x1] - Position of {M} with respect to {F}
    -%
    -% Outputs:
    -%    - stewart - A structure with the following added fields
    -%        - geometry.Aa    [3x6]   - The i'th column is the position of ai with respect to {A}
    -%        - geometry.Ab    [3x6]   - The i'th column is the position of bi with respect to {A}
    -%        - geometry.Ba    [3x6]   - The i'th column is the position of ai with respect to {B}
    -%        - geometry.Bb    [3x6]   - The i'th column is the position of bi with respect to {B}
    -%        - geometry.l     [6x1]   - The i'th element is the initial length of strut i
    -%        - geometry.As    [3x6]   - The i'th column is the unit vector of strut i expressed in {A}
    -%        - geometry.Bs    [3x6]   - The i'th column is the unit vector of strut i expressed in {B}
    -%        - struts_F.l     [6x1]   - Length of the Fixed part of the i'th strut
    -%        - struts_M.l     [6x1]   - Length of the Mobile part of the i'th strut
    -%        - platform_F.FRa [3x3x6] - The i'th 3x3 array is the rotation matrix to orientate the bottom of the i'th strut from {F}
    -%        - platform_M.MRb [3x3x6] - The i'th 3x3 array is the rotation matrix to orientate the top of the i'th strut from {M}
    +
      function [stewart] = computeJointsPose(stewart)
    +  % computeJointsPose -
    +  %
    +  % Syntax: [stewart] = computeJointsPose(stewart)
    +  %
    +  % Inputs:
    +  %    - stewart - A structure with the following 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}
    +  %        - platform_F.FO_A [3x1] - Position of {A} with respect to {F}
    +  %        - platform_M.MO_B [3x1] - Position of {B} with respect to {M}
    +  %        - geometry.FO_M   [3x1] - Position of {M} with respect to {F}
    +  %
    +  % Outputs:
    +  %    - stewart - A structure with the following added fields
    +  %        - geometry.Aa    [3x6]   - The i'th column is the position of ai with respect to {A}
    +  %        - geometry.Ab    [3x6]   - The i'th column is the position of bi with respect to {A}
    +  %        - geometry.Ba    [3x6]   - The i'th column is the position of ai with respect to {B}
    +  %        - geometry.Bb    [3x6]   - The i'th column is the position of bi with respect to {B}
    +  %        - geometry.l     [6x1]   - The i'th element is the initial length of strut i
    +  %        - geometry.As    [3x6]   - The i'th column is the unit vector of strut i expressed in {A}
    +  %        - geometry.Bs    [3x6]   - The i'th column is the unit vector of strut i expressed in {B}
    +  %        - struts_F.l     [6x1]   - Length of the Fixed part of the i'th strut
    +  %        - struts_M.l     [6x1]   - Length of the Mobile part of the i'th strut
    +  %        - platform_F.FRa [3x3x6] - The i'th 3x3 array is the rotation matrix to orientate the bottom of the i'th strut from {F}
    +  %        - platform_M.MRb [3x3x6] - The i'th 3x3 array is the rotation matrix to orientate the top of the i'th strut from {M}
     
    -
    -

    Check the stewart structure elements

    -
    +
    +

    Check the stewart structure elements

    +
    -
    assert(isfield(stewart.platform_F, 'Fa'),   'stewart.platform_F should have attribute Fa')
    -Fa = stewart.platform_F.Fa;
    +
      assert(isfield(stewart.platform_F, 'Fa'),   'stewart.platform_F should have attribute Fa')
    +  Fa = stewart.platform_F.Fa;
     
    -assert(isfield(stewart.platform_M, 'Mb'),   'stewart.platform_M should have attribute Mb')
    -Mb = stewart.platform_M.Mb;
    +  assert(isfield(stewart.platform_M, 'Mb'),   'stewart.platform_M should have attribute Mb')
    +  Mb = stewart.platform_M.Mb;
     
    -assert(isfield(stewart.platform_F, 'FO_A'), 'stewart.platform_F should have attribute FO_A')
    -FO_A = stewart.platform_F.FO_A;
    +  assert(isfield(stewart.platform_F, 'FO_A'), 'stewart.platform_F should have attribute FO_A')
    +  FO_A = stewart.platform_F.FO_A;
     
    -assert(isfield(stewart.platform_M, 'MO_B'), 'stewart.platform_M should have attribute MO_B')
    -MO_B = stewart.platform_M.MO_B;
    +  assert(isfield(stewart.platform_M, 'MO_B'), 'stewart.platform_M should have attribute MO_B')
    +  MO_B = stewart.platform_M.MO_B;
     
    -assert(isfield(stewart.geometry,   'FO_M'), 'stewart.geometry should have attribute FO_M')
    -FO_M = stewart.geometry.FO_M;
    +  assert(isfield(stewart.geometry,   'FO_M'), 'stewart.geometry should have attribute FO_M')
    +  FO_M = stewart.geometry.FO_M;
     
    -
    -

    Compute the position of the Joints

    -
    +
    +

    Compute the position of the Joints

    +
    -
    Aa = Fa - repmat(FO_A, [1, 6]);
    -Bb = Mb - repmat(MO_B, [1, 6]);
    +
      Aa = Fa - repmat(FO_A, [1, 6]);
    +  Bb = Mb - repmat(MO_B, [1, 6]);
     
    -Ab = Bb - repmat(-MO_B-FO_M+FO_A, [1, 6]);
    -Ba = Aa - repmat( MO_B+FO_M-FO_A, [1, 6]);
    +  Ab = Bb - repmat(-MO_B-FO_M+FO_A, [1, 6]);
    +  Ba = Aa - repmat( MO_B+FO_M-FO_A, [1, 6]);
     
    -
    -

    Compute the strut length and orientation

    -
    +
    +

    Compute the strut length and orientation

    +
    -
    As = (Ab - Aa)./vecnorm(Ab - Aa); % As_i is the i'th vector of As
    +
      As = (Ab - Aa)./vecnorm(Ab - Aa); % As_i is the i'th vector of As
     
    -l = vecnorm(Ab - Aa)';
    +  l = vecnorm(Ab - Aa)';
     
    -
    Bs = (Bb - Ba)./vecnorm(Bb - Ba);
    +
      Bs = (Bb - Ba)./vecnorm(Bb - Ba);
     
    -
    -

    Compute the orientation of the Joints

    -
    +
    +

    Compute the orientation of the Joints

    +
    -
    FRa = zeros(3,3,6);
    -MRb = zeros(3,3,6);
    +
      FRa = zeros(3,3,6);
    +  MRb = zeros(3,3,6);
     
    -for i = 1:6
    -  FRa(:,:,i) = [cross([0;1;0], As(:,i)) , cross(As(:,i), cross([0;1;0], As(:,i))) , As(:,i)];
    -  FRa(:,:,i) = FRa(:,:,i)./vecnorm(FRa(:,:,i));
    +  for i = 1:6
    +    FRa(:,:,i) = [cross([0;1;0], As(:,i)) , cross(As(:,i), cross([0;1;0], As(:,i))) , As(:,i)];
    +    FRa(:,:,i) = FRa(:,:,i)./vecnorm(FRa(:,:,i));
     
    -  MRb(:,:,i) = [cross([0;1;0], Bs(:,i)) , cross(Bs(:,i), cross([0;1;0], Bs(:,i))) , Bs(:,i)];
    -  MRb(:,:,i) = MRb(:,:,i)./vecnorm(MRb(:,:,i));
    -end
    +    MRb(:,:,i) = [cross([0;1;0], Bs(:,i)) , cross(Bs(:,i), cross([0;1;0], Bs(:,i))) , Bs(:,i)];
    +    MRb(:,:,i) = MRb(:,:,i)./vecnorm(MRb(:,:,i));
    +  end
     
    -
    -

    Populate the stewart structure

    -
    +
    +

    Populate the stewart structure

    +
    -
    stewart.geometry.Aa = Aa;
    -stewart.geometry.Ab = Ab;
    -stewart.geometry.Ba = Ba;
    -stewart.geometry.Bb = Bb;
    -stewart.geometry.As = As;
    -stewart.geometry.Bs = Bs;
    -stewart.geometry.l  = l;
    +
      stewart.geometry.Aa = Aa;
    +  stewart.geometry.Ab = Ab;
    +  stewart.geometry.Ba = Ba;
    +  stewart.geometry.Bb = Bb;
    +  stewart.geometry.As = As;
    +  stewart.geometry.Bs = Bs;
    +  stewart.geometry.l  = l;
     
    -stewart.struts_F.l  = l/2;
    -stewart.struts_M.l  = l/2;
    +  stewart.struts_F.l  = l/2;
    +  stewart.struts_M.l  = l/2;
     
    -stewart.platform_F.FRa = FRa;
    -stewart.platform_M.MRb = MRb;
    +  stewart.platform_F.FRa = FRa;
    +  stewart.platform_M.MRb = MRb;
     
    -
    -

    5 initializeStewartPose: Determine the initial stroke in each leg to have the wanted pose

    +
    +

    5 initializeStewartPose: Determine the initial stroke in each leg to have the wanted pose

    - +

    @@ -691,72 +696,72 @@ This Matlab function is accessible here

    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [stewart] = initializeStewartPose(stewart, args)
    -% initializeStewartPose - Determine the initial stroke in each leg to have the wanted pose
    -%                         It uses the inverse kinematic
    -%
    -% Syntax: [stewart] = initializeStewartPose(stewart, args)
    -%
    -% Inputs:
    -%    - stewart - A structure with the following fields
    -%        - Aa   [3x6] - The positions ai expressed in {A}
    -%        - Bb   [3x6] - The positions bi expressed in {B}
    -%    - args - Can have the following fields:
    -%        - AP   [3x1] - The wanted position of {B} with respect to {A}
    -%        - ARB  [3x3] - The rotation matrix that gives the wanted orientation of {B} with respect to {A}
    -%
    -% Outputs:
    -%    - stewart - updated Stewart structure with the added fields:
    -%      - actuators.Leq [6x1] - The 6 needed displacement of the struts from the initial position in [m] to have the wanted pose of {B} w.r.t. {A}
    +
      function [stewart] = initializeStewartPose(stewart, args)
    +  % initializeStewartPose - Determine the initial stroke in each leg to have the wanted pose
    +  %                         It uses the inverse kinematic
    +  %
    +  % Syntax: [stewart] = initializeStewartPose(stewart, args)
    +  %
    +  % Inputs:
    +  %    - stewart - A structure with the following fields
    +  %        - Aa   [3x6] - The positions ai expressed in {A}
    +  %        - Bb   [3x6] - The positions bi expressed in {B}
    +  %    - args - Can have the following fields:
    +  %        - AP   [3x1] - The wanted position of {B} with respect to {A}
    +  %        - ARB  [3x3] - The rotation matrix that gives the wanted orientation of {B} with respect to {A}
    +  %
    +  % Outputs:
    +  %    - stewart - updated Stewart structure with the added fields:
    +  %      - actuators.Leq [6x1] - The 6 needed displacement of the struts from the initial position in [m] to have the wanted pose of {B} w.r.t. {A}
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    stewart
    -    args.AP  (3,1) double {mustBeNumeric} = zeros(3,1)
    -    args.ARB (3,3) double {mustBeNumeric} = eye(3)
    -end
    +
      arguments
    +      stewart
    +      args.AP  (3,1) double {mustBeNumeric} = zeros(3,1)
    +      args.ARB (3,3) double {mustBeNumeric} = eye(3)
    +  end
     
    -
    -

    Use the Inverse Kinematic function

    -
    +
    +

    Use the Inverse Kinematic function

    +
    -
    [Li, dLi] = inverseKinematics(stewart, 'AP', args.AP, 'ARB', args.ARB);
    +
      [Li, dLi] = inverseKinematics(stewart, 'AP', args.AP, 'ARB', args.ARB);
     
    -
    -

    Populate the stewart structure

    -
    +
    +

    Populate the stewart structure

    +
    -
    stewart.actuators.Leq = dLi;
    +
      stewart.actuators.Leq = dLi;
     
    -
    -

    6 initializeCylindricalPlatforms: Initialize the geometry of the Fixed and Mobile Platforms

    +
    +

    6 initializeCylindricalPlatforms: Initialize the geometry of the Fixed and Mobile Platforms

    - +

    @@ -764,110 +769,110 @@ This Matlab function is accessible -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [stewart] = initializeCylindricalPlatforms(stewart, args)
    -% initializeCylindricalPlatforms - Initialize the geometry of the Fixed and Mobile Platforms
    -%
    -% Syntax: [stewart] = initializeCylindricalPlatforms(args)
    -%
    -% Inputs:
    -%    - args - Structure with the following fields:
    -%        - Fpm [1x1] - Fixed Platform Mass [kg]
    -%        - Fph [1x1] - Fixed Platform Height [m]
    -%        - Fpr [1x1] - Fixed Platform Radius [m]
    -%        - Mpm [1x1] - Mobile Platform Mass [kg]
    -%        - Mph [1x1] - Mobile Platform Height [m]
    -%        - Mpr [1x1] - Mobile Platform Radius [m]
    -%
    -% Outputs:
    -%    - stewart - updated Stewart structure with the added fields:
    -%      - platform_F [struct] - structure with the following fields:
    -%        - type = 1
    -%        - M [1x1] - Fixed Platform Mass [kg]
    -%        - I [3x3] - Fixed Platform Inertia matrix [kg*m^2]
    -%        - H [1x1] - Fixed Platform Height [m]
    -%        - R [1x1] - Fixed Platform Radius [m]
    -%      - platform_M [struct] - structure with the following fields:
    -%        - M [1x1] - Mobile Platform Mass [kg]
    -%        - I [3x3] - Mobile Platform Inertia matrix [kg*m^2]
    -%        - H [1x1] - Mobile Platform Height [m]
    -%        - R [1x1] - Mobile Platform Radius [m]
    +
      function [stewart] = initializeCylindricalPlatforms(stewart, args)
    +  % initializeCylindricalPlatforms - Initialize the geometry of the Fixed and Mobile Platforms
    +  %
    +  % Syntax: [stewart] = initializeCylindricalPlatforms(args)
    +  %
    +  % Inputs:
    +  %    - args - Structure with the following fields:
    +  %        - Fpm [1x1] - Fixed Platform Mass [kg]
    +  %        - Fph [1x1] - Fixed Platform Height [m]
    +  %        - Fpr [1x1] - Fixed Platform Radius [m]
    +  %        - Mpm [1x1] - Mobile Platform Mass [kg]
    +  %        - Mph [1x1] - Mobile Platform Height [m]
    +  %        - Mpr [1x1] - Mobile Platform Radius [m]
    +  %
    +  % Outputs:
    +  %    - stewart - updated Stewart structure with the added fields:
    +  %      - platform_F [struct] - structure with the following fields:
    +  %        - type = 1
    +  %        - M [1x1] - Fixed Platform Mass [kg]
    +  %        - I [3x3] - Fixed Platform Inertia matrix [kg*m^2]
    +  %        - H [1x1] - Fixed Platform Height [m]
    +  %        - R [1x1] - Fixed Platform Radius [m]
    +  %      - platform_M [struct] - structure with the following fields:
    +  %        - M [1x1] - Mobile Platform Mass [kg]
    +  %        - I [3x3] - Mobile Platform Inertia matrix [kg*m^2]
    +  %        - H [1x1] - Mobile Platform Height [m]
    +  %        - R [1x1] - Mobile Platform Radius [m]
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    stewart
    -    args.Fpm (1,1) double {mustBeNumeric, mustBePositive} = 1
    -    args.Fph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3
    -    args.Fpr (1,1) double {mustBeNumeric, mustBePositive} = 125e-3
    -    args.Mpm (1,1) double {mustBeNumeric, mustBePositive} = 1
    -    args.Mph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3
    -    args.Mpr (1,1) double {mustBeNumeric, mustBePositive} = 100e-3
    -end
    +
      arguments
    +      stewart
    +      args.Fpm (1,1) double {mustBeNumeric, mustBePositive} = 1
    +      args.Fph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3
    +      args.Fpr (1,1) double {mustBeNumeric, mustBePositive} = 125e-3
    +      args.Mpm (1,1) double {mustBeNumeric, mustBePositive} = 1
    +      args.Mph (1,1) double {mustBeNumeric, mustBePositive} = 10e-3
    +      args.Mpr (1,1) double {mustBeNumeric, mustBePositive} = 100e-3
    +  end
     
    -
    -

    Compute the Inertia matrices of platforms

    -
    +
    +

    Compute the Inertia matrices of platforms

    +
    -
    I_F = diag([1/12*args.Fpm * (3*args.Fpr^2 + args.Fph^2), ...
    -            1/12*args.Fpm * (3*args.Fpr^2 + args.Fph^2), ...
    -            1/2 *args.Fpm * args.Fpr^2]);
    +
      I_F = diag([1/12*args.Fpm * (3*args.Fpr^2 + args.Fph^2), ...
    +              1/12*args.Fpm * (3*args.Fpr^2 + args.Fph^2), ...
    +              1/2 *args.Fpm * args.Fpr^2]);
     
    -
    I_M = diag([1/12*args.Mpm * (3*args.Mpr^2 + args.Mph^2), ...
    -            1/12*args.Mpm * (3*args.Mpr^2 + args.Mph^2), ...
    -            1/2 *args.Mpm * args.Mpr^2]);
    +
      I_M = diag([1/12*args.Mpm * (3*args.Mpr^2 + args.Mph^2), ...
    +              1/12*args.Mpm * (3*args.Mpr^2 + args.Mph^2), ...
    +              1/2 *args.Mpm * args.Mpr^2]);
     
    -
    -

    Populate the stewart structure

    -
    +
    +

    Populate the stewart structure

    +
    -
    stewart.platform_F.type = 1;
    +
      stewart.platform_F.type = 1;
     
    -stewart.platform_F.I = I_F;
    -stewart.platform_F.M = args.Fpm;
    -stewart.platform_F.R = args.Fpr;
    -stewart.platform_F.H = args.Fph;
    +  stewart.platform_F.I = I_F;
    +  stewart.platform_F.M = args.Fpm;
    +  stewart.platform_F.R = args.Fpr;
    +  stewart.platform_F.H = args.Fph;
     
    -
    stewart.platform_M.type = 1;
    +
      stewart.platform_M.type = 1;
     
    -stewart.platform_M.I = I_M;
    -stewart.platform_M.M = args.Mpm;
    -stewart.platform_M.R = args.Mpr;
    -stewart.platform_M.H = args.Mph;
    +  stewart.platform_M.I = I_M;
    +  stewart.platform_M.M = args.Mpm;
    +  stewart.platform_M.R = args.Mpr;
    +  stewart.platform_M.H = args.Mph;
     
    -
    -

    7 initializeCylindricalStruts: Define the inertia of cylindrical struts

    +
    +

    7 initializeCylindricalStruts: Define the inertia of cylindrical struts

    - +

    @@ -875,122 +880,122 @@ This Matlab function is accessible -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [stewart] = initializeCylindricalStruts(stewart, args)
    -% initializeCylindricalStruts - Define the mass and moment of inertia of cylindrical struts
    -%
    -% Syntax: [stewart] = initializeCylindricalStruts(args)
    -%
    -% Inputs:
    -%    - args - Structure with the following fields:
    -%        - Fsm [1x1] - Mass of the Fixed part of the struts [kg]
    -%        - Fsh [1x1] - Height of cylinder for the Fixed part of the struts [m]
    -%        - Fsr [1x1] - Radius of cylinder for the Fixed part of the struts [m]
    -%        - Msm [1x1] - Mass of the Mobile part of the struts [kg]
    -%        - Msh [1x1] - Height of cylinder for the Mobile part of the struts [m]
    -%        - Msr [1x1] - Radius of cylinder for the Mobile part of the struts [m]
    -%
    -% Outputs:
    -%    - stewart - updated Stewart structure with the added fields:
    -%      - struts_F [struct] - structure with the following fields:
    -%        - M [6x1]   - Mass of the Fixed part of the struts [kg]
    -%        - I [3x3x6] - Moment of Inertia for the Fixed part of the struts [kg*m^2]
    -%        - H [6x1]   - Height of cylinder for the Fixed part of the struts [m]
    -%        - R [6x1]   - Radius of cylinder for the Fixed part of the struts [m]
    -%      - struts_M [struct] - structure with the following fields:
    -%        - M [6x1]   - Mass of the Mobile part of the struts [kg]
    -%        - I [3x3x6] - Moment of Inertia for the Mobile part of the struts [kg*m^2]
    -%        - H [6x1]   - Height of cylinder for the Mobile part of the struts [m]
    -%        - R [6x1]   - Radius of cylinder for the Mobile part of the struts [m]
    +
      function [stewart] = initializeCylindricalStruts(stewart, args)
    +  % initializeCylindricalStruts - Define the mass and moment of inertia of cylindrical struts
    +  %
    +  % Syntax: [stewart] = initializeCylindricalStruts(args)
    +  %
    +  % Inputs:
    +  %    - args - Structure with the following fields:
    +  %        - Fsm [1x1] - Mass of the Fixed part of the struts [kg]
    +  %        - Fsh [1x1] - Height of cylinder for the Fixed part of the struts [m]
    +  %        - Fsr [1x1] - Radius of cylinder for the Fixed part of the struts [m]
    +  %        - Msm [1x1] - Mass of the Mobile part of the struts [kg]
    +  %        - Msh [1x1] - Height of cylinder for the Mobile part of the struts [m]
    +  %        - Msr [1x1] - Radius of cylinder for the Mobile part of the struts [m]
    +  %
    +  % Outputs:
    +  %    - stewart - updated Stewart structure with the added fields:
    +  %      - struts_F [struct] - structure with the following fields:
    +  %        - M [6x1]   - Mass of the Fixed part of the struts [kg]
    +  %        - I [3x3x6] - Moment of Inertia for the Fixed part of the struts [kg*m^2]
    +  %        - H [6x1]   - Height of cylinder for the Fixed part of the struts [m]
    +  %        - R [6x1]   - Radius of cylinder for the Fixed part of the struts [m]
    +  %      - struts_M [struct] - structure with the following fields:
    +  %        - M [6x1]   - Mass of the Mobile part of the struts [kg]
    +  %        - I [3x3x6] - Moment of Inertia for the Mobile part of the struts [kg*m^2]
    +  %        - H [6x1]   - Height of cylinder for the Mobile part of the struts [m]
    +  %        - R [6x1]   - Radius of cylinder for the Mobile part of the struts [m]
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    stewart
    -    args.Fsm (1,1) double {mustBeNumeric, mustBePositive} = 0.1
    -    args.Fsh (1,1) double {mustBeNumeric, mustBePositive} = 50e-3
    -    args.Fsr (1,1) double {mustBeNumeric, mustBePositive} = 5e-3
    -    args.Msm (1,1) double {mustBeNumeric, mustBePositive} = 0.1
    -    args.Msh (1,1) double {mustBeNumeric, mustBePositive} = 50e-3
    -    args.Msr (1,1) double {mustBeNumeric, mustBePositive} = 5e-3
    -end
    +
      arguments
    +      stewart
    +      args.Fsm (1,1) double {mustBeNumeric, mustBePositive} = 0.1
    +      args.Fsh (1,1) double {mustBeNumeric, mustBePositive} = 50e-3
    +      args.Fsr (1,1) double {mustBeNumeric, mustBePositive} = 5e-3
    +      args.Msm (1,1) double {mustBeNumeric, mustBePositive} = 0.1
    +      args.Msh (1,1) double {mustBeNumeric, mustBePositive} = 50e-3
    +      args.Msr (1,1) double {mustBeNumeric, mustBePositive} = 5e-3
    +  end
     
    -
    -

    Compute the properties of the cylindrical struts

    -
    +
    +

    Compute the properties of the cylindrical struts

    +
    -
    Fsm = ones(6,1).*args.Fsm;
    -Fsh = ones(6,1).*args.Fsh;
    -Fsr = ones(6,1).*args.Fsr;
    +
      Fsm = ones(6,1).*args.Fsm;
    +  Fsh = ones(6,1).*args.Fsh;
    +  Fsr = ones(6,1).*args.Fsr;
     
    -Msm = ones(6,1).*args.Msm;
    -Msh = ones(6,1).*args.Msh;
    -Msr = ones(6,1).*args.Msr;
    +  Msm = ones(6,1).*args.Msm;
    +  Msh = ones(6,1).*args.Msh;
    +  Msr = ones(6,1).*args.Msr;
     
    -
    I_F = zeros(3, 3, 6); % Inertia of the "fixed" part of the strut
    -I_M = zeros(3, 3, 6); % Inertia of the "mobile" part of the strut
    +
      I_F = zeros(3, 3, 6); % Inertia of the "fixed" part of the strut
    +  I_M = zeros(3, 3, 6); % Inertia of the "mobile" part of the strut
     
    -for i = 1:6
    -  I_F(:,:,i) = diag([1/12 * Fsm(i) * (3*Fsr(i)^2 + Fsh(i)^2), ...
    -                     1/12 * Fsm(i) * (3*Fsr(i)^2 + Fsh(i)^2), ...
    -                     1/2  * Fsm(i) * Fsr(i)^2]);
    +  for i = 1:6
    +    I_F(:,:,i) = diag([1/12 * Fsm(i) * (3*Fsr(i)^2 + Fsh(i)^2), ...
    +                       1/12 * Fsm(i) * (3*Fsr(i)^2 + Fsh(i)^2), ...
    +                       1/2  * Fsm(i) * Fsr(i)^2]);
     
    -  I_M(:,:,i) = diag([1/12 * Msm(i) * (3*Msr(i)^2 + Msh(i)^2), ...
    -                     1/12 * Msm(i) * (3*Msr(i)^2 + Msh(i)^2), ...
    -                     1/2  * Msm(i) * Msr(i)^2]);
    -end
    +    I_M(:,:,i) = diag([1/12 * Msm(i) * (3*Msr(i)^2 + Msh(i)^2), ...
    +                       1/12 * Msm(i) * (3*Msr(i)^2 + Msh(i)^2), ...
    +                       1/2  * Msm(i) * Msr(i)^2]);
    +  end
     
    -
    -

    Populate the stewart structure

    -
    +
    +

    Populate the stewart structure

    +
    -
    stewart.struts_M.type = 1;
    +
      stewart.struts_M.type = 1;
     
    -stewart.struts_M.I = I_M;
    -stewart.struts_M.M = Msm;
    -stewart.struts_M.R = Msr;
    -stewart.struts_M.H = Msh;
    +  stewart.struts_M.I = I_M;
    +  stewart.struts_M.M = Msm;
    +  stewart.struts_M.R = Msr;
    +  stewart.struts_M.H = Msh;
     
    -
    stewart.struts_F.type = 1;
    +
      stewart.struts_F.type = 1;
     
    -stewart.struts_F.I = I_F;
    -stewart.struts_F.M = Fsm;
    -stewart.struts_F.R = Fsr;
    -stewart.struts_F.H = Fsh;
    +  stewart.struts_F.I = I_F;
    +  stewart.struts_F.M = Fsm;
    +  stewart.struts_F.R = Fsr;
    +  stewart.struts_F.H = Fsh;
     
    -
    -

    8 initializeStrutDynamics: Add Stiffness and Damping properties of each strut

    +
    +

    8 initializeStrutDynamics: Add Stiffness and Damping properties of each strut

    - +

    @@ -998,18 +1003,18 @@ This Matlab function is accessible he

    -
    -

    Documentation

    -
    +
    +

    Documentation

    +
    -
    +

    piezoelectric_stack.jpg

    Figure 5: Example of a piezoelectric stach actuator (PI)

    -A simplistic model of such amplified actuator is shown in Figure 6 where: +A simplistic model of such amplified actuator is shown in Figure 6 where:

    -
    +

    inertial_sensor.png

    Figure 7: Schematic of a Z-Axis geophone

    @@ -1362,11 +1367,11 @@ We generally want to have the smallest resonant frequency \(\omega_0\) to measur
    -
    -

    Accelerometer - Working Principle

    -
    +
    +

    Accelerometer - Working Principle

    +

    -From the schematic of the Z-axis accelerometer shown in Figure 8, we can write the transfer function from the support acceleration \(\ddot{w}\) to the relative position of the inertial mass \(d\): +From the schematic of the Z-axis accelerometer shown in Figure 8, we can write the transfer function from the support acceleration \(\ddot{w}\) to the relative position of the inertial mass \(d\): \[ \frac{d}{\ddot{w}} = \frac{-\frac{1}{{\omega_0}^2}}{\frac{s^2}{{\omega_0}^2} + 2 \xi \frac{s}{\omega_0} + 1} \] with:

    @@ -1376,7 +1381,7 @@ with: -
    +

    inertial_sensor.png

    Figure 8: Schematic of a Z-Axis geophone

    @@ -1401,93 +1406,93 @@ Note that there is trade-off between:
    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [stewart] = initializeInertialSensor(stewart, args)
    -% initializeInertialSensor - Initialize the inertial sensor in each strut
    -%
    -% Syntax: [stewart] = initializeInertialSensor(args)
    -%
    -% Inputs:
    -%    - args - Structure with the following fields:
    -%        - type       - 'geophone', 'accelerometer', 'none'
    -%        - mass [1x1] - Weight of the inertial mass [kg]
    -%        - freq [1x1] - Cutoff frequency [Hz]
    -%
    -% Outputs:
    -%    - stewart - updated Stewart structure with the added fields:
    -%      - stewart.sensors.inertial
    -%        - type    - 1 (geophone), 2 (accelerometer), 3 (none)
    -%        - K [1x1] - Stiffness [N/m]
    -%        - C [1x1] - Damping [N/(m/s)]
    -%        - M [1x1] - Inertial Mass [kg]
    -%        - G [1x1] - Gain
    +
      function [stewart] = initializeInertialSensor(stewart, args)
    +  % initializeInertialSensor - Initialize the inertial sensor in each strut
    +  %
    +  % Syntax: [stewart] = initializeInertialSensor(args)
    +  %
    +  % Inputs:
    +  %    - args - Structure with the following fields:
    +  %        - type       - 'geophone', 'accelerometer', 'none'
    +  %        - mass [1x1] - Weight of the inertial mass [kg]
    +  %        - freq [1x1] - Cutoff frequency [Hz]
    +  %
    +  % Outputs:
    +  %    - stewart - updated Stewart structure with the added fields:
    +  %      - stewart.sensors.inertial
    +  %        - type    - 1 (geophone), 2 (accelerometer), 3 (none)
    +  %        - K [1x1] - Stiffness [N/m]
    +  %        - C [1x1] - Damping [N/(m/s)]
    +  %        - M [1x1] - Inertial Mass [kg]
    +  %        - G [1x1] - Gain
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    stewart
    -    args.type       char   {mustBeMember(args.type,{'geophone', 'accelerometer', 'none'})} = 'none'
    -    args.mass (1,1) double {mustBeNumeric, mustBeNonnegative} = 1e-2
    -    args.freq (1,1) double {mustBeNumeric, mustBeNonnegative} = 1e3
    -end
    +
      arguments
    +      stewart
    +      args.type       char   {mustBeMember(args.type,{'geophone', 'accelerometer', 'none'})} = 'none'
    +      args.mass (1,1) double {mustBeNumeric, mustBeNonnegative} = 1e-2
    +      args.freq (1,1) double {mustBeNumeric, mustBeNonnegative} = 1e3
    +  end
     
    -
    -

    Compute the properties of the sensor

    -
    +
    +

    Compute the properties of the sensor

    +
    -
    sensor = struct();
    +
      sensor = struct();
     
    -switch args.type
    -  case 'geophone'
    -    sensor.type = 1;
    +  switch args.type
    +    case 'geophone'
    +      sensor.type = 1;
     
    -    sensor.M = args.mass;
    -    sensor.K = sensor.M * (2*pi*args.freq)^2;
    -    sensor.C = 2*sqrt(sensor.M * sensor.K);
    -  case 'accelerometer'
    -    sensor.type = 2;
    +      sensor.M = args.mass;
    +      sensor.K = sensor.M * (2*pi*args.freq)^2;
    +      sensor.C = 2*sqrt(sensor.M * sensor.K);
    +    case 'accelerometer'
    +      sensor.type = 2;
     
    -    sensor.M = args.mass;
    -    sensor.K = sensor.M * (2*pi*args.freq)^2;
    -    sensor.C = 2*sqrt(sensor.M * sensor.K);
    -    sensor.G = -sensor.K/sensor.M;
    -  case 'none'
    -    sensor.type = 3;
    -end
    +      sensor.M = args.mass;
    +      sensor.K = sensor.M * (2*pi*args.freq)^2;
    +      sensor.C = 2*sqrt(sensor.M * sensor.K);
    +      sensor.G = -sensor.K/sensor.M;
    +    case 'none'
    +      sensor.type = 3;
    +  end
     
    -
    -

    Populate the stewart structure

    -
    +
    +

    Populate the stewart structure

    +
    -
    stewart.sensors.inertial = sensor;
    +
      stewart.sensors.inertial = sensor;
     
    -
    -

    11 displayArchitecture: 3D plot of the Stewart platform architecture

    +
    +

    11 displayArchitecture: 3D plot of the Stewart platform architecture

    - +

    @@ -1495,98 +1500,98 @@ This Matlab function is accessible here

    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [] = displayArchitecture(stewart, args)
    -% displayArchitecture - 3D plot of the Stewart platform architecture
    -%
    -% Syntax: [] = displayArchitecture(args)
    -%
    -% Inputs:
    -%    - stewart
    -%    - args - Structure with the following fields:
    -%        - AP   [3x1] - The wanted position of {B} with respect to {A}
    -%        - ARB  [3x3] - The rotation matrix that gives the wanted orientation of {B} with respect to {A}
    -%        - ARB  [3x3] - The rotation matrix that gives the wanted orientation of {B} with respect to {A}
    -%        - F_color [color] - Color used for the Fixed elements
    -%        - M_color [color] - Color used for the Mobile elements
    -%        - L_color [color] - Color used for the Legs elements
    -%        - frames    [true/false] - Display the Frames
    -%        - legs      [true/false] - Display the Legs
    -%        - joints    [true/false] - Display the Joints
    -%        - labels    [true/false] - Display the Labels
    -%        - platforms [true/false] - Display the Platforms
    -%        - views     ['all', 'xy', 'yz', 'xz', 'default'] -
    -%
    -% Outputs:
    +
      function [] = displayArchitecture(stewart, args)
    +  % displayArchitecture - 3D plot of the Stewart platform architecture
    +  %
    +  % Syntax: [] = displayArchitecture(args)
    +  %
    +  % Inputs:
    +  %    - stewart
    +  %    - args - Structure with the following fields:
    +  %        - AP   [3x1] - The wanted position of {B} with respect to {A}
    +  %        - ARB  [3x3] - The rotation matrix that gives the wanted orientation of {B} with respect to {A}
    +  %        - ARB  [3x3] - The rotation matrix that gives the wanted orientation of {B} with respect to {A}
    +  %        - F_color [color] - Color used for the Fixed elements
    +  %        - M_color [color] - Color used for the Mobile elements
    +  %        - L_color [color] - Color used for the Legs elements
    +  %        - frames    [true/false] - Display the Frames
    +  %        - legs      [true/false] - Display the Legs
    +  %        - joints    [true/false] - Display the Joints
    +  %        - labels    [true/false] - Display the Labels
    +  %        - platforms [true/false] - Display the Platforms
    +  %        - views     ['all', 'xy', 'yz', 'xz', 'default'] -
    +  %
    +  % Outputs:
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    stewart
    -    args.AP  (3,1) double {mustBeNumeric} = zeros(3,1)
    -    args.ARB (3,3) double {mustBeNumeric} = eye(3)
    -    args.F_color = [0 0.4470 0.7410]
    -    args.M_color = [0.8500 0.3250 0.0980]
    -    args.L_color = [0 0 0]
    -    args.frames    logical {mustBeNumericOrLogical} = true
    -    args.legs      logical {mustBeNumericOrLogical} = true
    -    args.joints    logical {mustBeNumericOrLogical} = true
    -    args.labels    logical {mustBeNumericOrLogical} = true
    -    args.platforms logical {mustBeNumericOrLogical} = true
    -    args.views     char    {mustBeMember(args.views,{'all', 'xy', 'xz', 'yz', 'default'})} = 'default'
    -end
    +
      arguments
    +      stewart
    +      args.AP  (3,1) double {mustBeNumeric} = zeros(3,1)
    +      args.ARB (3,3) double {mustBeNumeric} = eye(3)
    +      args.F_color = [0 0.4470 0.7410]
    +      args.M_color = [0.8500 0.3250 0.0980]
    +      args.L_color = [0 0 0]
    +      args.frames    logical {mustBeNumericOrLogical} = true
    +      args.legs      logical {mustBeNumericOrLogical} = true
    +      args.joints    logical {mustBeNumericOrLogical} = true
    +      args.labels    logical {mustBeNumericOrLogical} = true
    +      args.platforms logical {mustBeNumericOrLogical} = true
    +      args.views     char    {mustBeMember(args.views,{'all', 'xy', 'xz', 'yz', 'default'})} = 'default'
    +  end
     
    -
    -

    Check the stewart structure elements

    -
    +
    +

    Check the stewart structure elements

    +
    -
    assert(isfield(stewart.platform_F, 'FO_A'), 'stewart.platform_F should have attribute FO_A')
    -FO_A = stewart.platform_F.FO_A;
    +
      assert(isfield(stewart.platform_F, 'FO_A'), 'stewart.platform_F should have attribute FO_A')
    +  FO_A = stewart.platform_F.FO_A;
     
    -assert(isfield(stewart.platform_M, 'MO_B'), 'stewart.platform_M should have attribute MO_B')
    -MO_B = stewart.platform_M.MO_B;
    +  assert(isfield(stewart.platform_M, 'MO_B'), 'stewart.platform_M should have attribute MO_B')
    +  MO_B = stewart.platform_M.MO_B;
     
    -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;
     
    -assert(isfield(stewart.platform_F, 'Fa'),   'stewart.platform_F should have attribute Fa')
    -Fa = stewart.platform_F.Fa;
    +  assert(isfield(stewart.platform_F, 'Fa'),   'stewart.platform_F should have attribute Fa')
    +  Fa = stewart.platform_F.Fa;
     
    -assert(isfield(stewart.platform_M, 'Mb'),   'stewart.platform_M should have attribute Mb')
    -Mb = stewart.platform_M.Mb;
    +  assert(isfield(stewart.platform_M, 'Mb'),   'stewart.platform_M should have attribute Mb')
    +  Mb = stewart.platform_M.Mb;
     
    -
    -

    Figure Creation, Frames and Homogeneous transformations

    -
    +
    +

    Figure Creation, Frames and Homogeneous transformations

    +

    The reference frame of the 3d plot corresponds to the frame \(\{F\}\).

    -
    if ~strcmp(args.views, 'all')
    -  figure;
    -else
    -  f = figure('visible', 'off');
    -end
    +
      if ~strcmp(args.views, 'all')
    +    figure;
    +  else
    +    f = figure('visible', 'off');
    +  end
     
    -hold on;
    +  hold on;
     
    @@ -1594,14 +1599,14 @@ hold on; We first compute homogeneous matrices that will be useful to position elements on the figure where the reference frame is \(\{F\}\).

    -
    FTa = [eye(3), FO_A; ...
    -       zeros(1,3), 1];
    -ATb = [args.ARB, args.AP; ...
    -       zeros(1,3), 1];
    -BTm = [eye(3), -MO_B; ...
    -       zeros(1,3), 1];
    +
      FTa = [eye(3), FO_A; ...
    +         zeros(1,3), 1];
    +  ATb = [args.ARB, args.AP; ...
    +         zeros(1,3), 1];
    +  BTm = [eye(3), -MO_B; ...
    +         zeros(1,3), 1];
     
    -FTm = FTa*ATb*BTm;
    +  FTm = FTa*ATb*BTm;
     
    @@ -1609,7 +1614,7 @@ FTm = FTa*ATb*BTm; Let’s define a parameter that define the length of the unit vectors used to display the frames.

    -
    d_unit_vector = H/4;
    +
      d_unit_vector = H/4;
     
    @@ -1617,30 +1622,30 @@ Let’s define a parameter that define the length of the unit vectors used t Let’s define a parameter used to position the labels with respect to the center of the element.

    -
    d_label = H/20;
    +
      d_label = H/20;
     
    -
    -

    Fixed Base elements

    -
    +
    +

    Fixed Base elements

    +

    Let’s first plot the frame \(\{F\}\).

    -
    Ff = [0, 0, 0];
    -if args.frames
    -  quiver3(Ff(1)*ones(1,3), Ff(2)*ones(1,3), Ff(3)*ones(1,3), ...
    -          [d_unit_vector 0 0], [0 d_unit_vector 0], [0 0 d_unit_vector], '-', 'Color', args.F_color)
    +
      Ff = [0, 0, 0];
    +  if args.frames
    +    quiver3(Ff(1)*ones(1,3), Ff(2)*ones(1,3), Ff(3)*ones(1,3), ...
    +            [d_unit_vector 0 0], [0 d_unit_vector 0], [0 0 d_unit_vector], '-', 'Color', args.F_color)
     
    -  if args.labels
    -    text(Ff(1) + d_label, ...
    -        Ff(2) + d_label, ...
    -        Ff(3) + d_label, '$\{F\}$', 'Color', args.F_color);
    +    if args.labels
    +      text(Ff(1) + d_label, ...
    +          Ff(2) + d_label, ...
    +          Ff(3) + d_label, '$\{F\}$', 'Color', args.F_color);
    +    end
       end
    -end
     
    @@ -1648,16 +1653,16 @@ Let’s first plot the frame \(\{F\}\). Now plot the frame \(\{A\}\) fixed to the Base.

    -
    if args.frames
    -  quiver3(FO_A(1)*ones(1,3), FO_A(2)*ones(1,3), FO_A(3)*ones(1,3), ...
    -          [d_unit_vector 0 0], [0 d_unit_vector 0], [0 0 d_unit_vector], '-', 'Color', args.F_color)
    +
      if args.frames
    +    quiver3(FO_A(1)*ones(1,3), FO_A(2)*ones(1,3), FO_A(3)*ones(1,3), ...
    +            [d_unit_vector 0 0], [0 d_unit_vector 0], [0 0 d_unit_vector], '-', 'Color', args.F_color)
     
    -  if args.labels
    -    text(FO_A(1) + d_label, ...
    -         FO_A(2) + d_label, ...
    -         FO_A(3) + d_label, '$\{A\}$', 'Color', args.F_color);
    +    if args.labels
    +      text(FO_A(1) + d_label, ...
    +           FO_A(2) + d_label, ...
    +           FO_A(3) + d_label, '$\{A\}$', 'Color', args.F_color);
    +    end
       end
    -end
     
    @@ -1665,18 +1670,18 @@ Now plot the frame \(\{A\}\) fixed to the Base. Let’s then plot the circle corresponding to the shape of the Fixed base.

    -
    if args.platforms && stewart.platform_F.type == 1
    -  theta = [0:0.01:2*pi+0.01]; % Angles [rad]
    -  v = null([0; 0; 1]'); % Two vectors that are perpendicular to the circle normal
    -  center = [0; 0; 0]; % Center of the circle
    -  radius = stewart.platform_F.R; % Radius of the circle [m]
    +
      if args.platforms && stewart.platform_F.type == 1
    +    theta = [0:0.01:2*pi+0.01]; % Angles [rad]
    +    v = null([0; 0; 1]'); % Two vectors that are perpendicular to the circle normal
    +    center = [0; 0; 0]; % Center of the circle
    +    radius = stewart.platform_F.R; % Radius of the circle [m]
     
    -  points = center*ones(1, length(theta)) + radius*(v(:,1)*cos(theta) + v(:,2)*sin(theta));
    +    points = center*ones(1, length(theta)) + radius*(v(:,1)*cos(theta) + v(:,2)*sin(theta));
     
    -  plot3(points(1,:), ...
    -        points(2,:), ...
    -        points(3,:), '-', 'Color', args.F_color);
    -end
    +    plot3(points(1,:), ...
    +          points(2,:), ...
    +          points(3,:), '-', 'Color', args.F_color);
    +  end
     
    @@ -1684,43 +1689,43 @@ Let’s then plot the circle corresponding to the shape of the Fixed base. Let’s now plot the position and labels of the Fixed Joints

    -
    if args.joints
    -  scatter3(Fa(1,:), ...
    -           Fa(2,:), ...
    -           Fa(3,:), 'MarkerEdgeColor', args.F_color);
    -  if args.labels
    -    for i = 1:size(Fa,2)
    -      text(Fa(1,i) + d_label, ...
    -           Fa(2,i), ...
    -           Fa(3,i), sprintf('$a_{%i}$', i), 'Color', args.F_color);
    +
      if args.joints
    +    scatter3(Fa(1,:), ...
    +             Fa(2,:), ...
    +             Fa(3,:), 'MarkerEdgeColor', args.F_color);
    +    if args.labels
    +      for i = 1:size(Fa,2)
    +        text(Fa(1,i) + d_label, ...
    +             Fa(2,i), ...
    +             Fa(3,i), sprintf('$a_{%i}$', i), 'Color', args.F_color);
    +      end
         end
       end
    -end
     
    -
    -

    Mobile Platform elements

    -
    +
    +

    Mobile Platform elements

    +

    Plot the frame \(\{M\}\).

    -
    Fm = FTm*[0; 0; 0; 1]; % Get the position of frame {M} w.r.t. {F}
    +
      Fm = FTm*[0; 0; 0; 1]; % Get the position of frame {M} w.r.t. {F}
     
    -if args.frames
    -  FM_uv = FTm*[d_unit_vector*eye(3); zeros(1,3)]; % Rotated Unit vectors
    -  quiver3(Fm(1)*ones(1,3), Fm(2)*ones(1,3), Fm(3)*ones(1,3), ...
    -          FM_uv(1,1:3), FM_uv(2,1:3), FM_uv(3,1:3), '-', 'Color', args.M_color)
    +  if args.frames
    +    FM_uv = FTm*[d_unit_vector*eye(3); zeros(1,3)]; % Rotated Unit vectors
    +    quiver3(Fm(1)*ones(1,3), Fm(2)*ones(1,3), Fm(3)*ones(1,3), ...
    +            FM_uv(1,1:3), FM_uv(2,1:3), FM_uv(3,1:3), '-', 'Color', args.M_color)
     
    -  if args.labels
    -    text(Fm(1) + d_label, ...
    -         Fm(2) + d_label, ...
    -         Fm(3) + d_label, '$\{M\}$', 'Color', args.M_color);
    +    if args.labels
    +      text(Fm(1) + d_label, ...
    +           Fm(2) + d_label, ...
    +           Fm(3) + d_label, '$\{M\}$', 'Color', args.M_color);
    +    end
       end
    -end
     
    @@ -1728,19 +1733,19 @@ Plot the frame \(\{M\}\). Plot the frame \(\{B\}\).

    -
    FB = FO_A + args.AP;
    +
      FB = FO_A + args.AP;
     
    -if args.frames
    -  FB_uv = FTm*[d_unit_vector*eye(3); zeros(1,3)]; % Rotated Unit vectors
    -  quiver3(FB(1)*ones(1,3), FB(2)*ones(1,3), FB(3)*ones(1,3), ...
    -          FB_uv(1,1:3), FB_uv(2,1:3), FB_uv(3,1:3), '-', 'Color', args.M_color)
    +  if args.frames
    +    FB_uv = FTm*[d_unit_vector*eye(3); zeros(1,3)]; % Rotated Unit vectors
    +    quiver3(FB(1)*ones(1,3), FB(2)*ones(1,3), FB(3)*ones(1,3), ...
    +            FB_uv(1,1:3), FB_uv(2,1:3), FB_uv(3,1:3), '-', 'Color', args.M_color)
     
    -  if args.labels
    -    text(FB(1) - d_label, ...
    -         FB(2) + d_label, ...
    -         FB(3) + d_label, '$\{B\}$', 'Color', args.M_color);
    +    if args.labels
    +      text(FB(1) - d_label, ...
    +           FB(2) + d_label, ...
    +           FB(3) + d_label, '$\{B\}$', 'Color', args.M_color);
    +    end
       end
    -end
     
    @@ -1748,18 +1753,18 @@ Plot the frame \(\{B\}\). Let’s then plot the circle corresponding to the shape of the Mobile platform.

    -
    if args.platforms && stewart.platform_M.type == 1
    -  theta = [0:0.01:2*pi+0.01]; % Angles [rad]
    -  v = null((FTm(1:3,1:3)*[0;0;1])'); % Two vectors that are perpendicular to the circle normal
    -  center = Fm(1:3); % Center of the circle
    -  radius = stewart.platform_M.R; % Radius of the circle [m]
    +
      if args.platforms && stewart.platform_M.type == 1
    +    theta = [0:0.01:2*pi+0.01]; % Angles [rad]
    +    v = null((FTm(1:3,1:3)*[0;0;1])'); % Two vectors that are perpendicular to the circle normal
    +    center = Fm(1:3); % Center of the circle
    +    radius = stewart.platform_M.R; % Radius of the circle [m]
     
    -  points = center*ones(1, length(theta)) + radius*(v(:,1)*cos(theta) + v(:,2)*sin(theta));
    +    points = center*ones(1, length(theta)) + radius*(v(:,1)*cos(theta) + v(:,2)*sin(theta));
     
    -  plot3(points(1,:), ...
    -        points(2,:), ...
    -        points(3,:), '-', 'Color', args.M_color);
    -end
    +    plot3(points(1,:), ...
    +          points(2,:), ...
    +          points(3,:), '-', 'Color', args.M_color);
    +  end
     
    @@ -1767,109 +1772,109 @@ Let’s then plot the circle corresponding to the shape of the Mobile platfo Plot the position and labels of the rotation joints fixed to the mobile platform.

    -
    if args.joints
    -  Fb = FTm*[Mb;ones(1,6)];
    +
      if args.joints
    +    Fb = FTm*[Mb;ones(1,6)];
     
    -  scatter3(Fb(1,:), ...
    -           Fb(2,:), ...
    -           Fb(3,:), 'MarkerEdgeColor', args.M_color);
    +    scatter3(Fb(1,:), ...
    +             Fb(2,:), ...
    +             Fb(3,:), 'MarkerEdgeColor', args.M_color);
     
    -  if args.labels
    -    for i = 1:size(Fb,2)
    -      text(Fb(1,i) + d_label, ...
    -           Fb(2,i), ...
    -           Fb(3,i), sprintf('$b_{%i}$', i), 'Color', args.M_color);
    +    if args.labels
    +      for i = 1:size(Fb,2)
    +        text(Fb(1,i) + d_label, ...
    +             Fb(2,i), ...
    +             Fb(3,i), sprintf('$b_{%i}$', i), 'Color', args.M_color);
    +      end
         end
       end
    -end
     
    -
    -

    Legs

    -
    +
    +

    Legs

    +

    Plot the legs connecting the joints of the fixed base to the joints of the mobile platform.

    -
    if args.legs
    -  for i = 1:6
    -    plot3([Fa(1,i), Fb(1,i)], ...
    -          [Fa(2,i), Fb(2,i)], ...
    -          [Fa(3,i), Fb(3,i)], '-', 'Color', args.L_color);
    +
      if args.legs
    +    for i = 1:6
    +      plot3([Fa(1,i), Fb(1,i)], ...
    +            [Fa(2,i), Fb(2,i)], ...
    +            [Fa(3,i), Fb(3,i)], '-', 'Color', args.L_color);
     
    -    if args.labels
    -      text((Fa(1,i)+Fb(1,i))/2 + d_label, ...
    -           (Fa(2,i)+Fb(2,i))/2, ...
    -           (Fa(3,i)+Fb(3,i))/2, sprintf('$%i$', i), 'Color', args.L_color);
    +      if args.labels
    +        text((Fa(1,i)+Fb(1,i))/2 + d_label, ...
    +             (Fa(2,i)+Fb(2,i))/2, ...
    +             (Fa(3,i)+Fb(3,i))/2, sprintf('$%i$', i), 'Color', args.L_color);
    +      end
         end
       end
    -end
     
    -
    -

    11.1 Figure parameters

    +
    +

    11.1 Figure parameters

    -
    switch args.views
    -  case 'default'
    -      view([1 -0.6 0.4]);
    -  case 'xy'
    -      view([0 0 1]);
    -  case 'xz'
    -      view([0 -1 0]);
    -  case 'yz'
    -      view([1 0 0]);
    -end
    -axis equal;
    -axis off;
    +
      switch args.views
    +    case 'default'
    +        view([1 -0.6 0.4]);
    +    case 'xy'
    +        view([0 0 1]);
    +    case 'xz'
    +        view([0 -1 0]);
    +    case 'yz'
    +        view([1 0 0]);
    +  end
    +  axis equal;
    +  axis off;
     
    -
    -

    11.2 Subplots

    +
    +

    11.2 Subplots

    -
    if strcmp(args.views, 'all')
    -  hAx = findobj('type', 'axes');
    +
      if strcmp(args.views, 'all')
    +    hAx = findobj('type', 'axes');
     
    -  figure;
    -  s1 = subplot(2,2,1);
    -  copyobj(get(hAx(1), 'Children'), s1);
    -  view([0 0 1]);
    -  axis equal;
    -  axis off;
    -  title('Top')
    +    figure;
    +    s1 = subplot(2,2,1);
    +    copyobj(get(hAx(1), 'Children'), s1);
    +    view([0 0 1]);
    +    axis equal;
    +    axis off;
    +    title('Top')
     
    -  s2 = subplot(2,2,2);
    -  copyobj(get(hAx(1), 'Children'), s2);
    -  view([1 -0.6 0.4]);
    -  axis equal;
    -  axis off;
    +    s2 = subplot(2,2,2);
    +    copyobj(get(hAx(1), 'Children'), s2);
    +    view([1 -0.6 0.4]);
    +    axis equal;
    +    axis off;
     
    -  s3 = subplot(2,2,3);
    -  copyobj(get(hAx(1), 'Children'), s3);
    -  view([1 0 0]);
    -  axis equal;
    -  axis off;
    -  title('Front')
    +    s3 = subplot(2,2,3);
    +    copyobj(get(hAx(1), 'Children'), s3);
    +    view([1 0 0]);
    +    axis equal;
    +    axis off;
    +    title('Front')
     
    -  s4 = subplot(2,2,4);
    -  copyobj(get(hAx(1), 'Children'), s4);
    -  view([0 -1 0]);
    -  axis equal;
    -  axis off;
    -  title('Side')
    +    s4 = subplot(2,2,4);
    +    copyobj(get(hAx(1), 'Children'), s4);
    +    view([0 -1 0]);
    +    axis equal;
    +    axis off;
    +    title('Side')
     
    -  close(f);
    -end
    +    close(f);
    +  end
     
    @@ -1877,11 +1882,11 @@ Plot the legs connecting the joints of the fixed base to the joints of the mobil
    -
    -

    12 describeStewartPlatform: Display some text describing the current defined Stewart Platform

    +
    +

    12 describeStewartPlatform: Display some text describing the current defined Stewart Platform

    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [] = describeStewartPlatform(stewart)
    -% describeStewartPlatform - Display some text describing the current defined Stewart Platform
    -%
    -% Syntax: [] = describeStewartPlatform(args)
    -%
    -% Inputs:
    -%    - stewart
    -%
    -% Outputs:
    +
      function [] = describeStewartPlatform(stewart)
    +  % describeStewartPlatform - Display some text describing the current defined Stewart Platform
    +  %
    +  % Syntax: [] = describeStewartPlatform(args)
    +  %
    +  % Inputs:
    +  %    - stewart
    +  %
    +  % Outputs:
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    stewart
    -end
    +
      arguments
    +      stewart
    +  end
     
    -
    -

    12.1 Geometry

    +
    +

    12.1 Geometry

    -
    fprintf('GEOMETRY:\n')
    -fprintf('- The height between the fixed based and the top platform is %.3g [mm].\n', 1e3*stewart.geometry.H)
    +
      fprintf('GEOMETRY:\n')
    +  fprintf('- The height between the fixed based and the top platform is %.3g [mm].\n', 1e3*stewart.geometry.H)
     
    -if stewart.platform_M.MO_B(3) > 0
    -  fprintf('- Frame {A} is located %.3g [mm] above the top platform.\n',  1e3*stewart.platform_M.MO_B(3))
    -else
    -  fprintf('- Frame {A} is located %.3g [mm] below the top platform.\n', - 1e3*stewart.platform_M.MO_B(3))
    -end
    +  if stewart.platform_M.MO_B(3) > 0
    +    fprintf('- Frame {A} is located %.3g [mm] above the top platform.\n',  1e3*stewart.platform_M.MO_B(3))
    +  else
    +    fprintf('- Frame {A} is located %.3g [mm] below the top platform.\n', - 1e3*stewart.platform_M.MO_B(3))
    +  end
     
    -fprintf('- The initial length of the struts are:\n')
    -fprintf('\t %.3g, %.3g, %.3g, %.3g, %.3g, %.3g [mm]\n', 1e3*stewart.geometry.l)
    -fprintf('\n')
    +  fprintf('- The initial length of the struts are:\n')
    +  fprintf('\t %.3g, %.3g, %.3g, %.3g, %.3g, %.3g [mm]\n', 1e3*stewart.geometry.l)
    +  fprintf('\n')
     
    -
    -

    12.2 Actuators

    +
    +

    12.2 Actuators

    -
    fprintf('ACTUATORS:\n')
    -if stewart.actuators.type == 1
    -    fprintf('- The actuators are classical.\n')
    -    fprintf('- The Stiffness and Damping of each actuators is:\n')
    -    fprintf('\t k = %.0e [N/m] \t c = %.0e [N/(m/s)]\n', stewart.actuators.K(1), stewart.actuators.C(1))
    -elseif stewart.actuators.type == 2
    -    fprintf('- The actuators are mechanicaly amplified.\n')
    -    fprintf('- The vertical stiffness and damping contribution of the piezoelectric stack is:\n')
    -    fprintf('\t ka = %.0e [N/m] \t ca = %.0e [N/(m/s)]\n', stewart.actuators.Ka(1), stewart.actuators.Ca(1))
    -    fprintf('- Vertical stiffness when the piezoelectric stack is removed is:\n')
    -    fprintf('\t kr = %.0e [N/m] \t cr = %.0e [N/(m/s)]\n', stewart.actuators.Kr(1), stewart.actuators.Cr(1))
    -end
    -fprintf('\n')
    +
      fprintf('ACTUATORS:\n')
    +  if stewart.actuators.type == 1
    +      fprintf('- The actuators are classical.\n')
    +      fprintf('- The Stiffness and Damping of each actuators is:\n')
    +      fprintf('\t k = %.0e [N/m] \t c = %.0e [N/(m/s)]\n', stewart.actuators.K(1), stewart.actuators.C(1))
    +  elseif stewart.actuators.type == 2
    +      fprintf('- The actuators are mechanicaly amplified.\n')
    +      fprintf('- The vertical stiffness and damping contribution of the piezoelectric stack is:\n')
    +      fprintf('\t ka = %.0e [N/m] \t ca = %.0e [N/(m/s)]\n', stewart.actuators.Ka(1), stewart.actuators.Ca(1))
    +      fprintf('- Vertical stiffness when the piezoelectric stack is removed is:\n')
    +      fprintf('\t kr = %.0e [N/m] \t cr = %.0e [N/(m/s)]\n', stewart.actuators.Kr(1), stewart.actuators.Cr(1))
    +  end
    +  fprintf('\n')
     
    -
    -

    12.3 Joints

    +
    +

    12.3 Joints

    -
    fprintf('JOINTS:\n')
    +
      fprintf('JOINTS:\n')
     
    @@ -1974,16 +1979,16 @@ fprintf('\n') Type of the joints on the fixed base.

    -
    switch stewart.joints_F.type
    -  case 1
    -    fprintf('- The joints on the fixed based are universal joints\n')
    -  case 2
    -    fprintf('- The joints on the fixed based are spherical joints\n')
    -  case 3
    -    fprintf('- The joints on the fixed based are perfect universal joints\n')
    -  case 4
    -    fprintf('- The joints on the fixed based are perfect spherical joints\n')
    -end
    +
      switch stewart.joints_F.type
    +    case 1
    +      fprintf('- The joints on the fixed based are universal joints\n')
    +    case 2
    +      fprintf('- The joints on the fixed based are spherical joints\n')
    +    case 3
    +      fprintf('- The joints on the fixed based are perfect universal joints\n')
    +    case 4
    +      fprintf('- The joints on the fixed based are perfect spherical joints\n')
    +  end
     
    @@ -1991,16 +1996,16 @@ Type of the joints on the fixed base. Type of the joints on the mobile platform.

    -
    switch stewart.joints_M.type
    -  case 1
    -    fprintf('- The joints on the mobile based are universal joints\n')
    -  case 2
    -    fprintf('- The joints on the mobile based are spherical joints\n')
    -  case 3
    -    fprintf('- The joints on the mobile based are perfect universal joints\n')
    -  case 4
    -    fprintf('- The joints on the mobile based are perfect spherical joints\n')
    -end
    +
      switch stewart.joints_M.type
    +    case 1
    +      fprintf('- The joints on the mobile based are universal joints\n')
    +    case 2
    +      fprintf('- The joints on the mobile based are spherical joints\n')
    +    case 3
    +      fprintf('- The joints on the mobile based are perfect universal joints\n')
    +    case 4
    +      fprintf('- The joints on the mobile based are perfect spherical joints\n')
    +  end
     
    @@ -2008,8 +2013,8 @@ Type of the joints on the mobile platform. Position of the fixed joints

    -
    fprintf('- The position of the joints on the fixed based with respect to {F} are (in [mm]):\n')
    -fprintf('\t % .3g \t % .3g \t % .3g\n', 1e3*stewart.platform_F.Fa)
    +
      fprintf('- The position of the joints on the fixed based with respect to {F} are (in [mm]):\n')
    +  fprintf('\t % .3g \t % .3g \t % .3g\n', 1e3*stewart.platform_F.Fa)
     
    @@ -2017,40 +2022,40 @@ fprintf('\t % .3g \t % .3g \t % .3g\n', 1e3
    -
    fprintf('- The position of the joints on the mobile based with respect to {M} are (in [mm]):\n')
    -fprintf('\t % .3g \t % .3g \t % .3g\n', 1e3*stewart.platform_M.Mb)
    -fprintf('\n')
    +
      fprintf('- The position of the joints on the mobile based with respect to {M} are (in [mm]):\n')
    +  fprintf('\t % .3g \t % .3g \t % .3g\n', 1e3*stewart.platform_M.Mb)
    +  fprintf('\n')
     
    -
    -

    12.4 Kinematics

    +
    +

    12.4 Kinematics

    -
    fprintf('KINEMATICS:\n')
    +
      fprintf('KINEMATICS:\n')
     
    -if isfield(stewart.kinematics, 'K')
    -  fprintf('- The Stiffness matrix K is (in [N/m]):\n')
    -  fprintf('\t % .0e \t % .0e \t % .0e \t % .0e \t % .0e \t % .0e\n', stewart.kinematics.K)
    -end
    +  if isfield(stewart.kinematics, 'K')
    +    fprintf('- The Stiffness matrix K is (in [N/m]):\n')
    +    fprintf('\t % .0e \t % .0e \t % .0e \t % .0e \t % .0e \t % .0e\n', stewart.kinematics.K)
    +  end
     
    -if isfield(stewart.kinematics, 'C')
    -  fprintf('- The Damping matrix C is (in [m/N]):\n')
    -  fprintf('\t % .0e \t % .0e \t % .0e \t % .0e \t % .0e \t % .0e\n', stewart.kinematics.C)
    -end
    +  if isfield(stewart.kinematics, 'C')
    +    fprintf('- The Damping matrix C is (in [m/N]):\n')
    +    fprintf('\t % .0e \t % .0e \t % .0e \t % .0e \t % .0e \t % .0e\n', stewart.kinematics.C)
    +  end
     
    -
    -

    13 generateCubicConfiguration: Generate a Cubic Configuration

    +
    +

    13 generateCubicConfiguration: Generate a Cubic Configuration

    - +

    @@ -2058,38 +2063,38 @@ This Matlab function is accessible

    -
    -

    Function description

    -
    +
    +

    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}
     
    -
    -

    Documentation

    -
    +
    +

    Documentation

    +
    -
    + -
    -

    Optional Parameters

    -
    +
    +

    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
     
    -
    -

    Check the stewart structure elements

    -
    +
    +

    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;
     
    -
    -

    Position of the Cube

    -
    +
    +

    Position of the Cube

    +

    We define the useful points of the cube with respect to the Cube’s center. \({}^{C}C\) are the 6 vertices of the cubes expressed in a frame {C} which is located at the center of the cube and aligned with {F} and {M}.

    -
    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
     
    -
    -

    Compute the pose

    -
    +
    +

    Compute the pose

    +

    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);
     
    @@ -2165,30 +2170,30 @@ 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;
     
    -
    -

    Populate the stewart structure

    -
    +
    +

    Populate the stewart structure

    +
    -
    stewart.platform_F.Fa = Fa;
    -stewart.platform_M.Mb = Mb;
    +
      stewart.platform_F.Fa = Fa;
    +  stewart.platform_M.Mb = Mb;
     
    -
    -

    14 computeJacobian: Compute the Jacobian Matrix

    +
    +

    14 computeJacobian: Compute the Jacobian Matrix

    - +

    @@ -2196,86 +2201,86 @@ This Matlab function is accessible here.

    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [stewart] = computeJacobian(stewart)
    -% computeJacobian -
    -%
    -% Syntax: [stewart] = computeJacobian(stewart)
    -%
    -% Inputs:
    -%    - stewart - With at least the following fields:
    -%      - geometry.As [3x6] - The 6 unit vectors for each strut expressed in {A}
    -%      - geometry.Ab [3x6] - The 6 position of the joints bi expressed in {A}
    -%      - actuators.K [6x1] - Total stiffness of the actuators
    -%
    -% Outputs:
    -%    - stewart - With the 3 added field:
    -%        - kinematics.J [6x6] - The Jacobian Matrix
    -%        - kinematics.K [6x6] - The Stiffness Matrix
    -%        - kinematics.C [6x6] - The Compliance Matrix
    +
      function [stewart] = computeJacobian(stewart)
    +  % computeJacobian -
    +  %
    +  % Syntax: [stewart] = computeJacobian(stewart)
    +  %
    +  % Inputs:
    +  %    - stewart - With at least the following fields:
    +  %      - geometry.As [3x6] - The 6 unit vectors for each strut expressed in {A}
    +  %      - geometry.Ab [3x6] - The 6 position of the joints bi expressed in {A}
    +  %      - actuators.K [6x1] - Total stiffness of the actuators
    +  %
    +  % Outputs:
    +  %    - stewart - With the 3 added field:
    +  %        - kinematics.J [6x6] - The Jacobian Matrix
    +  %        - kinematics.K [6x6] - The Stiffness Matrix
    +  %        - kinematics.C [6x6] - The Compliance Matrix
     
    -
    -

    Check the stewart structure elements

    -
    +
    +

    Check the stewart structure elements

    +
    -
    assert(isfield(stewart.geometry, 'As'),   'stewart.geometry should have attribute As')
    -As = stewart.geometry.As;
    +
      assert(isfield(stewart.geometry, 'As'),   'stewart.geometry should have attribute As')
    +  As = stewart.geometry.As;
     
    -assert(isfield(stewart.geometry, 'Ab'),   'stewart.geometry should have attribute Ab')
    -Ab = stewart.geometry.Ab;
    +  assert(isfield(stewart.geometry, 'Ab'),   'stewart.geometry should have attribute Ab')
    +  Ab = stewart.geometry.Ab;
     
    -assert(isfield(stewart.actuators, 'K'),   'stewart.actuators should have attribute K')
    -Ki = stewart.actuators.K;
    +  assert(isfield(stewart.actuators, 'K'),   'stewart.actuators should have attribute K')
    +  Ki = stewart.actuators.K;
     
    -
    -

    Compute Jacobian Matrix

    -
    +
    +

    Compute Jacobian Matrix

    +
    -
    J = [As' , cross(Ab, As)'];
    +
      J = [As' , cross(Ab, As)'];
     
    -
    -

    Compute Stiffness Matrix

    -
    +
    +

    Compute Stiffness Matrix

    +
    -
    K = J'*diag(Ki)*J;
    +
      K = J'*diag(Ki)*J;
     
    -
    -

    Compute Compliance Matrix

    -
    +
    +

    Compute Compliance Matrix

    +
    -
    C = inv(K);
    +
      C = inv(K);
     
    -
    -

    Populate the stewart structure

    -
    +
    +

    Populate the stewart structure

    +
    -
    stewart.kinematics.J = J;
    -stewart.kinematics.K = K;
    -stewart.kinematics.C = C;
    +
      stewart.kinematics.J = J;
    +  stewart.kinematics.K = K;
    +  stewart.kinematics.C = C;
     
    @@ -2283,11 +2288,11 @@ stewart.kinematics.C = C;
    -
    -

    15 inverseKinematics: Compute Inverse Kinematics

    +
    +

    15 inverseKinematics: Compute Inverse Kinematics

    -
    -

    Theory

    -
    +
    +

    Theory

    +

    For inverse kinematic analysis, it is assumed that the position \({}^A\bm{P}\) and orientation of the moving platform \({}^A\bm{R}_B\) are given and the problem is to obtain the joint variables, namely, \(\bm{L} = [l_1, l_2, \dots, l_6]^T\).

    @@ -2331,85 +2336,85 @@ Otherwise, when the limbs’ lengths derived yield complex numbers, then the
    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [Li, dLi] = inverseKinematics(stewart, args)
    -% inverseKinematics - Compute the needed length of each strut to have the wanted position and orientation of {B} with respect to {A}
    -%
    -% Syntax: [stewart] = inverseKinematics(stewart)
    -%
    -% Inputs:
    -%    - stewart - A structure with the following fields
    -%        - geometry.Aa   [3x6] - The positions ai expressed in {A}
    -%        - geometry.Bb   [3x6] - The positions bi expressed in {B}
    -%        - geometry.l    [6x1] - Length of each strut
    -%    - args - Can have the following fields:
    -%        - AP   [3x1] - The wanted position of {B} with respect to {A}
    -%        - ARB  [3x3] - The rotation matrix that gives the wanted orientation of {B} with respect to {A}
    -%
    -% Outputs:
    -%    - Li   [6x1] - The 6 needed length of the struts in [m] to have the wanted pose of {B} w.r.t. {A}
    -%    - dLi  [6x1] - The 6 needed displacement of the struts from the initial position in [m] to have the wanted pose of {B} w.r.t. {A}
    +
      function [Li, dLi] = inverseKinematics(stewart, args)
    +  % inverseKinematics - Compute the needed length of each strut to have the wanted position and orientation of {B} with respect to {A}
    +  %
    +  % Syntax: [stewart] = inverseKinematics(stewart)
    +  %
    +  % Inputs:
    +  %    - stewart - A structure with the following fields
    +  %        - geometry.Aa   [3x6] - The positions ai expressed in {A}
    +  %        - geometry.Bb   [3x6] - The positions bi expressed in {B}
    +  %        - geometry.l    [6x1] - Length of each strut
    +  %    - args - Can have the following fields:
    +  %        - AP   [3x1] - The wanted position of {B} with respect to {A}
    +  %        - ARB  [3x3] - The rotation matrix that gives the wanted orientation of {B} with respect to {A}
    +  %
    +  % Outputs:
    +  %    - Li   [6x1] - The 6 needed length of the struts in [m] to have the wanted pose of {B} w.r.t. {A}
    +  %    - dLi  [6x1] - The 6 needed displacement of the struts from the initial position in [m] to have the wanted pose of {B} w.r.t. {A}
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    stewart
    -    args.AP  (3,1) double {mustBeNumeric} = zeros(3,1)
    -    args.ARB (3,3) double {mustBeNumeric} = eye(3)
    -end
    +
      arguments
    +      stewart
    +      args.AP  (3,1) double {mustBeNumeric} = zeros(3,1)
    +      args.ARB (3,3) double {mustBeNumeric} = eye(3)
    +  end
     
    -
    -

    Check the stewart structure elements

    -
    +
    +

    Check the stewart structure elements

    +
    -
    assert(isfield(stewart.geometry, 'Aa'),   'stewart.geometry should have attribute Aa')
    -Aa = stewart.geometry.Aa;
    +
      assert(isfield(stewart.geometry, 'Aa'),   'stewart.geometry should have attribute Aa')
    +  Aa = stewart.geometry.Aa;
     
    -assert(isfield(stewart.geometry, 'Bb'),   'stewart.geometry should have attribute Bb')
    -Bb = stewart.geometry.Bb;
    +  assert(isfield(stewart.geometry, 'Bb'),   'stewart.geometry should have attribute Bb')
    +  Bb = stewart.geometry.Bb;
     
    -assert(isfield(stewart.geometry, 'l'),   'stewart.geometry should have attribute l')
    -l = stewart.geometry.l;
    +  assert(isfield(stewart.geometry, 'l'),   'stewart.geometry should have attribute l')
    +  l = stewart.geometry.l;
     
    -
    -

    Compute

    -
    +
    +

    Compute

    +
    -
    Li = sqrt(args.AP'*args.AP + diag(Bb'*Bb) + diag(Aa'*Aa) - (2*args.AP'*Aa)' + (2*args.AP'*(args.ARB*Bb))' - diag(2*(args.ARB*Bb)'*Aa));
    +
      Li = sqrt(args.AP'*args.AP + diag(Bb'*Bb) + diag(Aa'*Aa) - (2*args.AP'*Aa)' + (2*args.AP'*(args.ARB*Bb))' - diag(2*(args.ARB*Bb)'*Aa));
     
    -
    dLi = Li-l;
    +
      dLi = Li-l;
     
    -
    -

    16 forwardKinematicsApprox: Compute the Approximate Forward Kinematics

    +
    +

    16 forwardKinematicsApprox: Compute the Approximate Forward Kinematics

    - +

    @@ -2417,64 +2422,64 @@ This Matlab function is accessible he

    -
    -

    Function description

    -
    +
    +

    Function description

    +
    -
    function [P, R] = forwardKinematicsApprox(stewart, args)
    -% forwardKinematicsApprox - Computed the approximate pose of {B} with respect to {A} from the length of each strut and using
    -%                           the Jacobian Matrix
    -%
    -% Syntax: [P, R] = forwardKinematicsApprox(stewart, args)
    -%
    -% Inputs:
    -%    - stewart - A structure with the following fields
    -%        - kinematics.J  [6x6] - The Jacobian Matrix
    -%    - args - Can have the following fields:
    -%        - dL [6x1] - Displacement of each strut [m]
    -%
    -% Outputs:
    -%    - P  [3x1] - The estimated position of {B} with respect to {A}
    -%    - R  [3x3] - The estimated rotation matrix that gives the orientation of {B} with respect to {A}
    +
      function [P, R] = forwardKinematicsApprox(stewart, args)
    +  % forwardKinematicsApprox - Computed the approximate pose of {B} with respect to {A} from the length of each strut and using
    +  %                           the Jacobian Matrix
    +  %
    +  % Syntax: [P, R] = forwardKinematicsApprox(stewart, args)
    +  %
    +  % Inputs:
    +  %    - stewart - A structure with the following fields
    +  %        - kinematics.J  [6x6] - The Jacobian Matrix
    +  %    - args - Can have the following fields:
    +  %        - dL [6x1] - Displacement of each strut [m]
    +  %
    +  % Outputs:
    +  %    - P  [3x1] - The estimated position of {B} with respect to {A}
    +  %    - R  [3x3] - The estimated rotation matrix that gives the orientation of {B} with respect to {A}
     
    -
    -

    Optional Parameters

    -
    +
    +

    Optional Parameters

    +
    -
    arguments
    -    stewart
    -    args.dL (6,1) double {mustBeNumeric} = zeros(6,1)
    -end
    +
      arguments
    +      stewart
    +      args.dL (6,1) double {mustBeNumeric} = zeros(6,1)
    +  end
     
    -
    -

    Check the stewart structure elements

    -
    +
    +

    Check the stewart structure elements

    +
    -
    assert(isfield(stewart.kinematics, 'J'),   'stewart.kinematics should have attribute J')
    -J = stewart.kinematics.J;
    +
      assert(isfield(stewart.kinematics, 'J'),   'stewart.kinematics should have attribute J')
    +  J = stewart.kinematics.J;
     
    -
    -

    Computation

    -
    +
    +

    Computation

    +

    From a small displacement of each strut \(d\bm{\mathcal{L}}\), we can compute the position and orientation of {B} with respect to {A} using the following formula: \[ d \bm{\mathcal{X}} = \bm{J}^{-1} d\bm{\mathcal{L}} \]

    -
    X = J\args.dL;
    +
      X = J\args.dL;
     
    @@ -2482,7 +2487,7 @@ position and orientation of {B} with respect to {A} using the following formula: The position vector corresponds to the first 3 elements.

    -
    P = X(1:3);
    +
      P = X(1:3);
     
    @@ -2491,8 +2496,8 @@ The next 3 elements are the orientation of {B} with respect to {A} expressed using the screw axis.

    -
    theta = norm(X(4:6));
    -s = X(4:6)/theta;
    +
      theta = norm(X(4:6));
    +  s = X(4:6)/theta;
     
    @@ -2500,9 +2505,9 @@ s = X(4:6)/theta; We then compute the corresponding rotation matrix.

    -
    R = [s(1)^2*(1-cos(theta)) + cos(theta) ,        s(1)*s(2)*(1-cos(theta)) - s(3)*sin(theta), s(1)*s(3)*(1-cos(theta)) + s(2)*sin(theta);
    -     s(2)*s(1)*(1-cos(theta)) + s(3)*sin(theta), s(2)^2*(1-cos(theta)) + cos(theta),         s(2)*s(3)*(1-cos(theta)) - s(1)*sin(theta);
    -     s(3)*s(1)*(1-cos(theta)) - s(2)*sin(theta), s(3)*s(2)*(1-cos(theta)) + s(1)*sin(theta), s(3)^2*(1-cos(theta)) + cos(theta)];
    +
      R = [s(1)^2*(1-cos(theta)) + cos(theta) ,        s(1)*s(2)*(1-cos(theta)) - s(3)*sin(theta), s(1)*s(3)*(1-cos(theta)) + s(2)*sin(theta);
    +       s(2)*s(1)*(1-cos(theta)) + s(3)*sin(theta), s(2)^2*(1-cos(theta)) + cos(theta),         s(2)*s(3)*(1-cos(theta)) - s(1)*sin(theta);
    +       s(3)*s(1)*(1-cos(theta)) - s(2)*sin(theta), s(3)*s(2)*(1-cos(theta)) + s(1)*sin(theta), s(3)^2*(1-cos(theta)) + cos(theta)];
     
    @@ -2511,7 +2516,7 @@ We then compute the corresponding rotation matrix.

    Author: Dehaeze Thomas

    -

    Created: 2020-11-03 mar. 09:45

    +

    Created: 2021-02-20 sam. 23:09

    diff --git a/docs/uncertainty_experiment.html b/docs/uncertainty_experiment.html index 6a62a5e..da86716 100644 --- a/docs/uncertainty_experiment.html +++ b/docs/uncertainty_experiment.html @@ -1,57 +1,61 @@ - - + Evaluating the Plant Uncertainty in various experimental conditions - - - - - - - - + + + +

    Evaluating the Plant Uncertainty in various experimental conditions

    @@ -64,12 +68,12 @@ The goal of this document is to study how the dynamics of the system is changing These experimental conditions are:

      -
    • Section 1: Sample mass (from 1Kg to 50Kg)
    • -
    • Section 2: Sample dynamics (mostly main resonance frequency)
    • -
    • Section 3: The spindle angle
    • -
    • Section 4: The spindle rotation speed (from 1rpm to 60rpm)
    • -
    • Section 5: The tilt angle (from -3 to 3 degrees)
    • -
    • Section 6: Pose of the micro-hexapod
    • +
    • Section 1: Sample mass (from 1Kg to 50Kg)
    • +
    • Section 2: Sample dynamics (mostly main resonance frequency)
    • +
    • Section 3: The spindle angle
    • +
    • Section 4: The spindle rotation speed (from 1rpm to 60rpm)
    • +
    • Section 5: The tilt angle (from -3 to 3 degrees)
    • +
    • Section 6: Pose of the micro-hexapod

    @@ -89,14 +93,14 @@ The variability of the dynamics is studied for two nano-hexapod concepts:

    -The conclusions are drawn in Section 7 +The conclusions are drawn in Section 7

    -
    -

    1 Variation of the Sample Mass

    +
    +

    1 Variation of the Sample Mass

    - +

    We here study the change of dynamics due to the sample mass. @@ -107,34 +111,34 @@ We initialize all the stages with the default parameters. We identify the dynamics for the following sample masses, both with a soft and stiff nano-hexapod.

    -
    masses = [1, 10, 50]; % [kg]
    +
      masses = [1, 10, 50]; % [kg]
     

    The following transfer functions are shown:

      -
    • Figure 1: From actuator forces to force sensors in each nano-hexapod’s leg
    • -
    • Figure 2: From actuator forces to relative displacement of each nano-hexapod’s leg
    • -
    • Figure 3 (resp. 4): From forces applied in the task space by the nano-hexapod to displacement of the sample in the X direction (resp. in the Z direction)
    • +
    • Figure 1: From actuator forces to force sensors in each nano-hexapod’s leg
    • +
    • Figure 2: From actuator forces to relative displacement of each nano-hexapod’s leg
    • +
    • Figure 3 (resp. 4): From forces applied in the task space by the nano-hexapod to displacement of the sample in the X direction (resp. in the Z direction)
    -
    +

    dynamics_variability_iff_sample_mass.png

    Figure 1: Variability of the dynamics from actuator force to force sensor with the Sample Mass (png, pdf)

    -
    +

    dynamics_variability_dvf_sample_mass.png

    Figure 2: Variability of the dynamics from actuator force to relative motion sensor with the Sample Mass (png, pdf)

    -
    +

    dynamics_variability_err_x_sample_mass.png

    Figure 3: Variability of the dynamics from Forces applied in task space (X direction) to the displacement of the sample in the X direction (png, pdf)

    @@ -142,12 +146,12 @@ The following transfer functions are shown: -
    +

    dynamics_variability_err_z_sample_mass.png

    Figure 4: Variability of the dynamics from vertical forces applied in the task space to the displacement of the sample in the vertical direction (png, pdf)

    -
    +

    Let’s note \(\omega_0\) the first resonance which corresponds to the resonance of the payload+nano-hexapod top platform resonating on top of the nano-hexapod base.

    @@ -203,51 +207,51 @@ This is more easily seem with the soft nano-hexapod as the resonance \(\omega_0\
    -
    -

    2 Variation of the Sample Resonance Frequency

    +
    +

    2 Variation of the Sample Resonance Frequency

    - +

    We initialize all the stages with the default parameters. We identify the dynamics for the following sample resonance frequency.

    -
    mass_w = [50, 100, 500]; % [Hz]
    -mass = 10; % [Kg]
    +
      mass_w = [50, 100, 500]; % [Hz]
    +  mass = 10; % [Kg]
     

    The following transfer functions are shown:

      -
    • Figure 5: From actuator forces to force sensors in each nano-hexapod’s leg
    • -
    • Figure 6: From actuator forces to relative displacement of each nano-hexapod’s leg
    • -
    • Figure 7: From forces applied in the task space by the nano-hexapod to displacement of the sample in the X direction
    • +
    • Figure 5: From actuator forces to force sensors in each nano-hexapod’s leg
    • +
    • Figure 6: From actuator forces to relative displacement of each nano-hexapod’s leg
    • +
    • Figure 7: From forces applied in the task space by the nano-hexapod to displacement of the sample in the X direction
    -
    +

    dynamics_variability_iff_sample_w.png

    Figure 5: Variability of the dynamics from actuator force to force sensor with the Sample Mass (png, pdf)

    -
    +

    dynamics_variability_dvf_sample_w.png

    Figure 6: Variability of the dynamics from actuator force to relative motion sensor with the Sample Mass (png, pdf)

    -
    +

    dynamics_variability_err_sample_w.png

    Figure 7: Variability of the dynamics from a torque applied on the sample by the nano-hexapod in the X direction to the rotation of the sample around the X axis (png, pdf)

    -
    +

    Let’s note \(\omega_m\) the frequency of the resonance of the Payload.

    @@ -293,22 +297,22 @@ Let’s note \(\omega_m\) the frequency of the resonance of the Payload.
    -
    -

    3 Variation of the Spindle Angle

    +
    +

    3 Variation of the Spindle Angle

    - +

    -
    -

    3.1 Identification

    +
    +

    3.1 Identification

    We identify the dynamics for the following Tilt stage angles.

    -
    initializeSample('mass', 50);
    -Rz_amplitudes = [0, pi/4, pi/2, pi]; % [rad]
    +
      initializeSample('mass', 50);
    +  Rz_amplitudes = [0, pi/4, pi/2, pi]; % [rad]
     
    @@ -319,19 +323,19 @@ Rz_amplitudes = [0, pi/4, pi/2, pi]; % [rad] The following transfer functions are shown:

      -
    • Figure 8: From actuator forces to force sensors in each nano-hexapod’s leg
    • -
    • Figure 9: From forces applied in the task space by the nano-hexapod to displacement of the sample in the X direction
    • +
    • Figure 8: From actuator forces to force sensors in each nano-hexapod’s leg
    • +
    • Figure 9: From forces applied in the task space by the nano-hexapod to displacement of the sample in the X direction
    -
    +

    dynamics_variability_iff_spindle_angle.png

    Figure 8: Variability of the dynamics from the actuator force to the force sensor with the Spindle Angle (png, pdf)

    -
    +

    dynamics_variability_err_spindle_angle.png

    Figure 9: Variability of the dynamics from actuator force to absolute velocity with the Spindle Angle (png, pdf)

    @@ -339,7 +343,7 @@ The following transfer functions are shown:
    -
    +

    The Spindle angle has no visible effect for the soft nano-hexapod.

    @@ -354,23 +358,23 @@ This is probably due to the fact that the micro-station compliance is not unifor
    -
    -

    4 Variation of the Spindle Rotation Speed

    +
    +

    4 Variation of the Spindle Rotation Speed

    - +

    -
    -

    4.1 Initialization of gravity compensation forces

    +
    +

    4.1 Initialization of gravity compensation forces

    We initialize all the stages such that their joints are blocked and we record the total forces/torques applied in each of these joints. We set a payload mass of 10Kg.

    -
    initializeSample('type', 'init', 'mass', 10);
    -nano_hexapod = initializeNanoHexapod( 'type', 'init');
    +
      initializeSample('type', 'init', 'mass', 10);
    +  nano_hexapod = initializeNanoHexapod( 'type', 'init');
     
    @@ -379,56 +383,56 @@ Finally, we simulate the system and same the forces/torques applied in each join

    -
    -

    4.2 Identification

    +
    +

    4.2 Identification

    We initialize the stages with forces/torques compensating the gravity forces. We identify the dynamics for the following Spindle rotation periods.

    -
    Rz_periods = [60, 6, 2, 1]; % [s]
    +
      Rz_periods = [60, 6, 2, 1]; % [s]
     
    -
    -

    4.3 Plots

    +
    +

    4.3 Plots

    The following transfer functions are shown:

      -
    • Figure 10: From actuator forces to force sensors in each nano-hexapod’s leg
    • -
    • Figure 11: From actuator forces to relative displacement of each nano-hexapod’s leg
    • -
    • Figure 12: From forces applied in the task space by the nano-hexapod to displacement of the sample in the X direction
    • -
    • Figure 13: From forces applied in the task space in the X direction by the nano-hexapod to displacement of the sample in the Y direction (coupling)
    • +
    • Figure 10: From actuator forces to force sensors in each nano-hexapod’s leg
    • +
    • Figure 11: From actuator forces to relative displacement of each nano-hexapod’s leg
    • +
    • Figure 12: From forces applied in the task space by the nano-hexapod to displacement of the sample in the X direction
    • +
    • Figure 13: From forces applied in the task space in the X direction by the nano-hexapod to displacement of the sample in the Y direction (coupling)
    -
    +

    dynamics_variability_iff_spindle_speed.png

    Figure 10: Variability of the dynamics from the actuator force to the force sensor with the Spindle rotation speed (png, pdf)

    -
    +

    dynamics_variability_dvf_spindle_speed.png

    Figure 11: Variability of the dynamics from the actuator force to the relative motion sensor with the Spindle rotation speed (png, pdf)

    -
    +

    dynamics_variability_err_spindle_speed.png

    Figure 12: Variability of the dynamics from the actuator force in the task force to the position error of the sample (png, pdf)

    -
    +

    dynamics_variability_err_spindle_speed_coupling.png

    Figure 13: Variability of the coupling from the actuator force in the task force to the position error of the sample (png, pdf)

    @@ -437,7 +441,7 @@ The following transfer functions are shown:
    -
    +

    For the stiff nano-hexapod, the rotation speed of the Spindle does not affect the (main) dynamics. It only affects the coupling due to Coriolis forces. @@ -461,43 +465,43 @@ Also, the coupling from forces applied in the X direction to induced displacemen

    -
    -

    5 Variation of the Tilt Angle

    +
    +

    5 Variation of the Tilt Angle

    - +

    We initialize all the stages with the default parameters. We identify the dynamics for the following Tilt stage angles.

    -
    initializeSample('mass', 50);
    -Ry_amplitudes = [-3*pi/180 0 3*pi/180]; % [rad]
    +
      initializeSample('mass', 50);
    +  Ry_amplitudes = [-3*pi/180 0 3*pi/180]; % [rad]
     

    The following transfer functions are shown:

      -
    • Figure 14: From actuator forces to force sensors in each nano-hexapod’s leg
    • -
    • Figure 15: From forces applied in the task space by the nano-hexapod to displacement of the sample in the X direction
    • +
    • Figure 14: From actuator forces to force sensors in each nano-hexapod’s leg
    • +
    • Figure 15: From forces applied in the task space by the nano-hexapod to displacement of the sample in the X direction
    -
    +

    dynamics_variability_iff_tilt_angle.png

    Figure 14: Variability of the dynamics from the actuator force to the force sensor with the Tilt stage Angle (png, pdf)

    -
    +

    dynamics_variability_err_tilt_angle.png

    Figure 15: Variability of the dynamics from the actuator force in the task space to the displacement of the sample (png, pdf)

    -
    +

    The tilt angle has no visible effect on the dynamics.

    @@ -506,34 +510,34 @@ The tilt angle has no visible effect on the dynamics.
    -
    -

    6 Variation of the micro-hexapod pose

    +
    +

    6 Variation of the micro-hexapod pose

    - +

    We initialize all the stages with the default parameters. We identify the dynamics for the following translations of the micro-hexapod in the X direction.

    -
    Tx_amplitudes = [0, 5e-3, 10e-3]; % [m]
    +
      Tx_amplitudes = [0, 5e-3, 10e-3]; % [m]
     
    -
    +

    dynamics_variability_iff_micro_hexapod_x.png

    Figure 16: Variability of the dynamics from the actuator force to the force sensor with the Tilt stage Angle (png, pdf)

    -
    +

    dynamics_variability_err_micro_hexapod_x.png

    Figure 17: Variability of the dynamics from the actuator force in the task space to the displacement of the sample (png, pdf)

    -
    +

    The pose of the micro-hexapod has negligible effect on the dynamics.

    @@ -542,14 +546,14 @@ The pose of the micro-hexapod has negligible effect on the dynamics.
    -
    -

    7 Conclusion

    +
    +

    7 Conclusion

    - +

    -
    +

    From all the experimental condition studied, the only ones that have significant effect on the dynamics are:

    @@ -603,7 +607,7 @@ From all the experimental condition studied, the only ones that have significant

    Author: Dehaeze Thomas

    -

    Created: 2020-05-05 mar. 10:34

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/uncertainty_optimal_stiffness.html b/docs/uncertainty_optimal_stiffness.html index 6a1ca4b..4e8b055 100644 --- a/docs/uncertainty_optimal_stiffness.html +++ b/docs/uncertainty_optimal_stiffness.html @@ -3,66 +3,71 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> - + Determination of the optimal nano-hexapod’s stiffness - - - - - - - - + + + +

    Determination of the optimal nano-hexapod’s stiffness

    @@ -84,20 +89,20 @@ As seen before, the stiffness of the nano-hexapod greatly influence the effect o We wish here to see if we can determine an optimal stiffness of the nano-hexapod such that:

      -
    • Section 1: the change of its dynamics due to the spindle rotation speed is acceptable
    • -
    • Section 2: the support compliance dynamics is not much present in the nano-hexapod dynamics
    • -
    • Section 3: the change of payload impedance has acceptable effect on the plant dynamics
    • +
    • Section 1: the change of its dynamics due to the spindle rotation speed is acceptable
    • +
    • Section 2: the support compliance dynamics is not much present in the nano-hexapod dynamics
    • +
    • Section 3: the change of payload impedance has acceptable effect on the plant dynamics

    The overall goal is to design a nano-hexapod that will allow the highest possible control bandwidth.

    -
    -

    1 Spindle Rotation Speed

    +
    +

    1 Spindle Rotation Speed

    - +

    In this section, we look at the effect of the spindle rotation speed on the plant dynamics. @@ -108,21 +113,21 @@ The rotation speed will have an effect due to the Coriolis effect.

    -
    -

    1.1 Initialization

    +
    +

    1.1 Initialization

    We initialize all the stages with the default parameters.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
     
    @@ -130,7 +135,7 @@ initializeMirror(); We use a sample mass of 10kg.

    -
    initializeSample('mass', 10);
    +
      initializeSample('mass', 10);
     
    @@ -139,23 +144,23 @@ We don’t include disturbances in this model as it adds complexity to the s We however include gravity.

    -
    initializeSimscapeConfiguration('gravity', true);
    -initializeDisturbances('enable', false);
    -initializeLoggingConfiguration('log', 'none');
    -initializeController();
    +
      initializeSimscapeConfiguration('gravity', true);
    +  initializeDisturbances('enable', false);
    +  initializeLoggingConfiguration('log', 'none');
    +  initializeController();
     
    -
    -

    1.2 Identification when rotating at maximum speed

    +
    +

    1.2 Identification when rotating at maximum speed

    We identify the dynamics for the following spindle rotation speeds Rz_rpm:

    -
    Rz_rpm = linspace(0, 60, 6);
    +
      Rz_rpm = linspace(0, 60, 6);
     
    @@ -163,55 +168,55 @@ We identify the dynamics for the following spindle rotation speeds Rz_rpm< And for the following nano-hexapod actuator stiffness Ks:

    -
    Ks = logspace(3,9,7); % [N/m]
    +
      Ks = logspace(3,9,7); % [N/m]
     
    -
    -

    1.3 Change of dynamics

    +
    +

    1.3 Change of dynamics

    We plot the change of dynamics due to the change of the spindle rotation speed (from 0rpm to 60rpm):

      -
    • Figure 2: from actuator force \(\tau\) to force sensor \(\tau_m\) (IFF plant)
    • -
    • Figure 3: from actuator force \(\tau\) to actuator relative displacement \(d\mathcal{L}\) (Decentralized positioning plant)
    • -
    • Figure 4: from force in the task space \(\mathcal{F}_x\) to sample displacement \(\mathcal{X}_x\) (Centralized positioning plant)
    • -
    • Figure 5: from force in the task space \(\mathcal{F}_x\) to sample displacement \(\mathcal{X}_y\) (coupling of the centralized positioning plant)
    • +
    • Figure 2: from actuator force \(\tau\) to force sensor \(\tau_m\) (IFF plant)
    • +
    • Figure 3: from actuator force \(\tau\) to actuator relative displacement \(d\mathcal{L}\) (Decentralized positioning plant)
    • +
    • Figure 4: from force in the task space \(\mathcal{F}_x\) to sample displacement \(\mathcal{X}_x\) (Centralized positioning plant)
    • +
    • Figure 5: from force in the task space \(\mathcal{F}_x\) to sample displacement \(\mathcal{X}_y\) (coupling of the centralized positioning plant)
    -
    +

    opti_stiffness_iff_root_locus.png

    Figure 1: Root Locus plot for IFF control when not rotating (in red) and when rotating at 60rpm (in blue) for 4 different nano-hexapod stiffnesses (png, pdf)

    -
    +

    opt_stiffness_wz_iff.png

    Figure 2: Change of dynamics from actuator \(\tau\) to actuator force sensor \(\tau_m\) for a spindle rotation speed from 0rpm to 60rpm (png, pdf)

    -
    +

    opt_stiffness_wz_dvf.png

    Figure 3: Change of dynamics from actuator force \(\tau\) to actuator displacement \(d\mathcal{L}\) for a spindle rotation speed from 0rpm to 60rpm (png, pdf)

    -
    +

    opt_stiffness_wz_fx_dx.png

    Figure 4: Change of dynamics from force \(\mathcal{F}_x\) to displacement \(\mathcal{X}_x\) for a spindle rotation speed from 0rpm to 60rpm (png, pdf)

    -
    +

    opt_stiffness_wz_coupling.png

    Figure 5: Change of Coupling from force \(\mathcal{F}_x\) to displacement \(\mathcal{X}_y\) for a spindle rotation speed from 0rpm to 60rpm (png, pdf)

    @@ -220,7 +225,7 @@ We plot the change of dynamics due to the change of the spindle rotation speed (
    -
    +

    The leg stiffness should be at higher than \(k_i = 10^4\ [N/m]\) such that the main resonance frequency does not shift too much when rotating. For the coupling, it is more difficult to conclude about the minimum required leg stiffness. @@ -228,7 +233,7 @@ For the coupling, it is more difficult to conclude about the minimum required le

    -
    +

    Note that we can use very soft nano-hexapod if we limit the spindle rotating speed.

    @@ -237,11 +242,11 @@ Note that we can use very soft nano-hexapod if we limit the spindle rotating spe
    -
    -

    2 Micro-Station Compliance Effect

    +
    +

    2 Micro-Station Compliance Effect

    - +

    • take the 6dof compliance of the micro-station
    • @@ -249,19 +254,19 @@ Note that we can use very soft nano-hexapod if we limit the spindle rotating spe
    -
    -

    2.1 Identification of the micro-station compliance

    +
    +

    2.1 Identification of the micro-station compliance

    We initialize all the stages with the default parameters.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod('type', 'compliance');
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod('type', 'compliance');
     
    @@ -269,20 +274,20 @@ initializeMicroHexapod('type', 'compliance'); We put nothing on top of the micro-hexapod.

    -
    initializeAxisc('type', 'none');
    -initializeMirror('type', 'none');
    -initializeNanoHexapod('type', 'none');
    -initializeSample('type', 'none');
    +
      initializeAxisc('type', 'none');
    +  initializeMirror('type', 'none');
    +  initializeNanoHexapod('type', 'none');
    +  initializeSample('type', 'none');
     

    And we identify the dynamics from forces/torques applied on the micro-hexapod top platform to the motion of the micro-hexapod top platform at the same point. -The diagonal element of the identified Micro-Station compliance matrix are shown in Figure 6. +The diagonal element of the identified Micro-Station compliance matrix are shown in Figure 6.

    -
    +

    opt_stiff_micro_station_compliance.png

    Figure 6: Identified Compliance of the Micro-Station (png, pdf)

    @@ -290,8 +295,8 @@ The diagonal element of the identified Micro-Station compliance matrix are shown
    -
    -

    2.2 Identification of the dynamics with a rigid micro-station

    +
    +

    2.2 Identification of the dynamics with a rigid micro-station

    We now identify the dynamics when the micro-station is rigid. @@ -299,7 +304,7 @@ This is equivalent of identifying the dynamics of the nano-hexapod when fixed to We also choose the sample to be rigid and to have a mass of 10kg.

    -
    initializeSample('type', 'rigid', 'mass', 10);
    +
      initializeSample('type', 'rigid', 'mass', 10);
     
    @@ -307,14 +312,14 @@ We also choose the sample to be rigid and to have a mass of 10kg. As before, we identify the dynamics for the following actuator stiffnesses:

    -
    Ks = logspace(3,9,7); % [N/m]
    +
      Ks = logspace(3,9,7); % [N/m]
     
    -
    -

    2.3 Identification of the dynamics with a flexible micro-station

    +
    +

    2.3 Identification of the dynamics with a flexible micro-station

    We now initialize all the micro-station stages to be flexible. @@ -322,43 +327,43 @@ And we identify the dynamics of the nano-hexapod.

    -
    -

    2.4 Obtained Dynamics

    +
    +

    2.4 Obtained Dynamics

    We plot the change of dynamics due to the compliance of the Micro-Station. The solid curves are corresponding to the nano-hexapod without the micro-station, and the dashed curves with the micro-station:

      -
    • Figure 7: from actuator force \(\tau\) to force sensor \(\tau_m\) (IFF plant)
    • -
    • Figure 8: from actuator force \(\tau\) to actuator relative displacement \(d\mathcal{L}\) (Decentralized positioning plant)
    • -
    • Figure 9: from force in the task space \(\mathcal{F}_x\) to sample displacement \(\mathcal{X}_x\) (Centralized positioning plant)
    • -
    • Figure 10: from force in the task space \(\mathcal{F}_z\) to sample displacement \(\mathcal{X}_z\) (Centralized positioning plant)
    • +
    • Figure 7: from actuator force \(\tau\) to force sensor \(\tau_m\) (IFF plant)
    • +
    • Figure 8: from actuator force \(\tau\) to actuator relative displacement \(d\mathcal{L}\) (Decentralized positioning plant)
    • +
    • Figure 9: from force in the task space \(\mathcal{F}_x\) to sample displacement \(\mathcal{X}_x\) (Centralized positioning plant)
    • +
    • Figure 10: from force in the task space \(\mathcal{F}_z\) to sample displacement \(\mathcal{X}_z\) (Centralized positioning plant)
    -
    +

    opt_stiffness_micro_station_iff.png

    Figure 7: Change of dynamics from actuator \(\tau\) to actuator force sensor \(\tau_m\) due to the micro-station compliance (png, pdf)

    -
    +

    opt_stiffness_micro_station_dvf.png

    Figure 8: Change of dynamics from actuator force \(\tau\) to actuator displacement \(d\mathcal{L}\) due to the micro-station compliance (png, pdf)

    -
    +

    opt_stiffness_micro_station_fx_dx.png

    Figure 9: Change of dynamics from force \(\mathcal{F}_x\) to displacement \(\mathcal{X}_x\) due to the micro-station compliance (png, pdf)

    -
    +

    opt_stiffness_micro_station_fz_dz.png

    Figure 10: Change of dynamics from force \(\mathcal{F}_z\) to displacement \(\mathcal{X}_z\) due to the micro-station compliance (png, pdf)

    @@ -367,7 +372,7 @@ The solid curves are corresponding to the nano-hexapod without the micro-station
    -
    +

    The dynamics of the nano-hexapod is not affected by the micro-station dynamics (compliance) when the stiffness of the legs is less than \(10^6\ [N/m]\). When the nano-hexapod is stiff (\(k>10^7\ [N/m]\)), the compliance of the micro-station appears in the primary plant. @@ -377,23 +382,23 @@ When the nano-hexapod is stiff (\(k>10^7\ [N/m]\)), the compliance of the micro-

    -
    -

    3 Payload “Impedance” Effect

    +
    +

    3 Payload “Impedance” Effect

    - +

    -
    -

    3.1 Initialization

    +
    +

    3.1 Initialization

    We initialize all the stages with the default parameters. We don’t include disturbances in this model as it adds complexity to the simulations and does not alter the obtained dynamics. :exports none

    -
    initializeDisturbances('enable', false);
    +
      initializeDisturbances('enable', false);
     
    @@ -401,17 +406,17 @@ We don’t include disturbances in this model as it adds complexity to the s We set the controller type to Open-Loop, and we do not need to log any signal.

    -
    initializeSimscapeConfiguration('gravity', true);
    -initializeController();
    -initializeLoggingConfiguration('log', 'none');
    -initializeReferences();
    +
      initializeSimscapeConfiguration('gravity', true);
    +  initializeController();
    +  initializeLoggingConfiguration('log', 'none');
    +  initializeReferences();
     
    -
    -

    3.2 Identification of the dynamics while change the payload dynamics

    +
    +

    3.2 Identification of the dynamics while change the payload dynamics

    We make the following change of payload dynamics: @@ -426,8 +431,8 @@ We make the following change of payload dynamics: We identify the dynamics for the following payload masses Ms and nano-hexapod leg’s stiffnesses Ks:

    -
    Ms = [1, 20, 50]; % [Kg]
    -Ks = logspace(3,9,7); % [N/m]
    +
      Ms = [1, 20, 50]; % [Kg]
    +  Ks = logspace(3,9,7); % [N/m]
     
    @@ -435,29 +440,29 @@ Ks = logspace(3,9,7); % [N/m] We then identify the dynamics for the following payload resonance frequencies Fs:

    -
    Fs = [50, 200, 500]; % [Hz]
    +
      Fs = [50, 200, 500]; % [Hz]
     
    -
    -

    3.3 Change of dynamics for the primary controller

    +
    +

    3.3 Change of dynamics for the primary controller

    -
    -

    3.3.1 Frequency variation

    +
    +

    3.3.1 Frequency variation

    We here compare the dynamics for the same payload mass, but different stiffness resulting in different resonance frequency of the payload:

      -
    • Figure 11: dynamics from a force \(\mathcal{F}_z\) applied in the task space in the vertical direction to the vertical displacement of the sample \(\mathcal{X}_z\) for both a very soft and a very stiff nano-hexapod.
    • -
    • Figure 12: same, but for all tested nano-hexapod stiffnesses
    • +
    • Figure 11: dynamics from a force \(\mathcal{F}_z\) applied in the task space in the vertical direction to the vertical displacement of the sample \(\mathcal{X}_z\) for both a very soft and a very stiff nano-hexapod.
    • +
    • Figure 12: same, but for all tested nano-hexapod stiffnesses

    -We can see two mass lines for the soft nano-hexapod (Figure 11): +We can see two mass lines for the soft nano-hexapod (Figure 11):

    -
    +

    opt_stiffness_payload_mass_fz_dz.png

    Figure 13: Dynamics from \(\mathcal{F}_z\) to \(\mathcal{X}_z\) for varying payload mass, both for a soft nano-hexapod and a stiff nano-hexapod

    -
    +

    opt_stiffness_payload_mass_all.png

    Figure 14: Dynamics from \(\mathcal{F}_z\) to \(\mathcal{X}_z\) for varying payload mass (png, pdf)

    @@ -518,11 +523,11 @@ We can see here that for the soft nano-hexapod:
    -
    -

    3.3.3 Total variation

    +
    +

    3.3.3 Total variation

    -We now plot the total change of dynamics due to change of the payload (Figures 15 and 16): +We now plot the total change of dynamics due to change of the payload (Figures 15 and 16):

    • mass from 1kg to 50kg
    • @@ -530,14 +535,14 @@ We now plot the total change of dynamics due to change of the payload (Figures <
    -
    +

    opt_stiffness_payload_impedance_all_fz_dz.png

    Figure 15: Dynamics from \(\mathcal{F}_z\) to \(\mathcal{X}_z\) for varying payload dynamics, both for a soft nano-hexapod and a stiff nano-hexapod (png, pdf)

    -
    +

    opt_stiffness_payload_impedance_fz_dz.png

    Figure 16: Dynamics from \(\mathcal{F}_z\) to \(\mathcal{X}_z\) for varying payload dynamics, both for a soft nano-hexapod and a stiff nano-hexapod (png, pdf)

    @@ -547,7 +552,7 @@ We now plot the total change of dynamics due to change of the payload (Figures <
    -
    +

    @@ -556,8 +561,8 @@ We now plot the total change of dynamics due to change of the payload (Figures <
    -
    -

    4 Total Change of dynamics

    +
    +

    4 Total Change of dynamics

    We now consider the total change of nano-hexapod dynamics due to: @@ -572,53 +577,53 @@ We now consider the total change of nano-hexapod dynamics due to: The obtained dynamics are shown:

      -
    • Figure 17 for a stiffness \(k = 10^3\ [N/m]\)
    • -
    • Figure 18 for a stiffness \(k = 10^5\ [N/m]\)
    • -
    • Figure 19 for a stiffness \(k = 10^7\ [N/m]\)
    • -
    • Figure 20 for a stiffness \(k = 10^9\ [N/m]\)
    • +
    • Figure 17 for a stiffness \(k = 10^3\ [N/m]\)
    • +
    • Figure 18 for a stiffness \(k = 10^5\ [N/m]\)
    • +
    • Figure 19 for a stiffness \(k = 10^7\ [N/m]\)
    • +
    • Figure 20 for a stiffness \(k = 10^9\ [N/m]\)

    -And finally, in Figures 21 and 22 are shown an animation of the change of dynamics with the nano-hexapod’s stiffness. +And finally, in Figures 21 and 22 are shown an animation of the change of dynamics with the nano-hexapod’s stiffness.

    -
    +

    opt_stiffness_plant_dynamics_fx_dx_k_1e3.png

    Figure 17: Total variation of the dynamics from \(\mathcal{F}_x\) to \(\mathcal{X}_x\). Nano-hexapod leg’s stiffness is equal to \(k = 10^3\ [N/m]\) (png, pdf)

    -
    +

    opt_stiffness_plant_dynamics_fx_dx_k_1e5.png

    Figure 18: Total variation of the dynamics from \(\mathcal{F}_x\) to \(\mathcal{X}_x\). Nano-hexapod leg’s stiffness is equal to \(k = 10^5\ [N/m]\) (png, pdf)

    -
    +

    opt_stiffness_plant_dynamics_fx_dx_k_1e7.png

    Figure 19: Total variation of the dynamics from \(\mathcal{F}_x\) to \(\mathcal{X}_x\). Nano-hexapod leg’s stiffness is equal to \(k = 10^7\ [N/m]\) (png, pdf)

    -
    +

    opt_stiffness_plant_dynamics_fx_dx_k_1e9.png

    Figure 20: Total variation of the dynamics from \(\mathcal{F}_x\) to \(\mathcal{X}_x\). Nano-hexapod leg’s stiffness is equal to \(k = 10^9\ [N/m]\) (png, pdf)

    -
    +

    opt_stiffness_plant_dynamics_task_space.gif

    Figure 21: Variability of the dynamics from \(\mathcal{F}_x\) to \(\mathcal{X}_x\) with varying nano-hexapod stiffness

    -
    +

    opt_stiffness_plant_dynamics_task_space_colors.gif

    Figure 22: Variability of the dynamics from \(\mathcal{F}_x\) to \(\mathcal{X}_x\) with varying nano-hexapod stiffness

    @@ -628,7 +633,7 @@ And finally, in Figures 21 and 2

    Author: Dehaeze Thomas

    -

    Created: 2020-05-20 mer. 15:49

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/uncertainty_payload.html b/docs/uncertainty_payload.html index 7b729a5..b8c7cad 100644 --- a/docs/uncertainty_payload.html +++ b/docs/uncertainty_payload.html @@ -1,66 +1,70 @@ - - + Effect of Uncertainty on the payload’s dynamics on the isolation platform dynamics - - - - - - - - + + + +

    Effect of Uncertainty on the payload’s dynamics on the isolation platform dynamics

    Table of Contents

    @@ -84,18 +88,18 @@ The goal is to study: Two models are made to study these effects:

      -
    • In section 1, simple mass-spring-damper systems are chosen to model both the isolation platform and the payload
    • -
    • In section 2, we consider arbitrary payload dynamics with multiplicative input uncertainty to study the unmodelled dynamics of the payload
    • +
    • In section 1, simple mass-spring-damper systems are chosen to model both the isolation platform and the payload
    • +
    • In section 2, we consider arbitrary payload dynamics with multiplicative input uncertainty to study the unmodelled dynamics of the payload
    -
    -

    1 Simple Introductory Example

    +
    +

    1 Simple Introductory Example

    - +

    -Let’s consider the system shown in Figure 1 consisting of: +Let’s consider the system shown in Figure 1 consisting of:

    -
    mpi = 50;
    -kpi = 5e6;
    -cpi = 3e3;
    +
      mpi = 50;
    +  kpi = 5e6;
    +  cpi = 3e3;
     
    -kpi = (2*pi*50)^2*mpi;
    -cpi = 0.2*sqrt(kpi*mpi);
    +  kpi = (2*pi*50)^2*mpi;
    +  cpi = 0.2*sqrt(kpi*mpi);
     
    @@ -161,14 +165,14 @@ cpi = 0.2*sqrt(kpi*mpi); Let’s also consider some uncertainty in those parameters:

    -
    mp = ureal('m', mpi, 'Range', [1, 100]);
    -cp = ureal('c', cpi, 'Percentage', 30);
    -kp = ureal('k', kpi, 'Percentage', 30);
    +
      mp = ureal('m', mpi, 'Range', [1, 100]);
    +  cp = ureal('c', cpi, 'Percentage', 30);
    +  kp = ureal('k', kpi, 'Percentage', 30);
     

    -The compliance of the payload without the isolation platform is \(\frac{1}{m^\prime s^2 + c^\prime s + k^\prime}\) and its bode plot is shown in Figure 2. +The compliance of the payload without the isolation platform is \(\frac{1}{m^\prime s^2 + c^\prime s + k^\prime}\) and its bode plot is shown in Figure 2.

    @@ -176,7 +180,7 @@ One can see that the payload has a resonance frequency of \(\omega_0^\prime = 25

    -
    +

    nominal_payload_compliance_dynamics.png

    Figure 2: Nominal compliance of the payload (png, pdf)

    @@ -184,14 +188,14 @@ One can see that the payload has a resonance frequency of \(\omega_0^\prime = 25
    -
    -

    1.3 Initialization of the isolation platform

    +
    +

    1.3 Initialization of the isolation platform

    Let’s first fix the mass of the isolation platform:

    -
    m = 10;
    +
      m = 10;
     
    @@ -206,15 +210,15 @@ And we generate three isolation platforms:
    -
    -

    1.4 Comparison

    +
    +

    1.4 Comparison

    -The obtained dynamics from \(F\) to \(x\) for the three isolation platform are shown in Figure 3. +The obtained dynamics from \(F\) to \(x\) for the three isolation platform are shown in Figure 3.

    -
    +

    plant_dynamics_uncertainty_payload_variability.png

    Figure 3: Obtained plant for the three isolation platforms considered (png, pdf)

    @@ -222,10 +226,10 @@ The obtained dynamics from \(F\) to \(x\) for the three isolation platform are s
    -
    -

    1.5 Conclusion

    +
    +

    1.5 Conclusion

    -
    +

    The stiff platform dynamics does not seems to depend on the dynamics of the payload.

    @@ -235,21 +239,21 @@ The stiff platform dynamics does not seems to depend on the dynamics of the payl
    -
    -

    2 Generalization to arbitrary dynamics

    +
    +

    2 Generalization to arbitrary dynamics

    - +

    -
    -

    2.1 Introduction

    +
    +

    2.1 Introduction

    -Let’s now consider a general payload described by its impedance \(G^\prime(s) = \frac{F^\prime}{x}\) as shown in Figure 4. +Let’s now consider a general payload described by its impedance \(G^\prime(s) = \frac{F^\prime}{x}\) as shown in Figure 4.

    -
    +

    Note here that we use the term impedance, however, the mechanical impedance is usually defined as the ratio of the force over the velocity \(F^\prime/\dot{x}\). We should refer to resistance instead of impedance.

    @@ -257,17 +261,17 @@ Note here that we use the term impedance, however, the mechanical impedan
    -
    +

    general_payload_impedance.png

    Figure 4: General support

    -Now let’s consider the system consisting of a mass-spring-system (the isolation platform) supporting the general payload as shown in Figure 5. +Now let’s consider the system consisting of a mass-spring-system (the isolation platform) supporting the general payload as shown in Figure 5.

    -
    +

    general_payload_with_isolator.png

    Figure 5: Mass-Spring-Damper (isolation platform) supporting a general payload

    @@ -275,8 +279,8 @@ Now let’s consider the system consisting of a mass-spring-system (the isol
    -
    -

    2.2 Equations of motion

    +
    +

    2.2 Equations of motion

    We have to following equations of motion: @@ -290,9 +294,9 @@ We have to following equations of motion: And by eliminating \(F^\prime\), we find the plant dynamics \(G(s) = \frac{x}{F}\).

    -
    +
    \begin{equation} -\label{org8b9a6a7} +\label{org11f0d43} \frac{x}{F} = \frac{1}{ms^2 + cs + k + G^\prime(s)} \end{equation} @@ -308,11 +312,11 @@ We can learn few things about the obtained transfer function:
    -
    -

    2.3 Impedance \(G^\prime(s)\) of a mass-spring-damper payload

    +
    +

    2.3 Impedance \(G^\prime(s)\) of a mass-spring-damper payload

    -In order to verify that the formula is correct, let’s take the same mass-spring-damper system used in the system shown in Figure 1: +In order to verify that the formula is correct, let’s take the same mass-spring-damper system used in the system shown in Figure 1:

    \begin{align*} m^\prime s^2 x^\prime &= (x - x^\prime) (c^\prime s + k^\prime) \\ @@ -322,7 +326,7 @@ In order to verify that the formula is correct, let’s take the same mass-s

    By eliminating \(x^\prime\) of the equations, we obtain:

    -
    +
    \begin{equation} G^\prime(s) = \frac{F^\prime}{x} = \frac{m^\prime s^2 (c^\prime s + k)}{m^\prime s^2 + c^\prime s + k^\prime} \label{eq:impedance_mass_spring_damper} \end{equation} @@ -343,11 +347,11 @@ And we obtain \end{align*}

    -Which is the same transfer function that was obtained in section 1 (Eq. \eqref{eq:plant_simple_system}). +Which is the same transfer function that was obtained in section 1 (Eq. \eqref{eq:plant_simple_system}).

    -The impedance of the mass-spring-damper system is shown in Figure 6. +The impedance of the mass-spring-damper system is shown in Figure 6.

    • Before the resonance frequency \(\omega_0^\prime\), the impedance follows the mass line
    • @@ -356,7 +360,7 @@ The impedance of the mass-spring-damper system is shown in Figure +

      example_impedance_mass_spring_damper.png

      Figure 6: Example of the impedance of a mass-spring-damper system (png, pdf)

      @@ -364,8 +368,8 @@ The impedance of the mass-spring-damper system is shown in Figure -

      2.4 First Analytical analysis

      +
      +

      2.4 First Analytical analysis

      To summarize, we consider: @@ -421,7 +425,7 @@ Until \(\omega_0^\prime\), we have \(m^\prime \ll m\) which is the same conditio Above \(\omega_0^\prime\), we obtain \(|jc^\prime \omega + k| \ll m \omega^2\).

      -
      +

      When using a soft isolation platform and a stiff payload such that the payload resonate above the first resonance of the isolation platform, the mass of the payload should be small compared to the isolation platform mass in order to not disturb the dynamics of the isolation platform.

      @@ -430,8 +434,8 @@ When using a soft isolation platform and a stiff payload such that the payload r
      -
      -

      2.5 Impedance of the Payload and Dynamical Uncertainty

      +
      +

      2.5 Impedance of the Payload and Dynamical Uncertainty

      We model the payload by a mass-spring-damper model with some uncertainty. @@ -451,16 +455,16 @@ The main resonance of the payload is then \(\omega^\prime = \sqrt{\frac{m^\prime

      -
      m0 = 10;
      -c0 = 3e2;
      -k0 = 5e5;
      +
        m0 = 10;
      +  c0 = 3e2;
      +  k0 = 5e5;
       
      -Gp0 = (m0*s^2 * (c0*s + k0))/(m0*s^2 + c0*s + k0);
      +  Gp0 = (m0*s^2 * (c0*s + k0))/(m0*s^2 + c0*s + k0);
       

      -Let’s represent the uncertainty on the impedance of the payload by a multiplicative uncertainty (Figure 7): +Let’s represent the uncertainty on the impedance of the payload by a multiplicative uncertainty (Figure 7): \[ G^\prime(s) = G_0^\prime(s)(1 + w_I^\prime(s)\Delta_I(s)) \quad |\Delta_I(j\omega)| < 1\ \forall \omega \]

      @@ -469,7 +473,7 @@ This could represent unmodelled dynamics or unknown parameters of the pay

      -
      +

      input_uncertainty_set.png

      Figure 7: Input Multiplicative Uncertainty

      @@ -485,11 +489,11 @@ where \(r_0\) is the relative uncertainty at steady-state, \(1/\tau\) is the fre The parameters are defined below.

      -
      r0 = 0.5;
      -tau = 1/(50*2*pi);
      -rinf = 10;
      +
        r0 = 0.5;
      +  tau = 1/(50*2*pi);
      +  rinf = 10;
       
      -wI = (tau*s + r0)/((tau/rinf)*s + 1);
      +  wI = (tau*s + r0)/((tau/rinf)*s + 1);
       
      @@ -497,7 +501,7 @@ wI = (tau*s + r0)/((tau/rinf)*s + 1); We then generate a complex \(\Delta\).

      -
      DeltaI = ucomplex('A',0);
      +
        DeltaI = ucomplex('A',0);
       
      @@ -505,16 +509,16 @@ We then generate a complex \(\Delta\). We generate the uncertain plant \(G^\prime(s)\).

      -
      Gp = Gp0*(1+wI*DeltaI);
      +
        Gp = Gp0*(1+wI*DeltaI);
       

      -A set of uncertainty payload’s impedance transfer functions is shown in Figure 8. +A set of uncertainty payload’s impedance transfer functions is shown in Figure 8.

      -
      +

      payload_impedance_uncertainty.png

      Figure 8: Uncertainty of the payload’s impedance (png, pdf)

      @@ -522,8 +526,8 @@ A set of uncertainty payload’s impedance transfer functions is shown in Fi
      -
      -

      2.6 Equivalent Inverse Multiplicative Uncertainty

      +
      +

      2.6 Equivalent Inverse Multiplicative Uncertainty

      Let’s express the uncertainty of the plant \(x/F\) as a function of the parameters as well as of the uncertainty on the platform’s compliance: @@ -533,9 +537,9 @@ Let’s express the uncertainty of the plant \(x/F\) as a function of the pa &= \frac{1}{ms^2 + cs + k + G_0^\prime(s)} \cdot \frac{1}{1 + \frac{G_0^\prime(s) w_I(s)}{ms^2 + cs + k + G_0^\prime(s)} \Delta(s)}\\ \end{align*} -

      +

      -We can the plant dynamics that as an inverse multiplicative uncertainty (Figure 9): +We can the plant dynamics that as an inverse multiplicative uncertainty (Figure 9):

      \begin{equation} \frac{x}{F} = G_0(s) (1 + w_{iI}(s) \Delta(s))^{-1} @@ -551,7 +555,7 @@ with:
      -
      +

      inverse_uncertainty_set.png

      Figure 9: Inverse Multiplicative Uncertainty

      @@ -559,14 +563,14 @@ with:
      -
      -

      2.7 Effect of the Isolation platform Stiffness

      +
      +

      2.7 Effect of the Isolation platform Stiffness

      Let’s first fix the mass of the isolation platform:

      -
      m = 20;
      +
        m = 20;
       
      @@ -583,12 +587,12 @@ And we generate three isolation platforms: Soft Isolation Platform:

      -
      k_soft = m*(2*pi*5)^2;
      -c_soft = 0.1*sqrt(m*k_soft);
      +
        k_soft = m*(2*pi*5)^2;
      +  c_soft = 0.1*sqrt(m*k_soft);
       
      -G_soft = 1/(m*s^2 + c_soft*s + k_soft + Gp);
      -G0_soft = 1/(m*s^2 + c_soft*s + k_soft + Gp0);
      -wiI_soft = Gp0*G0_soft*wI;
      +  G_soft = 1/(m*s^2 + c_soft*s + k_soft + Gp);
      +  G0_soft = 1/(m*s^2 + c_soft*s + k_soft + Gp0);
      +  wiI_soft = Gp0*G0_soft*wI;
       
      @@ -596,12 +600,12 @@ wiI_soft = Gp0*G0_soft*wI; Mid Isolation Platform

      -
      k_mid = m*(2*pi*50)^2;
      -c_mid = 0.1*sqrt(m*k_mid);
      +
        k_mid = m*(2*pi*50)^2;
      +  c_mid = 0.1*sqrt(m*k_mid);
       
      -G_mid = 1/(m*s^2 + c_mid*s + k_mid + Gp);
      -G0_mid = 1/(m*s^2 + c_mid*s + k_mid + Gp0);
      -wiI_mid = Gp0*G0_mid*wI;
      +  G_mid = 1/(m*s^2 + c_mid*s + k_mid + Gp);
      +  G0_mid = 1/(m*s^2 + c_mid*s + k_mid + Gp0);
      +  wiI_mid = Gp0*G0_mid*wI;
       
      @@ -609,21 +613,21 @@ wiI_mid = Gp0*G0_mid*wI; Stiff Isolation Platform

      -
      k_stiff = m*(2*pi*500)^2;
      -c_stiff = 0.1*sqrt(m*k_stiff);
      +
        k_stiff = m*(2*pi*500)^2;
      +  c_stiff = 0.1*sqrt(m*k_stiff);
       
      -G_stiff = 1/(m*s^2 + c_stiff*s + k_stiff + Gp);
      -G0_stiff = 1/(m*s^2 + c_stiff*s + k_stiff + Gp0);
      -wiI_stiff = Gp0*G0_stiff*wI;
      +  G_stiff = 1/(m*s^2 + c_stiff*s + k_stiff + Gp);
      +  G0_stiff = 1/(m*s^2 + c_stiff*s + k_stiff + Gp0);
      +  wiI_stiff = Gp0*G0_stiff*wI;
       

      -The obtained transfer functions \(x/F\) for each of the three platforms are shown in Figure 10. +The obtained transfer functions \(x/F\) for each of the three platforms are shown in Figure 10.

      -
      +

      plant_uncertainty_impedance_payload.png

      Figure 10: Obtained plant for the three isolators (png, pdf)

      @@ -631,8 +635,8 @@ The obtained transfer functions \(x/F\) for each of the three platforms are show
      -
      -

      2.8 Reduce the Uncertainty on the plant

      +
      +

      2.8 Reduce the Uncertainty on the plant

      Now that we know the expression of the uncertainty on the plant, we can wonder what parameters of the isolation platform would lower the plant uncertainty, or at least bring the uncertainty to reasonable level. @@ -648,30 +652,30 @@ Let’s study separately the effect of the platform’s mass, damping an

      -
      -

      2.8.1 Effect of the platform’s stiffness \(k\)

      +
      +

      2.8.1 Effect of the platform’s stiffness \(k\)

      Let’s fix \(\xi = \frac{c}{2\sqrt{km}} = 0.1\), \(m = 100\ [kg]\) and see the evolution of \(|w_{iI}(j\omega)|\) with \(k\).

      -This is first shown for few values of the stiffness \(k\) in figure 11 +This is first shown for few values of the stiffness \(k\) in figure 11

      -
      +

      inverse_multiplicative_uncertainty_payload_few_k.png

      Figure 11: Norm of the inverse multiplicative uncertainty weight for various values of the the isolation platform’s stiffness (png, pdf)

      -The norm of the uncertainty weight \(|w_iI(j\omega)|\) is displayed as a function of \(\omega\) and \(k\) in Figure 12. +The norm of the uncertainty weight \(|w_iI(j\omega)|\) is displayed as a function of \(\omega\) and \(k\) in Figure 12.

      -
      +

      inverse_multiplicative_payload_uncertainty_norm_k.png

      Figure 12: Evolution of the norm of the uncertainty weight \(|w_{iI}(j\omega)|\) as a function of the platform’s stiffness \(k\) (png, pdf)

      @@ -686,12 +690,12 @@ Instead of plotting as a function of the platform’s stiffness, we can plot

    -The obtain plot is shown in Figure 13. +The obtain plot is shown in Figure 13. In that case, we can see that with a platform’s resonance frequency 10 times higher than the resonance of the payload, we get less than \(1\%\) uncertainty until some fairly high frequency.

    -
    +

    inverse_multiplicative_payload_uncertainty_k_normalized_frequency.png

    Figure 13: Evolution of the norm of the uncertainty weight \(|w_{iI}(j\omega)|\) as a function of the frequency ratio \(\omega_0/\omega_0^\prime\) (png, pdf)

    @@ -699,15 +703,15 @@ In that case, we can see that with a platform’s resonance frequency 10 tim
    -
    -

    2.8.2 Effect of the platform’s damping \(c\)

    +
    +

    2.8.2 Effect of the platform’s damping \(c\)

    -Let’s fix \(k = 10^7\ [N/m]\), \(m = 100\ [kg]\) and see the evolution of \(|w_{iI}(j\omega)|\) with the isolation platform damping \(c\) (Figure 14). +Let’s fix \(k = 10^7\ [N/m]\), \(m = 100\ [kg]\) and see the evolution of \(|w_{iI}(j\omega)|\) with the isolation platform damping \(c\) (Figure 14).

    -
    +

    inverse_multiplicative_payload_uncertainty_c.png

    Figure 14: Evolution of the norm of the uncertainty weight \(|w_{iI}(j\omega)|\) as a function of the platform’s damping ratio \(\xi\) (png, pdf)

    @@ -715,15 +719,15 @@ Let’s fix \(k = 10^7\ [N/m]\), \(m = 100\ [kg]\) and see the evolution of
    -
    -

    2.8.3 Effect of the platform’s mass \(m\)

    +
    +

    2.8.3 Effect of the platform’s mass \(m\)

    -Let’s fix \(k = 10^7\ [N/m]\), \(\xi = \frac{c}{2\sqrt{km}} = 0.1\) and see the evolution of \(|w_{iI}(j\omega)|\) with the payload mass \(m\) (Figure 15). +Let’s fix \(k = 10^7\ [N/m]\), \(\xi = \frac{c}{2\sqrt{km}} = 0.1\) and see the evolution of \(|w_{iI}(j\omega)|\) with the payload mass \(m\) (Figure 15).

    -
    +

    inverse_multiplicative_payload_uncertainty_m.png

    Figure 15: Evolution of the norm of the uncertainty weight \(|w_{iI}(j\omega)|\) as a function of the payload mass \(m\) (png, pdf)

    @@ -732,12 +736,12 @@ Let’s fix \(k = 10^7\ [N/m]\), \(\xi = \frac{c}{2\sqrt{km}} = 0.1\) and se
    -
    -

    2.9 Conclusion

    +
    +

    2.9 Conclusion

    -
    +

    -As was expected from Eq. \eqref{org8b9a6a7}, it is usually a good idea to maximize the mass, damping and stiffness of the isolation platform in order to be less sensible to the payload dynamics. +As was expected from Eq. \eqref{org11f0d43}, it is usually a good idea to maximize the mass, damping and stiffness of the isolation platform in order to be less sensible to the payload dynamics.

    @@ -745,7 +749,7 @@ The best thing to do is to have a stiff isolation platform.

    -If a soft isolation platform is to be used, it is first a good idea to damp the isolation platform as shown in Figure 14. +If a soft isolation platform is to be used, it is first a good idea to damp the isolation platform as shown in Figure 14. This can make the uncertainty quite low until the first resonance of the payload. In that case, maximizing the stiffness of the payload is a good idea.

    @@ -757,7 +761,7 @@ In that case, maximizing the stiffness of the payload is a good idea.

    Author: Dehaeze Thomas

    -

    Created: 2020-05-05 mar. 10:33

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/uncertainty_support.html b/docs/uncertainty_support.html index 3d05d25..30bd4bf 100644 --- a/docs/uncertainty_support.html +++ b/docs/uncertainty_support.html @@ -1,64 +1,68 @@ - - + Effect of Uncertainty on the support’s dynamics on the isolation platform dynamics - - - - - - - - + + + +

    Effect of Uncertainty on the support’s dynamics on the isolation platform dynamics

    Table of Contents

    @@ -82,18 +86,18 @@ The goal is to study: Two models are made to study these effects:

      -
    • In section 1, simple mass-spring-damper systems are chosen to model both the isolation platform and the flexible support
    • -
    • In section 2, we consider arbitrary support dynamics with multiplicative input uncertainty to study the unmodelled dynamics of the support
    • +
    • In section 1, simple mass-spring-damper systems are chosen to model both the isolation platform and the flexible support
    • +
    • In section 2, we consider arbitrary support dynamics with multiplicative input uncertainty to study the unmodelled dynamics of the support
    -
    -

    1 Simple Introductory Example

    +
    +

    1 Simple Introductory Example

    - +

    -Let’s consider the system shown in Figure 1 consisting of: +Let’s consider the system shown in Figure 1 consisting of:

    -
    mpi = 1e3;
    -cpi = 5e4;
    -kpi = 1e8;
    +
      mpi = 1e3;
    +  cpi = 5e4;
    +  kpi = 1e8;
     
    @@ -156,14 +160,14 @@ kpi = 1e8; Let’s also consider some uncertainty in those parameters:

    -
    mp = ureal('m', mpi, 'Percentage', 30);
    -cp = ureal('c', cpi, 'Percentage', 30);
    -kp = ureal('k', kpi, 'Percentage', 30);
    +
      mp = ureal('m', mpi, 'Percentage', 30);
    +  cp = ureal('c', cpi, 'Percentage', 30);
    +  kp = ureal('k', kpi, 'Percentage', 30);
     

    -The compliance of the support without the isolation platform is \(\frac{1}{m^\prime s^2 + c^\prime s + k^\prime}\) and its bode plot is shown in Figure 2. +The compliance of the support without the isolation platform is \(\frac{1}{m^\prime s^2 + c^\prime s + k^\prime}\) and its bode plot is shown in Figure 2.

    @@ -171,7 +175,7 @@ One can see that support has a resonance frequency of \(\omega_0^\prime = 50\ Hz

    -
    +

    nominal_support_compliance_dynamics.png

    Figure 2: Nominal compliance of the support (png, pdf)

    @@ -179,14 +183,14 @@ One can see that support has a resonance frequency of \(\omega_0^\prime = 50\ Hz
    -
    -

    1.3 Initialization of the isolation platform

    +
    +

    1.3 Initialization of the isolation platform

    Let’s first fix the mass of the payload to be isolated:

    -
    m = 100;
    +
      m = 100;
     
    @@ -201,15 +205,15 @@ And we generate three isolation platforms:
    -
    -

    1.4 Comparison

    +
    +

    1.4 Comparison

    -The obtained dynamics from \(F\) to \(x\) for the three isolation platform are shown in Figure 3. +The obtained dynamics from \(F\) to \(x\) for the three isolation platform are shown in Figure 3.

    -
    +

    plant_dynamics_uncertainty_stiff_mid_soft.png

    Figure 3: Obtained plant for the three isolation platforms considered (png, pdf)

    @@ -217,10 +221,10 @@ The obtained dynamics from \(F\) to \(x\) for the three isolation platform are s
    -
    -

    1.5 Conclusion

    +
    +

    1.5 Conclusion

    -
    +

    The soft platform dynamics does not seems to depend on the dynamics of the support nor to be affect by the dynamic uncertainty of the support.

    @@ -230,32 +234,32 @@ The soft platform dynamics does not seems to depend on the dynamics of the suppo
    -
    -

    2 Generalization to arbitrary dynamics

    +
    +

    2 Generalization to arbitrary dynamics

    - +

    -
    -

    2.1 Introduction

    +
    +

    2.1 Introduction

    -Let’s now consider a general support described by its compliance \(G^\prime(s) = \frac{x^\prime}{F^\prime}\) as shown in Figure 4. +Let’s now consider a general support described by its compliance \(G^\prime(s) = \frac{x^\prime}{F^\prime}\) as shown in Figure 4.

    -
    +

    general_support_compliance.png

    Figure 4: General support

    -Now let’s consider the system consisting of a mass-spring-system (the isolation platform) on top of a general support as shown in Figure 5. +Now let’s consider the system consisting of a mass-spring-system (the isolation platform) on top of a general support as shown in Figure 5.

    -
    +

    general_support_with_isolator.png

    Figure 5: Mass-Spring-Damper system on top of a general support

    @@ -263,8 +267,8 @@ Now let’s consider the system consisting of a mass-spring-system (the isol
    -
    -

    2.2 Equations of motion

    +
    +

    2.2 Equations of motion

    We have to following equations of motion: @@ -279,7 +283,7 @@ We have to following equations of motion: And by eliminating \(F^\prime\) and \(x^\prime\), we find the plant dynamics \(G(s) = \frac{x}{F}\).

    -
    +
    \begin{equation} \frac{x}{F} = \frac{1}{ms^2 + cs + k + ms^2(cs + k)G^\prime(s)} \label{eq:plant_dynamics_general_support} \end{equation} @@ -287,20 +291,20 @@ And by eliminating \(F^\prime\) and \(x^\prime\), we find the plant dynamics \(G

    -In order to verify that the formula is correct, let’s take the same mass-spring-damper system used in the system shown in Figure 1: +In order to verify that the formula is correct, let’s take the same mass-spring-damper system used in the system shown in Figure 1: \[ \frac{x^\prime}{F^\prime} = \frac{1}{m^\prime s^2 + c^\prime s + k^\prime} \]

    And we obtain \[ \frac{x}{F} = \frac{m^\prime s^2 + c^\prime s + k^\prime}{(ms^2 + cs + k)(m^\prime s^2 + c^\prime s + k^\prime) + ms^2(cs + k)} \] -Which is the same transfer function that was obtained in section 1 (Eq. \eqref{eq:plant_simple_system}). +Which is the same transfer function that was obtained in section 1 (Eq. \eqref{eq:plant_simple_system}).

    -
    -

    2.3 Compliance of the Support

    +
    +

    2.3 Compliance of the Support

    We model the support by a mass-spring-damper model with some uncertainty. @@ -312,16 +316,16 @@ The main resonance of the support is then \(\omega^\prime = \sqrt{\frac{m^\prime

    -
    m0 = 1e3;
    -c0 = 5e4;
    -k0 = 1e8;
    +
      m0 = 1e3;
    +  c0 = 5e4;
    +  k0 = 1e8;
     
    -Gp0 = 1/(m0*s^2 + c0*s + k0);
    +  Gp0 = 1/(m0*s^2 + c0*s + k0);
     

    -Let’s represent the uncertainty on the compliance of the support by a multiplicative uncertainty (Figure 6): +Let’s represent the uncertainty on the compliance of the support by a multiplicative uncertainty (Figure 6): \[ G^\prime(s) = G_0^\prime(s)(1 + w_I^\prime(s)\Delta_I(s)) \quad |\Delta_I(j\omega)| < 1\ \forall \omega \]

    @@ -330,7 +334,7 @@ This could represent unmodelled dynamics or unknown parameters of the sup

    -
    +

    input_uncertainty_set.png

    Figure 6: Input Multiplicative Uncertainty

    @@ -346,11 +350,11 @@ where \(r_0\) is the relative uncertainty at steady-state, \(1/\tau\) is the fre The parameters are defined below.

    -
    r0 = 0.5;
    -tau = 1/(100*2*pi);
    -rinf = 10;
    +
      r0 = 0.5;
    +  tau = 1/(100*2*pi);
    +  rinf = 10;
     
    -wI = (tau*s + r0)/((tau/rinf)*s + 1);
    +  wI = (tau*s + r0)/((tau/rinf)*s + 1);
     
    @@ -358,7 +362,7 @@ wI = (tau*s + r0)/((tau/rinf)*s + 1); We then generate a complex \(\Delta\).

    -
    DeltaI = ucomplex('A',0);
    +
      DeltaI = ucomplex('A',0);
     
    @@ -366,16 +370,16 @@ We then generate a complex \(\Delta\). We generate the uncertain plant \(G^\prime(s)\).

    -
    Gp = Gp0*(1+wI*DeltaI);
    +
      Gp = Gp0*(1+wI*DeltaI);
     

    -A set of uncertainty support’s compliance transfer functions is shown in Figure 7. +A set of uncertainty support’s compliance transfer functions is shown in Figure 7.

    -
    +

    compliance_support_uncertainty.png

    Figure 7: Uncertainty of the support’s compliance (png, pdf)

    @@ -383,8 +387,8 @@ A set of uncertainty support’s compliance transfer functions is shown in F
    -
    -

    2.4 Equivalent Inverse Multiplicative Uncertainty

    +
    +

    2.4 Equivalent Inverse Multiplicative Uncertainty

    Let’s express the uncertainty of the plant \(x/F\) as a function of the parameters as well as of the uncertainty on the platform’s compliance: @@ -395,9 +399,9 @@ Let’s express the uncertainty of the plant \(x/F\) as a function of the pa &= \frac{1}{ms^2 + cs + k + ms^2(cs + k)G_0^\prime(s)} \cdot \frac{1}{1 + \frac{ms^2(cs + k)G_0^\prime(s) w_I(s)}{ms^2 + cs + k + ms^2(cs + k)G_0^\prime(s)} \Delta(s)}\\ \end{align*} -

    +

    -We can the plant dynamics that as an inverse multiplicative uncertainty (Figure 8): +We can the plant dynamics that as an inverse multiplicative uncertainty (Figure 8):

    \begin{equation} \frac{x}{F} = G_0(s) (1 + w_{iI}(s) \Delta(s))^{-1} @@ -413,7 +417,7 @@ with:
    -
    +

    inverse_uncertainty_set.png

    Figure 8: Inverse Multiplicative Uncertainty

    @@ -421,14 +425,14 @@ with:
    -
    -

    2.5 Effect of the Isolation platform Stiffness

    +
    +

    2.5 Effect of the Isolation platform Stiffness

    Let’s first fix the mass of the payload to be isolated:

    -
    m = 100;
    +
      m = 100;
     
    @@ -445,12 +449,12 @@ And we generate three isolation platforms: Soft Isolation Platform:

    -
    k_soft = m*(2*pi*5)^2;
    -c_soft = 0.1*sqrt(m*k_soft);
    +
      k_soft = m*(2*pi*5)^2;
    +  c_soft = 0.1*sqrt(m*k_soft);
     
    -G_soft = 1/(m*s^2 + c_soft*s + k_soft + m*s^2*(c_soft*s + k_soft)*Gp);
    -G0_soft = 1/(m*s^2 + c_soft*s + k_soft + m*s^2*(c_soft*s + k_soft)*Gp0);
    -wiI_soft = Gp0*m*s^2*(c_soft*s + k_soft)*G0_soft*wI;
    +  G_soft = 1/(m*s^2 + c_soft*s + k_soft + m*s^2*(c_soft*s + k_soft)*Gp);
    +  G0_soft = 1/(m*s^2 + c_soft*s + k_soft + m*s^2*(c_soft*s + k_soft)*Gp0);
    +  wiI_soft = Gp0*m*s^2*(c_soft*s + k_soft)*G0_soft*wI;
     
    @@ -458,12 +462,12 @@ wiI_soft = Gp0*m*s^2*(c_soft*s + k_soft)*G0_soft*wI; Mid Isolation Platform

    -
    k_mid = m*(2*pi*50)^2;
    -c_mid = 0.1*sqrt(m*k_mid);
    +
      k_mid = m*(2*pi*50)^2;
    +  c_mid = 0.1*sqrt(m*k_mid);
     
    -G_mid = 1/(m*s^2 + c_mid*s + k_mid + m*s^2*(c_mid*s + k_mid)*Gp);
    -G0_mid = 1/(m*s^2 + c_mid*s + k_mid + m*s^2*(c_mid*s + k_mid)*Gp0);
    -wiI_mid = Gp0*m*s^2*(c_mid*s + k_mid)*G0_mid*wI;
    +  G_mid = 1/(m*s^2 + c_mid*s + k_mid + m*s^2*(c_mid*s + k_mid)*Gp);
    +  G0_mid = 1/(m*s^2 + c_mid*s + k_mid + m*s^2*(c_mid*s + k_mid)*Gp0);
    +  wiI_mid = Gp0*m*s^2*(c_mid*s + k_mid)*G0_mid*wI;
     
    @@ -471,35 +475,35 @@ wiI_mid = Gp0*m*s^2*(c_mid*s + k_mid)*G0_mid*wI; Stiff Isolation Platform

    -
    k_stiff = m*(2*pi*500)^2;
    -c_stiff = 0.1*sqrt(m*k_stiff);
    +
      k_stiff = m*(2*pi*500)^2;
    +  c_stiff = 0.1*sqrt(m*k_stiff);
     
    -G_stiff = 1/(m*s^2 + c_stiff*s + k_stiff + m*s^2*(c_stiff*s + k_stiff)*Gp);
    -G0_stiff = 1/(m*s^2 + c_stiff*s + k_stiff + m*s^2*(c_stiff*s + k_stiff)*Gp0);
    -wiI_stiff = Gp0*m*s^2*(c_stiff*s + k_stiff)*G0_stiff*wI;
    +  G_stiff = 1/(m*s^2 + c_stiff*s + k_stiff + m*s^2*(c_stiff*s + k_stiff)*Gp);
    +  G0_stiff = 1/(m*s^2 + c_stiff*s + k_stiff + m*s^2*(c_stiff*s + k_stiff)*Gp0);
    +  wiI_stiff = Gp0*m*s^2*(c_stiff*s + k_stiff)*G0_stiff*wI;
     

    -The obtained transfer functions \(x/F\) for each of the three platforms are shown in Figure 9. +The obtained transfer functions \(x/F\) for each of the three platforms are shown in Figure 9.

    -
    +

    plant_uncertainty_stiffness_isolator.png

    Figure 9: Obtained plant for the three isolators (png, pdf)

    -The obtain result is very similar to the one obtain in section 1, except for the stiff isolation that experience lot’s of uncertainty at high frequency. +The obtain result is very similar to the one obtain in section 1, except for the stiff isolation that experience lot’s of uncertainty at high frequency. This is due to the fact that with the current model, at high frequency, the support’s compliance uncertainty is much higher than the previous model.

    -
    -

    2.6 Reduce the Uncertainty on the plant

    +
    +

    2.6 Reduce the Uncertainty on the plant

    Now that we know the expression of the uncertainty on the plant, we can wonder what parameters of the isolation platform would lower the plant uncertainty, or at least bring the uncertainty to reasonable level. @@ -515,30 +519,30 @@ Let’s study separately the effect of the platform’s mass, damping an

    -
    -

    2.6.1 Effect of the platform’s stiffness \(k\)

    +
    +

    2.6.1 Effect of the platform’s stiffness \(k\)

    Let’s fix \(\xi = \frac{c}{2\sqrt{km}} = 0.1\), \(m = 100\ [kg]\) and see the evolution of \(|w_{iI}(j\omega)|\) with \(k\).

    -This is first shown for few values of the stiffness \(k\) in figure 10 +This is first shown for few values of the stiffness \(k\) in figure 10

    -
    +

    inverse_multiplicative_uncertainty_norm_few_k.png

    Figure 10: caption (png, pdf)

    -The norm of the uncertainty weight \(|w_iI(j\omega)|\) is displayed as a function of \(\omega\) and \(k\) in Figure 11. +The norm of the uncertainty weight \(|w_iI(j\omega)|\) is displayed as a function of \(\omega\) and \(k\) in Figure 11.

    -
    +

    inverse_multiplicative_uncertainty_norm_k.png

    Figure 11: Evolution of the norm of the uncertainty weight \(|w_{iI}(j\omega)|\) as a function of the platform’s stiffness \(k\) (png, pdf)

    @@ -553,12 +557,12 @@ Instead of plotting as a function of the platform’s stiffness, we can plot

    -The obtain plot is shown in Figure 12. +The obtain plot is shown in Figure 12. In that case, we can see that with a platform’s resonance frequency 10 times lower than the resonance of the support, we get less than \(1\%\) uncertainty.

    -
    +

    inverse_multiplicative_uncertainty_k_normalized_frequency.png

    Figure 12: Evolution of the norm of the uncertainty weight \(|w_{iI}(j\omega)|\) as a function of the frequency ratio \(\omega_0/\omega_0^\prime\) (png, pdf)

    @@ -566,15 +570,15 @@ In that case, we can see that with a platform’s resonance frequency 10 tim
    -
    -

    2.6.2 Effect of the platform’s damping \(c\)

    +
    +

    2.6.2 Effect of the platform’s damping \(c\)

    -Let’s fix \(k = 10^7\ [N/m]\), \(m = 100\ [kg]\) and see the evolution of \(|w_{iI}(j\omega)|\) with the isolator damping \(c\) (Figure 13). +Let’s fix \(k = 10^7\ [N/m]\), \(m = 100\ [kg]\) and see the evolution of \(|w_{iI}(j\omega)|\) with the isolator damping \(c\) (Figure 13).

    -
    +

    inverse_multiplicative_uncertainty_norm_c.png

    Figure 13: Evolution of the norm of the uncertainty weight \(|w_{iI}(j\omega)|\) as a function of the platform’s damping ratio \(\xi\) (png, pdf)

    @@ -583,15 +587,15 @@ Let’s fix \(k = 10^7\ [N/m]\), \(m = 100\ [kg]\) and see the evolution of
    -
    -

    2.6.3 Effect of the platform’s mass \(m\)

    +
    +

    2.6.3 Effect of the platform’s mass \(m\)

    -Let’s fix \(k = 10^7\ [N/m]\), \(\xi = \frac{c}{2\sqrt{km}} = 0.1\) and see the evolution of \(|w_{iI}(j\omega)|\) with the payload mass \(m\) (Figure 14). +Let’s fix \(k = 10^7\ [N/m]\), \(\xi = \frac{c}{2\sqrt{km}} = 0.1\) and see the evolution of \(|w_{iI}(j\omega)|\) with the payload mass \(m\) (Figure 14).

    -
    +

    inverse_multiplicative_uncertainty_norm_m.png

    Figure 14: Evolution of the norm of the uncertainty weight \(|w_{iI}(j\omega)|\) as a function of the payload mass \(m\) (png, pdf)

    @@ -600,10 +604,10 @@ Let’s fix \(k = 10^7\ [N/m]\), \(\xi = \frac{c}{2\sqrt{km}} = 0.1\) and se
    -
    -

    2.7 Conclusion

    +
    +

    2.7 Conclusion

    -
    +

    If the goal is to have an acceptable (\(<10\%\)) uncertainty on the plant until the highest frequency, two design choice for the isolation platform are possible:

    @@ -629,7 +633,7 @@ Thus, if a stiff isolation platform is used, the recommendation is to have the l

    Author: Dehaeze Thomas

    -

    Created: 2020-05-05 mar. 10:33

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/docs/uniaxial.html b/docs/uniaxial.html index d6d0252..9a3b968 100644 --- a/docs/uniaxial.html +++ b/docs/uniaxial.html @@ -1,106 +1,110 @@ - - + Simscape Uniaxial Model - - - - - - - - + + + +

    Simscape Uniaxial Model

    Table of Contents

    @@ -115,15 +119,15 @@ The idea is to use the same model as the full Simscape Model but to restrict the This is done in order to more easily study the system and evaluate control techniques.

    -
    -

    1 Simscape Model

    +
    +

    1 Simscape Model

    - +

    -A schematic of the uniaxial model used for simulations is represented in figure 1. +A schematic of the uniaxial model used for simulations is represented in figure 1.

    @@ -167,7 +171,7 @@ The control signal \(u\) is: -

    +

    uniaxial-model-nass-flexible.png

    Figure 1: Schematic of the uniaxial model used

    @@ -176,11 +180,11 @@ The control signal \(u\) is:

    Few active damping techniques will be compared in order to decide which sensor is to be included in the system. -Schematics of the active damping techniques are displayed in figure 2. +Schematics of the active damping techniques are displayed in figure 2.

    -
    +

    uniaxial-model-nass-flexible-active-damping.png

    Figure 2: Comparison of used active damping techniques

    @@ -188,18 +192,18 @@ Schematics of the active damping techniques are displayed in figure -

    2 Undamped System

    +
    +

    2 Undamped System

    - +

    Let’s start by study the undamped system.

    -
    -

    2.1 Init

    +
    +

    2.1 Init

    We initialize all the stages with the default parameters. @@ -211,19 +215,19 @@ All the controllers are set to 0 (Open Loop).

    -
    -

    2.2 Identification

    +
    +

    2.2 Identification

    We identify the dynamics of the system.

    -
    %% Options for Linearized
    -options = linearizeOptions;
    -options.SampleTime = 0;
    +
      %% Options for Linearized
    +  options = linearizeOptions;
    +  options.SampleTime = 0;
     
    -%% Name of the Simulink File
    -mdl = 'sim_nano_station_uniaxial';
    +  %% Name of the Simulink File
    +  mdl = 'sim_nano_station_uniaxial';
     
    @@ -231,18 +235,18 @@ mdl = 'sim_nano_station_uniaxial'; The inputs and outputs are defined below and corresponds to the name of simulink blocks.

    -
    %% Input/Output definition
    -io(1)  = linio([mdl, '/Dw'],   1, 'input'); % Ground Motion
    -io(2)  = linio([mdl, '/Fs'],   1, 'input'); % Force applied on the sample
    -io(3)  = linio([mdl, '/Fnl'],  1, 'input'); % Force applied by the NASS
    -io(4)  = linio([mdl, '/Fdty'], 1, 'input'); % Parasitic force Ty
    -io(5)  = linio([mdl, '/Fdrz'], 1, 'input'); % Parasitic force Rz
    +
      %% Input/Output definition
    +  io(1)  = linio([mdl, '/Dw'],   1, 'input'); % Ground Motion
    +  io(2)  = linio([mdl, '/Fs'],   1, 'input'); % Force applied on the sample
    +  io(3)  = linio([mdl, '/Fnl'],  1, 'input'); % Force applied by the NASS
    +  io(4)  = linio([mdl, '/Fdty'], 1, 'input'); % Parasitic force Ty
    +  io(5)  = linio([mdl, '/Fdrz'], 1, 'input'); % Parasitic force Rz
     
    -io(6)  = linio([mdl, '/Dsm'],  1, 'output'); % Displacement of the sample
    -io(7)  = linio([mdl, '/Fnlm'], 1, 'output'); % Force sensor in NASS's legs
    -io(8)  = linio([mdl, '/Dnlm'], 1, 'output'); % Displacement of NASS's legs
    -io(9)  = linio([mdl, '/Dgm'],  1, 'output'); % Absolute displacement of the granite
    -io(10) = linio([mdl, '/Vlm'],  1, 'output'); % Measured absolute velocity of the top NASS platform
    +  io(6)  = linio([mdl, '/Dsm'],  1, 'output'); % Displacement of the sample
    +  io(7)  = linio([mdl, '/Fnlm'], 1, 'output'); % Force sensor in NASS's legs
    +  io(8)  = linio([mdl, '/Dnlm'], 1, 'output'); % Displacement of NASS's legs
    +  io(9)  = linio([mdl, '/Dgm'],  1, 'output'); % Absolute displacement of the granite
    +  io(10) = linio([mdl, '/Vlm'],  1, 'output'); % Measured absolute velocity of the top NASS platform
     
    @@ -250,18 +254,18 @@ io(10) = linio([mdl, '/Vl Finally, we use the linearize Matlab function to extract a state space model from the simscape model.

    -
    %% Run the linearization
    -G = linearize(mdl, io, options);
    -G.InputName  = {'Dw',   ... % Ground Motion [m]
    -                'Fs',   ... % Force Applied on Sample [N]
    -                'Fn',   ... % Force applied by NASS [N]
    -                'Fty',  ... % Parasitic Force Ty [N]
    -                'Frz'};     % Parasitic Force Rz [N]
    -G.OutputName = {'D',    ... % Measured sample displacement x.r.t. granite [m]
    -                'Fnm',  ... % Force Sensor in NASS [N]
    -                'Dnm',  ... % Displacement Sensor in NASS [m]
    -                'Dgm',  ... % Asbolute displacement of Granite [m]
    -                'Vlm'}; ... % Absolute Velocity of NASS [m/s]
    +
      %% Run the linearization
    +  G = linearize(mdl, io, options);
    +  G.InputName  = {'Dw',   ... % Ground Motion [m]
    +                  'Fs',   ... % Force Applied on Sample [N]
    +                  'Fn',   ... % Force applied by NASS [N]
    +                  'Fty',  ... % Parasitic Force Ty [N]
    +                  'Frz'};     % Parasitic Force Rz [N]
    +  G.OutputName = {'D',    ... % Measured sample displacement x.r.t. granite [m]
    +                  'Fnm',  ... % Force Sensor in NASS [N]
    +                  'Dnm',  ... % Displacement Sensor in NASS [m]
    +                  'Dgm',  ... % Asbolute displacement of Granite [m]
    +                  'Vlm'}; ... % Absolute Velocity of NASS [m/s]
     
    @@ -269,25 +273,25 @@ G.OutputName = {'D', ... -
    save('./mat/uniaxial_plants.mat', 'G');
    +
      save('./mat/uniaxial_plants.mat', 'G');
     
    -
    -

    2.3 Sensitivity to Disturbances

    +
    +

    2.3 Sensitivity to Disturbances

    We show several plots representing the sensitivity to disturbances:

      -
    • in figure 3 the transfer functions from ground motion \(D_w\) to the sample position \(D\) and the transfer function from direct force on the sample \(F_s\) to the sample position \(D\) are shown
    • -
    • in figure 4, it is the effect of parasitic forces of the positioning stages (\(F_{ty}\) and \(F_{rz}\)) on the position \(D\) of the sample that are shown
    • +
    • in figure 3 the transfer functions from ground motion \(D_w\) to the sample position \(D\) and the transfer function from direct force on the sample \(F_s\) to the sample position \(D\) are shown
    • +
    • in figure 4, it is the effect of parasitic forces of the positioning stages (\(F_{ty}\) and \(F_{rz}\)) on the position \(D\) of the sample that are shown
    -
    +

    uniaxial-sensitivity-disturbances.png

    Figure 3: Sensitivity to disturbances (png, pdf)

    @@ -295,7 +299,7 @@ We show several plots representing the sensitivity to disturbances: -
    +

    uniaxial-sensitivity-force-dist.png

    Figure 4: Sensitivity to disturbances (png, pdf)

    @@ -303,25 +307,25 @@ We show several plots representing the sensitivity to disturbances:
    -
    -

    2.4 Noise Budget

    +
    +

    2.4 Noise Budget

    We first load the measured PSD of the disturbance.

    -
    load('./mat/disturbances_dist_psd.mat', 'dist_f');
    +
      load('./mat/disturbances_dist_psd.mat', 'dist_f');
     

    The effect of these disturbances on the distance \(D\) is computed below. -The PSD of the obtain distance \(D\) due to each of the perturbation is shown in figure 5 and the Cumulative Amplitude Spectrum is shown in figure 6. +The PSD of the obtain distance \(D\) due to each of the perturbation is shown in figure 5 and the Cumulative Amplitude Spectrum is shown in figure 6.

    -The Root Mean Square value of the obtained displacement \(D\) is computed below and can be determined from the figure 6. +The Root Mean Square value of the obtained displacement \(D\) is computed below and can be determined from the figure 6.

     3.3793e-06
    @@ -329,7 +333,7 @@ The Root Mean Square value of the obtained displacement \(D\) is computed below
     
     
     
    -
    +

    uniaxial-psd-dist.png

    Figure 5: PSD of the effect of disturbances on \(D\) (png, pdf)

    @@ -337,7 +341,7 @@ The Root Mean Square value of the obtained displacement \(D\) is computed below -
    +

    uniaxial-cas-dist.png

    Figure 6: CAS of the effect of disturbances on \(D\) (png, pdf)

    @@ -345,16 +349,16 @@ The Root Mean Square value of the obtained displacement \(D\) is computed below
    -
    -

    2.5 Plant

    +
    +

    2.5 Plant

    -The transfer function from the force \(F\) applied by the nano-hexapod to the position of the sample \(D\) is shown in figure 7. +The transfer function from the force \(F\) applied by the nano-hexapod to the position of the sample \(D\) is shown in figure 7. It corresponds to the plant to control.

    -
    +

    uniaxial-plant.png

    Figure 7: Bode plot of the Plant (png, pdf)

    @@ -363,24 +367,24 @@ It corresponds to the plant to control.
    -
    -

    3 Integral Force Feedback

    +
    +

    3 Integral Force Feedback

    - +

    -
    +

    uniaxial-model-nass-flexible-iff.png

    Figure 8: Uniaxial IFF Control Schematic

    -
    -

    3.1 Control Design

    +
    +

    3.1 Control Design

    -
    load('./mat/uniaxial_plants.mat', 'G');
    +
      load('./mat/uniaxial_plants.mat', 'G');
     
    @@ -389,7 +393,7 @@ Let’s look at the transfer function from actuator forces in the nano-hexap

    -
    +

    uniaxial_iff_plant.png

    Figure 9: Transfer function from forces applied in the legs to force sensor (png, pdf)

    @@ -399,12 +403,12 @@ Let’s look at the transfer function from actuator forces in the nano-hexap The controller for each pair of actuator/sensor is:

    -
    K_iff = -1000/s;
    +
      K_iff = -1000/s;
     
    -
    +

    uniaxial_iff_open_loop.png

    Figure 10: Loop Gain for the Integral Force Feedback (png, pdf)

    @@ -412,23 +416,23 @@ The controller for each pair of actuator/sensor is:
    -
    -

    3.2 Identification

    +
    +

    3.2 Identification

    Let’s initialize the system prior to identification.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    -initializeNanoHexapod('actuator', 'piezo');
    -initializeSample('mass', 50);
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
    +  initializeNanoHexapod('actuator', 'piezo');
    +  initializeSample('mass', 50);
     
    @@ -436,78 +440,78 @@ initializeSample('mass', 50); All the controllers are set to 0.

    -
    K = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K', '-append');
    -K_iff = -K_iff;
    -save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    -K_rmc = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    -K_dvf = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
    +
      K = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K', '-append');
    +  K_iff = -K_iff;
    +  save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    +  K_rmc = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    +  K_dvf = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
     
    -
    %% Options for Linearized
    -options = linearizeOptions;
    -options.SampleTime = 0;
    +
      %% Options for Linearized
    +  options = linearizeOptions;
    +  options.SampleTime = 0;
     
    -%% Name of the Simulink File
    -mdl = 'sim_nano_station_uniaxial';
    +  %% Name of the Simulink File
    +  mdl = 'sim_nano_station_uniaxial';
     
    -
    %% Input/Output definition
    -io(1)  = linio([mdl, '/Dw'],    1, 'input');  % Ground Motion
    -io(2)  = linio([mdl, '/Fs'],    1, 'input');  % Force applied on the sample
    -io(3)  = linio([mdl, '/Fnl'],   1, 'input');  % Force applied by the NASS
    -io(4)  = linio([mdl, '/Fdty'],  1, 'input');  % Parasitic force Ty
    -io(5)  = linio([mdl, '/Fdrz'],  1, 'input');  % Parasitic force Rz
    +
      %% Input/Output definition
    +  io(1)  = linio([mdl, '/Dw'],    1, 'input');  % Ground Motion
    +  io(2)  = linio([mdl, '/Fs'],    1, 'input');  % Force applied on the sample
    +  io(3)  = linio([mdl, '/Fnl'],   1, 'input');  % Force applied by the NASS
    +  io(4)  = linio([mdl, '/Fdty'],  1, 'input');  % Parasitic force Ty
    +  io(5)  = linio([mdl, '/Fdrz'],  1, 'input');  % Parasitic force Rz
     
    -io(6)  = linio([mdl, '/Dsm'],  1, 'output'); % Displacement of the sample
    -io(7)  = linio([mdl, '/Fnlm'], 1, 'output'); % Force sensor in NASS's legs
    -io(8)  = linio([mdl, '/Dnlm'], 1, 'output'); % Displacement of NASS's legs
    -io(9)  = linio([mdl, '/Dgm'],  1, 'output'); % Absolute displacement of the granite
    -io(10) = linio([mdl, '/Vlm'],  1, 'output'); % Measured absolute velocity of the top NASS platform
    +  io(6)  = linio([mdl, '/Dsm'],  1, 'output'); % Displacement of the sample
    +  io(7)  = linio([mdl, '/Fnlm'], 1, 'output'); % Force sensor in NASS's legs
    +  io(8)  = linio([mdl, '/Dnlm'], 1, 'output'); % Displacement of NASS's legs
    +  io(9)  = linio([mdl, '/Dgm'],  1, 'output'); % Absolute displacement of the granite
    +  io(10) = linio([mdl, '/Vlm'],  1, 'output'); % Measured absolute velocity of the top NASS platform
     
    -
    %% Run the linearization
    -G_iff = linearize(mdl, io, options);
    -G_iff.InputName  = {'Dw',   ... % Ground Motion [m]
    -                    'Fs',   ... % Force Applied on Sample [N]
    -                    'Fn',   ... % Force applied by NASS [N]
    -                    'Fty',  ... % Parasitic Force Ty [N]
    -                    'Frz'};     % Parasitic Force Rz [N]
    -G_iff.OutputName = {'D',    ... % Measured sample displacement x.r.t. granite [m]
    -                    'Fnm',  ... % Force Sensor in NASS [N]
    -                    'Dnm',  ... % Displacement Sensor in NASS [m]
    -                    'Dgm',  ... % Asbolute displacement of Granite [m]
    -                    'Vlm'}; ... % Absolute Velocity of NASS [m/s]
    +
      %% Run the linearization
    +  G_iff = linearize(mdl, io, options);
    +  G_iff.InputName  = {'Dw',   ... % Ground Motion [m]
    +                      'Fs',   ... % Force Applied on Sample [N]
    +                      'Fn',   ... % Force applied by NASS [N]
    +                      'Fty',  ... % Parasitic Force Ty [N]
    +                      'Frz'};     % Parasitic Force Rz [N]
    +  G_iff.OutputName = {'D',    ... % Measured sample displacement x.r.t. granite [m]
    +                      'Fnm',  ... % Force Sensor in NASS [N]
    +                      'Dnm',  ... % Displacement Sensor in NASS [m]
    +                      'Dgm',  ... % Asbolute displacement of Granite [m]
    +                      'Vlm'}; ... % Absolute Velocity of NASS [m/s]
     
    -
    save('./mat/uniaxial_plants.mat', 'G_iff', '-append');
    +
      save('./mat/uniaxial_plants.mat', 'G_iff', '-append');
     
    -
    -

    3.3 Sensitivity to Disturbance

    +
    +

    3.3 Sensitivity to Disturbance

    -
    +

    uniaxial_sensitivity_dist_iff.png

    Figure 11: Sensitivity to disturbance once the IFF controller is applied to the system (png, pdf)

    -
    +

    uniaxial_sensitivity_dist_stages_iff.png

    Figure 12: Sensitivity to force disturbances in various stages when IFF is applied (png, pdf)

    @@ -515,11 +519,11 @@ G_iff.OutputName = {'D', ... -

    3.4 Damped Plant

    +
    +

    3.4 Damped Plant

    -
    +

    uniaxial_plant_iff_damped.png

    Figure 13: Damped Plant after IFF is applied (png, pdf)

    @@ -527,10 +531,10 @@ G_iff.OutputName = {'D', ... -

    3.5 Conclusion

    +
    +

    3.5 Conclusion

    -
    +

    Integral Force Feedback:

    @@ -540,28 +544,28 @@ Integral Force Feedback:
    -
    -

    4 Relative Motion Control

    +
    +

    4 Relative Motion Control

    - +

    In the Relative Motion Control (RMC), a derivative feedback is applied between the measured actuator displacement to the actuator force input.

    -
    +

    uniaxial-model-nass-flexible-rmc.png

    Figure 14: Uniaxial RMC Control Schematic

    -
    -

    4.1 Control Design

    +
    +

    4.1 Control Design

    -
    load('./mat/uniaxial_plants.mat', 'G');
    +
      load('./mat/uniaxial_plants.mat', 'G');
     
    @@ -570,7 +574,7 @@ Let’s look at the transfer function from actuator forces in the nano-hexap

    -
    +

    uniaxial_rmc_plant.png

    Figure 15: Transfer function from forces applied in the legs to leg displacement sensor (png, pdf)

    @@ -581,12 +585,12 @@ The Relative Motion Controller is defined below. A Low pass Filter is added to make the controller transfer function proper.

    -
    K_rmc = s*50000/(1 + s/2/pi/10000);
    +
      K_rmc = s*50000/(1 + s/2/pi/10000);
     
    -
    +

    uniaxial_rmc_open_loop.png

    Figure 16: Loop Gain for the Integral Force Feedback (png, pdf)

    @@ -594,23 +598,23 @@ A Low pass Filter is added to make the controller transfer function proper.
    -
    -

    4.2 Identification

    +
    +

    4.2 Identification

    Let’s initialize the system prior to identification.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    -initializeNanoHexapod('actuator', 'piezo');
    -initializeSample('mass', 50);
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
    +  initializeNanoHexapod('actuator', 'piezo');
    +  initializeSample('mass', 50);
     
    @@ -618,79 +622,79 @@ initializeSample('mass', 50); And initialize the controllers.

    -
    K = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K', '-append');
    -K_iff = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    -K_rmc = -K_rmc;
    -save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    -K_dvf = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
    +
      K = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K', '-append');
    +  K_iff = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    +  K_rmc = -K_rmc;
    +  save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    +  K_dvf = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
     
    -
    %% Options for Linearized
    -options = linearizeOptions;
    -options.SampleTime = 0;
    +
      %% Options for Linearized
    +  options = linearizeOptions;
    +  options.SampleTime = 0;
     
    -%% Name of the Simulink File
    -mdl = 'sim_nano_station_uniaxial';
    +  %% Name of the Simulink File
    +  mdl = 'sim_nano_station_uniaxial';
     
    -
    %% Input/Output definition
    -io(1)  = linio([mdl, '/Dw'],    1, 'input');  % Ground Motion
    -io(2)  = linio([mdl, '/Fs'],    1, 'input');  % Force applied on the sample
    -io(3)  = linio([mdl, '/Fnl'],   1, 'input');  % Force applied by the NASS
    -io(4)  = linio([mdl, '/Fdty'],  1, 'input');  % Parasitic force Ty
    -io(5)  = linio([mdl, '/Fdrz'],  1, 'input');  % Parasitic force Rz
    +
      %% Input/Output definition
    +  io(1)  = linio([mdl, '/Dw'],    1, 'input');  % Ground Motion
    +  io(2)  = linio([mdl, '/Fs'],    1, 'input');  % Force applied on the sample
    +  io(3)  = linio([mdl, '/Fnl'],   1, 'input');  % Force applied by the NASS
    +  io(4)  = linio([mdl, '/Fdty'],  1, 'input');  % Parasitic force Ty
    +  io(5)  = linio([mdl, '/Fdrz'],  1, 'input');  % Parasitic force Rz
     
    -io(6)  = linio([mdl, '/Dsm'],  1, 'output'); % Displacement of the sample
    -io(7)  = linio([mdl, '/Fnlm'], 1, 'output'); % Force sensor in NASS's legs
    -io(8)  = linio([mdl, '/Dnlm'], 1, 'output'); % Displacement of NASS's legs
    -io(9)  = linio([mdl, '/Dgm'],  1, 'output'); % Absolute displacement of the granite
    -io(10) = linio([mdl, '/Vlm'],  1, 'output'); % Measured absolute velocity of the top NASS platform
    +  io(6)  = linio([mdl, '/Dsm'],  1, 'output'); % Displacement of the sample
    +  io(7)  = linio([mdl, '/Fnlm'], 1, 'output'); % Force sensor in NASS's legs
    +  io(8)  = linio([mdl, '/Dnlm'], 1, 'output'); % Displacement of NASS's legs
    +  io(9)  = linio([mdl, '/Dgm'],  1, 'output'); % Absolute displacement of the granite
    +  io(10) = linio([mdl, '/Vlm'],  1, 'output'); % Measured absolute velocity of the top NASS platform
     
    -
    %% Run the linearization
    -G_rmc = linearize(mdl, io, options);
    -G_rmc.InputName  = {'Dw',   ... % Ground Motion [m]
    -                    'Fs',   ... % Force Applied on Sample [N]
    -                    'Fn',   ... % Force applied by NASS [N]
    -                    'Fty',  ... % Parasitic Force Ty [N]
    -                    'Frz'};     % Parasitic Force Rz [N]
    -G_rmc.OutputName = {'D',    ... % Measured sample displacement x.r.t. granite [m]
    -                    'Fnm',  ... % Force Sensor in NASS [N]
    -                    'Dnm',  ... % Displacement Sensor in NASS [m]
    -                    'Dgm',  ... % Asbolute displacement of Granite [m]
    -                    'Vlm'}; ... % Absolute Velocity of NASS [m/s]
    +
      %% Run the linearization
    +  G_rmc = linearize(mdl, io, options);
    +  G_rmc.InputName  = {'Dw',   ... % Ground Motion [m]
    +                      'Fs',   ... % Force Applied on Sample [N]
    +                      'Fn',   ... % Force applied by NASS [N]
    +                      'Fty',  ... % Parasitic Force Ty [N]
    +                      'Frz'};     % Parasitic Force Rz [N]
    +  G_rmc.OutputName = {'D',    ... % Measured sample displacement x.r.t. granite [m]
    +                      'Fnm',  ... % Force Sensor in NASS [N]
    +                      'Dnm',  ... % Displacement Sensor in NASS [m]
    +                      'Dgm',  ... % Asbolute displacement of Granite [m]
    +                      'Vlm'}; ... % Absolute Velocity of NASS [m/s]
     
    -
    save('./mat/uniaxial_plants.mat', 'G_rmc', '-append');
    +
      save('./mat/uniaxial_plants.mat', 'G_rmc', '-append');
     
    -
    -

    4.3 Sensitivity to Disturbance

    +
    +

    4.3 Sensitivity to Disturbance

    -
    +

    uniaxial_sensitivity_dist_rmc.png

    Figure 17: Sensitivity to disturbance once the RMC controller is applied to the system (png, pdf)

    -
    +

    uniaxial_sensitivity_dist_stages_rmc.png

    Figure 18: Sensitivity to force disturbances in various stages when RMC is applied (png, pdf)

    @@ -698,11 +702,11 @@ G_rmc.OutputName = {'D', ... -

    4.4 Damped Plant

    +
    +

    4.4 Damped Plant

    -
    +

    uniaxial_plant_rmc_damped.png

    Figure 19: Damped Plant after RMC is applied (png, pdf)

    @@ -710,10 +714,10 @@ G_rmc.OutputName = {'D', ... -

    4.5 Conclusion

    +
    +

    4.5 Conclusion

    -
    +

    Relative Motion Control:

    @@ -723,45 +727,45 @@ Relative Motion Control:
    -
    -

    5 Direct Velocity Feedback

    +
    +

    5 Direct Velocity Feedback

    - +

    In the Relative Motion Control (RMC), a feedback is applied between the measured velocity of the platform to the actuator force input.

    -
    +

    uniaxial-model-nass-flexible-dvf.png

    Figure 20: Uniaxial DVF Control Schematic

    -
    -

    5.1 Control Design

    +
    +

    5.1 Control Design

    -
    load('./mat/uniaxial_plants.mat', 'G');
    +
      load('./mat/uniaxial_plants.mat', 'G');
     
    -
    +

    uniaxial_dvf_plant.png

    Figure 21: Transfer function from forces applied in the legs to leg velocity sensor (png, pdf)

    -
    K_dvf = tf(5e4);
    +
      K_dvf = tf(5e4);
     
    -
    +

    uniaxial_dvf_loop_gain.png

    Figure 22: Transfer function from forces applied in the legs to leg velocity sensor (png, pdf)

    @@ -769,23 +773,23 @@ In the Relative Motion Control (RMC), a feedback is applied between the measured
    -
    -

    5.2 Identification

    +
    +

    5.2 Identification

    Let’s initialize the system prior to identification.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    -initializeNanoHexapod('actuator', 'piezo');
    -initializeSample('mass', 50);
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
    +  initializeNanoHexapod('actuator', 'piezo');
    +  initializeSample('mass', 50);
     
    @@ -793,78 +797,78 @@ initializeSample('mass', 50); And initialize the controllers.

    -
    K = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K', '-append');
    -K_iff = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    -K_rmc = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    -K_dvf = -K_dvf;
    -save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
    +
      K = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K', '-append');
    +  K_iff = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    +  K_rmc = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    +  K_dvf = -K_dvf;
    +  save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
     
    -
    %% Options for Linearized
    -options = linearizeOptions;
    -options.SampleTime = 0;
    +
      %% Options for Linearized
    +  options = linearizeOptions;
    +  options.SampleTime = 0;
     
    -%% Name of the Simulink File
    -mdl = 'sim_nano_station_uniaxial';
    +  %% Name of the Simulink File
    +  mdl = 'sim_nano_station_uniaxial';
     
    -
    %% Input/Output definition
    -io(1)  = linio([mdl, '/Dw'],    1, 'input');  % Ground Motion
    -io(2)  = linio([mdl, '/Fs'],    1, 'input');  % Force applied on the sample
    -io(3)  = linio([mdl, '/Fnl'],   1, 'input');  % Force applied by the NASS
    -io(4)  = linio([mdl, '/Fdty'],  1, 'input');  % Parasitic force Ty
    -io(5)  = linio([mdl, '/Fdrz'],  1, 'input');  % Parasitic force Rz
    +
      %% Input/Output definition
    +  io(1)  = linio([mdl, '/Dw'],    1, 'input');  % Ground Motion
    +  io(2)  = linio([mdl, '/Fs'],    1, 'input');  % Force applied on the sample
    +  io(3)  = linio([mdl, '/Fnl'],   1, 'input');  % Force applied by the NASS
    +  io(4)  = linio([mdl, '/Fdty'],  1, 'input');  % Parasitic force Ty
    +  io(5)  = linio([mdl, '/Fdrz'],  1, 'input');  % Parasitic force Rz
     
    -io(6)  = linio([mdl, '/Dsm'],  1, 'output'); % Displacement of the sample
    -io(7)  = linio([mdl, '/Fnlm'], 1, 'output'); % Force sensor in NASS's legs
    -io(8)  = linio([mdl, '/Dnlm'], 1, 'output'); % Displacement of NASS's legs
    -io(9)  = linio([mdl, '/Dgm'],  1, 'output'); % Absolute displacement of the granite
    -io(10) = linio([mdl, '/Vlm'],  1, 'output'); % Measured absolute velocity of the top NASS platform
    +  io(6)  = linio([mdl, '/Dsm'],  1, 'output'); % Displacement of the sample
    +  io(7)  = linio([mdl, '/Fnlm'], 1, 'output'); % Force sensor in NASS's legs
    +  io(8)  = linio([mdl, '/Dnlm'], 1, 'output'); % Displacement of NASS's legs
    +  io(9)  = linio([mdl, '/Dgm'],  1, 'output'); % Absolute displacement of the granite
    +  io(10) = linio([mdl, '/Vlm'],  1, 'output'); % Measured absolute velocity of the top NASS platform
     
    -
    %% Run the linearization
    -G_dvf = linearize(mdl, io, options);
    -G_dvf.InputName  = {'Dw',   ... % Ground Motion [m]
    -                    'Fs',   ... % Force Applied on Sample [N]
    -                    'Fn',   ... % Force applied by NASS [N]
    -                    'Fty',  ... % Parasitic Force Ty [N]
    -                    'Frz'};     % Parasitic Force Rz [N]
    -G_dvf.OutputName = {'D',    ... % Measured sample displacement x.r.t. granite [m]
    -                    'Fnm',  ... % Force Sensor in NASS [N]
    -                    'Dnm',  ... % Displacement Sensor in NASS [m]
    -                    'Dgm',  ... % Asbolute displacement of Granite [m]
    -                    'Vlm'}; ... % Absolute Velocity of NASS [m/s]
    +
      %% Run the linearization
    +  G_dvf = linearize(mdl, io, options);
    +  G_dvf.InputName  = {'Dw',   ... % Ground Motion [m]
    +                      'Fs',   ... % Force Applied on Sample [N]
    +                      'Fn',   ... % Force applied by NASS [N]
    +                      'Fty',  ... % Parasitic Force Ty [N]
    +                      'Frz'};     % Parasitic Force Rz [N]
    +  G_dvf.OutputName = {'D',    ... % Measured sample displacement x.r.t. granite [m]
    +                      'Fnm',  ... % Force Sensor in NASS [N]
    +                      'Dnm',  ... % Displacement Sensor in NASS [m]
    +                      'Dgm',  ... % Asbolute displacement of Granite [m]
    +                      'Vlm'}; ... % Absolute Velocity of NASS [m/s]
     
    -
    save('./mat/uniaxial_plants.mat', 'G_dvf', '-append');
    +
      save('./mat/uniaxial_plants.mat', 'G_dvf', '-append');
     
    -
    -

    5.3 Sensitivity to Disturbance

    +
    +

    5.3 Sensitivity to Disturbance

    -
    +

    uniaxial_sensitivity_dist_dvf.png

    Figure 23: Sensitivity to disturbance once the DVF controller is applied to the system (png, pdf)

    -
    +

    uniaxial_sensitivity_dist_stages_dvf.png

    Figure 24: Sensitivity to force disturbances in various stages when DVF is applied (png, pdf)

    @@ -872,11 +876,11 @@ G_dvf.OutputName = {'D', ... -

    5.4 Damped Plant

    +
    +

    5.4 Damped Plant

    -
    +

    uniaxial_plant_dvf_damped.png

    Figure 25: Damped Plant after DVF is applied (png, pdf)

    @@ -884,10 +888,10 @@ G_dvf.OutputName = {'D', ... -

    5.5 Conclusion

    +
    +

    5.5 Conclusion

    -
    +

    Direct Velocity Feedback:

    @@ -896,41 +900,41 @@ Direct Velocity Feedback:
    -
    -

    6 With Cedrat Piezo-electric Actuators

    +
    +

    6 With Cedrat Piezo-electric Actuators

    - +

    -The model used for the Cedrat actuator is shown in figure 26. +The model used for the Cedrat actuator is shown in figure 26.

    -
    +

    cedrat-uniaxial-actuator.png

    Figure 26: Schematic of the model used for the Cedrat Actuator

    -
    -

    6.1 Identification

    +
    +

    6.1 Identification

    Let’s initialize the system prior to identification.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    -initializeNanoHexapod('actuator', 'piezo');
    -initializeCedratPiezo();
    -initializeSample('mass', 50);
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
    +  initializeNanoHexapod('actuator', 'piezo');
    +  initializeCedratPiezo();
    +  initializeSample('mass', 50);
     
    @@ -938,14 +942,14 @@ initializeSample('mass', 50); And initialize the controllers.

    -
    K = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K', '-append');
    -K_iff = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    -K_rmc = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    -K_dvf = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
    +
      K = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K', '-append');
    +  K_iff = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    +  K_rmc = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    +  K_dvf = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
     
    @@ -953,12 +957,12 @@ save('./mat/controllers_uniaxial.mat',
    -
    %% Options for Linearized
    -options = linearizeOptions;
    -options.SampleTime = 0;
    +
      %% Options for Linearized
    +  options = linearizeOptions;
    +  options.SampleTime = 0;
     
    -%% Name of the Simulink File
    -mdl = 'sim_nano_station_uniaxial_cedrat_bis';
    +  %% Name of the Simulink File
    +  mdl = 'sim_nano_station_uniaxial_cedrat_bis';
     
    @@ -966,18 +970,18 @@ mdl = 'sim_nano_station_uniaxial_cedrat_bis'; The inputs and outputs are defined below and corresponds to the name of simulink blocks.

    -
    %% Input/Output definition
    -io(1)  = linio([mdl, '/Dw'],   1, 'input'); % Ground Motion
    -io(2)  = linio([mdl, '/Fs'],   1, 'input'); % Force applied on the sample
    -io(3)  = linio([mdl, '/Fnl'],  1, 'input'); % Force applied by the NASS
    -io(4)  = linio([mdl, '/Fdty'], 1, 'input'); % Parasitic force Ty
    -io(5)  = linio([mdl, '/Fdrz'], 1, 'input'); % Parasitic force Rz
    +
      %% Input/Output definition
    +  io(1)  = linio([mdl, '/Dw'],   1, 'input'); % Ground Motion
    +  io(2)  = linio([mdl, '/Fs'],   1, 'input'); % Force applied on the sample
    +  io(3)  = linio([mdl, '/Fnl'],  1, 'input'); % Force applied by the NASS
    +  io(4)  = linio([mdl, '/Fdty'], 1, 'input'); % Parasitic force Ty
    +  io(5)  = linio([mdl, '/Fdrz'], 1, 'input'); % Parasitic force Rz
     
    -io(6)  = linio([mdl, '/Dsm'],  1, 'output'); % Displacement of the sample
    -io(7)  = linio([mdl, '/Fnlm'], 1, 'output'); % Force sensor in NASS's legs
    -io(8)  = linio([mdl, '/Dnlm'], 1, 'output'); % Displacement of NASS's legs
    -io(9)  = linio([mdl, '/Dgm'],  1, 'output'); % Absolute displacement of the granite
    -io(10) = linio([mdl, '/Vlm'],  1, 'output'); % Measured absolute velocity of the top NASS platform
    +  io(6)  = linio([mdl, '/Dsm'],  1, 'output'); % Displacement of the sample
    +  io(7)  = linio([mdl, '/Fnlm'], 1, 'output'); % Force sensor in NASS's legs
    +  io(8)  = linio([mdl, '/Dnlm'], 1, 'output'); % Displacement of NASS's legs
    +  io(9)  = linio([mdl, '/Dgm'],  1, 'output'); % Absolute displacement of the granite
    +  io(10) = linio([mdl, '/Vlm'],  1, 'output'); % Measured absolute velocity of the top NASS platform
     
    @@ -985,32 +989,32 @@ io(10) = linio([mdl, '/Vl Finally, we use the linearize Matlab function to extract a state space model from the simscape model.

    -
    %% Run the linearization
    -G = linearize(mdl, io, options);
    -G.InputName  = {'Dw',   ... % Ground Motion [m]
    -                'Fs',   ... % Force Applied on Sample [N]
    -                'Fn',   ... % Force applied by NASS [N]
    -                'Fty',  ... % Parasitic Force Ty [N]
    -                'Frz'};     % Parasitic Force Rz [N]
    -G.OutputName = {'D',    ... % Measured sample displacement x.r.t. granite [m]
    -                'Fnm',  ... % Force Sensor in NASS [N]
    -                'Dnm',  ... % Displacement Sensor in NASS [m]
    -                'Dgm',  ... % Asbolute displacement of Granite [m]
    -                'Vlm'}; ... % Absolute Velocity of NASS [m/s]
    +
      %% Run the linearization
    +  G = linearize(mdl, io, options);
    +  G.InputName  = {'Dw',   ... % Ground Motion [m]
    +                  'Fs',   ... % Force Applied on Sample [N]
    +                  'Fn',   ... % Force applied by NASS [N]
    +                  'Fty',  ... % Parasitic Force Ty [N]
    +                  'Frz'};     % Parasitic Force Rz [N]
    +  G.OutputName = {'D',    ... % Measured sample displacement x.r.t. granite [m]
    +                  'Fnm',  ... % Force Sensor in NASS [N]
    +                  'Dnm',  ... % Displacement Sensor in NASS [m]
    +                  'Dgm',  ... % Asbolute displacement of Granite [m]
    +                  'Vlm'}; ... % Absolute Velocity of NASS [m/s]
     
    -
    -

    6.2 Control Design

    +
    +

    6.2 Control Design

    Let’s look at the transfer function from actuator forces in the nano-hexapod to the force sensor in the nano-hexapod legs for all 6 pairs of actuator/sensor.

    -
    +

    uniaxial_cedrat_plant.png

    Figure 27: Transfer function from forces applied in the legs to force sensor (png, pdf)

    @@ -1020,12 +1024,12 @@ Let’s look at the transfer function from actuator forces in the nano-hexap The controller for each pair of actuator/sensor is:

    -
    K_cedrat = -5000/s;
    +
      K_cedrat = -5000/s;
     
    -
    +

    uniaxial_cedrat_open_loop.png

    Figure 28: Loop Gain for the Integral Force Feedback (png, pdf)

    @@ -1033,24 +1037,24 @@ The controller for each pair of actuator/sensor is:
    -
    -

    6.3 Identification

    +
    +

    6.3 Identification

    Let’s initialize the system prior to identification.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    -initializeNanoHexapod('actuator', 'piezo');
    -initializeCedratPiezo();
    -initializeSample('mass', 50);
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
    +  initializeNanoHexapod('actuator', 'piezo');
    +  initializeCedratPiezo();
    +  initializeSample('mass', 50);
     
    @@ -1058,78 +1062,78 @@ initializeSample('mass', 50); All the controllers are set to 0.

    -
    K = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K', '-append');
    -K_iff = -K_cedrat;
    -save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    -K_rmc = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    -K_dvf = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
    +
      K = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K', '-append');
    +  K_iff = -K_cedrat;
    +  save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    +  K_rmc = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    +  K_dvf = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
     
    -
    %% Options for Linearized
    -options = linearizeOptions;
    -options.SampleTime = 0;
    +
      %% Options for Linearized
    +  options = linearizeOptions;
    +  options.SampleTime = 0;
     
    -%% Name of the Simulink File
    -mdl = 'sim_nano_station_uniaxial_cedrat_bis';
    +  %% Name of the Simulink File
    +  mdl = 'sim_nano_station_uniaxial_cedrat_bis';
     
    -
    %% Input/Output definition
    -io(1)  = linio([mdl, '/Dw'],    1, 'input');  % Ground Motion
    -io(2)  = linio([mdl, '/Fs'],    1, 'input');  % Force applied on the sample
    -io(3)  = linio([mdl, '/Fnl'],   1, 'input');  % Force applied by the NASS
    -io(4)  = linio([mdl, '/Fdty'],  1, 'input');  % Parasitic force Ty
    -io(5)  = linio([mdl, '/Fdrz'],  1, 'input');  % Parasitic force Rz
    +
      %% Input/Output definition
    +  io(1)  = linio([mdl, '/Dw'],    1, 'input');  % Ground Motion
    +  io(2)  = linio([mdl, '/Fs'],    1, 'input');  % Force applied on the sample
    +  io(3)  = linio([mdl, '/Fnl'],   1, 'input');  % Force applied by the NASS
    +  io(4)  = linio([mdl, '/Fdty'],  1, 'input');  % Parasitic force Ty
    +  io(5)  = linio([mdl, '/Fdrz'],  1, 'input');  % Parasitic force Rz
     
    -io(6)  = linio([mdl, '/Dsm'],  1, 'output'); % Displacement of the sample
    -io(7)  = linio([mdl, '/Fnlm'], 1, 'output'); % Force sensor in NASS's legs
    -io(8)  = linio([mdl, '/Dnlm'], 1, 'output'); % Displacement of NASS's legs
    -io(9)  = linio([mdl, '/Dgm'],  1, 'output'); % Absolute displacement of the granite
    -io(10) = linio([mdl, '/Vlm'],  1, 'output'); % Measured absolute velocity of the top NASS platform
    +  io(6)  = linio([mdl, '/Dsm'],  1, 'output'); % Displacement of the sample
    +  io(7)  = linio([mdl, '/Fnlm'], 1, 'output'); % Force sensor in NASS's legs
    +  io(8)  = linio([mdl, '/Dnlm'], 1, 'output'); % Displacement of NASS's legs
    +  io(9)  = linio([mdl, '/Dgm'],  1, 'output'); % Absolute displacement of the granite
    +  io(10) = linio([mdl, '/Vlm'],  1, 'output'); % Measured absolute velocity of the top NASS platform
     
    -
    %% Run the linearization
    -G_cedrat = linearize(mdl, io, options);
    -G_cedrat.InputName  = {'Dw',   ... % Ground Motion [m]
    -                    'Fs',   ... % Force Applied on Sample [N]
    -                    'Fn',   ... % Force applied by NASS [N]
    -                    'Fty',  ... % Parasitic Force Ty [N]
    -                    'Frz'};     % Parasitic Force Rz [N]
    -G_cedrat.OutputName = {'D',    ... % Measured sample displacement x.r.t. granite [m]
    -                    'Fnm',  ... % Force Sensor in NASS [N]
    -                    'Dnm',  ... % Displacement Sensor in NASS [m]
    -                    'Dgm',  ... % Asbolute displacement of Granite [m]
    -                    'Vlm'}; ... % Absolute Velocity of NASS [m/s]
    +
      %% Run the linearization
    +  G_cedrat = linearize(mdl, io, options);
    +  G_cedrat.InputName  = {'Dw',   ... % Ground Motion [m]
    +                      'Fs',   ... % Force Applied on Sample [N]
    +                      'Fn',   ... % Force applied by NASS [N]
    +                      'Fty',  ... % Parasitic Force Ty [N]
    +                      'Frz'};     % Parasitic Force Rz [N]
    +  G_cedrat.OutputName = {'D',    ... % Measured sample displacement x.r.t. granite [m]
    +                      'Fnm',  ... % Force Sensor in NASS [N]
    +                      'Dnm',  ... % Displacement Sensor in NASS [m]
    +                      'Dgm',  ... % Asbolute displacement of Granite [m]
    +                      'Vlm'}; ... % Absolute Velocity of NASS [m/s]
     
    -
    % save('./mat/uniaxial_plants.mat', 'G_cedrat', '-append');
    +
      % save('./mat/uniaxial_plants.mat', 'G_cedrat', '-append');
     
    -
    -

    6.4 Sensitivity to Disturbance

    +
    +

    6.4 Sensitivity to Disturbance

    -
    +

    uniaxial_sensitivity_dist_cedrat.png

    Figure 29: Sensitivity to disturbance once the CEDRAT controller is applied to the system (png, pdf)

    -
    +

    uniaxial_sensitivity_dist_stages_cedrat.png

    Figure 30: Sensitivity to force disturbances in various stages when CEDRAT is applied (png, pdf)

    @@ -1137,11 +1141,11 @@ G_cedrat.OutputName = {'D', ... -

    6.5 Damped Plant

    +
    +

    6.5 Damped Plant

    -
    +

    uniaxial_plant_cedrat_damped.png

    Figure 31: Damped Plant after CEDRAT is applied (png, pdf)

    @@ -1149,10 +1153,10 @@ G_cedrat.OutputName = {'D', ... -

    6.6 Conclusion

    +
    +

    6.6 Conclusion

    -
    +

    This gives similar results than with a classical force sensor.

    @@ -1162,28 +1166,28 @@ This gives similar results than with a classical force sensor.
    -
    -

    7 Comparison of Active Damping Techniques

    +
    +

    7 Comparison of Active Damping Techniques

    - +

    -
    -

    7.1 Load the plants

    +
    +

    7.1 Load the plants

    -
    load('./mat/uniaxial_plants.mat', 'G', 'G_iff', 'G_rmc', 'G_dvf');
    +
      load('./mat/uniaxial_plants.mat', 'G', 'G_iff', 'G_rmc', 'G_dvf');
     
    -
    -

    7.2 Sensitivity to Disturbance

    +
    +

    7.2 Sensitivity to Disturbance

    -
    +

    uniaxial_sensitivity_ground_motion.png

    Figure 32: Sensitivity to Ground Motion - Comparison (png, pdf)

    @@ -1191,21 +1195,21 @@ This gives similar results than with a classical force sensor. -
    +

    uniaxial_sensitivity_direct_force.png

    Figure 33: Sensitivity to disturbance - Comparison (png, pdf)

    -
    +

    uniaxial_sensitivity_fty.png

    Figure 34: Sensitivity to force disturbances - Comparison (png, pdf)

    -
    +

    uniaxial_sensitivity_frz.png

    Figure 35: Sensitivity to force disturbances - Comparison (png, pdf)

    @@ -1213,23 +1217,23 @@ This gives similar results than with a classical force sensor.
    -
    -

    7.3 Noise Budget

    +
    +

    7.3 Noise Budget

    We first load the measured PSD of the disturbance.

    -
    load('./mat/disturbances_dist_psd.mat', 'dist_f');
    +
      load('./mat/disturbances_dist_psd.mat', 'dist_f');
     

    The effect of these disturbances on the distance \(D\) is computed for all active damping techniques. -We then compute the Cumulative Amplitude Spectrum (figure 36). +We then compute the Cumulative Amplitude Spectrum (figure 36).

    -
    +

    uniaxial-comp-cas-dist.png

    Figure 36: Comparison of the Cumulative Amplitude Spectrum of \(D\) for different active damping techniques (png, pdf)

    @@ -1238,7 +1242,7 @@ We then compute the Cumulative Amplitude Spectrum (figure

    The obtained Root Mean Square Value for each active damping technique is shown below.

    -
    Table 2: Joint primitives for each joint type
    +
    @@ -1281,11 +1285,11 @@ It is important to note that the effect of direct forces applied to the sample a -
    -

    7.4 Damped Plant

    +
    +

    7.4 Damped Plant

    -
    +

    uniaxial_plant_damped_comp.png

    Figure 37: Damped Plant - Comparison (png, pdf)

    @@ -1293,10 +1297,10 @@ It is important to note that the effect of direct forces applied to the sample a
    -
    -

    7.5 Conclusion

    +
    +

    7.5 Conclusion

    -
    Table 1: Obtain Root Mean Square value of \(D\) for each Active Damping Technique applied
    +
    @@ -1363,15 +1367,15 @@ It is important to note that the effect of direct forces applied to the sample a -
    -

    8 Voice Coil

    +
    +

    8 Voice Coil

    - +

    -
    -

    8.1 Init

    +
    +

    8.1 Init

    We initialize all the stages with the default parameters. @@ -1383,19 +1387,19 @@ All the controllers are set to 0 (Open Loop).

    -
    -

    8.2 Identification

    +
    +

    8.2 Identification

    We identify the dynamics of the system.

    -
    %% Options for Linearized
    -options = linearizeOptions;
    -options.SampleTime = 0;
    +
      %% Options for Linearized
    +  options = linearizeOptions;
    +  options.SampleTime = 0;
     
    -%% Name of the Simulink File
    -mdl = 'sim_nano_station_uniaxial';
    +  %% Name of the Simulink File
    +  mdl = 'sim_nano_station_uniaxial';
     
    @@ -1403,18 +1407,18 @@ mdl = 'sim_nano_station_uniaxial'; The inputs and outputs are defined below and corresponds to the name of simulink blocks.

    -
    %% Input/Output definition
    -io(1)  = linio([mdl, '/Dw'],   1, 'input'); % Ground Motion
    -io(2)  = linio([mdl, '/Fs'],   1, 'input'); % Force applied on the sample
    -io(3)  = linio([mdl, '/Fnl'],  1, 'input'); % Force applied by the NASS
    -io(4)  = linio([mdl, '/Fdty'], 1, 'input'); % Parasitic force Ty
    -io(5)  = linio([mdl, '/Fdrz'], 1, 'input'); % Parasitic force Rz
    +
      %% Input/Output definition
    +  io(1)  = linio([mdl, '/Dw'],   1, 'input'); % Ground Motion
    +  io(2)  = linio([mdl, '/Fs'],   1, 'input'); % Force applied on the sample
    +  io(3)  = linio([mdl, '/Fnl'],  1, 'input'); % Force applied by the NASS
    +  io(4)  = linio([mdl, '/Fdty'], 1, 'input'); % Parasitic force Ty
    +  io(5)  = linio([mdl, '/Fdrz'], 1, 'input'); % Parasitic force Rz
     
    -io(6)  = linio([mdl, '/Dsm'],  1, 'output'); % Displacement of the sample
    -io(7)  = linio([mdl, '/Fnlm'], 1, 'output'); % Force sensor in NASS's legs
    -io(8)  = linio([mdl, '/Dnlm'], 1, 'output'); % Displacement of NASS's legs
    -io(9)  = linio([mdl, '/Dgm'],  1, 'output'); % Absolute displacement of the granite
    -io(10) = linio([mdl, '/Vlm'],  1, 'output'); % Measured absolute velocity of the top NASS platform
    +  io(6)  = linio([mdl, '/Dsm'],  1, 'output'); % Displacement of the sample
    +  io(7)  = linio([mdl, '/Fnlm'], 1, 'output'); % Force sensor in NASS's legs
    +  io(8)  = linio([mdl, '/Dnlm'], 1, 'output'); % Displacement of NASS's legs
    +  io(9)  = linio([mdl, '/Dgm'],  1, 'output'); % Absolute displacement of the granite
    +  io(10) = linio([mdl, '/Vlm'],  1, 'output'); % Measured absolute velocity of the top NASS platform
     
    @@ -1422,18 +1426,18 @@ io(10) = linio([mdl, '/Vl Finally, we use the linearize Matlab function to extract a state space model from the simscape model.

    -
    %% Run the linearization
    -G_vc = linearize(mdl, io, options);
    -G_vc.InputName  = {'Dw',   ... % Ground Motion [m]
    -                   'Fs',   ... % Force Applied on Sample [N]
    -                   'Fn',   ... % Force applied by NASS [N]
    -                   'Fty',  ... % Parasitic Force Ty [N]
    -                   'Frz'};     % Parasitic Force Rz [N]
    -G_vc.OutputName = {'D',    ... % Measured sample displacement x.r.t. granite [m]
    -                   'Fnm',  ... % Force Sensor in NASS [N]
    -                   'Dnm',  ... % Displacement Sensor in NASS [m]
    -                   'Dgm',  ... % Asbolute displacement of Granite [m]
    -                   'Vlm'}; ... % Absolute Velocity of NASS [m/s]
    +
      %% Run the linearization
    +  G_vc = linearize(mdl, io, options);
    +  G_vc.InputName  = {'Dw',   ... % Ground Motion [m]
    +                     'Fs',   ... % Force Applied on Sample [N]
    +                     'Fn',   ... % Force applied by NASS [N]
    +                     'Fty',  ... % Parasitic Force Ty [N]
    +                     'Frz'};     % Parasitic Force Rz [N]
    +  G_vc.OutputName = {'D',    ... % Measured sample displacement x.r.t. granite [m]
    +                     'Fnm',  ... % Force Sensor in NASS [N]
    +                     'Dnm',  ... % Displacement Sensor in NASS [m]
    +                     'Dgm',  ... % Asbolute displacement of Granite [m]
    +                     'Vlm'}; ... % Absolute Velocity of NASS [m/s]
     
    @@ -1441,20 +1445,20 @@ G_vc.OutputName = {'D', ... -
    save('./mat/uniaxial_plants.mat', 'G_vc', '-append');
    +
      save('./mat/uniaxial_plants.mat', 'G_vc', '-append');
     
    -
    -

    8.3 Sensitivity to Disturbances

    +
    +

    8.3 Sensitivity to Disturbances

    We load the dynamics when using a piezo-electric nano hexapod to compare the results.

    -
    load('./mat/uniaxial_plants.mat', 'G');
    +
      load('./mat/uniaxial_plants.mat', 'G');
     
    @@ -1462,19 +1466,19 @@ We load the dynamics when using a piezo-electric nano hexapod to compare the res We show several plots representing the sensitivity to disturbances:

      -
    • in figure 38 the transfer functions from ground motion \(D_w\) to the sample position \(D\) and the transfer function from direct force on the sample \(F_s\) to the sample position \(D\) are shown
    • -
    • in figure 39, it is the effect of parasitic forces of the positioning stages (\(F_{ty}\) and \(F_{rz}\)) on the position \(D\) of the sample that are shown
    • +
    • in figure 38 the transfer functions from ground motion \(D_w\) to the sample position \(D\) and the transfer function from direct force on the sample \(F_s\) to the sample position \(D\) are shown
    • +
    • in figure 39, it is the effect of parasitic forces of the positioning stages (\(F_{ty}\) and \(F_{rz}\)) on the position \(D\) of the sample that are shown
    -
    +

    uniaxial-sensitivity-vc-disturbances.png

    Figure 38: Sensitivity to disturbances (png, pdf)

    -
    +

    uniaxial-sensitivity-vc-force-dist.png

    Figure 39: Sensitivity to disturbances (png, pdf)

    @@ -1482,24 +1486,24 @@ We show several plots representing the sensitivity to disturbances:
    -
    -

    8.4 Noise Budget

    +
    +

    8.4 Noise Budget

    We first load the measured PSD of the disturbance.

    -
    load('./mat/disturbances_dist_psd.mat', 'dist_f');
    +
      load('./mat/disturbances_dist_psd.mat', 'dist_f');
     

    The effect of these disturbances on the distance \(D\) is computed below. -The PSD of the obtain distance \(D\) due to each of the perturbation is shown in figure 40 and the Cumulative Amplitude Spectrum is shown in figure 41. +The PSD of the obtain distance \(D\) due to each of the perturbation is shown in figure 40 and the Cumulative Amplitude Spectrum is shown in figure 41.

    -The Root Mean Square value of the obtained displacement \(D\) is computed below and can be determined from the figure 41. +The Root Mean Square value of the obtained displacement \(D\) is computed below and can be determined from the figure 41.

     4.8793e-06
    @@ -1507,20 +1511,20 @@ The Root Mean Square value of the obtained displacement \(D\) is computed below
     
     
     
    -
    +

    uniaxial-vc-psd-dist.png

    Figure 40: PSD of the displacement \(D\) due to disturbances (png, pdf)

    -
    +

    uniaxial-vc-cas-dist.png

    Figure 41: CAS of the displacement \(D\) due the disturbances (png, pdf)

    -
    +

    Even though the RMS value of the displacement \(D\) is lower when using a piezo-electric actuator, the motion is mainly due to high frequency disturbances which are more difficult to control (an higher control bandwidth is required).

    @@ -1532,16 +1536,16 @@ Thus, it may be desirable to use voice coil actuators.
    -
    -

    8.5 Integral Force Feedback

    +
    +

    8.5 Integral Force Feedback

    -
    K_iff = -20/s;
    +
      K_iff = -20/s;
     
    -
    +

    uniaxial_iff_vc_open_loop.png

    Figure 42: Open Loop Transfer Function for IFF control when using a voice coil actuator (png, pdf)

    @@ -1549,23 +1553,23 @@ Thus, it may be desirable to use voice coil actuators.
    -
    -

    8.6 Identification of the Damped Plant

    +
    +

    8.6 Identification of the Damped Plant

    Let’s initialize the system prior to identification.

    -
    initializeGround();
    -initializeGranite();
    -initializeTy();
    -initializeRy();
    -initializeRz();
    -initializeMicroHexapod();
    -initializeAxisc();
    -initializeMirror();
    -initializeNanoHexapod('actuator', 'lorentz');
    -initializeSample('mass', 50);
    +
      initializeGround();
    +  initializeGranite();
    +  initializeTy();
    +  initializeRy();
    +  initializeRz();
    +  initializeMicroHexapod();
    +  initializeAxisc();
    +  initializeMirror();
    +  initializeNanoHexapod('actuator', 'lorentz');
    +  initializeSample('mass', 50);
     
    @@ -1573,69 +1577,69 @@ initializeSample('mass', 50); All the controllers are set to 0.

    -
    K = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K', '-append');
    -K_iff = -K_iff;
    -save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    -K_rmc = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    -K_dvf = tf(0);
    -save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
    +
      K = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K', '-append');
    +  K_iff = -K_iff;
    +  save('./mat/controllers_uniaxial.mat', 'K_iff', '-append');
    +  K_rmc = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K_rmc', '-append');
    +  K_dvf = tf(0);
    +  save('./mat/controllers_uniaxial.mat', 'K_dvf', '-append');
     
    -
    %% Options for Linearized
    -options = linearizeOptions;
    -options.SampleTime = 0;
    +
      %% Options for Linearized
    +  options = linearizeOptions;
    +  options.SampleTime = 0;
     
    -%% Name of the Simulink File
    -mdl = 'sim_nano_station_uniaxial';
    +  %% Name of the Simulink File
    +  mdl = 'sim_nano_station_uniaxial';
     
    -
    %% Input/Output definition
    -io(1)  = linio([mdl, '/Dw'],    1, 'input');  % Ground Motion
    -io(2)  = linio([mdl, '/Fs'],    1, 'input');  % Force applied on the sample
    -io(3)  = linio([mdl, '/Fnl'],   1, 'input');  % Force applied by the NASS
    -io(4)  = linio([mdl, '/Fdty'],  1, 'input');  % Parasitic force Ty
    -io(5)  = linio([mdl, '/Fdrz'],  1, 'input');  % Parasitic force Rz
    +
      %% Input/Output definition
    +  io(1)  = linio([mdl, '/Dw'],    1, 'input');  % Ground Motion
    +  io(2)  = linio([mdl, '/Fs'],    1, 'input');  % Force applied on the sample
    +  io(3)  = linio([mdl, '/Fnl'],   1, 'input');  % Force applied by the NASS
    +  io(4)  = linio([mdl, '/Fdty'],  1, 'input');  % Parasitic force Ty
    +  io(5)  = linio([mdl, '/Fdrz'],  1, 'input');  % Parasitic force Rz
     
    -io(6)  = linio([mdl, '/Dsm'],  1, 'output'); % Displacement of the sample
    -io(7)  = linio([mdl, '/Fnlm'], 1, 'output'); % Force sensor in NASS's legs
    -io(8)  = linio([mdl, '/Dnlm'], 1, 'output'); % Displacement of NASS's legs
    -io(9)  = linio([mdl, '/Dgm'],  1, 'output'); % Absolute displacement of the granite
    -io(10) = linio([mdl, '/Vlm'],  1, 'output'); % Measured absolute velocity of the top NASS platform
    +  io(6)  = linio([mdl, '/Dsm'],  1, 'output'); % Displacement of the sample
    +  io(7)  = linio([mdl, '/Fnlm'], 1, 'output'); % Force sensor in NASS's legs
    +  io(8)  = linio([mdl, '/Dnlm'], 1, 'output'); % Displacement of NASS's legs
    +  io(9)  = linio([mdl, '/Dgm'],  1, 'output'); % Absolute displacement of the granite
    +  io(10) = linio([mdl, '/Vlm'],  1, 'output'); % Measured absolute velocity of the top NASS platform
     
    -
    %% Run the linearization
    -G_vc_iff = linearize(mdl, io, options);
    -G_vc_iff.InputName  = {'Dw',   ... % Ground Motion [m]
    -                       'Fs',   ... % Force Applied on Sample [N]
    -                       'Fn',   ... % Force applied by NASS [N]
    -                       'Fty',  ... % Parasitic Force Ty [N]
    -                       'Frz'};     % Parasitic Force Rz [N]
    -G_vc_iff.OutputName = {'D',    ... % Measured sample displacement x.r.t. granite [m]
    -                       'Fnm',  ... % Force Sensor in NASS [N]
    -                       'Dnm',  ... % Displacement Sensor in NASS [m]
    -                       'Dgm',  ... % Asbolute displacement of Granite [m]
    -                       'Vlm'}; ... % Absolute Velocity of NASS [m/s]
    +
      %% Run the linearization
    +  G_vc_iff = linearize(mdl, io, options);
    +  G_vc_iff.InputName  = {'Dw',   ... % Ground Motion [m]
    +                         'Fs',   ... % Force Applied on Sample [N]
    +                         'Fn',   ... % Force applied by NASS [N]
    +                         'Fty',  ... % Parasitic Force Ty [N]
    +                         'Frz'};     % Parasitic Force Rz [N]
    +  G_vc_iff.OutputName = {'D',    ... % Measured sample displacement x.r.t. granite [m]
    +                         'Fnm',  ... % Force Sensor in NASS [N]
    +                         'Dnm',  ... % Displacement Sensor in NASS [m]
    +                         'Dgm',  ... % Asbolute displacement of Granite [m]
    +                         'Vlm'}; ... % Absolute Velocity of NASS [m/s]
     
    -
    -

    8.7 Noise Budget

    +
    +

    8.7 Noise Budget

    We compute the obtain PSD of the displacement \(D\) when using IFF.

    -
    +

    uniaxial-cas-iff-vc.png

    Figure 43: CAS of the displacement \(D\) (png, pdf)

    @@ -1643,10 +1647,10 @@ We compute the obtain PSD of the displacement \(D\) when using IFF.
    -
    -

    8.8 Conclusion

    +
    +

    8.8 Conclusion

    -
    +

    The use of voice coil actuators would allow a better disturbance rejection for a fixed bandwidth compared with a piezo-electric hexapod.

    @@ -1662,7 +1666,7 @@ Similarly, it would require much lower bandwidth to attain the same level of dis

    Author: Dehaeze Thomas

    -

    Created: 2020-04-17 ven. 09:35

    +

    Created: 2021-02-20 sam. 23:08

    diff --git a/org/setup/org-setup-file.org b/org/setup/org-setup-file.org index da956e4..d4a1f0c 100644 --- a/org/setup/org-setup-file.org +++ b/org/setup/org-setup-file.org @@ -4,15 +4,11 @@ #+EMAIL: dehaeze.thomas@gmail.com #+AUTHOR: Dehaeze Thomas -#+HTML_LINK_HOME: ./index.html +#+HTML_LINK_HOME: ../../index.html #+HTML_LINK_UP: ./index.html -#+HTML_HEAD: -#+HTML_HEAD: -#+HTML_HEAD: -#+HTML_HEAD: -#+HTML_HEAD: -#+HTML_HEAD: +#+HTML_HEAD: +#+HTML_HEAD: #+PROPERTY: header-args:matlab :session *MATLAB* #+PROPERTY: header-args:matlab+ :comments org @@ -29,8 +25,11 @@ #+PROPERTY: header-args:latex+ :imagemagick t :fit yes #+PROPERTY: header-args:latex+ :iminoptions -scale 100% -density 150 #+PROPERTY: header-args:latex+ :imoutoptions -quality 100 -#+PROPERTY: header-args:latex+ :results raw replace :buffer no +#+PROPERTY: header-args:latex+ :results file raw replace +#+PROPERTY: header-args:latex+ :buffer no +#+PROPERTY: header-args:latex+ :tangle no #+PROPERTY: header-args:latex+ :eval no-export #+PROPERTY: header-args:latex+ :exports results #+PROPERTY: header-args:latex+ :mkdirp yes #+PROPERTY: header-args:latex+ :output-dir figs +#+PROPERTY: header-args:latex+ :post pdf2svg(file=*this*, ext="png")
    Table 2: Comparison of proposed active damping techniques