Geometric primitives
Important remarks
- All geometric primitives and there operations can be used in realtime. None of the operations lead to dynamic memory allocations and all of the operations are deterministic in time.
- All values are in [m] for translational components and [rad] for rotational components.
Header files
- frames.hpp: Definition of all geometric primitives and there transformations/operators.
- frames_io.hpp: Definition of the input/output operators.
|
Table of Contents
|
Vector
A Vector represents the 3D position of a point/object wrt the reference frame. It can be seen as a 3-element vector containing X-Y-Z values:
![]() |
(1) |
Creating Vectors
Vector v1; //The default constructor, X-Y-Z are initialized to zero Vector v2(x,y,z); //X-Y-Z are initialized with the given values Vector v3(v2); //The copy constructor Vector v4 = Vector::Zero(); //All values are set to zero
Get/Set individual elements
The operators [ ] and ( ) use indeces from 0..2, index checking is enabled/disabled by the DEBUG/NDEBUG definitions: v1[0]=v2[1];//copy y value of v2 to x value of v1 v2(1)=v3(3);//copy z value of v3 to y value of v2 v3.x( v4.y() );//copy y value of v4 to x value of v3
Multiply/Divide with a scalar
You can multiply or divide a Vector with a double using the operator * and /: v2=2*v1; v3=v1/2;
Add and subtract vectors
v2+=v1; v3-=v1; v4=v1+v2; v5=v2-v3;
Cross and scalar product
v3=v1*v2; //Cross product double a=dot(v1,v2)//Scalar product
Resetting
You can reset the values of a vector to zero: SetToZero(v1);
Comparing vectors
With or without giving an accuracy: v1==v2; v2!=v3; Equal(v3,v4,eps);//with accuracy eps
Rotation
Represents the 3D rotation of an object wrt the reference frame. Internally it is represented by a 3x3 matrix which is a non-minimal representation:
![]() |
(2) |
Creating Rotations
Safe ways to create a Rotation
The following result always in consistent Rotations. This means the rows/columns are always normalized and orthogonal: Rotation r1; //The default constructor, initializes to an 3x3 identity matrix Rotation r1 = Rotation::Identity();//Identity Rotation = zero rotation Rotation r2 = Rotation::RPY(roll,pitch,yaw); //Rotation build out off Roll-Pitch-Yaw angles Rotation r3 = Rotation::EulerZYZ(alpha,beta,gamma); //Rotation build out off Euler Z-Y-Z angles Rotation r4 = Rotation::EulerZYX(alpha,beta,gamma); //Rotation build out off Euler Z-Y-X angles Rotation r5 = Rotation::Rot(vector,angle); //Rotation build out off an equivalent axis(vector) and an angle.
Other ways
The following should be used with care, they can result in inconsistent rotation matrices, since there is no checking if columns/rows are normalized or orthogonal Rotation r6( Xx,Yx,Zx,Xy,Yy,Zy,Xz,Yz,Zz);//Give each individual element (Column-Major) Rotation r7(vectorX,vectorY,vectorZ);//Give each individual column
Getting values
Individual values, the indices go from 0..2: double Zx = r1(0,2); Getting EulerZYZ, Euler ZYX, Roll-Pitch-Yaw angles , equivalent rotation axis with angle: r1.GetEulerZYZ(alpha,beta,gamma); r1.GetEulerZYX(alpha,beta,gamma); r1.GetRPY(roll,pitch,yaw); axis = r1.GetRot();//gives only rotation axis angle = r1.GetRotAngle(axis);//gives both angle and rotation axis Getting the Unit vectors: vecX=r1.UnitX();//or r1.UnitX(vecX); vecY=r1.UnitY();//or r1.UnitY(vecY); vecZ=r1.UnitZ();//or r1.UnitZ(vecZ);
Inverse Rotations
Inverting the rotation: r1.SetInverse();//r1 is inverted Getting the inverted rotation: r2=r1.Inverse();//r2 is the inverse rotation of r1
Composing rotations
You can compose two rotations to a new rotation, the order of the rotations is important: r3=r1*r2; You can add a rotation around X-Y-Z directly to an existing rotation r1.DoRotX(angle); r2.DoRotY(angle); r3.DorotZ(angle); The rotation around X-Y-Z is applied to the rotation (r1) such that r1 = r1*Rotation::RotX(angle)
Using a Rotation to rotate a Vector
You can rotate a Vector using a Rotation and the operator *. v2=r1*v1; A different way to see this: You can calculate the new (v2) X-Y-Z values of a vector (v1) if the reference frame is rotated with a Rotation r1.
Comparing Rotations
This can be done in the same way as vectors are compared, with operators == and != or with the function Equal: r1==r2; r1!=r2; Equal(r1,r2,eps);
Frame
A Frame can represents the pose of an object/frame wrt a reference frame (4x4 matrix)
- It contains a Rotation M that holds the rotation of the object/frame wrt the reference frame.
- It containts a Vector p that holds the position of the origin of the object/frame in the reference frame
![]() |
(3) |
Creating Frames
Since a Frame contains a Rotation and a Vector it can only be build by supplying their values: Frame f1;//Creates Identity frame Frame f1=Frame::Identity();//Creates an identity frame: Rotation::Identity() and Vector::Zero() Frame f2(your_rotation);//Create a frame with your_rotation and a zero vector Frame f3(your_vector);//Create a frame with your_vector and a identity rotation Frame f4(your_rotation,your_vector);//Create a frame with your_rotation Frame f5(your_vector,your_rotation);//and your_vector Frame f5(f6);//the copy constructor
Getting values
You can get an individual element of a frame using it's 4x4 matrix representation: double x = f1(0,3); double Yy = f1(1,1); A better way is to go through the underlying Rotation and vector: Vector p = f1.p; Rotation M = f1.M;
Composing pose transformations
You can use the operator * to compose pose transformations. If you have a Frame F_A_B that specifies the pose transformation from a frame A to a frame B and a Frame F_B_C that specifies the pose transformation from a frame B to a frame C you can calculate the Frame F_A_C as follows: Frame F_A_C = F_A_B * F_B_C; The Frame F_A_C now specifies the pose transformation from frame A to frame C, or said otherwise, F_A_C.p is the location of the origin of frame C expressed in frame A, and F_A_C.M is the rotation of frame C expressed in frame A.
Comparing frames
Again the operators == and != or Equal can be used: f1==f2; f1!=f2; Equal(f1,f2,eps);
Twist
A Twist represents a 6D velocity with a 3D translational and a 3D rotational part (6x1 matrix). Internally it is represented with by two Vectors, one containing the translational velocitity, vel, and one containing the rotational velocity, rot:
![]() |
(4) |
Creating Twists
Twist t1; //Default constructor, initializes to Zero through Vector Twist t2(vel,rot);//Vector vel, and Vector rot Twist t3 = Twist::Zero();//Zero twist
Getting values
Using the operators [ ] and ( ), the indeces from 0..2 return the elements of vel, the indeces from 3..5 return the elements of rot: double vx = t1(0); double omega_y = t1[4]; t1(1) = vy; t1[5] = omega_z; Because some robotics literature put the rotation part on top it is safer to use the vel, rot members to access the individual elements: double vx = t1.vel.x();//or vx = t1.vel(0); double omega_y = t1.rot.y();//or omega_y = t1.rot(1); t1.vel.y(v_y);//or t1.vel(1)=v_y;//etc
Multiply/Divide with a scalar
The same operators as for Vector are available: t2=2*t1; t2=t1*2; t2=t1/2;
Adding/subtracting Twists
The same operators as for Vector are available: t1+=t2; t1-=t2; t3=t1+t2; t3=t1-t2;
Comparing Twists
Again the operators == and != or Equal can be used: t1==t2; t1!=t2; Equal(t1,t2,eps);
Wrench
A Wrench represents a 6D force with a 3D force and a 3D torque part (6x1 matrix). Internally it is represented with by two Vectors, one containing the forces, force, and one containing the torques, torque:
![]() |
(5) |
Creating Wrenchs
Wrench w1; //Default constructor, initializes to Zero through Vector Wrench w2(force,torque);//Vector force, and Vector torque Wrench w3 = Wrench::Zero();//Zero wrench
Getting values
Using the operators [ ] and ( ), the indeces from 0..2 return the elements of force, the indeces from 3..5 return the elements of torque: double fx = w1(0); double ty = w1[4]; w1(1) = fy; w1[5] = tz; Because some robotics literature put the torque part on top it is safer to use the torque, force members to access the individual elements: double fx = w1.force.x();//or fx = w1.force(0); double ty = w1.torque.y();//or ty = w1.torque(1); w1.force.y(fy);//or w1.force(1)=fy;//etc
Multiply/Divide with a scalar
The same operators as for Vector are available: w2=2*w1; w2=w1*2; w2=w1/2;
Adding/subtracting Wrenchs
The same operators as for Twist are available: w1+=w2; w1-=w2; w3=w1+w2; w3=w1-w2;
Comparing Wrenchs
Again the operators == and != or Equal can be used: w1==w2; w1!=w2; Equal(w1,w2,eps);
Twist and Wrench transformations
A Wrench or Twist is expressed in a certain reference frame and reference point, most of the times the reference point coincides with the base point of the reference frame, but this does not have to be the case.
The values of a Wrench or Twist changes if the reference frame or reference point is changed.
Changing the reference point
If you want to change the reference point you need the vector p from the old reference point to the new reference point expressed in the reference frame of the Wrench or Twist:
t2 = t1.RefPoint(v_old_new); w2 = w1.RefPoint(v_old_new);
Changing the reference frame
If you want to change the reference frame but want to keep the reference point intact you can use a Rotation matrix which expresses the rotation of the current reference frame B wrt to the new reference frame A:
ta = R_AB*tb; wa = R_AB*wb;
Changing both the reference frame and the reference point
Use a Frame that contains both the rotation and the pose change, changing the reference frame and reference point from B to A:
ta = F_AB*tb; wa = F_AB*wb;
First order differentiation and integration
t_ab = diff(F_b_A,F_b_B,timestep) F_b_B = F_b_A.addDelta(t_ab,timestep)

