Files
delta-robot/delta-robot.org
2025-12-02 16:32:26 +01:00

109 KiB

Delta Robot

The Delta Robot Kinematics

<<sec:delta_robot_kinematics>>

Introduction   ignore

Studied Geometry

The Delta Robot geometry is defined as shown in Figure fig:delta_robot_schematic.

The geometry is fully defined by three parameters:

  • d: Cube's size (i.e., the length of the cube edge)
  • b: Distance from cube's vertex to top flexible joint
  • L: Distance between two flexible joints (i.e., the length of the struts)
figs/delta_robot_schematic.png
Schematic of the Delta Robot

Several frames are defined:

  • $\{C\}$: Cube's center
  • $\{M\}$: Frame attached to the mobile platform, and located at the height of the top flexible joints
  • $\{F\}$: Frame attached to the fixed platform, and located at the height of the bottom flexible joints

Several points are defined:

  • $c_i$: vertices of the cubes which are relevant for the Delta Robot
  • $b_i$: location of the top flexible joints
  • $a_i$: location of the bottom flexible joints
  • $\hat{s}_i$: unit vector aligned with the struts

Static properties:

  • All top and bottom flexible joints are identical. The following properties can be specified:

    • $k_a$: Axial stiffness
    • $k_r$: Radial stiffness
    • $k_b$: Bending stiffness
    • $k_t$: Torsion stiffness
  • The guiding mechanism of the actuator is here supposed to be perfect (i.e. 1dof system without any stiffness)
  • The Actuator is modelled as a 1DoF or 2DoF (good to model APA):

    • The custom developed APA has an axial stiffness of $1.3\,N/\mu m$

Dynamical properties:

  • Top platform inertia: It has a mass of ~300g
  • Payloads: payloads can weight up to 1kg

Let's initialize a Delta Robot architecture, and plot the obtained geometry (Figures fig:delta_robot_architecture and fig:delta_robot_architecture_top).

%% Geometry
d = 50e-3; % Cube's edge length [m]
b = 20e-3; % Distance between cube's vertices and top joints [m]
L = 50e-3; % Length of the struts [m]
%% Initialize the Delta Robot
delta_robot = initializeStewartPlatform();
delta_robot = generateDeltaRobot(delta_robot, 'd', d, 'b', b, 'L', L);
delta_robot = computeJointsPose(delta_robot);
delta_robot = initializeActuatorDynamics(delta_robot);
delta_robot = initializeJointDynamics(delta_robot);
delta_robot = initializeCylindricalStruts(delta_robot);
delta_robot = computeJacobian(delta_robot);
delta_robot = initializeStewartPose(delta_robot);

figs/delta_robot_architecture.png

Delta Robot Architecture

figs/delta_robot_architecture_top.png

Delta Robot Architecture - Top View

Kinematics: Jacobian Matrix and Mobility

There are three actuators in the following directions $\hat{s}_1$, $\hat{s}_2$ and $\hat{s}_3$;

\begin{equation}\label{eq:delta_robot_unit_vectors} \hat{\bm{s}}_1 = \begin{bmatrix} \frac{-1}{\sqrt{6}} \\ \frac{-1}{\sqrt{2}} \\ \frac{1}{\sqrt{3}} \end{bmatrix}\quad \hat{\bm{s}}_2 = \begin{bmatrix} \frac{\sqrt{2}}{\sqrt{3}} \\ 0 \\ \frac{1}{\sqrt{3}} \end{bmatrix}\quad \hat{\bm{s}}_3 = \begin{bmatrix} \frac{-1}{\sqrt{6}} \\ \frac{ 1}{\sqrt{2}} \\ \frac{1}{\sqrt{3}} \end{bmatrix}\quad \hat{\bm{s}}_2 = \begin{bmatrix} \frac{\sqrt{2}}{\sqrt{3}} \\ 0 \\ \frac{1}{\sqrt{3}} \end{bmatrix}\quad \hat{\bm{s}}_3 = \begin{bmatrix} \frac{-1}{\sqrt{6}} \\ \frac{ 1}{\sqrt{2}} \\ \frac{1}{\sqrt{3}} \end{bmatrix}\quad \hat{\bm{s}}_3 = \begin{bmatrix} \frac{-1}{\sqrt{6}} \\ \frac{ 1}{\sqrt{2}} \\ \frac{1}{\sqrt{3}} \end{bmatrix}

\end{equation}

The Jacobian matrix is defined as shown in eqref:eq:delta_robot_jacobian.

\begin{equation}\label{eq:delta_robot_jacobian} \bm{J} = \begin{bmatrix} \hat{\bm{s}}_1^T \\ \hat{\bm{s}}_2^T \\ \hat{\bm{s}}_3^T

\end{bmatrix}

\end{equation}

%% Jacobian matrix
s1 = delta_robot.geometry.As(:,1);
s2 = delta_robot.geometry.As(:,3);
s3 = delta_robot.geometry.As(:,5);

