Manipulator Modeling & Control 1 Content of This Lab: 1.1 Installing and Loading The Lab in QT Creator
Manipulator Modeling & Control 1 Content of This Lab: 1.1 Installing and Loading The Lab in QT Creator
Manipulator Modeling & Control 1 Content of This Lab: 1.1 Installing and Loading The Lab in QT Creator
As it is not a lab on C++, most of the code is already written and you only have to fill the
required functions:
Robot::init wMe() to initialize the fixed transform between the wrist and end-effector
Robot::fMw(q) for the direct geometric model wrist-to-fixed frame
Robot::inverseGeometry(M) for...well, the inverse geometry
Robot::fJw for the kinematic model wrist-to-fixed frame
O. Kermorgant 1
Control & Robotics Master Manipulator Modeling & Control
2 The robots
Three robots are proposed with increasing complexity. You should start with the Turret, then
the Kuka KR16 then the UR-10.
For each of these robots, the table of Modified Denavit-Hartenberg parameters should be de-
fined. As we saw during the lectures, once you have the table then the Direct Geometric and
Direct Kinematic Models can be almost automatically derived. A tool is provided in this pack-
age to generate C++ code for the Geometric and Kinematic models, see Appendix B for details
on this tool.
The fixed frame and the end-effector frame are imposed by the schematics. All intermediary
frames have to be placed according to MDH convention, with a final fixed transform between
the wrist and end-effector frames.
This is a very simple robot to begin the modeling, as shown in the figure.
The fixed frame F0 and end-effector frame Fe are imposed, as well as the
joint direction.
The constant values for this model are: b = 0.5 m and d = 0.1 m.
2
Visual Servoing Platform, http://visp.inria.fr
O. Kermorgant 2
Control & Robotics Master Manipulator Modeling & Control
Figure 1: Model of the Kuka KR16 with imposed fixed and end-effector frames
The wrist frame is typically at the common point between joints 4, 5 and 6. The constant
transform w Me between the wrist and the end-effector should include the 0.158 distance and
potential rotations.
O. Kermorgant 3
Control & Robotics Master Manipulator Modeling & Control
Figure 2: Model of the UR-10 with imposed fixed and end-effector frames
RViz is the 3D simulator to show the current configuration of the robot. It will also
display the base and end-effector frames, and the one that you compute. You can thus
easily check if the computation is fine.
O. Kermorgant 4
Control & Robotics Master Manipulator Modeling & Control
Robot::fMw(q) where you have to write and return the transform M between the fixed
and wrist frame
Once you have computed the M matrix, the code calls robot->checkPose(M); in order to print
both your matrix and the true one. No need to tell that they should be equal.
What can be told is that it is useless to continue until they are.
In the main code, the commanded velocity then to be mapped to the joint velocity in two steps:
f
f ∗ Re 0 e ∗
1. Map to the fixed frame: ve = ve
0 f Re
Call M.getRotationMatrix() to get this rotation.
The ecn::putAt function may be of good use.
You can check that the end-effector is able to follow straight 3D lines in x, y or z direction in
its own frame. Similarly, it should be able to rotate around x, y or z. This means the Jacobian
computation is correct.
O. Kermorgant 5
Control & Robotics Master Manipulator Modeling & Control
In practice, this exercise is to check that the Inverse Geometric Model is correct: the robot
should reach the desired pose.
When computing the inverse geometry, try to find a solution as near as possible to the passed q0.
Many useful functions are available to solve classical trigonometric equations. They are detailed
in Appendix C.
A given potential solution should be stored using addCandidate({q1, q2, ..., qn});
At the end of the Inverse Geometry function, use return bestCandidate(q0); that will pick
the candidate that is the nearest from the current joint position and also within joint limits.
Here the goal is to compute the current setpoint qc = q0 + p(t)(qf − q0 ). The interpolation
function p(t) was defined during the lectures and should take into account the maximum joint
velocity and acceleration that are stored in the vMax and aMax vectors. Basically this amounts
to computing the minimum time tf needed to reach qf from q0 . This computation should be
done in the if(robot->newRef()) and then used to compute the current qCommand.
O. Kermorgant 6
Control & Robotics Master Manipulator Modeling & Control
As seen in class, this command should make the end-effector approach its desired pose. The
steps are:
2. Compute the desired linear and angular velocities: v = −λf Me∗ t, ω = −λf Me (θu)
+ v
3. Map these velocities to the joint space: q̇ = J
ω
λ is a gain that can be changed from the GUI. Increasing it will lead to a faster convergence.
It can be obtained through robot->lambda().
O. Kermorgant 7
Control & Robotics Master Manipulator Modeling & Control
A Using ViSP
ViSP is a library for Visual Servoing (wait for the M2 Robotics to know more!) and also
includes all necessary tools to play with mathematical vectors, matrices and 3D transforms.
The full documentation is here: http://visp-doc.inria.fr/doxygen/visp-3.1.0/classes.html.
The main classes to be used are:
vpMatrix: a classical matrix of given dimensions, can be multiplied with other matrices
and vectors if the dimensions are ok. The pseudo-inverse of matrix M is available with
M.pseudoInverse()
Most of the model computation is about initializing a matrix or vector to correct dimensions
(which is already done) and fill its elements with formulae.
To write 1 at element (i,j) of matrix M, just write M[i][j] = 1;
Similarly, to write 1 at element (i) of vector q, just write q[i] = 1;
3D transforms can be easily changed between homogeneous matrix, rotation matrix, translation
vector or θu vector. Another type called a pose vector consists in the full (t, θu) vector of
dimension 6:
1 vpHomogeneousMatrix M;
2 vpPoseVector p;
3 vpRotationMatrix R;
4 vpTranslationVector t;
5 vpColVector tu(3);
6
7 M.getRotationMatrix()*t; // extract the rotation part from M and multiply with t
8 p.buildFrom(M); // build (t, theta-u) from M
9 t = M.getTranslationVector(); // extract the translation part
10
11 // copy the theta-u part of p into tu
12 for(int i = 0; i < 3; ++i)
13 tu[i] = p[i+3];
14
15 // compute inverse transform
16 M = M.inverse();
Two utility functions are provided to put a matrix or vector into a bigger one:
void ecn::putAt(M, Ms, r, c): Writes matrix Ms inside matrix M, starting from given
row and column.
void ecn::putAt(V, Vs, r): Writes column vector Vs inside vector V, starting from
given row. These two functions do nothing but print an error if the submatrix or vector
does not fit in the main one.
O. Kermorgant 8
Control & Robotics Master Manipulator Modeling & Control
The command to be run is: rosrun ecn manip dh code.py <name of the file>.
In the case of the above MDH table, it leads to these outputs:
1 // Generated Jacobian code
2 const double c1 = cos(q[0]);
3 const double c1p3 = cos(q[0]+q[2]);
1 // Generated pose code 4 const double s1 = sin(q[0]);
2 const double c1 = cos(q[0]); 5 const double s1p3 = sin(q[0]+q[2]);
3 const double c1p3 = cos(q[0]+q[2]); 6 J[0][0] = -a4*s1p3 - q[1]*c1;
4 const double c4 = cos(q[3]); 7 J[0][1] = -s1;
5 const double s1 = sin(q[0]); 8 J[0][2] = -a4*s1p3;
6 const double s1p3 = sin(q[0]+q[2]); 9 //J[0][3] = 0;
7 const double s4 = sin(q[3]); 10 J[1][0] = a4*c1p3 - q[1]*s1;
8 M[0][0] = -s4*c1p3; 11 J[1][1] = c1;
9 M[0][1] = -c4*c1p3; 12 J[1][2] = a4*c1p3;
10 M[0][2] = -s1p3; 13 //J[1][3] = 0;
11 M[0][3] = a4*c1p3 - q[1]*s1; 14 //J[2][0] = 0;
12 M[1][0] = -s4*s1p3; 15 //J[2][1] = 0;
13 M[1][1] = -s1p3*c4; 16 //J[2][2] = 0;
14 M[1][2] = c1p3; 17 //J[2][3] = 0;
15 M[1][3] = a4*s1p3 + q[1]*c1; 18 //J[3][0] = 0;
16 M[2][0] = -c4; 19 //J[3][1] = 0;
17 M[2][1] = s4; 20 //J[3][2] = 0;
18 M[2][2] = 0; 21 J[3][3] = -s1p3;
19 M[2][3] = r3; 22 //J[4][0] = 0;
20 M[3][0] = 0; 23 //J[4][1] = 0;
21 M[3][1] = 0; 24 //J[4][2] = 0;
22 M[3][2] = 0; 25 J[4][3] = c1p3;
23 M[3][3] = 1.; 26 J[5][0] = 1.;
24 // End of pose code 27 //J[5][1] = 0;
28 J[5][2] = 1.;
29 //J[5][3] = 0;
30 // End of Jacobian code
This is exactly what you would get by doing the manual computation from the initial table,
which I hope is quite appreciated.
Fixed transforms for initial and end-effector frames can also be written with keys f: and e:
If passing --display the script will display the direct geometry with classical math notations.
It can be useful for the inverse geometry computation.
For a 6-DOF robot, passing --wrist will display useful information to benefit from a spherical
wrist: math expressions for 0 t6 (q1 , q2 , q3 ) and 3 R6 (q4 , q5 , q6 ), and code for 0 R3 (q1 , q2 , q3 ).
O. Kermorgant 9
Control & Robotics Master Manipulator Modeling & Control
C Trigonometric solvers
The code contains solvers for all types of trigonometric equations (except type 1 that is obvious).
They take as argument the coefficients of the equations. They return:
Furthermore, a function allows retrieving the 12 elements of 0 Mn∗ from the matrix f Me∗ given
to the inverse geometry solver:
1 const auto [xx,xy,xz,yx,yy,yz,zx,zy,zz,tx,ty,tz] = explodeMatrix(fMe_des);
O. Kermorgant 10
Control & Robotics Master Manipulator Modeling & Control
Returns
Type Equation Syntax
(vector of)
2 Xsi + Y ci = Z solveType2(x, y, z) qi
X1 qj si = Y1
4 solveType4(x1, y1, x2, y2) (qi , qj )
X 2 q j ci = Y 2
W sj = Xci + Y si + Z1
6 solveType6(x, y, z1, z2, w) (qi , qj )
W cj = Xsi − Y ci + Z2
W1 cj + W2 sj = Xci + Y si + Z1
7 solveType7(x, y, z1, z2, w1, w2) (qi , qj )
W1 sj − W2 cj = Xsi − Y ci + Z2
Xci + Y cij = Z1
8 solveType8(x, y, z1, z2) (qi , qj )
Xsi + Y sij = Z2
O. Kermorgant 11