UnderAutomation
Any question?

[email protected]

Contact us
UnderAutomation
⌘Q

Forward and inverse kinematics

Compute the forward and inverse kinematics of UR cobots without a robot: DH parameters of each model, flange pose, up to 8 solutions, singularities.

  • DH parameters
  • Nominal or custom parameters
  • Parameters of a connected robot
  • Forward kinematics
  • Inverse kinematics
  • Singularities
  • Try it in the demo application
  • Reference
  • Implementation

The namespace UnderAutomation.UniversalRobots.Kinematics computes the forward and inverse kinematics of Universal Robots cobots, without a connection to a robot. This page shows how to get the DH parameters of a robot, compute the position of the flange from the joint positions and back, and detect the singularities.

  • Forward kinematics: 6 joint positions give the position and the orientation of the flange.
  • Inverse kinematics: a position and an orientation of the flange give up to 8 sets of joint positions.

DH parameters

The Denavit-Hartenberg (DH) parameters describe the geometry of the arm. Each joint has four parameters: θ (rotation around z, the joint variable), d (offset along z), a (length along x) and α (rotation around x). On UR cobots, only a2, a3, d1, d4, d5 and d6 change between the models:

Jointa [m]d [m]α [rad]θ [rad]
J10d1+π/2θ1
J2a200θ2
J3a300θ3
J40d4+π/2θ4
J50d5−π/2θ5
J60d60θ6

See the DH parameters of each model by Universal Robots.

Nominal or custom parameters

GetDhParametersFromModel returns the nominal parameters of a model (UR3 to UR30, CB-Series and e-Series). CustomUrDhParameters takes your own values.

static void Main(string[] args)
{
// Nominal DH parameters of a model
IUrDhParameters ur5e = KinematicsUtils.GetDhParametersFromModel(RobotModelsExtended.UR5e);
// Or your own values, in meters
IUrDhParameters custom = new CustomUrDhParameters(
a2: -0.425,
a3: -0.3922,
d1: 0.1625,
d4: 0.1333,
d5: 0.0997,
d6: 0.0996);
}
}
Click to see the full code

Parameters of a connected robot

The Primary Interface sends the DH parameters of the robot, with its calibration, in KinematicsInfo and ConfigurationData. Both implement IUrDhParameters.

static void Main(string[] args)
{
var robot = new UR();
// The Primary Interface is enabled by default
robot.Connect("192.168.0.1");
// Wait for the first packages (10 Hz)
Thread.Sleep(500);
// DH parameters of this robot, with its calibration
IUrDhParameters dh = robot.PrimaryInterface.KinematicsInfo;
// Current joint positions, in radians
JointDataPackageEventArgs j = robot.PrimaryInterface.JointData;
double[] joints =
{
j.Base.Position, j.Shoulder.Position, j.Elbow.Position,
j.Wrist1.Position, j.Wrist2.Position, j.Wrist3.Position
};
// Current position of the tool center point
Pose pose = robot.PrimaryInterface.CartesianInfo.AsPose();
}
}
Click to see the full code
Interface
IUrDhParameters
C#Python

Denavit–Hartenberg (DH) parameters for Universal Robots with only the relevant parameters

MemberTypeDescription
A2
Property
read only
double
DH parameter a2 (Shoulder)
A3
Property
read only
double
DH parameter a3 (Elbow)
D1
Property
read only
double
DH parameter d1 (Base)
D4
Property
read only
double
DH parameter d4 (Wrist1)
D5
Property
read only
double
DH parameter d5 (Wrist2)
D6
Property
read only
double
DH parameter d6 (Wrist3/Tool)

Forward kinematics

ForwardKinematics takes 6 joint positions in radians. ToolTransform is the 4x4 transform of the flange in the base frame: Pose.From4x4MatrixToRotationVector converts it to a pose in meters and radians. Add the TCP offset of your tool to get the position of the tool center point.

static void Main(string[] args)
{
IUrDhParameters dh = KinematicsUtils.GetDhParametersFromModel(RobotModelsExtended.UR5e);
// Joint positions in radians: base, shoulder, elbow, wrist 1, wrist 2, wrist 3
double[] joints = { 0, -1.57, 1.57, -1.57, -1.57, 0 };
KinematicsResult result = KinematicsUtils.ForwardKinematics(joints, dh);
// 4x4 transform of the flange, as a pose: X, Y, Z in m, rotation vector in rad
Pose flange = Pose.From4x4MatrixToRotationVector(result.ToolTransform);
// Transform of each joint, alone and composed with the previous ones
TransformationSet local = result.IndividualLocalTransforms;
TransformationSet global = result.CumulativeGlobalTransforms;
}
}
Click to see the full code