J = [s1' ; s2' ; s3']

It links the small actuator displacement to the top platform displacement eqref:eq:delta_robot_inverse_kinematics.

\begin{equation}\label{eq:delta_robot_inverse_kinematics} d\mathcal{L} = J d\mathcal{L}

\end{equation}

\begin{equation}\label{eq:delta_robot_forward_kinematics} d\mathcal{X} = J-1 d\mathcal{L}

\end{equation}

The achievable workspace is a cube whose edge length is equal to the actuator stroke.

%% Estimation of the mobility
L_max =  50e-6; % Maximum actuator stroke (+/-) [m]

thetas = linspace(0, pi, 100);
phis = linspace(0, 2*pi, 100);
rs = zeros(length(thetas), length(phis));

for i = 1:length(thetas)
    for j = 1:length(phis)
        Tx = sin(thetas(i))*cos(phis(j));
        Ty = sin(thetas(i))*sin(phis(j));
        Tz = cos(thetas(i));

        dL = J*[Tx; Ty; Tz]; % dL required for 1m displacement in theta/phi direction

        rs(i, j) = L_max/max(abs(dL));
    end
end

figs/delta_robot_3d_workspace.png

3D workspace

As most likely, the system will be used to perform YZ scans, it is interesting to see the mobility of the system in the ZY plane.

Depending on how the YZ plane is oriented (i.e., depending on the Rz angle of the delta robot with respect to the beam, defining the x direction), we get different mobility.

%% 2D mobility for different angles
L_max =  150e-6; % Maximum actuator stroke (+/-) [m]

thetas = linspace(0, 2*pi, 1001);
phis = linspace(0, pi/2, 101);
rs = zeros(length(thetas), length(phis));

for i = 1:length(thetas)
    for j = 1:length(phis)
        Tx = cos(thetas(i))*cos(phis(j));
        Ty = cos(thetas(i))*sin(phis(j));
        Tz = sin(thetas(i));

        dL = J*[Tx; Ty; Tz]; % dL required for 1m displacement in theta/phi direction

        rs(i, j) = L_max/max(abs(dL));
    end
end

%% Get minimum square in the Y/Z plane
[~, i] = min(abs(thetas-pi/4));
L = 1/sqrt(2)*min(abs(rs(i,:)));

figs/delta_robot_2d_workspace.png

2D mobility for different orientations and worst case
%% Get the orientation that gives the best YZ mobility
L_max =  150e-6; % Maximum actuator stroke (+/-) [m]

thetas = [pi/4, pi/4+pi/2, pi/4+pi, pi/4+3*pi/2];
phis = linspace(0, 2*pi, 1001);
rs = zeros(length(thetas), length(phis));

for i = 1:length(thetas)
    for j = 1:length(phis)
        Tx = cos(thetas(i))*cos(phis(j));
        Ty = cos(thetas(i))*sin(phis(j));
        Tz = sin(thetas(i));

        dL = J*[Tx; Ty; Tz]; % dL required for 1m displacement in theta/phi direction

        rs(i, j) = L_max/max(abs(dL));
    end
end

[Lmax, imax] = max(min(rs));
Dmax = Lmax/sqrt(2); % Size of the cube
Maximum YZ mobility for an angle of 270 degrees, square with edge size of 117 um

figs/delta_robot_2d_workspace_optimal.png

2D mobility for the optimal Rz angle

Kinematics: Degrees of Freedom

In the perfect case (flexible joints having no stiffness in bending, and infinite stiffness in torsion and in the axial direction), the top platform is allowed to move only in the X, Y and Z directions while the three rotations are fixed.

In order to have some compliance in rotation, the flexible joints need to have some compliance in torsion and in the axial direction. If only the torsional compliance is considered, or only the axial compliance, the top platform will still not be able to do any rotation.

This is shown below with the Simscape model.

Perfect Delta Robot:

  • infinite axial stiffness
  • infinite torsional stiffness
  • no bending stiffness

It gives infinite stiffness in rotations, and a stiffness of $1\,N/\mu m$ in X, Y and Z directions (i.e. equal to the actuator stiffness).

%% Initialize the Delta Robot

% Geometry
d = 50e-3; % Cube's edge length [m]
b = 20e-3; % Distance between cube's vertices and top joints [m]
L = 50e-3; % Length of the struts [m]

% Actuator
k = 1e6; % [N/m]

delta_robot = initializeStewartPlatform();
delta_robot = generateDeltaRobot(delta_robot, 'd', d, 'b', b, 'L', L);
delta_robot = computeJointsPose(delta_robot);
delta_robot = initializeActuatorDynamics(delta_robot, 'type', '1dof', 'k', k);
delta_robot = initializeJointDynamics(delta_robot, 'type_F', '2dof', 'type_M', '2dof');
delta_robot = initializeCylindricalStruts(delta_robot);
delta_robot = computeJacobian(delta_robot);
delta_robot = initializeStewartPose(delta_robot);

% Sample on top
sample = initializeSample('type', 'cylindrical', 'm', 1, 'H', 50e-3, 'R', 20e-3);
%% Perfect Joints
delta_robot = initializeJointDynamics(delta_robot, 'type_F', '2dof', 'type_M', '2dof');

clear io; io_i = 1;
io(io_i) = linio([mdl, '/Fd'],             1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
io(io_i) = linio([mdl, '/6dof_metrology'], 1, 'openoutput'); io_i = io_i + 1; % Actuator Displacement [m]

% Run the linearization
G_perfect = linearize(mdl, io);
G_perfect.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
G_perfect.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};
Stiffness in X,Y and Z directions: 1.0 N/um

If we consider the torsion of the flexible joints:

  • infinite axial stiffness
  • finite torsional stiffness
  • no bending stiffness

We get the same result.

%% Consider some torsional stiffness
delta_robot = initializeJointDynamics(delta_robot, 'type_F', '3dof', 'type_M', '3dof', 'kt', 100);

% Run the linearization
G_kt = linearize(mdl, io);
G_kt.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
G_kt.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};

dcgain(G_kt)

If we consider the axial of the flexible joints:

  • finite axial stiffness
  • infinite torsional stiffness
  • no bending stiffness

We get the same result.

%% Consider some axial stiffness
delta_robot = initializeJointDynamics(delta_robot, 'type_F', '2dof_a', 'type_M', '2dof_a', 'ka', 100e6);