![\[ \textrm{KDL::Vector} = \left[ \begin{array}{ccc}<br />
x \\ y \\ z \end{array}\right] \]](/files/tex/ac51341d89fdeebb8bd70f7e65f5ae7fa542862c.png)
![\[ $ \textrm{KDL::Rotation} = \left[\begin{array}{ccc}Xx&Yx&Zx\\Xy&Yy&Zy\\Xz&Yz&Zz\end{array}\right] $ \]](/files/tex/4b8f73319c0f7e4108c04fcf5b7b0a7d2f5b70f8.png)
![\[ $ \textrm{KDL::Frame} = \left[\begin{array}{cc}\mathbf{M}(3 \times 3) &p(3 \times 1)\\ 0(1 \times 3)&1 \end{array}\right] $ \]](/files/tex/83347ee55964449b9a2430404f36967dc09236ab.png)
![\[ $\textrm{KDL::Twist} = \left[\begin{array}{c} v_x\\v_y\\v_z\\ \hline \omega_x \\ \omega_y \\ \omega_z \end{array} \right] = \left[\begin{array}{c} \textrm{vel} \\ \hline \textrm{rot}\end{array} \right] $ \]](/files/tex/d6e31fbe4b812c07d253f65b6f21b4cca7d0fcf0.png)
![\[ $\textrm{KDL::Wrench} = \left[\begin{array}{c} f_x\\f_y\\f_z\\ \hline t_x \\ t_y \\ t_z \end{array} \right] = \left[\begin{array}{c} \textrm{force} \\ \hline \textrm{torque}\end{array} \right] $ \]](/files/tex/7ca7f22dbf37ea029b16b18f0e19f6a5d64d12ca.png)