IndividualLocalTransforms gives the transform of each joint alone, and CumulativeGlobalTransforms the transform of each joint composed with the previous ones.

Class
KinematicsResult
C#Python

Result of a forward kinematics calculation

MemberTypeDescription
KinematicsResult()
Constructor
CumulativeGlobalTransforms
Property
TransformationSet
Cumulative global transformation matrices of each joint
IndividualLocalTransforms
Property
TransformationSet
Individual local transformation matrices of each joint
ToolTransform
Property
double[,]
4x4 transformation matrix of the tool
Equals(object)
Method
bool
GetHashCode()
Method
int
ToString()
Method
string
Class
TransformationSet
C#Python

Set of transformation matrices for each joint

MemberTypeDescription
TransformationSet()
Constructor
Base
Property
double[,]
4x4 transformation matrix of the base joint 1
Elbow
Property
double[,]
4x4 transformation matrix of the elbow joint 3
Shoulder
Property
double[,]
4x4 transformation matrix of the shoulder joint 2
Wrist1
Property
double[,]
4x4 transformation matrix of the wrist1 joint 4
Wrist2
Property
double[,]
4x4 transformation matrix of the wrist2 joint 5
Wrist3
Property
double[,]
4x4 transformation matrix of the wrist3 (Tool) joint 6
Equals(object)
Method
bool
GetHashCode()
Method
int
ToString()
Method
string

Inverse kinematics

InverseKinematics takes the 4x4 transform of the flange and returns up to 8 solutions, of 6 joint positions each. GetNearestSolution picks the solution nearest to a reference, usually the current joint positions. The solutions close to a singularity are included.

static void Main(string[] args)
{
IUrDhParameters dh = KinematicsUtils.GetDhParametersFromModel(RobotModelsExtended.UR5e);
// Target of the flange: X, Y, Z in m, rotation vector in rad
var target = new Pose(0.4, -0.1, 0.3, 0, 3.14, 0);
// Up to 8 solutions, 6 joint positions in radians each
double[][] solutions = KinematicsUtils.InverseKinematics(target.FromRotationVectorTo4x4Matrix(), dh);
// The solution nearest to the current joint positions
double[] current = { 0, -1.57, 1.57, -1.57, -1.57, 0 };
double[] nearest = KinematicsUtils.GetNearestSolution(solutions, current);
}
}
Click to see the full code

Singularities

Near a singularity, the robot loses a degree of freedom: a small move of the tool needs a large move of a joint, and the inverse kinematics has no unique answer. GetSingularity returns the singularities near a set of joint positions: Wrist, Elbow, Shoulder, or None.

static void Main(string[] args)
{
IUrDhParameters dh = KinematicsUtils.GetDhParametersFromModel(RobotModelsExtended.UR5e);
// Joint positions in radians
double q2 = -1.57; // shoulder
double q3 = 0.0; // elbow
double q4 = -1.57; // wrist 1
double q5 = 1.57; // wrist 2
// The 4 joint positions are given in the order q2, q3, q4, q5
SingularityType singularity = KinematicsUtils.GetSingularity(q2, q3, q4, q5, dh);
// Flags: Wrist, Elbow, Shoulder, or None
if (singularity != SingularityType.None)
Console.WriteLine("Close to a singularity: " + singularity);
}
}
Click to see the full code
Enum
SingularityType
C#Python

Types of singularities

NameValueDescription
Elbow
2
Elbow singularity
None
0
No singularity
Shoulder
4
Shoulder singularity
Wrist
1
Wrist singularity

Try it in the demo application

Everything on this page can be tried without writing code, in the Forward & Invert Kinematics page of the demo application.

Forward & Invert Kinematics page of the Universal Robots SDK demo application

The demo application is open source. The C# source of this page is KinematicsControl.cs.

Reference

Class
KinematicsUtils
C#Python