% Run the linearization
G_ka = linearize(mdl, io);
G_ka.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
G_ka.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};

dcgain(G_ka)

No we consider both finite torsional stiffness and finite axial stiffness. In that case we get some compliance in rotation. So it is a combination of axial and torsion stiffness that gives some rotational stiffness of the top platform.

%% Consider both the axial and torsional compliances of the joints
delta_robot = initializeJointDynamics(delta_robot, 'type_F', '3dof_a', 'type_M', '3dof_a', 'ka', 100e6, 'kt', 100);

% Run the linearization
G_ka_kt = linearize(mdl, io);
G_ka_kt.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
G_ka_kt.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};

dcgain(G_ka_kt)

Therefore, to model some compliance of the top platform in rotation, both the axial compliance and the torsional compliance of the flexible joints should be considered.

Kinematics: Number of modes

In the perfect condition (i.e. infinite stiffness in torsion and in compression of the flexible joints), the system has 6 states (i.e. 3 modes, one for each DoF: X, Y and Z).

When considering some compliance in torsion of the flexible joints, 12 states are added (one internal mode of the struts). To remove these internal states (that might not be interesting but that could slow the simulations), one of the joint can have this torsional compliance while the other can have the torsional DoF constrained.

%% Verify that we get 6 states in the ideal case

% Geometry
d = 50e-3; % Cube's edge length [m]
b = 20e-3; % Distance between cube's vertices and top joints [m]
L = 50e-3; % Length of the struts [m]

% Actuator
k = 1e6; % [N/m]

% Initialize the Delta Robot
delta_robot = initializeStewartPlatform();
delta_robot = generateDeltaRobot(delta_robot, 'd', d, 'b', b, 'L', L);
delta_robot = computeJointsPose(delta_robot);
delta_robot = initializeActuatorDynamics(delta_robot, 'type', '1dof', 'k', k);
delta_robot = initializeJointDynamics(delta_robot, 'type_F', '2dof', 'type_M', '3dof');
delta_robot = initializeCylindricalStruts(delta_robot);
delta_robot = computeJacobian(delta_robot);
delta_robot = initializeStewartPose(delta_robot);

% Sample on top
sample = initializeSample('type', 'cylindrical', 'm', 1, 'H', 50e-3, 'R', 20e-3);

