ETS for 3D space
An ET is one elementary \(\SE{3}\)
transform: a rotation about, or a translation along, the x-, y- or z-axis. The
angle or distance is either a constant or, if it is left out, a variable, which
makes the transform a joint. An ETS is a sequence of
them. The two-dimensional equivalents are on the ETS for 2D space page.
We can use ETS to describes a planar arm that moves in 3D space.
>>> from roboticstoolbox import ET
>>> ET.Rz() # a revolute joint
ET.Rz()
>>> ET.tx(0.5) # a constant translation
ET.tx(param=0.5)
>>> ET.Ry(90, 'deg') # a constant rotation
ET.Ry(param=1.5707963267948966)
>>> ET.tz(flip=True, qlim=[0, 1]) # a prismatic joint, flipped, with limits
ET.tz(flip=True, qlim=array([0., 1.]))
>>> e = ET.Rz() * ET.tx(1) * ET.Ry() * ET.tz()
>>> e.structure # the joint types
'RRP'
>>> e.n, e.m # joints, and transforms
(3, 4)
ET: Elementary Transform
Creating an elementary transform
The constructors Rx, Ry, Rz, tx, ty and tz take the
same arguments. The first, param, is what makes the transform a constant
or a joint.
Call |
Result |
|---|---|
|
a joint, its value is supplied at evaluation time |
|
a constant, the angle in radians |
|
a constant, the angle in degrees (rotations only) |
|
a constant, the distance in the units of the robot |
|
a joint that moves in the opposite sense |
|
a joint with an explicit index in the joint vector of a robot |
|
a joint with joint limits |
|
a joint described by a string, see Joint descriptors |
|
a constant, an arbitrary \(\SE{3}\) transform |
The arguments are:
paramthe angle (radians) or distance of a constant transform, left out for a joint, or a string that names a joint, see Joint descriptors
unit'rad'(default) or'deg', the unit of the angle of a constant rotationflipif True the joint moves in the opposite sense,
qis negatedjindexthe index of this joint in the joint vector of a robot, by default the joints are numbered in the order they appear
qlimthe joint limits, a 2-vector
[lower, upper]
>>> from roboticstoolbox import ET
>>> ET.Rz() # a joint
ET.Rz()
>>> ET.Rz(0.3) # a constant, radians
ET.Rz(param=0.3)
>>> ET.Rz(30, 'deg') # a constant, degrees
ET.Rz(param=0.5235987755982988)
>>> ET.tz(flip=True, qlim=[0, 1]) # a flipped prismatic joint with limits
ET.tz(flip=True, qlim=array([0., 1.]))
>>> ET.Rz(jindex=2).jindex # an explicit joint index
2
>>> from spatialmath import SE3
>>> ET.SE3(SE3(1, 2, 3)) # a constant arbitrary transform
ET.SE3(T=array([[1., 0., 0., 1.],
[0., 1., 0., 2.],
[0., 0., 1., 3.],
[0., 0., 0., 1.]]))
Pure rotation about the x-axis |
|
Pure rotation about the y-axis |
|
Pure rotation about the z-axis |
|
Pure translation along the x-axis |
|
Pure translation along the y-axis |
|
Pure translation along the z-axis |
|
A static SE3 |
Information
The transform type and axis |
|
The transform type and axis |
|
The Cartesian axis this transform acts along/about |
|
Get the transform constant |
|
Test if ET is a joint |
|
Test if ET joint is flipped |
|
Test if ET is a rotation |
|
Test if ET is a translation |
|
Test if ET is an elementary transform |
|
Get ET joint index |
|
Joint limits |
Kinematics
Evaluate an elementary transformation |
|
Inverse of ET |
|
Motion subspace of the joint |
Joint descriptors
The parameter of a transform can also be a string that names a joint. This is
convenient when a robot is written down from a datasheet or a URDF, where joints
have names such as q1, theta2 or A3. The string is parsed once, when
the transform is created, into the joint index, whether the joint is flipped,
and the name that is displayed.
>>> from roboticstoolbox import ET
>>> e = ET.Rz("q2") # the number is the joint index
>>> e, e.jindex, e.isflip
(ET.Rz(jindex=2), 2, False)
>>> e = ET.Rz("-q1") # a leading minus flips the joint
>>> e, e.jindex, e.isflip
(ET.Rz(jindex=1, flip=True), 1, True)
>>> e = ET.Rz("theta2") # any name, the first number is the index
>>> e, e.jindex
(ET.Rz(jindex=2), 2)
>>> e = ET.Rz("A1_") # trailing underscore: counts from one
>>> e, e.jindex
(ET.Rz(jindex=0), 0)
>>> ET.Rz("joint").jindex # no number, numbered automatically
>>> ET.Rz("1.5") # a number, it is a constant
ET.Rz(param=1.5)
A whole robot can be written with names that match its documentation.
>>> from roboticstoolbox import ET
>>> e = ET.tz(0.4) * ET.Rz("A1_") * ET.Ry("-A2_") * ET.tx(0.5) * ET.Ry("A3_")
>>> e
[ET.tz(param=0.4), ET.Rz(jindex=0), ET.Ry(jindex=1, flip=True), ET.tx(param=0.5), ET.Ry(jindex=2)]
>>> e.jindices
array([0, 1, 2])
>>> e.structure
'RRR'
The rules are:
the first number in the string is the joint index, so
"q0"is joint 0 and"theta2"is joint 2;"q(3)"and"θ_3"are joint 3a leading
-(or the Unicode minus sign−) negates the joint variable,flip, so"-q1"is joint 1, flipped. A leading+is ignoredjoint indices count from zero. If the names count from one, as
"A1"to"A6"of a Kuka arm do, end the name with an underscore:"A1_"is joint 0, and"-A1_"is joint 0, flipped. The underscore is not part of the name that is displayeda string with no number, such as
"joint", is a variable joint that is numbered automaticallya string that is a number, such as
"1.5", is a constantjindexandflipmust not also be given,ET.Rz("q1", jindex=2)raisesValueError
The name is shown when the transform is displayed, Rz(A1).
Note
A robot built from names "A1" to "A6", without the
underscores, has joint indices 1 to 6, and is rejected as the index 6 is
out of range for 6 joints.
Changed in version 1.5.0: A trailing underscore, and the Unicode minus sign, are accepted.
Details
- class ET(**kwargs)[source]
- A(q=0.0)[source]
Evaluate an elementary transformation
- Parameters:
- Returns:
The SE(3) matrix value of the ET
- Return type:
Examples
- property s: ndarray
Motion subspace of the joint
- Returns:
the 6-vector \((v, \omega)\) that is the unit twist of the transform: a unit translation or a unit rotation about the axis
- classmethod Rx(param=None, unit='rad', *, eta=None, **kwargs)[source]
Pure rotation about the x-axis
- Parameters:
param (
float|None|str) – rotation about the x-axis, or a joint name such as"q2", see Joint descriptorsunit (
str) – angular unit, “rad” [default] or “deg”j – Explicit joint number within the robot
flip – Joint moves in opposite direction
- Returns:
An elementary transform
- Return type:
ET.Rx(param)is an elementary rotation about the x-axis by a constant angleET.Rx()is an elementary rotation about the x-axis by a variable angle, i.e. a revolute robot joint.jorflipcan be set in this case.
- classmethod Ry(param=None, unit='rad', *, eta=None, **kwargs)[source]
Pure rotation about the y-axis
- Parameters:
param (
float|None|str) – rotation about the y-axis, or a joint name such as"q2", see Joint descriptorsunit (
str) – angular unit, “rad” [default] or “deg”j – Explicit joint number within the robot
flip – Joint moves in opposite direction
- Returns:
An elementary transform
- Return type:
ET.Ry(param)is an elementary rotation about the y-axis by a constant angleET.Ry()is an elementary rotation about the y-axis by a variable angle, i.e. a revolute robot joint.jorflipcan be set in this case.
- classmethod Rz(param=None, unit='rad', *, eta=None, **kwargs)[source]
Pure rotation about the z-axis
- Parameters:
param (
float|None|str) – rotation about the z-axis, or a joint name such as"q2", see Joint descriptorsunit (
str) – angular unit, “rad” [default] or “deg”j – Explicit joint number within the robot
flip – Joint moves in opposite direction
- Returns:
An elementary transform
- Return type:
ET.Rz(param)is an elementary rotation about the z-axis by a constant angleET.Rz()is an elementary rotation about the z-axis by a variable angle, i.e. a revolute robot joint.jorflipcan be set in this case.
- classmethod tx(param=None, *, eta=None, **kwargs)[source]
Pure translation along the x-axis
- Parameters:
param (
float|None|str) – translation distance along the x-axis, or a joint name such as"q2", see Joint descriptorsj – Explicit joint number within the robot
flip – Joint moves in opposite direction
- Returns:
An elementary transform
- Return type:
ET.tx(param)is an elementary translation along the x-axis by a distance constantET.tx()is an elementary translation along the x-axis by a variable distance, i.e. a prismatic robot joint.jorflipcan be set in this case.
- classmethod ty(param=None, *, eta=None, **kwargs)[source]
Pure translation along the y-axis
- Parameters:
param (
float|None|str) – translation distance along the y-axis, or a joint name such as"q2", see Joint descriptorsj – Explicit joint number within the robot
flip – Joint moves in opposite direction
- Returns:
An elementary transform
- Return type:
ET.ty(param)is an elementary translation along the y-axis by a distance constantET.ty()is an elementary translation along the y-axis by a variable distance, i.e. a prismatic robot joint.jorflipcan be set in this case.
- classmethod tz(param=None, *, eta=None, **kwargs)[source]
Pure translation along the z-axis
- Parameters:
- Returns:
An elementary transform
- Return type:
ET.tz(param)is an elementary translation along the z-axis by a distance constantET.tz()is an elementary translation along the z-axis by a variable distance, i.e. a prismatic robot joint.jorflipcan be set in this case.
- property ax: str | None
The Cartesian axis this transform acts along/about
- Returns:
"x","y", or"z"for an elementary transform, otherwiseNone(e.g.ET2’s rotation, which has no axis letter, or a compound/arbitrarySE3/SE2transform)- Return type:
str or None
Examples
- property axis: str
The transform type and axis
Deprecated since version 1.4.0: Use
kindinstead.axisis kept as an alias and will not be repurposed to mean something else in a future release.- Returns:
The transform type and axis
- Return type:
- inv()
Inverse of ET
- Returns:
Inverse of the ET
- Return type:
The inverse of a given ET.
Examples
- property iselementary: bool
Test if ET is an elementary transform
- Returns:
True if an elementary transform
- Return type:
Notes
- ET’s may not actually be “elementary”, it can be a complex
mix of rotations and translations.
See also
- property isflip: bool
Test if ET joint is flipped
- Returns:
True if joint is flipped
- Return type:
A flipped joint uses the negative of the joint variable, ie. it rotates or moves in the opposite direction.
Examples
- property isrotation: bool
Test if ET is a rotation
- Returns:
True if a rotation
- Return type:
Examples
- property istranslation: bool
Test if ET is a translation
- Returns:
True if a translation
- Return type:
Examples
- property jindex: int | None
Get ET joint index
- Returns:
The assigned joint index
- Return type:
int or None
Allows an ET to be associated with a numbered joint in a robot.
Examples
- Setter accepts:
- property kind: str
The transform type and axis
- Returns:
The transform type and axis, e.g.
"Rx","tx","SE3"- Return type:
Examples
ETS: Elementary Transform Sequence
An ETS is a list-like object. It supports len, indexing and slicing, iteration, and
the list methods append, extend, pop, remove, reverse,
index and count. Multiplying elementary transforms, or sequences,
gives a new sequence.
Information
Number of joints |
|
Number of transforms |
|
Joint structure string |
|
Get a list of the variable ETs with this ETS |
|
Get index of joint transforms |
|
Get an array of joint indices |
|
Get set of joint indices |
|
Get/Set Joint limits |
|
Generate a random valid joint configuration |
Modification
Insert value |
|
Inverse of ETS |
|
Return an independent ETS with the specified joint held constant. |
|
Split ETS into link segments |
|
Swap two transforms in the ETS |
|
Merge two transforms in the ETS |
|
Compile an ETS |
Kinematics
Forward kinematics |
|
Forward kinematics (returns raw ndarray) |
|
Manipulator geometric Jacobian in the base frame |
|
Manipulator geometric Jacobian in the end-effector frame |
|
Manipulator analytical Jacobian in the base frame |
|
Manipulator Hessian in the base frame |
|
Manipulator Hessian in the end-effector frame |
|
Manipulator Forward Kinematics nth Partial Derivative |
|
Manipulability measure |
|
The manipulability Jacobian |
Inverse kinematics
There are three ways to solve the numerical inverse kinematics problem for a sequence. All are described, with examples and the shared arguments, on the IK page. The first two are methods of the ETS, and a robot has the same methods, which call them on its own sequence.
Method |
Poses |
Notes |
|---|---|---|
one |
fast, written in C++, not easy to extend |
|
one, or a trajectory |
methods that use the solver objects in the next row, and add the quadratic programming solver |
|
one, or a trajectory |
solver objects, written in Python so easy to extend,
|
Each returns an IKSolution.
Other
Plot the sequence as a robot |
|
Interactively explore the sequence as a robot |
Details
- class ETS(arg=None)[source]
This class implements an elementary transform sequence (ETS) for 3D
An instance can contain an elementary transform (ET) or an elementary transform sequence (ETS). It has list-like properties by subclassing UserList, which means we can perform indexing, slicing pop, insert, as well as using it as an iterator over its values.
ETS()an empty ETS listETS(et)an ETS containing a single ETETS([et0, et1, et2])an ETS consisting of three ET’s
- Parameters:
arg (
list[ETS|ET] |list[ET] |list[ETS] |ET|ETS|None) – list of ETs or a single ET to initialise the ETS
Examples
References
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part II: Acceleration and Advanced Applications.” arXiv preprint arXiv:2207.01794 (2022).
See also
rxryrztxtytz- fixjoint(j, value, unit='rad')[source]
Return an independent ETS with the specified joint held constant.
j is the zero-based position among joint ETs, independent of their jindex values. Remaining joints retain explicit global jindices; automatically indexed joints are renumbered to fill the gap. Joint limits and flip flags are preserved. The original is not modified.
- Parameters:
- Return type:
- Returns:
ETS with one fewer joint
- Raises:
ValueError – for an invalid joint position or angular unit
- compile()[source]
Compile an ETS
- Returns:
optimised ETS
- Return type:
Perform constant folding for faster evaluation. Consecutive constant ETs are compounded, leading to a constant ET which is denoted by
SE3when displayed.Examples
>>> import roboticstoolbox as rtb >>> robot = rtb.models.ETS.Panda() >>> ets = robot.ets() >>> ets [ET.tz(param=0.333), ET.Rz(jindex=0), ET.Rx(param=-1.5707963267948966), ET.Rz(jindex=1), ET.Rx(param=1.5707963267948966), ET.tz(param=0.316), ET.Rz(jindex=2), ET.tx(param=0.0825), ET.Rx(param=1.5707963267948966), ET.Rz(jindex=3), ET.tx(param=-0.0825), ET.Rx(param=-1.5707963267948966), ET.tz(param=0.384), ET.Rz(jindex=4), ET.Rx(param=1.5707963267948966), ET.Rz(jindex=5), ET.tx(param=0.088), ET.Rx(param=1.5707963267948966), ET.tz(param=0.107), ET.Rz(jindex=6), ET.tz(param=0.10300000000000001), ET.Rz(param=-0.7853981633974483)] >>> ets.compile() [ET.SE3(T=array([[1. , 0. , 0. , 0. ], [0. , 1. , 0. , 0. ], [0. , 0. , 1. , 0.333], [0. , 0. , 0. , 1. ]])), ET.Rz(jindex=0), ET.SE3(T=array([[ 1., 0., 0., 0.], [ 0., 0., 1., 0.], [ 0., -1., 0., 0.], [ 0., 0., 0., 1.]])), ET.Rz(jindex=1), ET.SE3(T=array([[ 1. , 0. , 0. , 0. ], [ 0. , 0. , -1. , -0.316], [ 0. , 1. , 0. , 0. ], [ 0. , 0. , 0. , 1. ]])), ET.Rz(jindex=2), ET.SE3(T=array([[ 1. , 0. , 0. , 0.0825], [ 0. , 0. , -1. , 0. ], [ 0. , 1. , 0. , 0. ], [ 0. , 0. , 0. , 1. ]])), ET.Rz(jindex=3), ET.SE3(T=array([[ 1. , 0. , 0. , -0.0825], [ 0. , 0. , 1. , 0.384 ], [ 0. , -1. , 0. , 0. ], [ 0. , 0. , 0. , 1. ]])), ET.Rz(jindex=4), ET.SE3(T=array([[ 1., 0., 0., 0.], [ 0., 0., -1., 0.], [ 0., 1., 0., 0.], [ 0., 0., 0., 1.]])), ET.Rz(jindex=5), ET.SE3(T=array([[ 1. , 0. , 0. , 0.088], [ 0. , 0. , -1. , -0.107], [ 0. , 1. , 0. , 0. ], [ 0. , 0. , 0. , 1. ]])), ET.Rz(jindex=6), ET.SE3(T=array([[ 0.7071, 0.7071, 0. , 0. ], [-0.7071, 0.7071, 0. , 0. ], [ 0. , 0. , 1. , 0.103 ], [ 0. , 0. , 0. , 1. ]]))]
See also
isconstant
- insert(index, value)[source]
Insert value
- Parameters:
- Return type:
Inserts an ET or ETS into the ET sequence. The inserted ET is at position
index; an ETS is expanded and inserted element by element.Examples
- fkine(q=None, base=None, tool=None, include_base=True)[source]
Forward kinematics
- Parameters:
- Returns:
the transformation matrix representing the pose of the end-effector
- Return type:
T = ets.fkine(q)evaluates forward kinematics for the ets at joint configurationq.Trajectory operation: If
qhas multiple rows (mxn), it is considered a trajectory and the result is anSE3instance withmvalues.Examples
The following example makes a
pandarobot object, gets the ets, and solves for the forward kinematics at the listed configuration.>>> import roboticstoolbox as rtb >>> panda = rtb.models.Panda().ets() >>> panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854]) SE3(array([[ 0.995 , -0. , 0.0998, 0.484 ], [-0. , -1. , 0. , 0. ], [ 0.0998, -0. , -0.995 , 0.4126], [ 0. , 0. , 0. , 1. ]]))
Notes
A tool transform, if provided, is incorporated into the result.
Works from the end-effector link to the base
References
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).
- eval(q=None, base=None, tool=None, include_base=True)[source]
Forward kinematics (returns raw ndarray)
- Parameters:
q (
ndarray|Sequence[float] |None) – Joint coordinates – either global (lengthmax(self.jindices) + 1, addressed by each joint’s ownjindex) or compact (lengthself.n, positionally ordered to matchjoints()). These only differ when this ETS is one branch of a larger, branched robot – e.g. it’s whatikine_LM/ik_LMreturn when solving for just this ETS. For a whole, unbranched robot the two coincide.base (
ndarray|SE3|None) – a base transform applied before the ETSinclude_base (
bool) – set to True if the base transform should be considered
- Raises:
ValueError – if
q’s length matches neither interpretation- Returns:
the transformation matrix representing the pose of the end-effector
- Return type:
T = ets.eval(q)evaluates forward kinematics for the ets at joint configurationq.Trajectory operation: If
qhas multiple rows (mxn), it is considered a trajectory and the result is a 3d array withmplanes.Examples
>>> import roboticstoolbox as rtb >>> panda = rtb.models.Panda().ets() >>> panda.eval([0, -0.3, 0, -2.2, 0, 2, 0.7854]) array([[ 0.995 , -0. , 0.0998, 0.484 ], [-0. , -1. , -0. , -0. ], [ 0.0998, -0. , -0.995 , 0.4126], [ 0. , 0. , 0. , 1. ]])
Notes
A tool transform, if provided, is incorporated into the result.
Works from the end-effector link to the base
References
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).
- jacob0(q, tool=None)[source]
Manipulator geometric Jacobian in the base frame
- Parameters:
- Returns:
Manipulator Jacobian in the base frame
- Return type:
robot.jacob0(q)is the manipulator Jacobian matrix which maps joint velocity to end-effector spatial velocity expressed in the base frame.End-effector spatial velocity \(\nu = (v_x, v_y, v_z, \omega_x, \omega_y, \omega_z)^T\) is related to joint velocity by \({}^{E}\!\nu = \mathbf{J}_m(q) \dot{q}\).
Examples
The following example makes a
Puma560robot object, and solves for the base-frame Jacobian at the zero joint angle configuration>>> import roboticstoolbox as rtb >>> puma = rtb.models.Puma560().ets() >>> puma.jacob0([0, 0, 0, 0, 0, 0]) array([[ 0.1295, -0.4854, -0.4854, -0. , -0.0533, 0. ], [ 0.4318, 0. , 0. , 0. , 0. , 0. ], [-0. , 0.4318, 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. , 0. ], [ 0. , -1. , -1. , 0. , -1. , 0. ], [ 1. , 0. , 0. , 1. , 0. , 1. ]])
Notes
- This is the geometric Jacobian as described in texts by
Corke, Spong etal., Siciliano etal. The end-effector velocity is described in terms of translational and angular velocity, not a velocity twist as per the text by Lynch & Park.
References
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).
- jacobe(q, tool=None)[source]
Manipulator geometric Jacobian in the end-effector frame
- Parameters:
- Returns:
Manipulator Jacobian in the end-effector frame
- Return type:
robot.jacobe(q)is the manipulator Jacobian matrix which maps joint velocity to end-effector spatial velocity expressed in the end-effector frame.End-effector spatial velocity \(\nu = (v_x, v_y, v_z, \omega_x, \omega_y, \omega_z)^T\) is related to joint velocity by \({}^{E}\!\nu = \mathbf{J}_m(q) \dot{q}\).
Examples
The following example makes a
Puma560robot object, and solves for the end-effector frame Jacobian at the zero joint angle configuration>>> import roboticstoolbox as rtb >>> puma = rtb.models.Puma560().ets() >>> puma.jacobe([0, 0, 0, 0, 0, 0]) array([[ 0.1295, -0.4854, -0.4854, -0. , -0.0533, 0. ], [ 0.4318, 0. , 0. , 0. , 0. , 0. ], [-0. , 0.4318, 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. , 0. ], [ 0. , -1. , -1. , 0. , -1. , 0. ], [ 1. , 0. , 0. , 1. , 0. , 1. ]])
Notes
- This is the geometric Jacobian as described in texts by
Corke, Spong etal., Siciliano etal. The end-effector velocity is described in terms of translational and angular velocity, not a velocity twist as per the text by Lynch & Park.
References
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).
- hessian0(q=None, J0=None, tool=None)[source]
Manipulator Hessian in the base frame
- Parameters:
- Returns:
The manipulator Hessian in the base frame
- Return type:
This method computes the manipulator Hessian in the base frame. If we take the time derivative of the differential kinematic relationship
\[\begin{split}\nu &= \mat{J}(\vec{q}) \dvec{q} \\ \alpha &= \dmat{J} \dvec{q} + \mat{J} \ddvec{q}\end{split}\]where
\[\dmat{J} = \mat{H} \dvec{q}\]and \(\mat{H} \in \mathbb{R}^{6\times n \times n}\) is the Hessian tensor.
The elements of the Hessian are
\[\mat{H}_{i,j,k} = \frac{d^2 u_i}{d q_j d q_k}\]where \(u = \{t_x, t_y, t_z, r_x, r_y, r_z\}\) are the elements of the spatial velocity vector.
Similarly, we can write
\[\mat{J}_{i,j} = \frac{d u_i}{d q_j}\]Examples
The following example makes a
Pandarobot object, and solves for the base frame Hessian at the given joint angle configuration>>> import roboticstoolbox as rtb >>> panda = rtb.models.Panda().ets() >>> panda.hessian0([0, -0.3, 0, -2.2, 0, 2, 0.7854]) array([[[-0.484 , -0. , -0.486 , -0. , -0.1547, 0. , -0. ], [ 0. , 0.0796, 0. , 0.2466, 0. , 0.2006, 0. ], [ 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [ 0. , -1. , -0. , 1. , 0. , 1. , 0. ], [ 0. , -0. , -0.2955, -0. , 0.9463, -0. , 0.0998], [ 0. , 0. , -0. , -0. , 0. , -0. , 0. ]], [[-0. , -0.484 , -0. , 0.4986, -0. , 0.1086, 0. ], [ 0.0796, 0. , 0. , 0. , 0. , 0. , 0. ], [ 0. , -0.0796, -0. , -0.2466, -0. , -0.2006, -0. ], [ 0. , 0. , 0.9553, 0. , -0.3233, 0. , -0.995 ], [ 0. , 0. , -0. , -0. , 0. , -0. , 0. ], [ 0. , 0. , 0.2955, 0. , -0.9463, 0. , -0.0998]], [[-0.486 , -0. , -0.4643, -0. , -0.1478, 0. , 0. ], [ 0. , 0. , 0. , 0.383 , 0. , 0.2237, 0. ], [ 0. , -0. , -0.1436, -0. , -0.0457, -0. , -0. ], [ 0. , 0. , 0. , 0.9553, 0. , 0.9553, 0. ], [ 0. , 0. , 0. , -0. , 0.8085, -0. , -0.1987], [ 0. , 0. , 0. , 0.2955, 0. , 0.2955, 0. ]], [[-0. , 0.4986, -0. , -0.4986, 0. , -0.1086, -0. ], [ 0.2466, 0. , 0.383 , 0. , 0. , 0. , 0. ], [ 0. , -0.2466, -0. , 0.2466, 0. , 0.2006, 0. ], [ 0. , 0. , 0. , 0. , 0.3233, 0. , 0.995 ], [ 0. , 0. , 0. , 0. , 0. , 0. , -0. ], [ 0. , 0. , 0. , 0. , 0.9463, 0. , 0.0998]], [[-0.1547, -0. , -0.1478, 0. , 0.05 , -0. , 0. ], [ 0. , 0. , 0. , 0. , 0. , -0.1676, -0. ], [ 0. , -0. , -0.0457, 0. , 0.1464, 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. , -0.3233, 0. ], [ 0. , 0. , 0. , 0. , 0. , -0. , 0.9093], [ 0. , 0. , 0. , 0. , 0. , -0.9463, -0. ]], [[ 0. , 0.1086, 0. , -0.1086, -0. , -0.1086, -0. ], [ 0.2006, 0. , 0.2237, 0. , -0.1676, 0. , 0. ], [ 0. , -0.2006, -0. , 0.2006, 0. , 0.2006, 0. ], [ 0. , 0. , 0. , 0. , 0. , 0. , 0.995 ], [ 0. , 0. , 0. , 0. , 0. , 0. , -0. ], [ 0. , 0. , 0. , 0. , 0. , 0. , 0.0998]], [[-0. , 0. , 0. , -0. , 0. , -0. , 0. ], [ 0. , 0. , 0. , 0. , -0. , 0. , -0. ], [ 0. , -0. , -0. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. , 0. , 0. ]]])
References
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part II: Acceleration and Advanced Applications.” arXiv preprint arXiv:2207.01794 (2022).
- hessiane(q=None, Je=None, tool=None)[source]
Manipulator Hessian in the end-effector frame
- Parameters:
- Returns:
The manipulator Hessian in the end-effector frame
- Return type:
This method computes the manipulator Hessian in the end-effector frame. If we take the time derivative of the differential kinematic relationship
\[\begin{split}\nu &= \mat{J}(\vec{q}) \dvec{q} \\ \alpha &= \dmat{J} \dvec{q} + \mat{J} \ddvec{q}\end{split}\]where
\[\dmat{J} = \mat{H} \dvec{q}\]and \(\mat{H} \in \mathbb{R}^{6\times n \times n}\) is the Hessian tensor.
The elements of the Hessian are
\[\mat{H}_{i,j,k} = \frac{d^2 u_i}{d q_j d q_k}\]where \(u = \{t_x, t_y, t_z, r_x, r_y, r_z\}\) are the elements of the spatial velocity vector.
Similarly, we can write
\[\mat{J}_{i,j} = \frac{d u_i}{d q_j}\]Examples
The following example makes a
Pandarobot object, and solves for the end-effector frame Hessian at the given joint angle configuration>>> import roboticstoolbox as rtb >>> panda = rtb.models.Panda().ets() >>> panda.hessiane([0, -0.3, 0, -2.2, 0, 2, 0.7854]) array([[[-0.4816, -0. , -0.4835, -0. , -0.1539, -0. , 0. ], [ 0. , -0.0796, 0. , -0.2466, 0. , -0.2006, 0. ], [-0.0483, -0. , -0.0485, -0. , -0.0154, -0. , 0. ], [ 0. , -0.995 , 0. , 0.995 , -0. , 0.995 , -0. ], [ 0. , 0. , 0.2955, -0. , -0.9463, -0. , -0.0998], [ 0. , -0.0998, 0. , 0.0998, -0. , 0.0998, 0. ]], [[-0. , -0.4896, -0. , 0.4715, -0. , 0.088 , 0. ], [-0.0796, 0. , 0. , -0. , 0. , -0. , 0. ], [-0. , 0.0309, 0. , 0.2952, 0. , 0.2104, -0. ], [ 0. , 0. , 0.9801, 0. , -0.4161, 0. , -1. ], [ 0. , 0. , -0. , -0. , 0. , -0. , 0. ], [ 0. , 0. , -0.1987, -0. , 0.9093, -0. , 0. ]], [[-0.4835, -0. , -0.4763, -0. , -0.1516, -0. , 0. ], [ 0. , 0. , 0. , -0.383 , 0. , -0.2237, 0. ], [-0.0485, 0. , 0.0965, -0. , 0.0307, -0. , 0. ], [ 0. , 0. , 0. , 0.9801, -0. , 0.9801, 0. ], [ 0. , 0. , 0. , -0. , -0.8085, -0. , 0.1987], [ 0. , 0. , 0. , -0.1987, -0. , -0.1987, -0. ]], [[-0. , 0.4715, -0. , -0.4715, 0. , -0.088 , 0. ], [-0.2466, -0. , -0.383 , 0. , -0. , 0. , -0. ], [-0. , 0.2952, -0. , -0.2952, -0. , -0.2104, 0. ], [ 0. , 0. , 0. , 0. , 0.4161, 0. , 1. ], [ 0. , 0. , 0. , 0. , -0. , 0. , -0. ], [ 0. , 0. , 0. , 0. , -0.9093, 0. , 0. ]], [[-0.1539, -0. , -0.1516, 0. , 0.0644, 0. , -0. ], [ 0. , 0. , 0. , -0. , -0. , 0.1676, -0. ], [-0.0154, 0. , 0.0307, -0. , -0.1407, -0. , 0. ], [ 0. , 0. , 0. , 0. , 0. , -0.4161, -0. ], [ 0. , 0. , 0. , 0. , 0. , 0. , -0.9093], [ 0. , 0. , 0. , 0. , 0. , 0.9093, 0. ]], [[-0. , 0.088 , -0. , -0.088 , 0. , -0.088 , 0. ], [-0.2006, -0. , -0.2237, 0. , 0.1676, 0. , -0. ], [-0. , 0.2104, -0. , -0.2104, -0. , -0.2104, 0. ], [ 0. , 0. , 0. , 0. , 0. , 0. , 1. ], [ 0. , 0. , 0. , 0. , 0. , 0. , -0. ], [ 0. , 0. , 0. , 0. , 0. , 0. , 0. ]], [[ 0. , 0. , 0. , 0. , -0. , 0. , 0. ], [ 0. , 0. , 0. , -0. , -0. , -0. , -0. ], [ 0. , -0. , 0. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. , 0. , 0. ], [ 0. , 0. , 0. , 0. , 0. , 0. , 0. ]]])
References
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part II: Acceleration and Advanced Applications.” arXiv preprint arXiv:2207.01794 (2022).
- jacob0_analytical(q, representation='rpy/xyz', tool=None)[source]
Manipulator analytical Jacobian in the base frame
- Parameters:
- Returns:
Manipulator Jacobian in the base frame
- Return type:
ets.jacob0_analytical(q)is the manipulator Jacobian matrix which maps joint velocity to end-effector spatial velocity expressed in the base frame. End-effector spatial velocity \(\nu = (v_x, v_y, v_z, \omega_x, \omega_y, \omega_z)^T\) is related to joint velocity by \({}^{E}\!\nu = \mathbf{J}_m(q) \dot{q}\).representationrotational representation
'rpy/xyz'RPY angular rates in XYZ order
'rpy/zyx'RPY angular rates in ZYX order
'eul'Euler angular rates in ZYZ order
'exp'exponential coordinate rates
Examples
Makes a robot object and computes the analytic Jacobian for the given joint configuration
>>> import roboticstoolbox as rtb >>> puma = rtb.models.ETS.Puma560().ets() >>> puma.jacob0_analytical([0, 0, 0, 0, 0, 0]) array([[ 0.15 , 0.8636, 0.4318, 0. , 0. , 0. ], [ 0.2203, 0. , 0. , 0.2 , 0. , 0.2 ], [ 0. , -0.2203, -0.2 , 0. , -0.2 , 0. ], [ 1. , 0. , 0. , 1. , 0. , 1. ], [ 0. , 1. , 1. , 0. , 1. , 0. ], [ 0. , 0. , 0. , 0. , 0. , 0. ]])
- jacobm(q)[source]
The manipulability Jacobian
- Parameters:
q (
ndarray|Sequence[float]) – joint angles/configuration of the robot- Returns:
The manipulability Jacobian
- Return type:
This measure relates the rate of change of the manipulability to the joint velocities of the robot. Yoshikawa’s manipulability measure
\[m(\vec{q}) = \sqrt{\mat{J}(\vec{q}) \mat{J}(\vec{q})^T}\]This method returns its Jacobian with respect to configuration
\[\frac{\partial m(\vec{q})}{\partial \vec{q}}\]References
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part II: Acceleration and Advanced Applications.” arXiv preprint arXiv:2207.01794 (2022).
- manipulability(q, method='yoshikawa', axes='all')[source]
Manipulability measure
- Parameters:
q (
Any) – joint coordinates (trajectory as matrix(m,n))method (
Literal['yoshikawa','minsingular','invcondition']) – method to use,"yoshikawa"(default),"invcondition", or"minsingular"axes (
Union[Literal['all','trans','rot'],list[bool]]) – task space axes to consider:"all"[default],"trans", or"rot"
- Returns:
the manipulability metric
- Return type:
manipulability(q)is the scalar manipulability index for the ets at the joint configurationq. It indicates dexterity, that is, how well conditioned the ets is for motion with respect to the 6 degrees of Cartesian motion. The value is zero if the ets is at a singularity.Various measures are supported:
Measure
Description
"yoshikawa"volume of the velocity ellipsoid, distance from singularity [Yoshikawa85]
"invcondition"inverse condition number of Jacobian, isotropy of the velocity ellipsoid [Klein87]
"minsingular"minimum singular value of the Jacobian, distance from singularity [Klein87]
Trajectory operation:
If
qis a matrix (m,n) then the result (m,) is a vector of manipulability indices for each joint configuration specified by a row ofq.Notes
Invokes the
jacob0method of the robot ifJis not passedThe “all” option includes rotational and translational dexterity, but this involves adding different units. It can be more useful to look at the translational and rotational manipulability separately.
Examples in the RVC book (1st edition) can be replicated by using the “all” option
References
[Yoshikawa85]Manipulability of Robotic Mechanisms. Yoshikawa T., The International Journal of Robotics Research. 1985;4(2):3-9. doi:10.1177/027836498500400201
Robotics, Vision & Control in Python, 3e, P. Corke, Springer 2023, Chap 7.
Changed in version 1.0.4: Removed ‘both’ option for axes, added a custom list option.
- partial_fkine0(q, n)[source]
Manipulator Forward Kinematics nth Partial Derivative
- Parameters:
- Return type:
- Returns:
The nth partial derivative of the forward kinematics
This method computes the nth derivative of the forward kinematics where
nis greater than or equal to 3. This is an extension of the differential kinematics where the Jacobian is the first partial derivative and the Hessian is the second.Examples
The following example makes a
Pandarobot object, and solves for the base-effector frame 4th derivative of the forward kinematics at the given joint angle configuration>>> import roboticstoolbox as rtb >>> panda = rtb.models.Panda().ets() >>> dT = panda.partial_fkine0([0, -0.3, 0, -2.2, 0, 2, 0.7854], n=4) >>> dT.shape (7, 7, 7, 6, 7)
References
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part II: Acceleration and Advanced Applications.” arXiv preprint arXiv:2207.01794 (2022).
- ik_LM(Tep, q0=None, ilimit=30, slimit=100, tol=1e-06, mask=None, joint_limits=True, k=1.0, method='chan')[source]
Fast Levenberg-Marquardt numerical inverse kinematics solver
- Parameters:
ilimit (
int) – maximum iterations allowed per searchslimit (
int) – maximum search attempts before failuretol (
float) – maximum allowed residual error Emask (
ndarray|None) – a 6-vector weighting Cartesian DoF error priorityjoint_limits (
bool) – reject solutions with joint limit violationsk (
float) – gain value for the damping matrix Wnmethod (
Literal['chan','wampler','sugihara']) – one of"chan"(default),"sugihara"or"wampler"
- Returns:
an IKSolution containing joint coordinates
q,successflag,iterations,searchesandresidualerror value (reasonis always empty – this fast C++ solver doesn’t produce a granular failure reason string, unlikeikine_LM())- Return type:
Warning
This method requires the compiled C++ extension. It raises
RuntimeErrorif that extension is unavailable, e.g. in a pure-Python build/wheel or under Pyodide/JupyterLite. Useikine_LM()instead in those environments.A method which provides functionality to perform numerical inverse kinematics (IK) using the Levenberg-Marquardt method. This is a fast solver implemented in C++.
See the Inverse Kinematics Docs Page for more details and for a tutorial on numerical IK, see here.
The operation is defined by the choice of the
methodkwarg.The step is defined as
\[\begin{split}\vec{q}_{k+1} &= \vec{q}_k + \left( \mat{A}_k \right)^{-1} \bf{g}_k \\ % \mat{A}_k &= {\mat{J}(\vec{q}_k)}^\top \mat{W}_e \ {\mat{J}(\vec{q}_k)} + \mat{W}_n\end{split}\]where \(\mat{W}_n = \text{diag}(\vec{w_n})(\vec{w_n} \in \mathbb{R}^n_{>0})\) is a diagonal damping matrix. The damping matrix ensures that \(\mat{A}_k\) is non-singular and positive definite. The performance of the LM method largely depends on the choice of \(\mat{W}_n\).
Chan’s Method
Chan proposed
\[\mat{W}_n = λ E_k \mat{1}_n\]where λ is a constant which reportedly does not have much influence on performance. Use the kwarg
kto adjust the weighting term λ.Sugihara’s Method
Sugihara proposed
\[\mat{W}_n = E_k \mat{1}_n + \text{diag}(\hat{\vec{w}}_n)\]where \(\hat{\vec{w}}_n \in \mathbb{R}^n\), \(\hat{w}_{n_i} = l^2 \sim 0.01 l^2\), and \(l\) is the length of a typical link within the manipulator. We provide the variable
kas a kwarg to adjust the value of \(w_n\).Wampler’s Method
Wampler proposed \(\vec{w_n}\) to be a constant. This is set through the
kkwarg.Examples
The following example gets the
etsof apandarobot object, makes a goal poseTep, and then solves for the joint coordinates which result in the poseTepusing theikine_LMmethod.>>> import roboticstoolbox as rtb >>> panda = rtb.models.Panda().ets() >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854]) >>> panda.ikine_LM(Tep) IKSolution: q=[2.493, 0.3636, -2.569, -2.195, 0.2218, 1.978, 0.6104], success=True, iterations=22, searches=2, residual=1.81e-08
Notes
The value for the
kkwarg will depend on themethodchosen and the arm you are using. Use the following as a rough guidechan, k = 1.0 - 0.01,wampler, k = 0.01 - 0.0001, andsugihara, k = 0.1 - 0.0001When using this method, the initial joint coordinates \(q_0\), should correspond to a non-singular manipulator pose, since it uses the manipulator Jacobian.
This class supports null-space motion to assist with maximising manipulability and avoiding joint limits. These are enabled by setting kq and km to non-zero values.
References
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part II: Acceleration and Advanced Applications.” arXiv preprint arXiv:2207.01794 (2022).
See also
Changed in version 1.0.4: Merged the Levenberg-Marquardt IK solvers into the ik_LM method
- ik_NR(Tep, q0=None, ilimit=30, slimit=100, tol=1e-06, mask=None, joint_limits=True, pinv=True, pinv_damping=0.0)[source]
Fast numerical inverse kinematics using Newton-Raphson optimisation
- Parameters:
Tep (
ndarray|SE3) – the desired end-effector pose (a single pose only, for a trajectory useikine_NR())q0 (
ndarray|None) – initial joint configuration (random valid configuration if not supplied)ilimit (
int) – maximum number of iterations per searchslimit (
int) – maximum number of search attemptstol (
float) – final error tolerancemask (
ndarray|None) – a 6-vector weighting end-effector error priority (XYZ translation, XYZ rotation)joint_limits (
bool) – reject solutions with invalid joint configurationspinv (
int) – use the pseudo-inverse instead of the normal matrix inversepinv_damping (
float) – damping factor for the pseudo-inverse
- Returns:
an IKSolution containing joint coordinates
q,successflag,iterations,searchesandresidualerror value (reasonis always empty – this fast C++ solver doesn’t produce a granular failure reason string, unlikeikine_NR())- Return type:
Warning
This method requires the compiled C++ extension. It raises
RuntimeErrorif that extension is unavailable, e.g. in a pure-Python build/wheel or under Pyodide/JupyterLite. Useikine_NR()instead in those environments.sol = ets.ik_NR(Tep)are the joint coordinates (n) corresponding to the robot end-effector poseTepwhich is anSE3orndarrayobject. This method can be used for robots with any number of degrees of freedom. This is a fast solver implemented in C++.See the Inverse Kinematics Docs Page for more details and for a tutorial on numerical IK, see here.
When using this method with redundant robots (>6 DoF),
pinvmust be set toTrue.If
success == 0theqvalues will be valid numbers, but the solution will be in error. The amount of error is indicated by theresidual.Each iteration uses the Newton-Raphson optimisation method
\[\vec{q}_{k+1} = \vec{q}_k + {^0\mat{J}(\vec{q}_k)}^{-1} \vec{e}_k\]Examples
The following example gets the
etsof apandarobot object, makes a goal poseTep, and then solves for the joint coordinates which result in the poseTepusing theik_NRmethod.>>> import roboticstoolbox as rtb >>> panda = rtb.models.Panda().ets() >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854]) >>> panda.ik_NR(Tep) IKSolution: q=[-1.598, 1.026, 2.072, -2.122, -0.9157, 1.568, 1.479], success=True, iterations=16, searches=1, residual=1.46e-11
Notes
When using this method, the initial joint coordinates \(q_0\), should correspond to a non-singular manipulator pose, since it uses the manipulator Jacobian.
References
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part II: Acceleration and Advanced Applications.” arXiv preprint arXiv:2207.01794 (2022).
See also
- ik_GN(Tep, q0=None, ilimit=30, slimit=100, tol=1e-06, mask=None, joint_limits=True, pinv=True, pinv_damping=0.0)[source]
Fast numerical inverse kinematics by Gauss-Newton optimisation
- Parameters:
Tep (
ndarray|SE3) – the desired end-effector pose (a single pose only, for a trajectory useikine_GN())q0 (
ndarray|None) – initial joint configuration (random valid configuration if not supplied)ilimit (
int) – maximum number of iterations per searchslimit (
int) – maximum number of search attemptstol (
float) – final error tolerancemask (
ndarray|None) – a 6-vector weighting end-effector error priority (XYZ translation, XYZ rotation)joint_limits (
bool) – reject solutions with invalid joint configurationspinv (
int) – use the pseudo-inverse instead of the normal matrix inversepinv_damping (
float) – damping factor for the pseudo-inverse
- Returns:
an IKSolution containing joint coordinates
q,successflag,iterations,searchesandresidualerror value (reasonis always empty – this fast C++ solver doesn’t produce a granular failure reason string, unlikeikine_GN())- Return type:
sol = ets.ik_GN(Tep)are the joint coordinates (n) corresponding to the robot end-effector poseTepwhich is anSE3orndarrayobject. This method can be used for robots with any number of degrees of freedom. This is a fast solver implemented in C++.See the Inverse Kinematics Docs Page for more details and for a tutorial on numerical IK, see here.
When using this method with redundant robots (>6 DoF),
pinvmust be set toTrue.If
success == 0theqvalues will be valid numbers, but the solution will be in error. The amount of error is indicated by theresidual.Each iteration uses the Gauss-Newton optimisation method
\[\begin{split}\vec{q}_{k+1} &= \vec{q}_k + \left( {\mat{J}(\vec{q}_k)}^\top \mat{W}_e \ {\mat{J}(\vec{q}_k)} \right)^{-1} \bf{g}_k \\ \bf{g}_k &= {\mat{J}(\vec{q}_k)}^\top \mat{W}_e \vec{e}_k\end{split}\]where \(\mat{J} = {^0\mat{J}}\) is the base-frame manipulator Jacobian. If \(\mat{J}(\vec{q}_k)\) is non-singular, and \(\mat{W}_e = \mat{1}_n\), then the above provides the pseudoinverse solution. However, if \(\mat{J}(\vec{q}_k)\) is singular, the above can not be computed and the GN solution is infeasible.
Examples
The following example gets the
etsof apandarobot object, makes a goal poseTep, and then solves for the joint coordinates which result in the poseTepusing theikine_GNmethod.>>> import roboticstoolbox as rtb >>> panda = rtb.models.Panda().ets() >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854]) >>> panda.ik_GN(Tep) IKSolution: q=[-0.733, -0.3847, 0.6438, -2.193, 0.2593, 1.97, 0.581], success=True, iterations=349, searches=22, residual=6.84e-09
Notes
When using this method, the initial joint coordinates \(q_0\), should correspond to a non-singular manipulator pose, since it uses the manipulator Jacobian.
References
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part II: Acceleration and Advanced Applications.” arXiv preprint arXiv:2207.01794 (2022).
See also
- ikine_LM(Tep, q0=None, ilimit=30, slimit=100, tol=1e-06, mask=None, joint_limits=True, seed=None, k=1.0, method='chan', kq=0.0, km=0.0, ps=0.0, pi=0.3, **kwargs)[source]
Levenberg-Marquardt numerical inverse kinematics solver
- Parameters:
Tep (
ndarray|SE3) – the desired end-effector pose or pose trajectoryq0 (
ndarray|Sequence[float] |None) – the initial joint coordinates, a vector (n,), or a matrix (m, n) whose rows are the starting points of the first m searches (any further searches start from random valid coordinates)ilimit (
int) – maximum iterations allowed per searchslimit (
int) – maximum search attempts before failuretol (
float) – maximum allowed residual error Emask (
ndarray|Sequence[float] |None) – a 6-vector weighting Cartesian DoF error priorityjoint_limits (
bool) – reject solutions with joint limit violationsseed (
int|None) – seed for the RNG used to generate random joint configurationsk (
float) – gain value for the damping matrix Wnmethod (
Literal['chan','wampler','sugihara']) – one of"chan"(default),"sugihara"or"wampler"kq (
float) – gain for joint limit avoidance (0.0 disables)km (
float) – gain for manipulability maximisation (0.0 disables)ps (
float) – minimum joint approach distance to limit (radians or metres)pi (
ndarray|float) – null-space influence distance (radians or metres)
- Returns:
an IKSolution containing joint coordinates
q,successflag,iterations,searches,residualerror value, andreasonstring if applicable- Return type:
If
Tepis a trajectory (anSE3with N poses, or an array with shape (N, 4, 4)) each pose is solved independently from the sameq0, so consecutive solutions are not guaranteed to be on the same IK branch.qhas shape (N, n),successis True only if every pose succeeded, andresidualis the maximum over the poses. Seesolve().Changed in version 1.4.5: For a trajectory,
residualis the maximum over the poses, it was the minimum.A method which provides functionality to perform numerical inverse kinematics (IK) using the Levenberg-Marquardt method.
See the Inverse Kinematics Docs Page for more details and for a tutorial on numerical IK, see here.
The operation is defined by the choice of the
methodkwarg.The step is defined as
\[\begin{split}\vec{q}_{k+1} &= \vec{q}_k + \left( \mat{A}_k \right)^{-1} \bf{g}_k \\ % \mat{A}_k &= {\mat{J}(\vec{q}_k)}^\top \mat{W}_e \ {\mat{J}(\vec{q}_k)} + \mat{W}_n\end{split}\]where \(\mat{W}_n = \text{diag}(\vec{w_n})(\vec{w_n} \in \mathbb{R}^n_{>0})\) is a diagonal damping matrix. The damping matrix ensures that \(\mat{A}_k\) is non-singular and positive definite. The performance of the LM method largely depends on the choice of \(\mat{W}_n\).
Chan’s Method
Chan proposed
\[\mat{W}_n = λ E_k \mat{1}_n\]where λ is a constant which reportedly does not have much influence on performance. Use the kwarg
kto adjust the weighting term λ.Sugihara’s Method
Sugihara proposed
\[\mat{W}_n = E_k \mat{1}_n + \text{diag}(\hat{\vec{w}}_n)\]where \(\hat{\vec{w}}_n \in \mathbb{R}^n\), \(\hat{w}_{n_i} = l^2 \sim 0.01 l^2\), and \(l\) is the length of a typical link within the manipulator. We provide the variable
kas a kwarg to adjust the value of \(w_n\).Wampler’s Method
Wampler proposed \(\vec{w_n}\) to be a constant. This is set through the
kkwarg.Examples
The following example gets the
etsof apandarobot object, makes a goal poseTep, and then solves for the joint coordinates which result in the poseTepusing theikine_LMmethod.>>> import roboticstoolbox as rtb >>> panda = rtb.models.Panda().ets() >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854]) >>> panda.ikine_LM(Tep) IKSolution: q=[-0.7567, -0.3911, 0.6634, -2.192, 0.2702, 1.967, 0.5725], success=True, iterations=19, searches=1, residual=2.37e-11
Notes
The value for the
kkwarg will depend on themethodchosen and the arm you are using. Use the following as a rough guidechan, k = 1.0 - 0.01,wampler, k = 0.01 - 0.0001, andsugihara, k = 0.1 - 0.0001When using this method, the initial joint coordinates \(q_0\), should correspond to a non-singular manipulator pose, since it uses the manipulator Jacobian.
This class supports null-space motion to assist with maximising manipulability and avoiding joint limits. These are enabled by setting kq and km to non-zero values.
References
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part II: Acceleration and Advanced Applications.” arXiv preprint arXiv:2207.01794 (2022).
See also
Changed in version 1.0.4: Added the Levenberg-Marquardt IK solver method on the
ETSclass
- ikine_NR(Tep, q0=None, ilimit=30, slimit=100, tol=1e-06, mask=None, joint_limits=True, seed=None, pinv=False, kq=0.0, km=0.0, ps=0.0, pi=0.3, **kwargs)[source]
Newton-Raphson numerical inverse kinematics solver
- Parameters:
Tep (
ndarray|SE3) – the desired end-effector pose or pose trajectoryq0 (
ndarray|Sequence[float] |None) – the initial joint coordinates, a vector (n,), or a matrix (m, n) whose rows are the starting points of the first m searches (any further searches start from random valid coordinates)ilimit (
int) – maximum iterations allowed per searchslimit (
int) – maximum search attempts before failuretol (
float) – maximum allowed residual error Emask (
ndarray|Sequence[float] |None) – a 6-vector weighting Cartesian DoF error priorityjoint_limits (
bool) – reject solutions with joint limit violationsseed (
int|None) – seed for the RNG used to generate random joint configurationspinv (
bool) – use the pseudo-inverse in the step method instead of the normal inversekq (
float) – gain for joint limit avoidance (0.0 disables)km (
float) – gain for manipulability maximisation (0.0 disables)ps (
float) – minimum joint approach distance to limit (radians or metres)pi (
ndarray|float) – null-space influence distance (radians or metres)
- Returns:
an IKSolution containing joint coordinates
q,successflag,iterations,searches,residualerror value, andreasonstring if applicable- Return type:
If
Tepis a trajectory (anSE3with N poses, or an array with shape (N, 4, 4)) each pose is solved independently from the sameq0, so consecutive solutions are not guaranteed to be on the same IK branch.qhas shape (N, n),successis True only if every pose succeeded, andresidualis the maximum over the poses. Seesolve().Changed in version 1.4.5: For a trajectory,
residualis the maximum over the poses, it was the minimum.A method which provides functionality to perform numerical inverse kinematics (IK) using the Newton-Raphson method.
See the Inverse Kinematics Docs Page for more details and for a tutorial on numerical IK, see here.
When using this method with redundant robots (>6 DoF),
pinvmust be set toTrue.Each iteration uses the Newton-Raphson optimisation method
\[\vec{q}_{k+1} = \vec{q}_k + {^0\mat{J}(\vec{q}_k)}^{-1} \vec{e}_k\]Examples
The following example gets the
etsof apandarobot object, makes a goal poseTep, and then solves for the joint coordinates which result in the poseTepusing theikine_NRmethod.>>> import roboticstoolbox as rtb >>> panda = rtb.models.Panda().ets() >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854]) >>> panda.ikine_NR(Tep) IKSolution: q=[0.7567, 1.192, 2.47, -0.7633, 2.79, 0.3284, -2.66], success=False, reason=iteration and search limit reached, 100 numpy.LinAlgError encountered, iterations=100, searches=100, residual=3.75
Notes
When using this method, the initial joint coordinates \(q_0\), should correspond to a non-singular manipulator pose, since it uses the manipulator Jacobian.
This class supports null-space motion to assist with maximising manipulability and avoiding joint limits. These are enabled by setting kq and km to non-zero values.
References
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part II: Acceleration and Advanced Applications.” arXiv preprint arXiv:2207.01794 (2022).
See also
Changed in version 1.0.4: Added the Newton-Raphson IK solver method on the
ETSclass
- ikine_GN(Tep, q0=None, ilimit=30, slimit=100, tol=1e-06, mask=None, joint_limits=True, seed=None, pinv=False, kq=0.0, km=0.0, ps=0.0, pi=0.3, **kwargs)[source]
Gauss-Newton numerical inverse kinematics solver
- Parameters:
Tep (
ndarray|SE3) – the desired end-effector pose or pose trajectoryq0 (
ndarray|Sequence[float] |None) – the initial joint coordinates, a vector (n,), or a matrix (m, n) whose rows are the starting points of the first m searches (any further searches start from random valid coordinates)ilimit (
int) – maximum iterations allowed per searchslimit (
int) – maximum search attempts before failuretol (
float) – maximum allowed residual error Emask (
ndarray|Sequence[float] |None) – a 6-vector weighting Cartesian DoF error priorityjoint_limits (
bool) – reject solutions with joint limit violationsseed (
int|None) – seed for the RNG used to generate random joint configurationspinv (
bool) – use the pseudo-inverse in the step method instead of the normal inversekq (
float) – gain for joint limit avoidance (0.0 disables)km (
float) – gain for manipulability maximisation (0.0 disables)ps (
float) – minimum joint approach distance to limit (radians or metres)pi (
ndarray|float) – null-space influence distance (radians or metres)
- Returns:
an IKSolution containing joint coordinates
q,successflag,iterations,searches,residualerror value, andreasonstring if applicable- Return type:
If
Tepis a trajectory (anSE3with N poses, or an array with shape (N, 4, 4)) each pose is solved independently from the sameq0, so consecutive solutions are not guaranteed to be on the same IK branch.qhas shape (N, n),successis True only if every pose succeeded, andresidualis the maximum over the poses. Seesolve().Changed in version 1.4.5: For a trajectory,
residualis the maximum over the poses, it was the minimum.A method which provides functionality to perform numerical inverse kinematics (IK) using the Gauss-Newton method.
See the Inverse Kinematics Docs Page for more details and for a tutorial on numerical IK, see here.
When using this method with redundant robots (>6 DoF),
pinvmust be set toTrue.Each iteration uses the Gauss-Newton optimisation method
\[\begin{split}\vec{q}_{k+1} &= \vec{q}_k + \left( {\mat{J}(\vec{q}_k)}^\top \mat{W}_e \ {\mat{J}(\vec{q}_k)} \right)^{-1} \bf{g}_k \\ \bf{g}_k &= {\mat{J}(\vec{q}_k)}^\top \mat{W}_e \vec{e}_k\end{split}\]where \(\mat{J} = {^0\mat{J}}\) is the base-frame manipulator Jacobian. If \(\mat{J}(\vec{q}_k)\) is non-singular, and \(\mat{W}_e = \mat{1}_n\), then the above provides the pseudoinverse solution. However, if \(\mat{J}(\vec{q}_k)\) is singular, the above can not be computed and the GN solution is infeasible.
Examples
The following example gets the
etsof apandarobot object, makes a goal poseTep, and then solves for the joint coordinates which result in the poseTepusing theikine_GNmethod.>>> import roboticstoolbox as rtb >>> panda = rtb.models.Panda().ets() >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854]) >>> panda.ikine_GN(Tep) IKSolution: q=[-0.07258, 0.5624, -2.317, -0.7923, -1.749, 0.429, -1.806], success=False, reason=iteration and search limit reached, 100 numpy.LinAlgError encountered, iterations=100, searches=100, residual=1.99
Notes
When using this method, the initial joint coordinates \(q_0\), should correspond to a non-singular manipulator pose, since it uses the manipulator Jacobian.
This class supports null-space motion to assist with maximising manipulability and avoiding joint limits. These are enabled by setting kq and km to non-zero values.
References
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part II: Acceleration and Advanced Applications.” arXiv preprint arXiv:2207.01794 (2022).
See also
Changed in version 1.0.4: Added the Gauss-Newton IK solver method on the
ETSclass
- ikine_QP(Tep, q0=None, ilimit=30, slimit=100, tol=1e-06, mask=None, joint_limits=True, seed=None, kj=1.0, ks=1.0, kq=0.0, km=0.0, ps=0.0, pi=0.3, **kwargs)[source]
Quadratic programming numerical inverse kinematics solver
- Parameters:
Tep (
ndarray|SE3) – the desired end-effector pose or pose trajectoryq0 (
ndarray|Sequence[float] |None) – the initial joint coordinates, a vector (n,), or a matrix (m, n) whose rows are the starting points of the first m searches (any further searches start from random valid coordinates)ilimit (
int) – maximum iterations allowed per searchslimit (
int) – maximum search attempts before failuretol (
float) – maximum allowed residual error Emask (
ndarray|Sequence[float] |None) – a 6-vector weighting Cartesian DoF error priorityjoint_limits (
bool) – reject solutions with joint limit violationsseed (
int|None) – seed for the RNG used to generate random joint configurationskj (
float) – gain for joint velocity norm minimisationks (
float) – gain adjusting the cost of slack (intentional error)kq (
float) – gain for joint limit avoidance (0.0 disables)km (
float) – gain for manipulability maximisation (0.0 disables)ps (
float) – minimum joint approach distance to limit (radians or metres)pi (
ndarray|float) – null-space influence distance (radians or metres)
- Returns:
an IKSolution containing joint coordinates
q,successflag,iterations,searches,residualerror value, andreasonstring if applicable- Return type:
If
Tepis a trajectory (anSE3with N poses, or an array with shape (N, 4, 4)) each pose is solved independently from the sameq0, so consecutive solutions are not guaranteed to be on the same IK branch.qhas shape (N, n),successis True only if every pose succeeded, andresidualis the maximum over the poses. Seesolve().Changed in version 1.4.5: For a trajectory,
residualis the maximum over the poses, it was the minimum.- Raises:
ImportError – if the package
qpsolversis not installed
A method that provides functionality to perform numerical inverse kinematics (IK) using a quadratic programming approach.
See the Inverse Kinematics Docs Page for more details and for a tutorial on numerical IK, see here.
Each iteration uses the following approach
\[\vec{q}_{k+1} = \vec{q}_{k} + \dot{\vec{q}}.\]where the QP is defined as
\[\begin{split}\min_x \quad f_o(\vec{x}) &= \frac{1}{2} \vec{x}^\top \mathcal{Q} \vec{x}+ \mathcal{C}^\top \vec{x}, \\ \text{subject to} \quad \mathcal{J} \vec{x} &= \vec{\nu}, \\ \mathcal{A} \vec{x} &\leq \mathcal{B}, \\ \vec{x}^- &\leq \vec{x} \leq \vec{x}^+\end{split}\]with
\[\begin{split}\vec{x} &= \begin{pmatrix} \dvec{q} \\ \vec{\delta} \end{pmatrix} \in \mathbb{R}^{(n+6)} \\ \mathcal{Q} &= \begin{pmatrix} \lambda_q \mat{1}_{n} & \mathbf{0}_{6 \times 6} \\ \mathbf{0}_{n \times n} & \lambda_\delta \mat{1}_{6} \end{pmatrix} \in \mathbb{R}^{(n+6) \times (n+6)} \\ \mathcal{J} &= \begin{pmatrix} \mat{J}(\vec{q}) & \mat{1}_{6} \end{pmatrix} \in \mathbb{R}^{6 \times (n+6)} \\ \mathcal{C} &= \begin{pmatrix} \mat{J}_m \\ \bf{0}_{6 \times 1} \end{pmatrix} \in \mathbb{R}^{(n + 6)} \\ \mathcal{A} &= \begin{pmatrix} \mat{1}_{n \times n + 6} \\ \end{pmatrix} \in \mathbb{R}^{(l + n) \times (n + 6)} \\ \mathcal{B} &= \eta \begin{pmatrix} \frac{\rho_0 - \rho_s} {\rho_i - \rho_s} \\ \vdots \\ \frac{\rho_n - \rho_s} {\rho_i - \rho_s} \end{pmatrix} \in \mathbb{R}^{n} \\ \vec{x}^{-, +} &= \begin{pmatrix} \dvec{q}^{-, +} \\ \vec{\delta}^{-, +} \end{pmatrix} \in \mathbb{R}^{(n+6)},\end{split}\]where \(\vec{\delta} \in \mathbb{R}^6\) is the slack vector, \(\lambda_\delta \in \mathbb{R}^+\) is a gain term which adjusts the cost of the norm of the slack vector in the optimiser, \(\dvec{q}^{-,+}\) are the minimum and maximum joint velocities, and \(\dvec{\delta}^{-,+}\) are the minimum and maximum slack velocities.
Examples
The following example gets the
etsof apandarobot object, makes a goal poseTep, and then solves for the joint coordinates which result in the poseTepusing theikine_QPmethod.>>> import roboticstoolbox as rtb >>> panda = rtb.models.Panda().ets() >>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854]) >>> panda.ikine_QP(Tep) !! [RUNBLOCK-ERROR] ets/ETS.py:docstring of roboticstoolbox.ets.ETS.ETS.ikine_QP:1430 Install using 'pip install qpsolvers'
Notes
When using this method, the initial joint coordinates \(q_0\), should correspond to a non-singular manipulator pose, since it uses the manipulator Jacobian.
This class supports null-space motion to assist with maximising manipulability and avoiding joint limits. These are enabled by setting kq and km to non-zero values.
References
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).
J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part II: Acceleration and Advanced Applications.” arXiv preprint arXiv:2207.01794 (2022).
See also
Changed in version 1.0.4: Added the Quadratic Programming IK solver method on the
ETSclass
- inv()
Inverse of ETS
The inverse of a given ETS. It is computed as the inverse of the individual ETs in the reverse order.
\[(\mathbf{E}_0, \mathbf{E}_1 \cdots \mathbf{E}_{n-1} )^{-1} = (\mathbf{E}_{n-1}^{-1}, \mathbf{E}_{n-2}^{-1} \cdots \mathbf{E}_0^{-1}{n-1} )\]- Return type:
- Returns:
Inverse of the ETS
Examples
Notes
- It is essential to use explicit joint indices to account for
the reversed order of the transforms.
- jindex_set()
Get set of joint indices
Examples
>>> from roboticstoolbox import ET >>> e = ET.Rz(jindex=1) * ET.tx(jindex=2) * ET.Rz(jindex=1) * ET.tx(1) >>> e.jindex_set() {1, 2}
- property jindices: ndarray
Get an array of joint indices
- Returns:
array of unique joint indices
- Return type:
ndarray
Examples
>>> from roboticstoolbox import ET >>> e = ET.Rz(jindex=1) * ET.tx(jindex=2) * ET.Rz(jindex=1) * ET.tx(1) >>> e.jindices array([1, 2, 1])
- joint_idx()
Get index of joint transforms
- Returns:
indices of transforms that are joints
- Return type:
Examples
>>> from roboticstoolbox import ET >>> e = ET.Rz() * ET.tx(1) * ET.Rz() * ET.tx(1) >>> e.joint_idx() array([0, 2])
- joints()
Get a list of the variable ETs with this ETS
- Returns:
list of ETs that are joints
- Return type:
list[ETT]
Examples
>>> from roboticstoolbox import ET >>> e = ET.Rz() * ET.tx(1) * ET.Rz() * ET.tx(1) >>> e.joints() [ET.Rz(jindex=0), ET.Rz(jindex=1)]
- property m: int
Number of transforms
- Returns:
the number of transforms in the ETS
- Return type:
Counts the number of transforms in the ETS.
Examples
>>> from roboticstoolbox import ET >>> e = ET.Rx() * ET.tx(1) * ET.tz() >>> e.m 3
- merge(i)
Merge two transforms in the ETS
Merges the two transforms at indices
iandi+1. This is useful for reducing the number of transforms in an ETS.Examples
>>> from roboticstoolbox import ET >>> from math import pi >>> e = ET.Rz() * ET.tx(1) * ET.tx(2) * ET.Rz(1) >>> print(e) Rz(q) ⊕ tx(1) ⊕ tx(2) ⊕ Rz(57.3°) >>> e.merge(1) >>> print(e) Rz(q) ⊕ tx(3) ⊕ Rz(57.3°) >>> e = ET.tx(1) * ET.Rx(0.1) * ET.Rx(pi/2) * ET.tx(2) >>> print(e) tx(1) ⊕ Rx(5.73°) ⊕ Rx(90°) ⊕ tx(2) >>> e.merge(1) >>> print(e) tx(1) ⊕ Rx(95.73°) ⊕ tx(2)
Both transforms must be of the same kind, and at most one of them can be a joint.
- property n: int
Number of joints
- Returns:
the number of joints in the ETS
- Return type:
Counts the number of joints in the ETS.
Examples
>>> from roboticstoolbox import ET >>> e = ET.Rx() * ET.tx(1) * ET.tz() >>> e.n 2
See also
- plot(*args, **kwargs)
Plot the sequence as a robot
The sequence is wrapped in a
Robot(Robot2for a planar sequence) and itsplotmethod is called, which see for the arguments.- Return type:
- property qlim: ndarray
Get/Set Joint limits
Limits are extracted from the link objects. If joints limits are not set for:
a revolute joint [-𝜋. 𝜋] is returned
a prismatic joint an exception is raised
- Parameters:
new_qlim (ndarray(2,n)) – new joint limits to set
- Returns:
array of joint limit values
- Return type:
ndarray(2,n)
- Raises:
ValueError – unset limits for a prismatic joint
Examples
>>> import roboticstoolbox as rtb >>> robot = rtb.models.DH.Puma560() >>> robot.qlim array([[-2.7925, -0.7854, -3.927 , -1.9199, -1.7453, -4.6426], [ 2.7925, 3.927 , 0.7854, 2.9671, 1.7453, 4.6426]])
- random_q(i=1)
Generate a random valid joint configuration
- Parameters:
i (
int) – number of configurations to generate- Returns:
random joint configuration
- Return type:
Generates a random q vector within the joint limits defined by
self.qlim.Examples
- property structure: str
Joint structure string
A string comprising the characters ‘R’ or ‘P’ which indicate the types of joints in order from left to right.
- Returns:
a string indicating the joint types
- Return type:
Examples
>>> from roboticstoolbox import ET >>> e = ET.tz() * ET.tx(1) * ET.Rz() * ET.tx(1) >>> e.structure 'PR'
- swap(i)
Swap two transforms in the ETS
- Parameters:
i (
int) – index of first transform- Raises:
ValueError – if the two transforms do not commute
- Return type:
Swaps the two transforms at indices
iandi+1. This is useful for changing the order of commutative transforms in an ETS, and the kinematics of the sequence are unchanged. Two transforms commute if they areof the same kind, for example two translations along x
both translations, along any axes
a rotation and a translation along the axis of that rotation, for example
Rzandtz
Anything else, such as a rotation and a translation along a different axis, does not commute and raises
ValueError.Examples
>>> from roboticstoolbox import ET >>> e = ET.Rz() * ET.tx(1) * ET.ty(2) * ET.Rz(1) >>> print(e) Rz(q) ⊕ tx(1) ⊕ ty(2) ⊕ Rz(57.3°) >>> e.swap(1) >>> print(e) Rz(q) ⊕ ty(2) ⊕ tx(1) ⊕ Rz(57.3°) >>> e = ET.Rz() * ET.tz(1) * ET.Rx() * ET.Rz(1) >>> e.swap(0) >>> print(e) tz(1) ⊕ Rz(q0) ⊕ Rx(q1) ⊕ Rz(57.3°)
- teach(*args, **kwargs)
Interactively explore the sequence as a robot
The sequence is wrapped in a
Robot(Robot2for a planar sequence) and itsteachmethod is called, which see for the arguments.- Return type:
- split(method='last')[source]
Split ETS into link segments
- Parameters:
method (
str) – one of"first","last"(default),"dh", or"mdh".- Return type:
- Returns:
[base, *segments, gripper]– a list of lengthn_joints + 2.base/gripperare empty ETS when the method has no concept of one (e.g."dh"never populatesgripper,"mdh"never populatesbase).
Split an ETS into segments representing links, plus a base and gripper segment. Unpack with
base, *segments, gripper = ets.split(method).The behaviour depends on the
methodargument:"first": each link segment begins with a joint and continues upto, but not including the next joint. Any constant ET before the first joint are part of the base. There are no gripper ET, they are included in the last link segment."last": each link segment ends with a joint and include all ET after the previous joint. Any constant ET after the last joint are part of the gripper. There are no base ET, they are included in the first link segment."dh": similar to"first"but each segment is validated against the Denavit-Hartenberg convention: an ordered, 4-slot template Rz($θ_j$) tz($d_j$) tx($a_j$) Rx($α_j$), exactly one of Rz/tz being the segment’s joint and the rest optional (but present slots must occur in this order). Content between two joints that cannot be accounted for by the template raisesValueError. The base (content before the first joint’s template slots) is unvalidated and reported separately; trailing content past the last joint’s template is folded into the last segment."mdh": similar to"last"but validated against the modified Denavit-Hartenberg convention, template tx($a_{j-1}$) Rx($α_{j-1}$) Rz($θ_j$) tz($d_j$), same rules as"dh"mirrored: the gripper (content past the last joint’s template slots) is unvalidated and reported separately; leading content before the first joint’s template is folded into the first segment.
>>> from roboticstoolbox import ET >>> e = ET.tz(1) * ET.Rx("q1") * ET.tx(2) * ET.Ry("q2") * ET.ty(3) * ET.Rz("q3") * ET.tz(4) >>> base, *segments, gripper = e.split("first") >>> print("|".join(str(_) for _ in segments), f"+ base={str(base)}, gripper={str(gripper)}") Rx(q1) ⊕ tx(2)|Ry(q2) ⊕ ty(3)|Rz(q3) ⊕ tz(4) + base=tz(1), gripper=SE3() >>> base, *segments, gripper = e.split("last") >>> print("|".join(str(_) for _ in segments), f"+ base={str(base)}, gripper={str(gripper)}") tz(1) ⊕ Rx(q1)|tx(2) ⊕ Ry(q2)|ty(3) ⊕ Rz(q3) + base=SE3(), gripper=tz(4) >>> e = ET.tz(1) * ET.Rz("q1") * ET.tx(2) * ET.Rx(90, 'deg') * ET.Rz("q2") * ET.tz(4) * ET.Rz(180, 'deg') * ET.tz("q3") * ET.Rz(270, 'deg') * ET.tz(4) >>> base, *segments, gripper = e.split("dh") >>> print("|".join(str(_) for _ in segments), f"+ base={str(base)}, gripper={str(gripper)}") Rz(q1) ⊕ tx(2) ⊕ Rx(90°)|Rz(q2) ⊕ tz(4)|Rz(180°) ⊕ tz(q3) ⊕ Rz(270°) ⊕ tz(4) + base=tz(1), gripper=SE3() >>> base, *segments, gripper = e.split("mdh") >>> print("|".join(str(_) for _ in segments), f"+ base={str(base)}, gripper={str(gripper)}") tz(1) ⊕ Rz(q1)|tx(2) ⊕ Rx(90°) ⊕ Rz(q2) ⊕ tz(4)|Rz(180°) ⊕ tz(q3) + base=SE3(), gripper=Rz(270°) ⊕ tz(4)