Numerical inverse kinematics
The numerical solvers are methods of the ETS class, and a Robot has methods of the same names that call the ETS of the robot. The ikine_XX methods are written in Python and the ik_XX methods in C++, where XX is the algorithm, for example LM. The C++ methods have limits that the Python ones do not. Each solver adds arguments of its own, so check its documentation for the complete list.
Common arguments
Besides Tep the numerical solvers share these arguments.
Argument |
Meaning |
|---|---|
|
initial joint coordinates, a vector ( |
|
the number of iterations allowed in one search |
|
the number of searches allowed before the problem is deemed unsolvable |
|
the error tolerance for a solution to count as successful |
|
six weights, for translation and rotation about X, Y and Z, of how much each Cartesian degree of freedom matters; 0 ignores it |
|
if true, reject solutions that violate the joint limits |
The sections below describe each argument in detail.
ilimit
The ilimit specifies how many iterations are allowed within a single search. After ilimit is reached, either, a new attempt is made or the IK solution has failed depending on slimit
slimit
The slimit specifies how many searches are allowed before the problem is deemed unsolvable. The maximum number of iterations allowed is therefore ilimit x slimit. By having slimit > 1, a global search is performed. Since finding a solution with numerical IK heavily depends on the initial choice of q0, performing a global search where slimit >> 1 will provide a far greater chance of success.
q0
q0 is the initial joint coordinate vector. If q0 is 1 dimensional (, n), then q0 is only used for the first attempt, after which a new random valid initial joint coordinate vector will be generated. If q0 is 2 dimensional (slimit, n), then the next vector within q0 will be used for the next search.
tol
tol sets the error tolerance before the solution is deemed successful. The error is typically set by some quadratic error function
where \(\vec{e} \in \mathbb{R}^6\) is the angle-axis error, and \(\mat{W}_e\) assigns weights to Cartesian degrees-of-freedom
mask
mask is a (,6) array that sets \(\mat{W}_e\) in error equation above. The vector has six elements that correspond to translation in X, Y and Z, and rotation about X, Y and Z respectively. The value can be 0 (for ignore) or above to assign a priority relative to other Cartesian DoF.
For the case where the manipulator has fewer than 6 DoF the solution space has more dimensions than can be spanned by the manipulator joint coordinates.
In this case we use the mask option where the mask vector specifies the Cartesian DOF that will be ignored in reaching a solution. The number of non-zero elements must equal the number of manipulator DOF.
For example when using a 3 DOF manipulator tool orientation might be unimportant, in which case use the option mask=[1, 1, 1, 0, 0, 0].
joint_limits
setting joint_limits = True will reject solutions with joint limit violations. Note that finding a solution with valid joint coordinates is likely to take longer than without.
After convergence, prismatic joint coordinates are left unchanged. Revolute
coordinates already within their limits are preserved, including limits outside
the principal interval of \([-\pi, \pi]\). Other revolute coordinates are
reduced to the principal angle and, if necessary, shifted by whole turns towards
their limits. If no equivalent angle is within the limits, the solution is
rejected when joint_limits = True. Setting joint_limits = False disables
this rejection; it does not change a prismatic distance into an angle.
Others
There are other arguments which may be unique to the solver, so check the documentation of the solver you wish to use for a complete list and explanation of arguments.
C++ Solvers
The ik_XX methods are written in high performance C++ and wrapped in Python. They are extraordinarily fast, typically about 10 µs, but are hard to extend or modify. There are ik_LM, ik_GN and ik_NR, but no ik_QP.
These methods have been written purely for speed so they do not contain the niceties of the Python alternative. They handle a single pose only, Tep must not be a trajectory, and they give no failure reason, which is always empty. The lengths of q0 (n) and of mask (6) are checked, and a wrong length raises ValueError, but the other arguments are passed to the C++ code as they are, so it is important that you understand each of the parameters and that they are of the correct type. To solve for a trajectory use the Python solvers.
When the C++ solvers cannot be used
The ik_XX methods need the compiled C++ extension and raise RuntimeError if it cannot be used. This is so:
in the pure-Python wheel and in the browser under Pyodide/JupyterLite, which have no compiled code
if the sequence has a SymPy parameter, a symbol or expression as the parameter of a transform, even one with a numeric value such as
sympy.pi/2if the sequence has a joint with a nonzero
offset, which is what merging a constant into a joint produces
Everything else in the Toolbox, such as fkine and jacob0, falls back to Python in these cases, but the C++ solvers do not. Use the ikine_XX methods, which work in all of them as long as every parameter has a numeric value, are not much harder to call, and take the same arguments with the exceptions noted in their documentation.
ETS C++ IK Methods
Fast Levenberg-Marquardt numerical inverse kinematics solver |
|
Fast numerical inverse kinematics by Gauss-Newton optimisation |
|
Fast numerical inverse kinematics using Newton-Raphson optimisation |
Robot C++ IK Methods
|
Fast Levenberg-Marquardt Numerical Inverse Kinematics Solver |
|
Fast numerical inverse kinematics by Gauss-Newton optimization |
|
Fast numerical inverse kinematics using Newton-Raphson optimization |
In the following example, we create a Panda robot and use one of the fast IK solvers available within the Robot class.
>>> import roboticstoolbox as rtb
>>> panda = rtb.models.Panda() # Make a Panda robot
>>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854]) # Make a goal pose
>>> panda.ik_LM(Tep) # Solve the IK problem
IKSolution: q=[0.5007, -0.3356, -0.4457, -2.197, -0.1636, 1.988, 0.9144], success=True, iterations=16, searches=2, residual=9.98e-11
In the following example, we create a Panda robot and then get the ETS representation. Subsequently, we use one of the fast IK solvers available within the ETS class.
>>> import roboticstoolbox as rtb
>>> panda = rtb.models.Panda() # Make a Panda robot
>>> ets = panda.ets() # Get the ETS
>>> Tep = ets.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854]) # Make a goal pose
>>> ets.ik_LM(Tep) # Solve the IK problem
IKSolution: q=[-1.778, 0.7841, 2.091, -2.15, -0.716, 1.75, 1.339], success=True, iterations=20, searches=1, residual=8.39e-08
Python Solvers
The ikine_XX methods are built on Python classes, one for each algorithm, which extend the abstract base class IKSolver, and the solve() method of each returns an IKSolution. They are slower than the C++ solvers, typically about 1 ms, but are easy to extend and modify. They also handle trajectories and give a failure reason.
The Abstract Base Class
The IKSolver provides basic functionality for performing numerical IK. Subclasses inherit from this class and must implement the solve() method. Additionally a subclass can redefine any other methods necessary such as error() to provide a custom error function.
The Solution DataClass
The IKSolution is a dataclasses.dataclass(), described at the top of this page.
Solving for a trajectory
If Tep is a trajectory of N poses, each pose is solved independently, starting from the same q0 (and the same random restarts) for every pose. Consecutive solutions are therefore not guaranteed to be on the same IK branch. The members of the returned IKSolution are:
qhas shape (N, n), one row per posesuccessis True only if every pose was solvediterationsandsearchesare summed over all posesresidualis the maximum over all poses, the worst casereasonis the reason given by the last pose that failed, if any
Changed in version 1.5.0: For a trajectory, residual is the maximum over the poses, it was the minimum.
The Implemented IK Solvers
These solvers can be identified as classes with a name starting with IK_.
Class |
Method |
Notes |
|---|---|---|
Levenberg-Marquardt |
the solver used in the examples below |
|
Gauss-Newton |
set |
|
Newton-Raphson |
set |
|
quadratic programming |
needs the |
Examples
In the following example, we create an IK Solver class and pass an ETS to it to solve the problem. This style may be preferable to experiments where you wish to compare the same solver on different robots.
>>> import roboticstoolbox as rtb
>>> panda = rtb.models.Panda() # Make a Panda robot
>>> ets = panda.ets() # Get the ETS of the Panda
>>> solver = rtb.IK_LM() # Make an IK solver
>>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854]) # Make a goal pose
>>> solver.solve(ets, Tep) # Solve the IK problem
IKSolution: q=[0.1034, -0.3025, -0.09196, -2.203, -0.03145, 2.001, 0.8107], success=True, iterations=77, searches=6, residual=6.73e-07
Additionally, these class-based solvers have been implemented as methods within the ETS and Robot classes. The method names start with ikine_.
ETS Python IK Methods
Levenberg-Marquardt numerical inverse kinematics solver |
|
Quadratic programming numerical inverse kinematics solver |
|
Gauss-Newton numerical inverse kinematics solver |
|
Newton-Raphson numerical inverse kinematics solver |
Robot Python IK Methods
|
Levenberg-Marquardt Numerical Inverse Kinematics Solver |
|
Quadratic Programming Numerical Inverse Kinematics Solver |
|
Gauss-Newton Numerical Inverse Kinematics Solver |
|
Newton-Raphson Numerical Inverse Kinematics Solver |
Examples
In the following example, we create a Panda robot and use one of the IK solvers available within the Robot class. This style is far more convenient than the above example.
>>> import roboticstoolbox as rtb
>>> panda = rtb.models.Panda() # Make a Panda robot
>>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854]) # Make a goal pose
>>> panda.ikine_LM(Tep) # Solve the IK problem
IKSolution: q=[1.477, 1.211, -2.1, -2.102, 1.052, 1.411, 0.004908], success=True, iterations=31, searches=3, residual=3.67e-08
In the following example, we create a Panda robot and then get the ETS representation. Subsequently, we use one of the IK solvers available within the ETS class.
>>> import roboticstoolbox as rtb
>>> panda = rtb.models.Panda() # Make a Panda robot
>>> ets = panda.ets() # Get the ETS
>>> Tep = ets.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854]) # Make a goal pose
>>> ets.ikine_LM(Tep) # Solve the IK problem
IKSolution: q=[-1.187, 1.615, 2.262, -2.068, -1.337, 1.009, 1.703], success=True, iterations=41, searches=4, residual=3.33e-10