========================================================================================================= Implementation notes : --------------------------------------------------------------------------------------------------------- This class implements forward and inverse kinematics for a 6-DOF serial cobot using the analytical method described in Chen et al., IEEE ICASI 2017 ("A general analytical algorithm for collaborative robot (cobot) with 6 DOF"). The DH convention and the closed-form inverse steps follow the paper's derivations. References (equation numbers below refer to the paper): - DH homogeneous transform (Eq. (1.1)). - Forward kinematics chain product T_0^6 = Π_i T_{i-1}^i (Eq. (1.2)). - Inverse kinematics main steps: q1 from Eq. (1.12) ; q5 from Eq. (1.15) ; q6 from Eq. (1.17) ; q234 from Eq. (1.20) ; q2 from Eq. (1.25) ; q3 and q4 from Eq. (1.27). Singularity check equation used (paper text): det(J) ∝ s3 * s5 * a2 * a3 * (c2*a2 + c23*a3 + s234*d5) Paper: Chen, S., Luo, M., Abdelaziz, O., Jiang, G. "A General Analytical Algorithm for Collaborative Robot (cobot) with 6 DOF", IEEE ICASI 2017. =========================================================================================================

MemberTypeDescription
DHTransform(double, double, double, double)
Method
static
double[,]
Computes the 4×4 Denavit-Hartenberg homogeneous transformation matrix for one joint.
  • theta : Joint angle in radians.
  • d : Link offset along the previous z-axis, in meters.
  • a : Link length along the rotated x-axis, in meters.
  • alpha : Link twist angle in radians.
ForwardKinematics(double[], IUrDhParameters)
Method
static
KinematicsResult
Forward kinematics : compute tool transform and intermediate transforms from joint angles (radians) and DH parameters.
  • jointAnglesRad : Array of 6 joint angles in radians.
  • dhParameters : Robot DH parameters.
GetDhParametersFromModel(RobotModelsExtended)
Method
static
IUrDhParameters
Returns the factory Denavit-Hartenberg parameters for a given UR robot model.
  • model : UR robot model identifier.
GetNearestSolution(double[][], double[])
Method
static
double[]
Pick the solution nearest to a reference joint vector (L1 distance). Null if invalid inputs.
  • jointSolutions : Array of candidate joint angles (6 elements each).
  • jointReference : Reference joint angles (6 elements).
GetSingularity(double, double, double, double, IUrDhParameters)
Method
static
SingularityType
Detects singularities using Jacobian determinant factors: sin(q5)≈0 (wrist), sin(q3)≈0 (elbow), and c2·a2 + c23·a3 + s234·d5 ≈ 0 (shoulder).
  • elbow : Joint angle q2 in radians (shoulder joint in UR convention).
  • shoulder : Joint angle q3 in radians (elbow joint in UR convention).
  • wrist1 : Joint angle q4 in radians (wrist 1).
  • wrist2 : Joint angle q5 in radians (wrist 2).
  • dhParameters : Robot DH parameters.
HomogeneousMultiply(double[,], double[,])
Method
static
double[,]
Multiplies two 4×4 homogeneous transformation matrices, optimized for DH transforms.
  • A : Left 4×4 matrix.
  • B : Right 4×4 matrix.
InverseKinematics(double[,], IUrDhParameters)
Method
static
double[][]
Analytical inverse kinematics Returns a list of candidate joint vectors; filters out singularities.
  • toolTransform : 4×4 tool transform matrix.
  • dhParameters : Robot DH parameters.

Implementation

The solver is analytical (closed form), with the standard DH convention and the sequence of Chen et al., IEEE ICASI 2017. The forward kinematics is the product of the 6 homogeneous transforms of the joints. The inverse kinematics solves q1, then q5, q6, the sum q2 + q3 + q4, then q2, and q3 and q4 last. The singularities are detected from the factors of the determinant of the Jacobian: sin(q5) for the wrist, sin(q3) for the elbow, and a2·cos(q2) + a3·cos(q2 + q3) + d5·sin(q2 + q3 + q4) for the shoulder.

Reference: Chen et al., IEEE ICASI 2017, IEEE Xplore.


Easily integrate Universal Robots, Fanuc, Yaskawa, ABB or Staubli robots into your .NET, Python, LabVIEW or Matlab applications

UnderAutomation
Contact usLegal

© All rights reserved.