% Input/Output definition of the Simscape model
clear io; io_i = 1;
io(io_i) = linio([mdl, '/F'],           1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
io(io_i) = linio([mdl, '/delta_robot'], 1, 'openoutput'); io_i = io_i + 1; % Actuator Displacement [m]

% Run the linearization
G = linearize(mdl, io);
G.InputName  = {'F1', 'F2', 'F3'};
G.OutputName = {'D1', 'D2', 'D3'};
State-space model with 3 outputs, 3 inputs, and 6 states.

Flexible Joint Design

<<sec:delta_robot_flexible_joints>>

Introduction   ignore

First, in Section ssec:delta_robot_flexible_joints_geometry, the dynamics of a "perfect" Delta-Robot is identified (i.e. with perfect 2DoF rotational joints).

Then, the impact of the flexible joint's imperfections will be studied. The goal is to extract specifications for the flexible joints of the six struts, in terms of:

Studied Geometry

<<ssec:delta_robot_flexible_joints_geometry>>

The cube's edge length is equal to 50mm, the distance between cube's vertices and top joints is 20mm and the length of the struts (i.e. the distance between the two flexible joints of the same strut) is 50mm. The actuator stiffness is $1\,N/\mu m$.

The obtained geometry is shown in Figure fig:delta_robot_studied_geometry.

%% Geometry
d = 50e-3; % Cube's edge length [m]
b = 20e-3; % Distance between cube's vertices and top joints [m]
L = 50e-3; % Length of the struts [m]

%% Actuator
k = 1e6; % [N/m]
%% Initialize the Delta Robot
delta_robot = initializeStewartPlatform();
delta_robot = generateDeltaRobot(delta_robot, 'd', d, 'b', b, 'L', L);
delta_robot = computeJointsPose(delta_robot);
delta_robot = initializeActuatorDynamics(delta_robot, 'type', '1dof', 'k', k);
delta_robot = initializeJointDynamics(delta_robot, 'type_F', '3dof', 'type_M', '3dof');
delta_robot = initializeCylindricalStruts(delta_robot);
delta_robot = computeJacobian(delta_robot);
delta_robot = initializeStewartPose(delta_robot);

figs/delta_robot_studied_geometry.png

Geometry of the studied Delta Robot
%% Sample on top
sample = initializeSample('type', 'cylindrical', 'm', 1, 'H', 50e-3, 'R', 20e-3);

%% Input/Output definition of the Simscape model
clear io; io_i = 1;
io(io_i) = linio([mdl, '/F'],           1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
io(io_i) = linio([mdl, '/delta_robot'], 1, 'openoutput'); io_i = io_i + 1; % Actuator Displacement [m]

%% Run the linearization
G = linearize(mdl, io);
G.InputName  = {'F1', 'F2', 'F3'};
G.OutputName = {'D1', 'D2', 'D3'};

The dynamics is first identified in perfect conditions (infinite axial stiffness of the joints, zero bending stiffness). We get State-space model with 3 outputs, 3 inputs, and 6 states. We get a perfectly decoupled system, with three identical modes in the X, Y and Z directions. The dynamics is shown in Figure fig:delta_robot_dynamics_perfect.

figs/delta_robot_dynamics_perfect.png

Dynamics of the delta robot with perfect joints

Bending Stiffness

<<ssec:delta_robot_flexible_joints_bending>>

Stiffness seen by the actuator, and decrease of the achievable stroke

Because the flexible joints will have some bending stiffness, the actuator in one direction will "see" some stiffness due to the struts in the other directions. This will limit its effective stroke. We want this parallel stiffness to be much smaller than the stiffness of the actuator.

The parallel stiffness seen by the actuator as a function of the bending stiffness of the flexible joints is computed and shown in Figure fig:delta_robot_bending_stiffness_parallel_k.

%% Bending Stiffness
Kfs = [1, 2, 10, 20, 50, 100, 200, 500, 1000];
Kps_Kf = zeros(size(Kfs));

for i = 1:length(Kfs)
    delta_robot = initializeJointDynamics(delta_robot, 'type_F', '3dof', 'type_M', '3dof', 'Kf', Kfs(i));

    %% Run the linearization
    G = linearize(mdl, io);
    G.InputName  = {'F1', 'F2', 'F3'};
    G.OutputName = {'D1', 'D2', 'D3'};

    Kps_Kf(i) = (1-k*abs(evalfr(G(1,1), 1j*2*pi)))/abs(evalfr(G(1,1), 1j*2*pi));
end

figs/delta_robot_bending_stiffness_parallel_k.png

Effect of the bending stiffness of the flexible joints on the stiffness seen by the actuators

The parallel stiffness is therefore proportional to the bending stiffness. The "linear coefficient" depend on the geometry, and it is here equal to $3200 \frac{N/m}{Nm/\text{rad}}$.

If we want the parallel stiffness to be much smaller than the stiffness of the actuator ($k_p \ll k_a = 1.6\,N/\mu m$), the bending stiffness should be $\ll 500\,Nm/\text{rad}$. Therefore, we should aim at $k_f < 50\,Nm/\text{rad}$.

This should be validated with the final geometry.

Then, the dynamics is identified for a bending Stiffness of $50\,Nm/\text{rad}$ and compared with a Delta robot with no bending stiffness in Figure fig:delta_robot_bending_stiffness_dynamics.

It can be seen that the DC gain is a bit lower when the bending stiffness is considered and the resonance frequency is increased. This simply means that the system stiffness is increased. It is not critical from a dynamical point of view, it just decreases the achievable stroke as explained in the previous section.

%% Delta Robot with flexible joints having no bending compliance
delta_robot = initializeJointDynamics(delta_robot, 'type_F', '3dof', 'type_M', '3dof');

% Run the linearization
G_no_kf = linearize(mdl, io);
G_no_kf.InputName  = {'F1', 'F2', 'F3'};
G_no_kf.OutputName = {'D1', 'D2', 'D3'};

%% Delta Robot with flexible joints having some bending compliance
delta_robot = initializeJointDynamics(delta_robot, 'type_F', '3dof', 'type_M', '3dof', 'Kf', 50);

% Run the linearization
G_kf = linearize(mdl, io);
G_kf.InputName  = {'F1', 'F2', 'F3'};
G_kf.OutputName = {'D1', 'D2', 'D3'};

figs/delta_robot_bending_stiffness_dynamics.png

Effect of the bending stiffness on the dynamics

Effect on the coupling

Here, reasonable values for the flexible joints (modelled as a 6DoF joint) stiffness are taken:

  • Torsional stiffness of 500Nm/rad
  • Axial stiffness of 100N/um
  • Shear stiffness of 100N/um

And the bending stiffness is varied from low to high values. The obtained dynamics is shown in Figure fig:delta_robot_bending_stiffness_couplign. It can be seen that the low frequency coupling increases when the bending stiffness increases.

Therefore, the bending stiffness of the flexible joints should be minimized (10Nm/rad could be a reasonable objective).

%% Effect of bending stiffness on the plant dynamics
d = 50e-3; % Cube's edge length [m]
b = 20e-3; % Distance between cube's vertices and top joints [m]
L = 50e-3; % Length of the struts [m]

delta_robot = initializeStewartPlatform();
delta_robot = generateDeltaRobot(delta_robot, 'd', d, 'b', b, 'L', L);
delta_robot = computeJointsPose(delta_robot);
delta_robot = initializeActuatorDynamics(delta_robot, 'type', '1dof', 'k', k);
delta_robot = initializeCylindricalStruts(delta_robot);
delta_robot = computeJacobian(delta_robot);
delta_robot = initializeStewartPose(delta_robot);

joint_axial = 100e6; % [N/m]
joint_shear = 100e6; % [N/m]
joint_bending = 50; % [Nm/rad]
joint_torsion = 500; % [Nm/rad]

clear io; io_i = 1;
io(io_i) = linio([mdl, '/F'],           1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
io(io_i) = linio([mdl, '/delta_robot'], 1, 'openoutput'); io_i = io_i + 1; % Actuator Displacement [m]

Kfs = [1, 10, 100, 1000];
Gkf = {zeros(size(Kfs))};

for i = 1:length(Kfs)
    delta_robot = initializeJointDynamics(delta_robot, 'type_F', '6dof', 'type_M', '6dof', 'Ka', joint_axial, 'Kf', Kfs(i), 'Kt', joint_torsion, 'Ks', joint_shear);

    %% Run the linearization
    G = linearize(mdl, io);
    G.InputName  = {'F1', 'F2', 'F3'};
    G.OutputName = {'D1', 'D2', 'D3'};

    Gkf(i) = {G};
end

figs/delta_robot_bending_stiffness_couplign.png

Effect of the bending stiffness of the flexible joints on the coupling

Axial Stiffness

<<ssec:delta_robot_flexible_joints_axial>>

Now, the effect of the axial stiffness on the dynamics is studied (Figure fig:delta_robot_axial_stiffness_dynamics). Additional modes can be observed on the plant dynamics, which could limit the achievable bandwidth. Therefore the axial stiffness should be maximized. Having the axial stiffness 100 times stiffer than the actuator stiffness seems reasonable. Therefore, we should aim at $k_a > 100\,N/\mu m$.

%% Bending Stiffness
Kas = [5e8, 2e8, 1e8, 5e7, 2e7, 1e7];
Gka = {zeros(size(Kas))};

for i = 1:length(Kas)
    delta_robot = initializeJointDynamics(delta_robot, 'type_F', '2dof_a', 'type_M', '2dof_a', 'Ka', Kas(i));

    %% Run the linearization
    G = linearize(mdl, io);
    G.InputName  = {'F1', 'F2', 'F3'};
    G.OutputName = {'D1', 'D2', 'D3'};

    Gka(i) = {G};
end

figs/delta_robot_axial_stiffness_dynamics.png

Effect of the joint's axial stiffness on the plant dynamics

Torsional Stiffness

<<ssec:delta_robot_flexible_joints_torsion>>

Now the compliance in torsion of the flexible joints is considered.

If we look at the compliance of the delta robot in rotation as a function of the torsional stiffness of the flexible joints (Figure fig:delta_robot_kt_compliance), we see almost no effect: the system is not made more stiff by increasing the torsional stiffness of the joints.

%% Effect of torsional stiffness on the system compliance
joint_axial = 100e6; % [N/m]
joint_bending = 50; % [Nm/rad]

clear io; io_i = 1;
io(io_i) = linio([mdl, '/Fd'],             1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
io(io_i) = linio([mdl, '/6dof_metrology'], 1, 'openoutput'); io_i = io_i + 1; % Actuator Displacement [m]

% Torsional Stiffness
Kts = [1, 10, 100, 1000, 10000];
Gkt = {zeros(size(Kts))};

for i = 1:length(Kts)
    delta_robot = initializeJointDynamics(delta_robot, 'type_F', '3dof_a', 'type_M', '3dof_a', 'Ka', joint_axial, 'Kf', joint_bending, 'Kt', Kts(i));

    %% Run the linearization
    G = linearize(mdl, io);
    G.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    G.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};

    Gkt(i) = {G};
end

figs/delta_robot_kt_compliance.png

Effect of the joint's torsional stiffness on the Delta Robot compliance

If we have a look at the effect of the torsional stiffness on the plant dynamics (Figure fig:delta_robot_kt_dynamics), we see almost no effect, except when super high values are reached ($10^6\,Nm/\text{rad}$), which are unrealistic.

%% Effect of torsional stiffness on the plant dynamics
joint_axial = 100e6; % [N/m]
joint_bending = 50; % [Nm/rad]

clear io; io_i = 1;
io(io_i) = linio([mdl, '/F'],           1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
io(io_i) = linio([mdl, '/delta_robot'], 1, 'openoutput'); io_i = io_i + 1; % Actuator Displacement [m]

% Torsional Stiffness
Kts = [1, 10, 100, 1000, 10000];
Gkt = {zeros(size(Kts))};

for i = 1:length(Kts)
    delta_robot = initializeJointDynamics(delta_robot, 'type_F', '3dof_a', 'type_M', '3dof_a', 'Ka', joint_axial, 'Kf', joint_bending, 'Kt', Kts(i));

    %% Run the linearization
    G = linearize(mdl, io);
    G.InputName  = {'F1', 'F2', 'F3'};
    G.OutputName = {'D1', 'D2', 'D3'};

    Gkt(i) = {G};
end

figs/delta_robot_kt_dynamics.png

Effect of the joint's torsional stiffness on the Delta Robot plant dynamics

Therefore, the torsional stiffness is not a super important metric for the design of the delta robot.

Shear Stiffness

<<ssec:delta_robot_flexible_joints_shear>>

As shown in Figure fig:delta_robot_shear_stiffness_compliance, the shear stiffness of the flexible joints has some effect on the compliance in translation and almost no effect on the compliance in rotation.

This is quite logical, and so the shear stiffness should be maximized. A value of $100\,N/\mu m$ seems reasonable.

%% Effect of torsional stiffness on the system compliance
joint_axial = 100e6; % [N/m]
joint_bending = 50; % [Nm/rad]
joint_torsion = 500; % [Nm/rad]

clear io; io_i = 1;
io(io_i) = linio([mdl, '/Fd'],             1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
io(io_i) = linio([mdl, '/6dof_metrology'], 1, 'openoutput'); io_i = io_i + 1; % Actuator Displacement [m]

% Torsional Stiffness
Kss = [1e6, 1e7, 1e8, 1e9];
Gks = {zeros(size(Kss))};

for i = 1:length(Kss)
    delta_robot = initializeJointDynamics(delta_robot, 'type_F', '6dof', 'type_M', '6dof', 'Ka', joint_axial, 'Kf', joint_bending, 'Kt', joint_torsion, 'Ks', Kss(i));

    %% Run the linearization
    G = linearize(mdl, io);
    G.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    G.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};

    Gks(i) = {G};
end

figs/delta_robot_shear_stiffness_compliance.png

Effect of the shear stiffness of the flexible joints on the Delta Robot compliance

Conclusion

Joint's Stiffness Effect Recommendation
Bending Can reduce the stroke, and increase the coupling Below 50 to 10 Nm/rad
Axial Add modes that can limit the feedback bandwidth As high as possible, at least 100 Nm/um
Torsion Minor effect No recommendation
Shear Can limit the stiffness of the system As high as possible (less important than the axial stiffness), above 100 N/um if possible
Recommendations for the flexible joints

Effect of the Geometry

<<sec:delta_robot_flexible_geometry>>

Introduction   ignore

In this section, the effect of the geometry on the system properties are studied. The goal is to better understand the different trade-offs, and to extract specifications in terms of the Delta Robot geometry.

Reasonable values for the flexible joints are taken:

  • Bending stiffness of 50Nm/rad
  • Torsional stiffness of 500Nm/rad
  • Axial stiffness of 100N/um
  • Shear stiffness of 100N/um

The effect of the following geometrical features are studied:

Effect of cube's size

<<ssec:delta_robot_flexible_geometry_cube_size>>

Obtained geometries

The cube size is varied from 10mm (Figure fig:delta_robot_cube_size_small) to 100mm (Figure fig:delta_robot_cube_size_large) to study the effect on the system dynamics.

%% Effect of torsional stiffness on the plant dynamics
delta_robot = initializeStewartPlatform();
delta_robot = generateDeltaRobot(delta_robot, 'd', 10e-3, 'b', b, 'L', L);
delta_robot = computeJointsPose(delta_robot);
delta_robot = initializeActuatorDynamics(delta_robot);
delta_robot = initializeJointDynamics(delta_robot);
delta_robot = initializeCylindricalStruts(delta_robot);
delta_robot = computeJacobian(delta_robot);
delta_robot = initializeStewartPose(delta_robot);

figs/delta_robot_cube_size_small.png

Obtained Delta Robot for a cube's size of 10mm
%% Effect of torsional stiffness on the plant dynamics
delta_robot = initializeStewartPlatform();
delta_robot = generateDeltaRobot(delta_robot, 'd', 100e-3, 'b', b, 'L', L);
delta_robot = computeJointsPose(delta_robot);
delta_robot = initializeActuatorDynamics(delta_robot);
delta_robot = initializeJointDynamics(delta_robot);
delta_robot = initializeCylindricalStruts(delta_robot);
delta_robot = computeJacobian(delta_robot);
delta_robot = initializeStewartPose(delta_robot);

figs/delta_robot_cube_size_large.png

Obtained Delta Robot for a cube's size of 100mm

Effect on the plant dynamics

The effect of the cube's size on the plant dynamics is shown in Figure fig:delta_robot_cube_size_plant_dynamics:

  • coupling decreases with the cube's size (probably because of the reduced effect of the flexible joints' bending stiffness)
  • one resonance frequency increases with the cube's size (resonances in rotation), which may be beneficial from a control point of view
  • coupling at the main resonance varies with the cube's size, but it may also depend on the relative position between the CoM and the cube's center
%% Effect of torsional stiffness on the plant dynamics
joint_axial = 100e6; % [N/m]
joint_shear = 100e6; % [N/m]
joint_bending = 50; % [Nm/rad]
joint_torsion = 500; % [Nm/rad]

clear io; io_i = 1;
io(io_i) = linio([mdl, '/F'],           1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
io(io_i) = linio([mdl, '/delta_robot'], 1, 'openoutput'); io_i = io_i + 1; % Actuator Displacement [m]

% Cube's size
cube_sizes = [10e-3, 20e-3, 50e-3, 100e-3];
G_cube_size = {zeros(size(cube_sizes))};

for i = 1:length(cube_sizes)
    delta_robot = initializeStewartPlatform();
    delta_robot = generateDeltaRobot(delta_robot, 'd', cube_sizes(i), 'b', b, 'L', L);
    delta_robot = computeJointsPose(delta_robot);
    delta_robot = initializeActuatorDynamics(delta_robot, 'type', '1dof', 'k', k);
    delta_robot = initializeJointDynamics(delta_robot, 'type_F', '6dof', 'type_M', '6dof', 'Ka', joint_axial, 'Kf', joint_bending, 'Kt', joint_torsion, 'Ks', joint_shear);
    delta_robot = initializeCylindricalStruts(delta_robot);
    delta_robot = computeJacobian(delta_robot);
    delta_robot = initializeStewartPose(delta_robot);

    %% Run the linearization
    G = linearize(mdl, io);
    G.InputName  = {'F1', 'F2', 'F3'};
    G.OutputName = {'D1', 'D2', 'D3'};

    G_cube_size(i) = {G};
end

figs/delta_robot_cube_size_plant_dynamics.png

Effect of the cube's size on the plant dynamics

Effect on the compliance

As shown in Figure fig:delta_robot_cube_size_compliance_rotation, the stiffness of the delta robot in rotation increases with the cube's size.

Therefore, if possible the cube's size should be increased. With a cube size of 50mm, the resonance frequency is already above 1kHz with seems reasonable.

%% Effect of torsional stiffness on the plant dynamics
joint_axial = 100e6; % [N/m]
joint_bending = 50; % [Nm/rad]
joint_torsion = 500; % [Nm/rad]

clear io; io_i = 1;
io(io_i) = linio([mdl, '/Fd'],             1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
io(io_i) = linio([mdl, '/6dof_metrology'], 1, 'openoutput'); io_i = io_i + 1; % Actuator Displacement [m]

% Cube's size
cube_sizes = [10e-3, 20e-3, 50e-3, 100e-3];
G_cube_size = {zeros(size(cube_sizes))};

for i = 1:length(cube_sizes)
    delta_robot = initializeStewartPlatform();
    delta_robot = generateDeltaRobot(delta_robot, 'd', cube_sizes(i), 'b', b, 'L', L);
    delta_robot = computeJointsPose(delta_robot);
    delta_robot = initializeActuatorDynamics(delta_robot, 'type', '1dof', 'k', k);
    delta_robot = initializeJointDynamics(delta_robot, 'type_F', '3dof_a', 'type_M', '2dof_a', 'Ka', joint_axial, 'Kf', joint_bending, 'Kt', joint_torsion);
    delta_robot = initializeCylindricalStruts(delta_robot);
    delta_robot = computeJacobian(delta_robot);
    delta_robot = initializeStewartPose(delta_robot);

    %% Run the linearization
    G = linearize(mdl, io);
    G.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    G.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};

    G_cube_size(i) = {G};
end

figs/delta_robot_cube_size_compliance_rotation.png

Effect of the cube's size on the rotational compliance of the top platform

Effect of the strut length

<<ssec:delta_robot_flexible_geometry_strut_length>>

Obtained geometries

Let's choose reasonable values for the flexible joints:

  • Bending stiffness of 50Nm/rad
  • Torsional stiffness of 500Nm/rad
  • Axial stiffness of 100N/um

And we see the effect of changing the strut length.

The strut length is varied from 10mm (Figure fig:delta_robot_strut_small) to 100mm (Figure fig:delta_robot_strut_large) to study the effect on the system dynamics.

d = 50e-3; % Cube's edge length [m]
b = 20e-3; % Distance between cube's vertices and top joints [m]
L = 50e-3; % Length of the struts [m]
%% Effect of torsional stiffness on the plant dynamics
delta_robot = initializeStewartPlatform();
delta_robot = generateDeltaRobot(delta_robot, 'd', d, 'b', b, 'L', 10e-3);
delta_robot = computeJointsPose(delta_robot);
delta_robot = initializeActuatorDynamics(delta_robot);
delta_robot = initializeJointDynamics(delta_robot);
delta_robot = initializeCylindricalStruts(delta_robot);
delta_robot = computeJacobian(delta_robot);
delta_robot = initializeStewartPose(delta_robot);

figs/delta_robot_strut_small.png

Obtained Delta Robot for a cube's size of 10mm
%% Effect of torsional stiffness on the plant dynamics
delta_robot = initializeStewartPlatform();
delta_robot = generateDeltaRobot(delta_robot, 'd', d, 'b', b, 'L', 100e-3);
delta_robot = computeJointsPose(delta_robot);
delta_robot = initializeActuatorDynamics(delta_robot);
delta_robot = initializeJointDynamics(delta_robot);
delta_robot = initializeCylindricalStruts(delta_robot);
delta_robot = computeJacobian(delta_robot);
delta_robot = initializeStewartPose(delta_robot);

figs/delta_robot_strut_large.png

Obtained Delta Robot for a cube's size of 100mm

Effect on the compliance

As shown in Figure fig:delta_robot_strut_length_compliance_rotation, the strut length has an effect on the system stiffness in translation (left plot) but almost not in rotation (right plot).

Indeed, the stiffness in rotation is a combination of:

  • The stiffness of the actuator
  • The shear and axial stiffness of the flexible joints
  • The bending and torsional stiffness of the flexible joints, combine with the strut length
%% Effect of torsional stiffness on the plant dynamics
joint_axial = 100e6; % [N/m]
joint_bending = 50; % [Nm/rad]
joint_torsion = 500; % [Nm/rad]

% Geometry
d = 50e-3; % Cube's edge length [m]
b = 20e-3; % Distance between cube's vertices and top joints [m]

clear io; io_i = 1;
io(io_i) = linio([mdl, '/Fd'],             1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
io(io_i) = linio([mdl, '/6dof_metrology'], 1, 'openoutput'); io_i = io_i + 1; % Actuator Displacement [m]

% Cube's size
strut_length = [10e-3, 20e-3, 50e-3, 100e-3];
G_strut_length = {zeros(size(strut_length))};

for i = 1:length(strut_length)
    delta_robot = initializeStewartPlatform();
    delta_robot = generateDeltaRobot(delta_robot, 'd', d, 'b', b, 'L', strut_length(i));
    delta_robot = computeJointsPose(delta_robot);
    delta_robot = initializeActuatorDynamics(delta_robot, 'type', '1dof', 'k', k);
    delta_robot = initializeJointDynamics(delta_robot, 'type_F', '3dof_a', 'type_M', '2dof_a', 'Ka', joint_axial, 'Kf', joint_bending, 'Kt', joint_torsion);
    delta_robot = initializeCylindricalStruts(delta_robot);
    delta_robot = computeJacobian(delta_robot);
    delta_robot = initializeStewartPose(delta_robot);

    %% Run the linearization
    G = linearize(mdl, io);
    G.InputName  = {'Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz'};
    G.OutputName = {'Dx', 'Dy', 'Dz', 'Rx', 'Ry', 'Rz'};

    G_strut_length(i) = {G};
end

figs/delta_robot_strut_length_compliance_rotation.png

Effect of the cube's size on the rotational compliance of the top platform

Effect on the plant dynamics

As shown in Figure fig:delta_robot_strut_length_plant_dynamics, having longer struts:

  • decreases the main resonance frequency: this means that the stiffness in the X,Y and Z directions is decreased when the length of the strut is longer. This is reasonable as the "lever" arm is getting larger, so the bending stiffness and compression of the flexible joints have a larger effect on the top platform compliance.
  • decreases the low frequency coupling: this effect is more difficult to physically understand Probably: when pushing with one actuator, it induces some rotation of the struts corresponding to the other two actuators. This rotation is proportional to the strut length. Then, this rotation, combined with the limited compliance in bending of the flexible joints induces some force applied on the other actuators, hence the coupling. This is similar to what was observed when varying the bending stiffness of the flexible joints: the coupling was increased with an increased of the bending stiffness (See Figure fig:delta_robot_bending_stiffness_couplign)

But even with relatively short struts (20mm and above), the low frequency decoupling is already around two orders of magnitude, which is enough from a control point of view. So, the struts length can be optimized to not decrease too much the stiffness of the platform while still getting good low frequency decoupling.

%% Effect of torsional stiffness on the plant dynamics
joint_axial = 100e6; % [N/m]
joint_bending = 50; % [Nm/rad]
joint_torsion = 500; % [Nm/rad]

% Geometry
d = 50e-3; % Cube's edge length [m]
b = 20e-3; % Distance between cube's vertices and top joints [m]

clear io; io_i = 1;
io(io_i) = linio([mdl, '/F'],           1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
io(io_i) = linio([mdl, '/delta_robot'], 1, 'openoutput'); io_i = io_i + 1; % Actuator Displacement [m]

% Cube's size
strut_length = [10e-3, 20e-3, 50e-3, 100e-3];
G_strut_length = {zeros(size(strut_length))};

for i = 1:length(strut_length)
    delta_robot = initializeStewartPlatform();
    delta_robot = generateDeltaRobot(delta_robot, 'd', d, 'b', b, 'L', strut_length(i));
    delta_robot = computeJointsPose(delta_robot);
    delta_robot = initializeActuatorDynamics(delta_robot, 'type', '1dof', 'k', k);
    delta_robot = initializeJointDynamics(delta_robot, 'type_F', '3dof_a', 'type_M', '2dof_a', 'Ka', joint_axial, 'Kf', joint_bending, 'Kt', joint_torsion);
    delta_robot = initializeCylindricalStruts(delta_robot);
    delta_robot = computeJacobian(delta_robot);
    delta_robot = initializeStewartPose(delta_robot);

    %% Run the linearization
    G = linearize(mdl, io);
    G.InputName  = {'F1', 'F2', 'F3'};
    G.OutputName = {'D1', 'D2', 'D3'};

    G_strut_length(i) = {G};
end

figs/delta_robot_strut_length_plant_dynamics.png

Effect of the Strut length on the plant dynamics

Having the Center of Mass at the cube's center

<<ssec:delta_robot_flexible_geometry_com>>

To make things easier, we take a top platform with no mass, mass-less struts, and we put a payload on top of the platform.

As shown in Figure fig:delta_robot_CoM_pos_effect_plant, having the CoM of the payload at the cube's center allow to have better decoupling properties above the suspension mode of the system (i.e. above the first mode). This could allow to have a bandwidth exceeding the frequency of the first mode. But how sensitive this decoupling is to the exact position of the CoM still need to be studied.

%% Effect of torsional stiffness on the plant dynamics
joint_axial = 100e6; % [N/m]
joint_bending = 50; % [Nm/rad]
joint_torsion = 500; % [Nm/rad]

% Geometry
d = 50e-3; % Cube's edge length [m]
b = 20e-3; % Distance between cube's vertices and top joints [m]
L = 50e-3; % Strut length

clear io; io_i = 1;
io(io_i) = linio([mdl, '/F'],           1, 'openinput');  io_i = io_i + 1; % Actuator Force Inputs [N]
io(io_i) = linio([mdl, '/delta_robot'], 1, 'openoutput'); io_i = io_i + 1; % Actuator Displacement [m]

delta_robot = initializeStewartPlatform();
delta_robot = generateDeltaRobot(delta_robot, 'd', d, 'b', b, 'L', L, 'm_top', 1e-3);
delta_robot = computeJointsPose(delta_robot);
delta_robot = initializeActuatorDynamics(delta_robot, 'type', '1dof', 'k', k);
delta_robot = initializeJointDynamics(delta_robot, 'type_F', '3dof_a', 'type_M', '2dof_a', 'Ka', joint_axial, 'Kf', joint_bending, 'Kt', joint_torsion);
delta_robot = initializeCylindricalStruts(delta_robot, 'M', 1e-3);
delta_robot = computeJacobian(delta_robot);
delta_robot = initializeStewartPose(delta_robot);
%% Sample at the CoM
sample = initializeSample('type', 'cylindrical', 'm', 1, 'H', 2*(L/2+b)*1/sqrt(3), 'R', 20e-3);

G_com = linearize(mdl, io);
G_com.InputName  = {'F1', 'F2', 'F3'};
G_com.OutputName = {'D1', 'D2', 'D3'};

%% Sample above the CoM
sample = initializeSample('type', 'cylindrical', 'm', 1, 'H', 4*(L/2+b)*1/sqrt(3), 'R', 20e-3);

G_above = linearize(mdl, io);
G_above.InputName  = {'F1', 'F2', 'F3'};
G_above.OutputName = {'D1', 'D2', 'D3'};

%% Sample below the CoM
sample = initializeSample('type', 'cylindrical', 'm', 1, 'H', (L/2+b)*1/sqrt(3), 'R', 20e-3);

G_below = linearize(mdl, io);
G_below.InputName  = {'F1', 'F2', 'F3'};
G_below.OutputName = {'D1', 'D2', 'D3'};

figs/delta_robot_CoM_pos_effect_plant.png

Effect of the payload's Center of Mass position with respect to the cube's size on the plant dynamics

Conclusion

Geometrical feature Effect Recommendation
Cube's size d Increasing the cube's size increases the rotational stiffness Should be make as large as possible
Strut length L Changes the stiffness and coupling of the system (by changing the effect of the flexible joint bending stiffness) Trade-off between higher stiffness and lower coupling
Recommendations for the Delta Robot Geometry

Conclusion

Bibliography   ignore