Superclasses

Robot

Inheritance diagram of roboticstoolbox.ERobot

The various models ERobot models all subclass this class.

Collision checking

robot.iscollided(q, shape) checks the robot against an external shape. robot.isselfcollided(q) checks its own non-adjacent links, including gripper links; robot.iscollided(q, robot) is equivalent. Shapes on the same link, neighbouring links, and links within the same gripper are excluded. Links without collision geometry are transparent when determining neighbours, so each link’s nearest ancestor with collision geometry is excluded. Links in separate branches are checked unless they belong to the same gripper, and touching counts as a collision for the pairs that are checked.

The checks use collision geometry, not visual geometry, and require the optional coal dependency. A model without collision geometry raises ValueError for self-collision checking. Links without collision geometry are omitted, so ensure the model represents all the parts that need checking. Many DH models provide kinematics and dynamics without collision geometry.

Omitting q from isselfcollided uses the robot’s current configuration. Grippers use their own current q. The stored joint configurations are not changed. skip=True reuses existing world transforms and should only be used when the caller has already updated them.

@author: Jesse Haviland @author: Peter Corke

class Robot(arg, gripper_links=None, name='', manufacturer='', comment='', base=None, tool=None, gravity=[0, 0, -9.81], keywords=[], symbolic=False, configs=None, check_jindex=True)[source]

Bases: BaseRobot[Link], RobotKinematicsMixin

Robot manipulator defined by links or an elementary transform sequence

The robot is made from a list of links, an ETS or another robot. It can be a tree. It is the superclass of the robots defined by Denavit-Hartenberg parameters, DHRobot, and of those loaded from a URDF file.

classmethod URDF(file, gripper=None, manufacturer=None)[source]

Deprecated. Use URDFRobot as a base class, or call URDF_read() from roboticstoolbox.models.URDF.URDFRobot and construct Robot directly.

Return type:

Any

property reach: float

Reach of the robot

Returns:

Maximum reach of the robot

Return type:

float

A conservative estimate of the reach of the robot. It is computed as the sum of the translational ETs that define the link transform.

Computed on the first access. If kinematic parameters subsequently change this will not be reflected.

Notes

  • Probably an overestimate of reach

  • Used by numerical inverse kinematics to scale translational error.

  • For a prismatic joint, uses qlim if it is set

fkine_all(q)[source]

Compute the pose of every link frame

Parameters:

q (ndarray | Sequence[float]) – The joint configuration

Return type:

SE3

Returns:

Pose of all links

T = robot.fkine_all(q) is an SE3 instance with robot.nlinks + 1 values:

  • T[0] is the base transform

  • T[i] is the pose of link whose number is i

References

  • J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).

fkine_geometry(q, robot_alpha=1.0, collision_alpha=0.0)[source]

Compute the world-frame pose of every rendered geometry part

Parameters:
  • q (ndarray | Sequence[float]) – the joint configuration of the main kinematic chain

  • robot_alpha (float) – include visual geometry if > 0, matches _to_dict/_fk_dict’s own gating

  • collision_alpha (float) – include collision geometry if > 0

Returns:

one pose per geometry part, in the same order as _to_dict()/_fk_dict()

Return type:

list[SE3]

Pure with respect to q – computed directly via fkine_all() and each geometry’s fixed local offset (geom._T, spatialgeometry’s SceneNode), not via SceneNode._propogate_scene_tree()’s cached/mutated world transform. Intended for consumers (e.g. a Swift animation loop) that want link/geometry poses without needing a robot to carry live scene-graph state.

Gripper geometry is included, using each gripper’s own current .q (grippers keep their own separate joint state – not a parameter of this method, and not yet part of the pure-q computation this method provides for the main chain).

jacob0_dot(q, qd, J0=None, representation=None)[source]

Time derivative of manipulator Jacobian in frame {0}

Overloads:
Parameters:
  • q (Any) – The joint configuration of the robot. Must be provided if representation is specified; may be omitted if J0 is provided and representation is not.

  • qd (ndarray | Sequence[float]) – The joint velocity of the robot

  • J0 (Any) – Jacobian in {0} frame. Ignored if representation is specified; may be provided to save computation if representation is not specified.

  • representation (Optional[Literal['rpy/xyz', 'rpy/zyx', 'eul', 'exp']]) – Angular representation for analytical Jacobian (‘rpy/xyz’, ‘rpy/zyx’, ‘eul’, or ‘exp’)

Returns:

The time derivative of the manipulator Jacobian

Return type:

ndarray(6,n)

robot.jacob0_dot(q, qd) computes the rate of change of the manipulator Jacobian elements

\[\dmat{J} = \frac{d \mat{J}}{d \vec{q}} \frac{d \vec{q}}{dt}\]

where the first term is the rank-3 Hessian.

If J0 is already calculated for the joint coordinates q it can be passed in to save computation time.

For the geometric Jacobian (representation=None), it is computed analytically as the mode-3 product of the Hessian tensor and the joint velocity vector:

\[\dmat{J}_0 = \mathcal{H}_0 \times_3 \dot{\vec{q}}\]

The derivative of an analytical Jacobian can be obtained by setting representation as

representation

Rotational 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

When representation is specified, the Hessian of the analytical Jacobian is evaluated numerically using finite differences via spatialmath.base.numhess() and contracted with qd. This is an approximate, numerical calculation and is slower than the closed-form geometric Jacobian derivative.

Parameter interaction between representation, q, and J0

representation

q

J0

Behavior

Omitted / None

Provided

Omitted / None

Geometric Jacobian: computes \(\mat{J}_0\) and Hessian \(\mathcal{H}_0\) from q, then \(\dmat{J}_0 = \mathcal{H}_0 \times_3 \dot{\vec{q}}\).

Omitted / None

Omitted (or None)

Provided

Geometric Jacobian: reuses precomputed J0 to compute Hessian \(\mathcal{H}_0\), then \(\dmat{J}_0 = \mathcal{H}_0 \times_3 \dot{\vec{q}}\).

Specified (e.g. 'rpy/xyz')

Provided

Ignored

Analytical Jacobian: evaluates numerical Hessian via spatialmath.base.numhess() at q and contracts with qd.

Specified (e.g. 'rpy/xyz')

Omitted (or None)

Any

Raises ValueError (q is required to evaluate the analytical Jacobian).

References

  • Kinematic Derivatives using the Elementary Transform Sequence, J. Haviland and P. Corke

See also

jacob0(), hessian0

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> q = robot.qn
>>> qd = [0.1, -0.2, 0.3, -0.1, 0.2, -0.3]
>>> j0_dot = robot.jacob0_dot(q, qd)
>>> j0_dot.shape
(6, 6)
>>> (6, 6)
(6, 6)
>>> # If J0 is already computed, it can be passed in directly:
>>> J0 = robot.jacob0(q)
>>> j0_dot_fast = robot.jacob0_dot(None, qd, J0=J0)
>>> import numpy as np
>>> np.allclose(j0_dot, j0_dot_fast)
True
>>> True
True
jacobm(q=None, J=None, H=None, end=None, start=None, axes='all')[source]

The manipulability Jacobian

Overloads:
Parameters:
  • q (Any) – The joint angles/configuration of the robot (Optional, if not supplied will use the stored q values).

  • J (Any) – The manipulator Jacobian in any frame

  • H (Any) – The manipulator Hessian in any frame

  • end (str | Link | Gripper | None) – the final link or Gripper which the Hessian represents

  • start (str | Link | Gripper | None) – the first link which the Hessian represents

Returns:

The manipulability Jacobian

This measure relates the rate of change of the manipulability to the joint velocities of the robot. One of J or q is required. Supply J and H if already calculated to save computation time.

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=None, J=None, end=None, start=None, method='yoshikawa', axes='all', **kwargs)[source]

Manipulability measure

Overloads:
Parameters:
  • q (Any) – Joint coordinates, one of J or q required

  • J (Any) – Jacobian in base frame if already computed, one of J or q required

  • method (Literal['yoshikawa', 'asada', 'minsingular', 'invcondition']) – method to use, “yoshikawa” (default), “invcondition”, “minsingular” or “asada”

  • axes (Union[Literal['all', 'trans', 'rot'], list[bool]]) – Task space axes to consider: “all” [default], “trans”, or “rot”

Returns:

manipulability index

manipulability(q) is the scalar manipulability index for the robot at the joint configuration q. It indicates dexterity, that is, how well conditioned the robot is for motion with respect to the 6 degrees of Cartesian motion. The values is zero if the robot is at a singularity.

Various measures are supported:

  • "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]

  • "asada" – isotropy of the task-space acceleration ellipsoid which is a function of the Cartesian inertia matrix which depends on the inertial parameters [Asada83]

Trajectory operation:

If q is a matrix (m,n) then the result (m,) is a vector of manipulability indices for each joint configuration specified by a row of q.

Notes

  • Invokes the jacob0 method of the robot if J is not passed

  • The “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

  • Asada’s measure requires inertial a robot model with inertial

    parameters.

References

[Yoshikawa85]

Manipulability of Robotic Mechanisms. Yoshikawa T., The International Journal of Robotics Research. 1985;4(2):3-9. doi:10.1177/027836498500400201

[Asada83]

A geometrical representation of manipulator dynamics and its application to arm design, H. Asada, Journal of Dynamic Systems, Measurement, and Control, vol. 105, p. 131, 1983.

[Klein87] (1,2)

Dexterity Measures for the Design and Control of Kinematically Redundant Manipulators. Klein CA, Blaho BE. The International Journal of Robotics Research. 1987;6(2):72-83. doi:10.1177/027836498700600206

  • Robotics, Vision & Control, Chap 8, P. Corke, Springer 2011.

Changed in version 1.0.3: Removed ‘both’ option for axes, added a custom list option.

jtraj(q0, qf, t, qd0=None, qd1=None)[source]

Joint-space trajectory between two joint configurations

Parameters:
Raises:

TypeError – if q0 or qf is an SE3

Return type:

Any

Returns:

trajectory

traj = robot.jtraj(q0, qf, t) is a trajectory object whose attribute traj.q is a row-wise joint-space trajectory, a quintic polynomial in time from q0 to qf. It is the method form of jtraj().

Deprecated since version 1.5.0: Passing SE3 poses for q0 or qf is deprecated and now raises TypeError. The poses were converted to joint coordinates by inverse kinematics, which is never simple: which solution is chosen depends on the solver and its starting point, and it can fail. Do that explicitly, so you control and can check it::

q0 = robot.ikine_LM(T0, q0=robot.qr).q qf = robot.ikine_LM(Tf, q0=q0).q traj = robot.jtraj(q0, qf, t)

For a Cartesian trajectory see ctraj().

Changed in version 1.5.0: The arguments are joint coordinates only, they were named T1 and T2 and could be poses. The **kwargs that were passed to the inverse kinematics method are gone.

closest_point(q, shape, inf_dist=1.0, skip=False)[source]

Find the closest point between robot and shape

Parameters:
  • shape (Shape) – The shape to compare distance to

  • inf_dist (float) – The minimum distance within which to consider the shape

  • skip (bool) – Skip setting all shape transforms based on q, use this option if using this method in conjunction with Swift to save time

Return type:

tuple[float | None, ndarray | None, ndarray | None]

Returns:

tuple of (distance, point on robot, point on shape)

closest_point(shape, inf_dist) returns the minimum euclidean distance between this robot and shape, provided it is less than inf_dist. It will also return the points on self and shape in the world frame which connect the line of length distance between the shapes. If the distance is negative then the shapes are collided.

isselfcollided(q=None, skip=False)[source]

Check for collisions between non-adjacent links of this robot

Parameters:
  • q (ndarray | Sequence[float] | None) – joint configuration, defaults to the robot’s current q

  • skip (bool) – use the existing world transforms instead of updating them from q, defaults to False

Return type:

bool

Returns:

True if any non-adjacent link pair is in collision

Raises:

ValueError – the model has no collision geometry, or q is not a single finite joint configuration

Checks the collision geometry of the robot and all its grippers. Shapes attached to the same link, neighbouring links, and links in the same gripper are not tested against each other. Links without collision geometry are transparent when determining neighbours: a link’s nearest ancestor with collision geometry is its neighbour. Links in separate branches are tested, including siblings outside a shared gripper and links belonging to different grippers. Touching counts as a collision, as in iscollided().

Each gripper uses its own current joint configuration. The robot’s stored joint configuration is not changed. With skip=True, q is ignored and the caller must have updated all world transforms.

Collision checking requires the optional coal dependency. A model with only visual geometry cannot be checked; collision geometry must be supplied explicitly. Only pairs with geometry are checked, so a False result does not establish clearance for links without geometry.

Seealso:

iscollided() closest_point()

iscollided(q, shape, skip=False)[source]

Check if the robot is in collision with a shape

Parameters:
  • q (ndarray | Sequence[float] | None) – joint configuration, or None for the current configuration

  • shape (Shape | Robot) – the external shape to check, or this robot itself for self-collision checking

  • skip (bool) – Skip setting all shape transforms based on q, use this option if using this method in conjunction with Swift to save time

Return type:

bool

Returns:

True if shapes have collided

robot.iscollided(q, shape) checks for collision with an external shape. robot.iscollided(q, robot) calls isselfcollided().

Seealso:

isselfcollided() closest_point()

collided(q, shape, skip=False)[source]

Check if the robot is in collision with a shape (deprecated)

Parameters:
  • q (ndarray | Sequence[float] | None) – joint configuration, or None for the current configuration

  • shape (Shape | Robot) – the external shape to check, or this robot itself for self-collision checking

  • skip (bool) – Skip setting all shape transforms based on q, use this option if using this method in conjunction with Swift to save time

Return type:

bool

Returns:

True if shapes have collided

robot.collided(q, shape) issues a warning and returns the result of iscollided().

Seealso:

iscollided() isselfcollided()

joint_velocity_damper(q=None, ps=0.05, pi=0.1, n=None, gain=1.0)[source]

Compute the joint velocity damper for QP motion control

Parameters:
  • ps (float) – The minimum angle (in radians) in which the joint is allowed to approach to its limit

  • pi (float) – The influence angle (in radians) in which the velocity damper becomes active

  • n (int | None) – The number of joints to consider. Defaults to all joints

  • gain (float) – The gain for the velocity damper

Return type:

tuple[ndarray, ndarray]

Returns:

tuple of (Ain, Bin) inequality constraint matrices for an optimiser

Formulates an inequality constraint which, when optimised for will make it impossible for the robot to run into joint limits. Requires the joint limits of the robot to be specified. See examples/mmc.py for use case.

Compute a collision constrain for QP motion control

Parameters:
  • ds (float) – The minimum distance in which a joint is allowed to approach the collision object shape

  • di (float) – The influence distance in which the velocity damper becomes active

  • xi (float) – The gain for the velocity damper

  • end (Link | None) – The end link of the robot to consider

  • start (Link | None) – The start link of the robot to consider

  • collision_list (list[Shape] | None) – A list of shapes to consider for collision

Return type:

Any

Returns:

tuple of (Ain, Bin) inequality constraint matrices for an optimiser

Formulates an inequality constraint which, when optimised for will make it impossible for the robot to run into a collision. Requires See examples/neo.py for use case.

vision_collision_damper(shape, camera=None, camera_n=0, q=None, di=0.3, ds=0.05, xi=1.0, end=None, start=None, collision_list=None)[source]

Compute a vision collision constrain for QP motion control

Parameters:
  • camera (Robot | SE3 | None) – The camera link, either as a robotic link or SE3 pose

  • camera_n (int) – Degrees of freedom of the camera link

  • ds (float) – The minimum distance in which a joint is allowed to approach the collision object shape

  • di (float) – The influence distance in which the velocity damper becomes active

  • xi (float) – The gain for the velocity damper

  • end (str | Link | Gripper | None) – The end link of the robot to consider

  • start (str | Link | Gripper | None) – The start link of the robot to consider

  • collision_list (Any) – A list of shapes to consider for collision

Return type:

tuple[ndarray | None, ndarray | None]

Returns:

tuple of (Ain, Bin) inequality constraint matrices for an optimiser

Formulates an inequality constraint which, when optimised for will make it impossible for the robot to run into a line of sight. See examples/fetch_vision.py for use case.

rne(q, qd, qdd, symbolic=False, gravity=None)[source]

Compute inverse dynamics via recursive Newton-Euler formulation

Parameters:
  • q (ndarray) – Joint coordinates

  • qd (ndarray) – Joint velocity

  • qdd (ndarray) – Joint acceleration

  • symbolic (bool) – If True, supports symbolic expressions

  • gravity (ndarray | Sequence[float] | None) – gravitational acceleration in the world frame, downwards gravitational force is equivalent to robot base acceleration upwards (positive); defaults to attribute of self

Return type:

Any

Returns:

Joint force/torques

rne_dh(q, qd, qdd) where the arguments have shape (n,) where n is the number of robot joints. The result has shape (n,).

rne_dh(q, qd, qdd) where the arguments have shape (m,n) where n is the number of robot joints and where m is the number of steps in the joint trajectory. The result has shape (m,n).

rne_dh(p) where the input is a 1D array p = [q, qd, qdd] with shape (3n,), and the result has shape (n,).

rne_dh(p) where the input is a 2D array p = [q, qd, qdd] with shape (m,3n) and the result has shape (m,n).

Notes

  • This version supports symbolic model parameters

  • Verified against MATLAB code

Warning

Assumes each link’s joint is the last element of its own ETS segment (Featherstone’s spatial-vector convention – fixed geometry gets you to the joint, the joint is the last thing applied before the next link’s frame). This is guaranteed for any Robot/ERobot built normally, either from a raw ETS (Robot.__init__ splits it via ETS.split(), whose default “last” method enforces this per segment), from a URDF (each link’s ETS is built fixed-transform-then-joint, in that order), or from a PoERobot (_update_ets() appends the joint ET last too). It does not hold for a DHRobot using standard DH conventions (mdh=False), where the joint comes first, followed by d/a/alpha – calling Robot.rne(dh_instance, ...) directly (bypassing DHRobot’s own correct rne()/rne_python()) gives silently wrong answers. A DHRobot built with mdh=True is joint-last (DHLink._to_ets()’s MDH branch reorders a revolute link’s d translation to precede the joint rotation – valid since a z-rotation and a z-translation commute – so the joint ET is always last regardless of d) and works correctly through this path. See rne.md. Revisit this guard if the Robot/Link class hierarchy is ever redesigned – see https://github.com/petercorke/robotics-toolbox-python/issues/571.

property T: ndarray

Pose of the shape relative to its parent frame in the scene graph (or the world frame if it has no parent), as a 4x4 homogeneous transformation matrix. Set via the pose argument of the constructor.

This is a read/write property. The getter always returns a plain ndarray; the setter also accepts an SE3.

Warning

Because the getter returns an ndarray, in-place operators like shape.T *= delta do an elementwise multiply, not a pose composition, even when delta is an SE3 – use shape.T = shape.T * delta (or shape.T @= delta.A) instead.

Return type:

ndarray(4,4)

Setter accepts:

ndarray | SE3

__getitem__(i)

Get link

This also supports iterating over each link in the robot object, from the base to the tool.

Parameters:

i (int | str) – link number or name

Return type:

Link

Returns:

i’th link or named link

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> print(robot[1]) # print the 2nd link
RevoluteDH:   θ=q,  d=0,  a=0.4318,  ⍺=0.0
>>> print([link.a for link in robot])  # print all the a_j values
[0, 0.4318, 0.0203, 0, 0, 0]

Notes

Robot supports link lookup by name,

eg. robot['link1']

__str__()

Pretty prints the ETS Model of the robot.

Return type:

str

Returns:

Pretty print of the robot model

Notes

  • Constant links are shown in blue.

  • End-effector links are prefixed with an @

  • Angles in degrees

  • The robot base frame is denoted as BASE and is equal to the

    robot’s base attribute.

accel(q, qd, torque, gravity=None)

Compute acceleration due to applied torque

Parameters:
  • q (Any) – Joint coordinates

  • qd (Any) – Joint velocity

  • torque (Any) – Joint torques of the robot

  • gravity (Any) – gravitational acceleration in the world frame, downwards gravitational force is equivalent to robot base acceleration upwards (positive); if not supplied, uses the gravity attribute of self

Returns:

Joint accelerations

Return type:

Any

qdd = accel(q, qd, torque) calculates a vector (n) of joint accelerations that result from applying the actuator force/torque (n) to the manipulator in state q (n) and qd (n), and n is the number of robot joints.

\[\ddot{q} = \mathbf{M}^{-1} \left(\tau - \mathbf{C}(q)\dot{q} - \mathbf{g}(q)\right)\]

Trajectory operation

If q, qd, torque are matrices (m,n) then qdd is a matrix (m,n) where each row is the acceleration corresponding to the equivalent rows of q, qd, torque.

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.accel(puma.qz, 0.5 * np.ones(6), np.zeros(6))
array([ -7.5544, -12.22  ,  -6.4022,  -5.4303,  -4.9518,  -2.1178])

Notes

  • Useful for simulation of manipulator dynamics, in

    conjunction with a numerical integration function.

  • Uses the method 1 of Walker and Orin to compute the forward

    dynamics.

  • Featherstone’s method is more efficient for robots with large

    numbers of joints.

  • Joint friction is considered.

References

  • Efficient dynamic computer simulation of robotic mechanisms,

    M. W. Walker and D. E. Orin, ASME Journal of Dynamic Systems, Measurement and Control, vol. 104, no. 3, pp. 205-211, 1982.

accel_x(q, xd, wrench, gravity=None, pinv=False, representation='rpy/xyz')

Operational space acceleration due to applied wrench

Parameters:
  • q (Any) – Joint coordinates

  • xd (Any) – Operational space velocity of the end-effector

  • wrench (Any) – Wrench applied to the end-effector

  • gravity (Any) – gravitational acceleration in the world frame, downwards gravitational force is equivalent to robot base acceleration upwards (positive); if not supplied, uses the gravity attribute of self

  • pinv (bool) – use pseudo inverse rather than inverse

  • representation (Literal['rpy/xyz', 'rpy/zyx', 'eul', 'exp']) – the type of analytical Jacobian to use, default is 'rpy/xyz'

Returns:

Operational space accelerations of the end-effector

Return type:

Any

xdd = accel_x(q, xd, wrench) is the operational space acceleration due to wrench applied to the end-effector of a robot in joint configuration q and operational space velocity xd.

\[\ddot{x} = \dot{\mathbf{J}}_a(q, \dot{q})\dot{q} + \mathbf{J}_a(q) \mathbf{M}(q)^{-1} \left( \mathbf{J}_a(q)^T w - \mathbf{C}(q)\dot{q} - \mathbf{g}(q) \right)\]

Trajectory operation

If q is a matrix (m,n), and xd and wrench are matrices (m,6), then xdd is a matrix (m,6) where each row is the acceleration corresponding to the equivalent rows of q, xd, and wrench.

Notes

  • Useful for simulation of manipulator dynamics, in

    conjunction with a numerical integration function.

  • Uses the method 1 of Walker and Orin to compute the forward

    dynamics.

  • Featherstone’s method is more efficient for robots with large

    numbers of joints.

  • Joint friction is considered.

See also

accel()

addconfiguration(name, q)

Add a named joint configuration

Add a named configuration to the robot instance’s dictionary of named configurations.

Parameters:
Return type:

None

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> robot.addconfiguration_attr("mypos", [0.1, 0.2, 0.3, 0.4, 0.5, 0.6])
>>> robot.configs["mypos"]
array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6])
addconfiguration_attr(name, q, unit='rad')

Add a named joint configuration as an attribute

Parameters:
Return type:

None

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> robot.addconfiguration_attr("mypos", [0.1, 0.2, 0.3, 0.4, 0.5, 0.6])
>>> robot.mypos
array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6])
>>> robot.configs["mypos"]
array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6])

Notes

  • Used in robot model init method to store the qr configuration

  • Dynamically adding attributes to objects can cause issues with

    Python type checking.

  • Configuration is also added to the robot instance’s dictionary of

    named configurations.

attach(object)

Attach a child node

Parameters:

object (SceneNode) – the node to attach as a child of this node

Seealso:

attach_to() scene_children()

Return type:

None

attach_to(object)

Attach this node to a parent node

Parameters:

object (SceneNode) – the node to attach this node to, this node will become a child of the parent

Seealso:

attach() scene_parent()

Return type:

None

property base: SE3

Get/set robot base transform

  • robot.base is the robot base transform

  • robot.base = ... checks and sets the robot base transform

Parameters:

base – the new robot base transform

Returns:

the current robot base transform

Setter accepts:

ndarray | SE3

Get the robot base link

  • robot.base_link is the robot base link

Returns:

the first link in the robot tree

cinertia(q)

Deprecated, use inertia_x

Return type:

None

property comment: str

Get/set robot comment

  • robot.comment is the robot comment

  • robot.comment = ... checks and sets the robot comment

Parameters:

name – the new robot comment

Returns:

robot comment

property configs: dict[str, ndarray]

Named joint configurations

Returns:

dictionary of joint configurations, such as qr and qz, indexed by name

configurations_str(border='thin')
Return type:

Any

property control_mode: str

Get/set robot control mode

  • robot.control_type is the robot control mode

  • robot.control_type = ... checks and sets the robot control mode

Parameters:

control_mode – the new robot control mode

Returns:

the current robot control mode

copy()

Make a copy of the robot

Return type:

Any

Returns:

a deep copy, which shares no state with the original

coriolis(q, qd)

Coriolis and centripetal term

Parameters:
  • q (Any) – Joint coordinates

  • qd (Any) – Joint velocity

Returns:

Coriolis/centripetal velocity matrix

Return type:

Any

coriolis(q, qd) calculates the Coriolis/centripetal matrix (n,n) for the robot in configuration q and velocity qd, where n is the number of joints.

The product \(\mathbf{C} \dot{q}\) is the vector of joint force/torque due to velocity coupling. The diagonal elements are due to centripetal effects and the off-diagonal elements are due to Coriolis effects. This matrix is also known as the velocity coupling matrix, since it describes the disturbance forces on any joint due to velocity of all other joints.

Trajectory operation

If q and qd are matrices (m,n), each row is interpreted as a joint configuration, and the result (n,n,m) is a 3d-matrix where each plane corresponds to a row of q and qd.

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.coriolis(puma.qz, 0.5 * np.ones((6,)))
array([[-0.4017, -0.5513, -0.2025, -0.0007, -0.0013,  0.    ],
       [ 0.2023, -0.1937, -0.3868, -0.    , -0.002 ,  0.    ],
       [ 0.1987,  0.193 , -0.    ,  0.    , -0.0001,  0.    ],
       [ 0.    ,  0.    ,  0.    ,  0.    ,  0.    ,  0.    ],
       [ 0.0007,  0.0007,  0.0001,  0.    ,  0.    ,  0.    ],
       [ 0.    ,  0.    ,  0.    ,  0.    ,  0.    ,  0.    ]])

Notes

  • Joint viscous friction is also a joint force proportional to

    velocity but it is eliminated in the computation of this value.

  • Computationally slow, involves \(n^2/2\) invocations of RNE.

coriolis_x(q, qd, pinv=False, representation='rpy/xyz', J=None, Ji=None, Jd=None, C=None, Mx=None)

Operational space Coriolis and centripetal term

Parameters:
  • q (Any) – Joint coordinates

  • qd (Any) – Joint velocity

  • pinv (bool) – use pseudo inverse rather than inverse (Default value = False)

  • representation (Literal['rpy/xyz', 'rpy/zyx', 'eul', 'exp']) – the type of analytical Jacobian to use, default is 'rpy/xyz'

  • J (Any) – pre-computed analytical Jacobian (optional)

  • Ji (Any) – pre-computed inverse analytical Jacobian (optional)

  • Jd (Any) – pre-computed time-derivative of analytical Jacobian (optional)

  • C (Any) – pre-computed joint-space Coriolis matrix (optional)

  • Mx (Any) – pre-computed operational-space inertia matrix (optional)

Returns:

Operational space velocity matrix

Return type:

Any

coriolis_x(q, qd) is the Coriolis/centripetal matrix (m,m) in operational space for the robot in configuration q and velocity qd, where n is the number of joints.

\[\mathbf{C}_x = \mathbf{J}(q)^{-T} \mathbf{C}(q, \dot{q}) \mathbf{J}(q)^{-1} - \mathbf{M}_x(q) \dot{\mathbf{J}}(q, \dot{q}) \mathbf{J}(q)^{-1}\]

The product \(\mathbf{C} \dot{x}\) is the operational space wrench due to joint velocity coupling. This matrix is also known as the velocity coupling matrix, since it describes the disturbance forces on any joint due to velocity of all other joints.

The transformation to operational space requires an analytical, rather than geometric, Jacobian. analytical can be one of:

Value

Rotational representation

'rpy/xyz'

RPY angular rates in XYZ order (default)

'rpy/zyx'

RPY angular rates in XYZ order

'eul'

Euler angular rates in ZYZ order

'exp'

exponential coordinate rates

Trajectory operation

If q and qd are matrices (m,n), each row is interpreted as a joint configuration, and the result is an array (m,6,6) where each matrix corresponds to a row of q and qd.

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.coriolis_x(puma.qn, 0.5 * np.ones((6,)))
array([[     12.3365,       4.6387,      13.7633,      -0.0409,
              0.0043,      -0.0409],
       [     -4.788 ,  -31430.2949,      -3.4675,       0.3301,
             -0.3188,       0.3301],
       [    -11.5011,      -1.7324,     -10.0545,      -0.0405,
              0.    ,      -0.0405],
       [     -0.0165, 4869725.6671,      -0.0165,      -0.1245,
              0.0278,      -0.1245],
       [     -0.1112,       0.0531,       0.1332,      -0.0251,
             -0.    ,      -0.0251],
       [     -0.0165, 4869725.6671,      -0.0165,      -0.1245,
              0.0278,      -0.1245]])

Notes

  • Joint viscous friction is also a joint force proportional to

    velocity but it is eliminated in the computation of this value.

  • Computationally slow, involves \(n^2/2\) invocations of RNE.

  • If the robot is not 6 DOF the pinv option is set True.

  • pinv() is around 5x slower than inv()

Warning

Assumes that the operational space has 6 DOF.

property default_backend: Any

Get default graphical backend

  • robot.default_backend Get the default graphical backend, used when

    no explicit backend is passed to Robot.plot. This is the value set for the robot, otherwise the value set for all robots by set_default_backend(), otherwise None.

  • robot.default_backend = ... Set the default graphical backend, used when

    no explicit backend is passed to Robot.plot. The default set here will be overridden if the particular Robot subclass cannot support it.

Returns:

backend name

A link search method

Visit all links from start in depth-first order and will apply func to each visited link

Parameters:
Return type:

list[Link]

Returns:

A list of links

dotfile(filename, etsbox=False, ets='full', jtype=False, static=True)

Write a link transform graph as a GraphViz dot file

The file can be processed using dot:

% dot -Tpng -o out.png dotfile.dot

The nodes are:

  • Base is shown as a grey square. This is the world frame origin, but can be changed using the base attribute of the robot.

  • Link frames are indicated by circles

  • ETS transforms are indicated by rounded boxes

The edges are:

  • an arrow if jtype is False or the joint is fixed

  • an arrow with a round head if jtype is True and the joint is revolute

  • an arrow with a box head if jtype is True and the joint is prismatic

Edge labels or nodes in blue have a fixed transformation to the preceding link.

Notes

If filename is a file object then the file will not be closed after the GraphViz model is written.

Parameters:
  • file – Name of file to write to

  • etsbox (bool) – Put the link ETS in a box, otherwise an edge label

  • ets (Literal['full', 'brief']) – Display the full ets with “full” or a brief version with “brief”

  • jtype (bool) – Arrowhead to node indicates revolute or prismatic type

  • static (bool) – Show static joints in blue and bold

Return type:

None

See also

showgraph() graph()

dynamics()

Pretty print the dynamic parameters

The dynamic parameters (inertial and friction) are printed in a table, with one row per link.

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> robot.dynamics()
┌───────┬───────┬─────────────────────────┬────────────────────────────────────────┬──────────┬───────────┬───────────────────┬───────┐
│   j   │   m   │            r            │                   I                    │    Jm    │     B     │        Tc         │   G   │
├───────┼───────┼─────────────────────────┼────────────────────────────────────────┼──────────┼───────────┼───────────────────┼───────┤
│ link1 │  0    │  0,  0,  0              │  0,  0.35,  0,  0,  0,  0              │  0.0002  │  0.00148  │  0.395, -0.435    │ -62.6 │
│ link2 │  17.4 │ -0.364,  0.006,  0.228  │  0.13,  0.524,  0.539,  0,  0,  0      │  0.0002  │  0.000817 │  0.126, -0.071    │  108  │
│ link3 │  4.8  │ -0.0203, -0.0141,  0.07 │  0.066,  0.086,  0.0125,  0,  0,  0    │  0.0002  │  0.00138  │  0.132, -0.105    │ -53.7 │
│ link4 │  0.82 │  0,  0.019,  0          │  0.0018,  0.0013,  0.0018,  0,  0,  0  │  3.3e-05 │  7.12e-05 │  0.0112, -0.0169  │  76   │
│ link5 │  0.34 │  0,  0,  0              │  0.0003,  0.0004,  0.0003,  0,  0,  0  │  3.3e-05 │  8.26e-05 │  0.00926, -0.0145 │  71.9 │
│ link6 │  0.09 │  0,  0,  0.032          │  0.00015,  0.00015,  4e-05,  0,  0,  0 │  3.3e-05 │  3.67e-05 │  0.00396, -0.0105 │  76.7 │
└───────┴───────┴─────────────────────────┴────────────────────────────────────────┴──────────┴───────────┴───────────────────┴───────┘
Return type:

None

dynamics_list()

Print dynamic parameters

Display the kinematic and dynamic parameters to the console in reable format

Return type:

None

dynchanged(what=None)

Dynamic parameters have changed

Called from a property setter to inform the robot that the cache of dynamic parameters is invalid.

See also

roboticstoolbox.Link._dirties_frne()

Return type:

None

ets(start=None, end=None)

Robot to ETS

robot.ets() is an ETS representing the kinematics from base to end-effector.

robot.ets(end=link) is an ETS representing the kinematics from base to the link link specified as a Link reference or a name.

robot.ets(start=l1, end=l2) is an ETS representing the kinematics from link l1 to link l2.

Parameters:
  • start (:param) – start of path, defaults to base_link:

  • end (:param) – end of path, defaults to end-effector:

Raises:
Return type:

ETS

Returns:

elementary transform sequence

Examples

>>> import roboticstoolbox as rtb
>>> panda = rtb.models.ETS.Panda()
>>> panda.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)]
fdyn(T, q0, Q=None, Q_args=None, qd0=None, solver='RK45', solver_args=None, dt=None, progress=False)

Integrate forward dynamics

Parameters:
  • T (float) – integration time

  • q0 (ndarray | Sequence[float]) – initial joint coordinates

  • Q (Callable[[Any, float, ndarray, ndarray], ndarray] | None) – a function that computes generalized joint force as a function of time and/or state

  • Q_args (dict | None) – positional arguments passed to torque

  • qd0 (ndarray | Sequence[float] | None) – initial joint velocities, assumed zero if not given

  • solver (str) – name of SciPy integrator to use, default 'RK45'

  • solver_args (dict | None) – optional arguments passed to the SciPy integrator

  • dt (float | None) – if given, interpolate the results to this timestep

  • progress (bool) – show progress bar, default False

Returns:

robot trajectory

Return type:

Any

tg = R.fdyn(T, q) integrates the dynamics of the robot with zero input torques over the time interval 0 to T and returns the trajectory as a namedtuple with elements:

  • t the time vector (M,)

  • q the joint coordinates (M,n)

  • qd the joint velocities (M,n)

tg = R.fdyn(T, q, torqfun) as above but the torque applied to the joints is given by the provided function:

tau = function(robot, t, q, qd, **args)

where the inputs are:

  • the robot object

  • current time

  • current joint coordinates (n,)

  • current joint velocity (n,)

  • args, optional keyword arguments can be specified, these are passed in from the targs keyword argument.

The function must return a Numpy array (n,) of joint forces/torques.

Examples

To apply zero joint torque to the robot without Coulomb friction:

>>> def myfunc(robot, t, q, qd):
>>>     return np.zeros((robot.n,))
>>> tg = robot.nofriction().fdyn(5, q0, myfunc)
>>> plt.figure()
>>> plt.plot(tg.t, tg.q)
>>> plt.show()

We could also use a lambda function:

>>> tg = robot.nofriction().fdyn(
>>>     5, q0, lambda r, t, q, qd: np.zeros((r.n,)))

The robot is controlled by a PD controller. We first define a function to compute the control which has additional parameters for the setpoint and control gains (qstar, P, D):

>>> def myfunc(robot, t, q, qd, qstar, P, D):
>>>     return (qstar - q) * P + qd * D  # P, D are (6,)
>>> tg = robot.fdyn(10, q0, myfunc, torque_args=(qstar, P, D))

Many integrators have variable step length which is problematic if we want to animate the result. If dt is specified then the solver results are interpolated in time steps of dt.

Notes

  • This function performs poorly with non-linear joint friction,

    such as Coulomb friction. The R.nofriction() method can be used to set this friction to zero.

  • If the function is not specified then zero force/torque is

    applied to the manipulator joints.

  • Interpolation is performed using SciPy integrate.ode

  • The SciPy RK45 integrator is used by default

  • Interpolation is performed using SciPy interp1d

fellipse(q, opt='trans', unit='rad', centre='ee', add=True)

Create a force ellipsoid object for plotting with PyPlot.

Parameters:
  • q (ndarray | Sequence[float]) – the joint configuration of the robot

  • opt (Literal['trans', 'rot']) – 'trans' or 'rot' — plot the translational or rotational force ellipsoid

  • unit (Literal['rad', 'deg']) – 'rad' or 'deg'

  • centre (Union[Literal['ee'], ndarray, Sequence[float]]) – centre of the ellipsoid — 'ee' for the end-effector or a 3-vector [x, y, z] in the world frame

  • add (bool) – if True, add the ellipsoid to the active plot environment

Returns:

an EllipsePlot object

Return type:

EllipsePlot

robot.fellipse(q) creates a force ellipsoid for the robot at pose q. By default the ellipsoid is centered at the end-effector.

Notes

  • By default the ellipsoid related to translational motion is drawn. Use opt='rot' to draw the rotational velocity ellipsoid.

  • By default the ellipsoid is drawn at the end-effector. The option centre allows its origin to be set to the specified 3-vector, or the string "ee" ensures it is drawn at the end-effector position.

fkine(q, end=None, start=None, tool=None, include_base=True)

Forward kinematics

Parameters:
  • q (ndarray | Sequence[float]) – Joint coordinates – either global (length robot.n, addressed by each joint’s jindex, e.g. the whole robot’s current q) or, when end/start select just one branch of a branched robot, compact (length equal to the number of joints on that branch, positionally ordered from start to end – exactly what ikine_LM/ik_LM etc. return when solving for that same end)

  • end (str | Link | Gripper | None) – end-effector or gripper to compute forward kinematics to

  • start (str | Link | Gripper | None) – the link to compute forward kinematics from

  • tool (ndarray | SE3 | None) – tool transform, optional

Raises:

ValueError – if q’s length matches neither the compact nor the global interpretation for the selected start/end

Return type:

SE3

Returns:

The transformation matrix representing the pose of the end-effector

T = robot.fkine(q) evaluates forward kinematics for the robot at joint configuration q.

Trajectory operation: If q has multiple rows (mxn), it is considered a trajectory and the result is an SE3 instance with m values.

Examples

The following example makes a panda robot object, and solves for the forward kinematics at the listed configuration.

>>> import roboticstoolbox as rtb
>>> panda = rtb.models.Panda()
>>> 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.    ]]))

On a branched robot, end selects one branch, and q may be either the whole robot’s global q or just the solution for that branch on its own – both give the same result:

>>> import roboticstoolbox as rtb
>>> from spatialmath import SE3
>>> yumi = rtb.models.YuMi()
>>> sol = yumi.ikine_LM(SE3(0.4, 0.2, 0.3) * SE3.Rx(0.2), end="l_gripper", method="chan", k=0.1, seed=0)
>>> sol.q.shape
(7,)
>>> yumi.fkine(sol.q, end="l_gripper")
SE3(array([[ 1.    , -0.    ,  0.    ,  0.4   ],
           [ 0.    ,  0.9801, -0.1987,  0.2   ],
           [-0.    ,  0.1987,  0.9801,  0.3   ],
           [ 0.    ,  0.    ,  0.    ,  1.    ]]))

Notes

  • For a robot with a single end-effector there is no need to

    specify end

  • For a robot with multiple end-effectors, the end must

    be specified.

  • The robot’s own base transform (self.base), if set, is

    always incorporated into the result.

  • The robot’s own tool transform (self.tool), if set, is

    incorporated into the result unless the tool parameter is given explicitly, which overrides it.

  • 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).

  • J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part II: Acceleration and Advanced Applications.” arXiv preprint arXiv:2207.01794 (2022).

friction(qd)

Manipulator joint friction

Parameters:

qd (ndarray) – The joint velocities of the robot

Returns:

The joint friction forces/torques for the robot

Return type:

ndarray

robot.friction(qd) is a vector of joint friction forces/torques for the robot moving with joint velocities qd.

The friction model includes:

  • Viscous friction which is a linear function of velocity.

  • Coulomb friction which is proportional to sign(qd).

\[\begin{split}\tau_j = G^2 B \dot{q}_j + |G_j| \left\{ \begin{array}{ll} \tau_{C,j}^+ & \mbox{if $\dot{q}_j > 0$} \\ \tau_{C,j}^- & \mbox{if $\dot{q}_j < 0$} \end{array} \right.\end{split}\]

Notes

  • The friction value should be added to the motor output torque to

    determine the nett torque. It has a negative value when qd > 0.

  • The returned friction value is referred to the output of the

    gearbox.

  • The friction parameters in the Link object are referred to the

    motor.

  • Motor viscous friction is scaled up by \(G^2\).

  • Motor Coulomb friction is scaled up by \(G\).

  • The appropriate Coulomb friction value to use in the

    non-symmetric case depends on the sign of the joint velocity, not the motor velocity.

  • Coulomb friction is zero for zero joint velocity, stiction is

    not modeled.

  • The absolute value of the gear ratio is used. Negative gear

    ratios are tricky: the Puma560 robot has negative gear ratio for joints 1 and 3.

get_path(end=None, start=None)

Find a path from start to end

Parameters:
  • end (Union[Gripper, Link, str, None]) – end-effector or gripper to compute forward kinematics to

  • start (Union[Gripper, Link, str, None]) – name or reference to a base link, defaults to None

Raises:

ValueError – link not known or ambiguous

Return type:

tuple[list[Link], int, SE3]

Returns:

the path from start to end

Returns:

the number of joints in the path

Returns:

the tool transform present after end

graph(format='dot', filename=None, **kwargs)

Render a link transform graph as text

Parameters:
  • format (Literal['dot', 'mermaid', 'mermaid_fenced']) – graph output format: "dot", "mermaid" or "mermaid_fenced", defaults to "dot"

  • filename (Union[str, IO[str], None]) – destination path or open text stream, defaults to None

  • kwargs (Any) – for format="dot", forwarded to dotfile() (etsbox, ets, jtype, static); ignored otherwise

Return type:

str

Returns:

rendered graph text

Creates graph text representing the robot’s link transform graph – the same structure dotfile()/showgraph() render, in a choice of formats. If filename is provided, the rendered text is also written to it.

"dot" produces the same GraphViz output as dotfile(), just returned as a string rather than requiring a real file – etsbox/ets/jtype/static behave exactly as they do there.

"mermaid"/"mermaid_fenced" render a simplified Mermaid flowchart: one node per link (a double circle for end-effectors, a hexagon for gripper links), edges labelled with the joint type (R/P) and joint index for actuated joints. Mermaid has no equivalent of DOT’s per-edge arrowhead/colour styling, so jtype/static/etsbox only affect "dot" output. "mermaid_fenced" wraps the same text in a fenced mermaid code block, ready to paste into Markdown or render directly in a Jupyter cell:

from IPython.display import Markdown, display
display(Markdown(robot.graph(format="mermaid_fenced")))
property gravity: ndarray

Get/set default gravitational acceleration

  • robot.gravity is the default gravitational acceleration

  • robot.gravity = ... checks and sets default gravitational

    acceleration

Parameters:

gravity – gravitational acceleration in the world frame, downwards gravitational force is equivalent to robot base acceleration upwards (positive)

Returns:

gravitational acceleration

Setter accepts:

ndarray | Sequence[float]

gravload(q=None, gravity=None)

Compute gravity load

Parameters:
  • q (ndarray | Sequence[float] | None) – Joint coordinates

  • gravity (ndarray | Sequence[float] | None) – gravitational acceleration in the world frame, downwards gravitational force is equivalent to robot base acceleration upwards (positive); if not supplied, uses the stored gravity values

Returns:

The generalised joint force/torques due to gravity

Return type:

Any

robot.gravload(q) calculates the joint gravity loading (n) for the robot in the joint configuration q and using the default gravitational acceleration specified in the DHRobot object.

robot.gravload(q, gravity=g) as above except the gravitational acceleration is explicitly specified as g.

The return value is referenced to the load, not the motor, the gear ratio is not taken into account.

Trajectory operation

If q is a matrix (nxm) each column is interpreted as a joint configuration vector, and the result is a matrix (nxm) each column being the corresponding joint torques.

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.gravload(puma.qz)
array([ 0.    , 37.4837,  0.2489,  0.    ,  0.    ,  0.    ])
gravload_x(q=None, gravity=None, pinv=False, representation='rpy/xyz', Ji=None)

Operational space gravity load

Parameters:
  • q (Any) – Joint coordinates

  • gravity (Any) – gravitational acceleration in the world frame, downwards gravitational force is equivalent to robot base acceleration upwards (positive); if not supplied, uses the gravity attribute of self

  • pinv (bool) – use pseudo inverse rather than inverse (Default value = False)

  • representation (Literal['rpy/xyz', 'rpy/zyx', 'eul', 'exp']) – the type of analytical Jacobian to use, default is 'rpy/xyz'

  • Ji (Any) – pre-computed inverse analytical Jacobian (optional)

Returns:

The operational space gravity wrench

Return type:

Any

robot.gravload_x(q) calculates the gravity wrench for the robot in the joint configuration q and using the default gravitational acceleration specified in the robot object.

robot.gravload_x(q, gravity=g) as above except the gravitational acceleration is explicitly specified as g.

\[\mathbf{G}_x = \mathbf{J}(q)^{-T} \mathbf{G}(q)\]

The transformation to operational space requires an analytical, rather than geometric, Jacobian. analytical can be one of:

Value

Rotational representation

'rpy/xyz'

RPY angular rates in XYZ order (default)

'rpy/zyx'

RPY angular rates in XYZ order

'eul'

Euler angular rates in ZYZ order

'exp'

exponential coordinate rates

Trajectory operation

If q is a matrix (m,n), each row is interpreted as a joint configuration vector, and the result is a matrix (m,6) with one gravity wrench per row.

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.gravload_x(puma.qn)
array([-30.1218,   7.5797,  53.7378,  -0.    ,  -0.0283,  -0.    ])

Notes

  • If the robot is not 6 DOF the pinv option is set True.

  • pinv() is around 5x slower than inv()

Warning

Assumes that the operational space has 6 DOF.

See also

gravload()

property grippers: list[Gripper]

Grippers attached to the robot

Returns:

A list of grippers

property hascollision: Any

Robot has collision model

Returns:

Robot has collision model

Returns:

At least one link has associated collision model.

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> robot.hascollision
False

See also

hasgeometry()

property hasdynamics: bool

Robot has dynamic parameters

Returns:

True if at least one link has a non-zero mass or motor inertia

These are the parameters that the inertial dynamics need. It is false for a model of the kinematics only, such as the default rtb.models.Panda, and the dynamics methods gravload, inertia, coriolis, accel, fdyn, itorque and rne raise ValueError for such a model, rather than return zeros or a confusing error. It is any link and not all, since the first link of the DH Puma560 has a mass of zero.

The answer is cached, and recomputed only when the mass or motor inertia of a link has been changed, so it costs nothing to ask.

Changed in version 1.5.0: This was true if any dynamic parameter had been assigned, even to zero, and was not reset when the parameters were set back to zero. A robot made from DH links with no masses reported True. The dynamics methods now raise ValueError if it is False, where they returned zeros or raised LinAlgError.

Warning

Behaviour change. Scripts that call the dynamics methods on a kinematics-only model, and accept the zeros, now get a ValueError.

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> robot.hasdynamics
True
property hasgeometry: Any

Robot has geometry model

At least one link has associated mesh to describe its shape.

Returns:

Robot has geometry model

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> robot.hasgeometry
True

See also

hascollision()

hessian0(q=None, end=None, start=None, J0=None, tool=None)

Manipulator Hessian in the start frame

Overloads:
Parameters:
  • q (Any) – The joint angles/configuration of the robot (Optional, if not supplied will use the stored q values).

  • end (str | Link | Gripper | None) – the final link/Gripper which the Hessian represents

  • start (str | Link | Gripper | None) – the first link which the Hessian represents

  • J0 (Any) – The manipulator Jacobian in the start frame

  • tool (ndarray | SE3 | None) – a static tool transformation matrix to apply to the end of end, defaults to None

Returns:

The manipulator Hessian in the start frame

The manipulator Hessian tensor maps joint acceleration to end-effector spatial acceleration, expressed in the start frame. This function calulcates this based on the ETS of the robot. One of J0 or q is required. Supply J0 if already calculated to save computation time

This method computes the manipulator Hessian in the start 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 Panda robot object, and solves for the base frame Hessian at the given joint angle configuration

>>> import roboticstoolbox as rtb
>>> panda = rtb.models.Panda()
>>> 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, end=None, start=None, Je=None, tool=None)

Manipulator Hessian in the end-effector frame

Overloads:
Parameters:
  • q (Any) – The joint angles/configuration of the robot (Optional, if not supplied will use the stored q values).

  • end (str | Link | Gripper | None) – the final link/Gripper which the Hessian represents

  • start (str | Link | Gripper | None) – the first link which the Hessian represents

  • Je (Any) – The manipulator Jacobian in the end frame

  • tool (ndarray | SE3 | None) – a static tool transformation matrix to apply to the end of end, defaults to None

Returns:

The manipulator Hessian in end frame

The manipulator Hessian tensor maps joint acceleration to end-effector spatial acceleration, expressed in the end coordinate frame. This function calulcates this based on the ETS of the robot. One of J0 or q is required. Supply J0 if already calculated to save computation time

This method computes the manipulator Hessian in the end 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 Panda robot object, and solves for the end-effector frame Hessian at the given joint angle configuration

>>> import roboticstoolbox as rtb
>>> panda = rtb.models.Panda()
>>> 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).

hierarchy()

Pretty print the robot link hierarchy

Return type:

None

Returns:

Pretty print of the robot model

Examples

Makes a robot and prints the hierarchy

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.URDF.Panda()
>>> robot.hierarchy()
 panda_link0
   panda_link1
     panda_link2
       panda_link3
         panda_link4
           panda_link5
             panda_link6
               panda_link7
                 panda_link8
                   panda_hand
                     panda_leftfinger
                     panda_rightfinger
ik_GN(Tep, end=None, start=None, q0=None, ilimit=30, slimit=100, tol=1e-06, mask=None, joint_limits=True, pinv=True, pinv_damping=0.0, tool=None)

Fast numerical inverse kinematics by Gauss-Newton optimization

Parameters:
  • Tep (ndarray | SE3) – The desired end-effector pose (a single pose only, for a trajectory use ikine_GN())

  • end (str | Link | Gripper | None) – the link considered as the end-effector

  • start (str | Link | Gripper | None) – the link considered as the base frame, defaults to the robots’s base frame

  • q0 (ndarray | None) – initial joint configuration (default to random valid joint configuration constrained by the joint limits of the robot)

  • ilimit (int) – maximum number of iterations per search

  • slimit (int) – maximum number of search attempts

  • tol (float) – final error tolerance

  • mask (ndarray | None) – a mask vector which weights the end-effector error priority. Corresponds to translation in X, Y and Z and rotation about X, Y and Z respectively

  • joint_limits (bool) – constrain the solution to being within the joint limits of the robot (reject solution with invalid joint configurations and perform another search up to the slimit)

  • pinv (int) – Use the pseudo-inverse instead of the normal matrix inverse

  • pinv_damping (float) – Damping factor for the pseudo-inverse

  • tool (ndarray | SE3 | None) – a static tool transformation matrix to apply to the end of end; defaults to the robot’s own self.tool if not given

Returns:

an IKSolution containing joint coordinates q, success flag, iterations, searches and residual error value (reason is always empty – this fast C++ solver doesn’t produce a granular failure reason string, unlike ikine_GN())

Return type:

IKSolution

Warning

This method needs the compiled C++ extension. It raises RuntimeError if the extension is unavailable, for example in a pure-Python wheel or under Pyodide/JupyterLite, and if the sequence has a SymPy parameter, even a numeric one such as sympy.pi/2, or a joint with an offset, which the compiled code cannot use. In all of these cases use ikine_GN(), which has none of these limits.

sol = ets.ik_GN(Tep) are the joint coordinates (n) corresponding to the robot end-effector pose Tep which is an SE3 or ndarray object. 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.

Note

When using this method with redundant robots (>6 DoF), pinv must be set to True

The return value sol is an IKSolution with fields:

Field

Type

Description

q

ndarray(n)

joint coordinates in units of radians or metres

success

bool

whether a solution was found

iterations

int

total number of iterations

searches

int

total number of searches

residual

float

final value of cost function

reason

str

always empty for this C++ solver

If success == False the q values will be valid numbers, but the solution will be in error. The amount of error is indicated by the residual.

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 a panda robot object, makes a goal pose Tep, and then solves for the joint coordinates which result in the pose Tep using the ik_GN method.

>>> import roboticstoolbox as rtb
>>> panda = rtb.models.Panda()
>>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
>>> panda.ik_GN(Tep)
IKSolution: q=[-1.095, -0.5422, 0.9183, -2.177, 0.472, 1.897, 0.4155], success=True, iterations=111, searches=7, residual=1.41e-10

Notes

When using the 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).

ik_LM(Tep, end=None, start=None, q0=None, ilimit=30, slimit=100, tol=1e-06, mask=None, joint_limits=True, k=1.0, method='chan', tool=None)

Fast Levenberg-Marquardt Numerical Inverse Kinematics Solver

Parameters:
  • Tep (ndarray | SE3) – The desired end-effector pose

  • end (str | Link | Gripper | None) – the link considered as the end-effector

  • start (str | Link | Gripper | None) – the link considered as the base frame, defaults to the robots’s base frame

  • q0 (ndarray | None) – The initial joint coordinate vector

  • ilimit (int) – How many iterations are allowed within a search before a new search is started

  • slimit (int) – How many searches are allowed before being deemed unsuccessful

  • tol (float) – Maximum allowed residual error E

  • mask (ndarray | None) – A 6 vector which assigns weights to Cartesian degrees-of-freedom error priority

  • joint_limits (bool) – Reject solutions with joint limit violations

  • k (float) – Sets the gain value for the damping matrix Wn in the next iteration

  • method (Literal['chan', 'wampler', 'sugihara']) – One of “chan”, “sugihara” or “wampler”. Defines which method is used to calculate the damping matrix Wn in the step method

  • tool (ndarray | SE3 | None) – a static tool transformation matrix to apply to the end of end; defaults to the robot’s own self.tool if not given

Returns:

an IKSolution containing joint coordinates q, success flag, iterations, searches and residual error value (reason is always empty – this fast C++ solver doesn’t produce a granular failure reason string, unlike ikine_LM())

Return type:

IKSolution

Warning

This method needs the compiled C++ extension. It raises RuntimeError if the extension is unavailable, for example in a pure-Python wheel or under Pyodide/JupyterLite, and if the sequence has a SymPy parameter, even a numeric one such as sympy.pi/2, or a joint with an offset, which the compiled code cannot use. In all of these cases use ikine_LM(), which has none of these limits.

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 method kwarg.

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 k to 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 k as 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 k kwarg.

Examples

The following example makes a panda robot object, makes a goal pose Tep, and then solves for the joint coordinates which result in the pose Tep using the ik_LM method.

>>> import roboticstoolbox as rtb
>>> panda = rtb.models.Panda()
>>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
>>> panda.ik_LM(Tep)
IKSolution: q=[2.007, 0.5696, -2.199, -2.174, 0.5034, 1.882, 0.3916], success=True, iterations=30, searches=3, residual=2.51e-07

Notes

The value for the k kwarg will depend on the method chosen and the arm you are using. Use the following as a rough guide chan, k = 1.0 - 0.01, wampler, k = 0.01 - 0.0001, and sugihara, k = 0.1 - 0.0001

When using the 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).

Changed in version 1.0.4: Merged the Levenberg-Marquardt IK solvers into the ik_LM method

ik_NR(Tep, end=None, start=None, q0=None, ilimit=30, slimit=100, tol=1e-06, mask=None, joint_limits=True, pinv=True, pinv_damping=0.0, tool=None)

Fast numerical inverse kinematics using Newton-Raphson optimization

Parameters:
  • Tep (ndarray | SE3) – The desired end-effector pose (a single pose only, for a trajectory use ikine_NR())

  • end (str | Link | Gripper | None) – the link considered as the end-effector

  • start (str | Link | Gripper | None) – the link considered as the base frame, defaults to the robots’s base frame

  • q0 (ndarray | None) – initial joint configuration (default to random valid joint configuration constrained by the joint limits of the robot)

  • ilimit (int) – maximum number of iterations per search

  • slimit (int) – maximum number of search attempts

  • tol (float) – final error tolerance

  • mask (ndarray | None) – a mask vector which weights the end-effector error priority. Corresponds to translation in X, Y and Z and rotation about X, Y and Z respectively

  • joint_limits (bool) – constrain the solution to being within the joint limits of the robot (reject solution with invalid joint configurations and perform another search up to the slimit)

  • pinv (int) – Use the pseudo-inverse instead of the normal matrix inverse

  • pinv_damping (float) – Damping factor for the pseudo-inverse

  • tool (ndarray | SE3 | None) – a static tool transformation matrix to apply to the end of end; defaults to the robot’s own self.tool if not given

Returns:

an IKSolution containing joint coordinates q, success flag, iterations, searches and residual error value (reason is always empty – this fast C++ solver doesn’t produce a granular failure reason string, unlike ikine_NR())

Return type:

IKSolution

Warning

This method needs the compiled C++ extension. It raises RuntimeError if the extension is unavailable, for example in a pure-Python wheel or under Pyodide/JupyterLite, and if the sequence has a SymPy parameter, even a numeric one such as sympy.pi/2, or a joint with an offset, which the compiled code cannot use. In all of these cases use ikine_NR(), which has none of these limits.

sol = ets.ik_NR(Tep) are the joint coordinates (n) corresponding to the robot end-effector pose Tep which is an SE3 or ndarray object. 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.

Note

When using this method with redundant robots (>6 DoF), pinv must be set to True

The return value sol is an IKSolution with fields:

Field

Type

Description

q

ndarray(n)

joint coordinates in units of radians or metres

success

bool

whether a solution was found

iterations

int

total number of iterations

searches

int

total number of searches

residual

float

final value of cost function

reason

str

always empty for this C++ solver

If success == False the q values will be valid numbers, but the solution will be in error. The amount of error is indicated by the residual.

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 a panda robot object, makes a goal pose Tep, and then solves for the joint coordinates which result in the pose Tep using the ik_NR method.

>>> import roboticstoolbox as rtb
>>> panda = rtb.models.Panda()
>>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
>>> panda.ik_NR(Tep)
IKSolution: q=[0.753, -0.3904, -0.6602, -2.193, -0.2681, 1.968, 0.9963], success=True, iterations=11, searches=2, residual=6.32e-07

Notes

When using the 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).

ikine_GN(Tep, end=None, start=None, 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, tool=None, **kwargs)

Gauss-Newton Numerical Inverse Kinematics Solver

Parameters:
  • Tep (ndarray | SE3) – The desired end-effector pose or pose trajectory

  • end (str | Link | Gripper | None) – the link considered as the end-effector

  • start (str | Link | Gripper | None) – the link considered as the base frame, defaults to the robots’s base frame

  • q0 (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) – How many iterations are allowed within a search before a new search is started

  • slimit (int) – How many searches are allowed before being deemed unsuccessful

  • tol (float) – Maximum allowed residual error E

  • mask (ndarray | Sequence[float] | None) – A 6 vector which assigns weights to Cartesian degrees-of-freedom error priority

  • joint_limits (bool) – Reject solutions with joint limit violations

  • seed (int | None) – A seed for the private RNG used to generate random joint coordinate vectors

  • pinv (bool) – If True, will use the pseudoinverse in the step method instead of the normal inverse

  • kq (float) – The gain for joint limit avoidance. Setting to 0.0 will remove this completely from the solution

  • km (float) – The gain for maximisation. Setting to 0.0 will remove this completely from the solution

  • ps (float) – The minimum angle/distance (in radians or metres) in which the joint is allowed to approach to its limit

  • pi (ndarray | float) – The influence angle/distance (in radians or metres) in null space motion becomes active

  • tool (ndarray | SE3 | None) – a static tool transformation matrix to apply to the end of end; defaults to the robot’s own self.tool if not given

Returns:

an IKSolution containing joint coordinates q, success flag, iterations, searches, residual error value, and reason string if applicable

Return type:

Any

If Tep is a trajectory (an SE3 with N poses, or an array with shape (N, 4, 4)) each pose is solved independently from the same q0, so consecutive solutions are not guaranteed to be on the same IK branch. q has shape (N, n), success is True only if every pose succeeded, and residual is the maximum over the poses. See solve().

Changed in version 1.5.0: For a trajectory, residual is 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.

Note

When using this method with redundant robots (>6 DoF), pinv must be set to True

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 a panda robot object, makes a goal pose Tep, and then solves for the joint coordinates which result in the pose Tep using the ikine_GN method.

>>> import roboticstoolbox as rtb
>>> panda = rtb.models.Panda()
>>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
>>> panda.ikine_GN(Tep)
IKSolution: q=[1.372, 0.3554, -2.277, -1.312, -1.108, 1.806, -0.1273], success=False, reason=iteration and search limit reached, 100 numpy.LinAlgError encountered, iterations=100, searches=100, residual=1.49

Notes

When using the 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

IK_GN

An IK Solver class which implements the Gauss-Newton optimisation technique

ikine_LM

Implements the IK_LM class as a method within the ETS class

ikine_NR

Implements the IK_NR class as a method within the ETS class

ikine_QP

Implements the IK_QP class as a method within the ETS class

ik_GN()

The fast, C++-backed equivalent of this method (requires the compiled extension)

Changed in version 1.0.4: Added the Gauss-Newton IK solver method on the Robot class

ikine_LM(Tep, end=None, start=None, 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, tool=None, **kwargs)

Levenberg-Marquardt Numerical Inverse Kinematics Solver

Parameters:
  • Tep (ndarray | SE3) – The desired end-effector pose or pose trajectory

  • end (str | Link | Gripper | None) – the link considered as the end-effector

  • start (str | Link | Gripper | None) – the link considered as the base frame, defaults to the robots’s base frame

  • q0 (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) – How many iterations are allowed within a search before a new search is started

  • slimit (int) – How many searches are allowed before being deemed unsuccessful

  • tol (float) – Maximum allowed residual error E

  • mask (ndarray | Sequence[float] | None) – A 6 vector which assigns weights to Cartesian degrees-of-freedom error priority

  • joint_limits (bool) – Reject solutions with joint limit violations

  • seed (int | None) – A seed for the private RNG used to generate random joint coordinate vectors

  • k (float) – Sets the gain value for the damping matrix Wn in the next iteration

  • method (Literal['chan', 'wampler', 'sugihara']) – One of “chan”, “sugihara” or “wampler”. Defines which method is used to calculate the damping matrix Wn in the step method

  • kq (float) – The gain for joint limit avoidance. Setting to 0.0 will remove this completely from the solution

  • km (float) – The gain for maximisation. Setting to 0.0 will remove this completely from the solution

  • ps (float) – The minimum angle/distance (in radians or metres) in which the joint is allowed to approach to its limit

  • pi (ndarray | float) – The influence angle/distance (in radians or metres) in null space motion becomes active

  • tool (ndarray | SE3 | None) – a static tool transformation matrix to apply to the end of end; defaults to the robot’s own self.tool if not given

Returns:

an IKSolution containing joint coordinates q, success flag, iterations, searches, residual error value, and reason string if applicable

Return type:

Any

If Tep is a trajectory (an SE3 with N poses, or an array with shape (N, 4, 4)) each pose is solved independently from the same q0, so consecutive solutions are not guaranteed to be on the same IK branch. q has shape (N, n), success is True only if every pose succeeded, and residual is the maximum over the poses. See solve().

Changed in version 1.5.0: For a trajectory, residual is 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 method kwarg.

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 k to 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 k as 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 k kwarg.

Examples

The following example makes a panda robot object, makes a goal pose Tep, and then solves for the joint coordinates which result in the pose Tep using the ikine_LM method.

>>> import roboticstoolbox as rtb
>>> panda = rtb.models.Panda()
>>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
>>> panda.ikine_LM(Tep)
IKSolution: q=[-1.957, -1.617, 0.8777, -2.067, 1.339, 1.007, -0.1326], success=True, iterations=11, searches=1, residual=4.36e-11

Notes

The value for the k kwarg will depend on the method chosen and the arm you are using. Use the following as a rough guide chan, k = 1.0 - 0.01, wampler, k = 0.01 - 0.0001, and sugihara, k = 0.1 - 0.0001

When using the 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

IK_LM

An IK Solver class which implements the Levenberg-Marquardt optimisation technique

ikine_NR

Implements the IK_NR class as a method within the Robot class

ikine_GN

Implements the IK_GN class as a method within the Robot class

ikine_QP

Implements the IK_QP class as a method within the Robot class

ik_LM()

The fast, C++-backed equivalent of this method (requires the compiled extension)

Changed in version 1.0.4: Added the Levenberg-Marquardt IK solver method on the Robot class

ikine_NR(Tep, end=None, start=None, 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, tool=None, **kwargs)

Newton-Raphson Numerical Inverse Kinematics Solver

Parameters:
  • Tep (ndarray | SE3) – The desired end-effector pose or pose trajectory

  • end (str | Link | Gripper | None) – the link considered as the end-effector

  • start (str | Link | Gripper | None) – the link considered as the base frame, defaults to the robots’s base frame

  • q0 (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) – How many iterations are allowed within a search before a new search is started

  • slimit (int) – How many searches are allowed before being deemed unsuccessful

  • tol (float) – Maximum allowed residual error E

  • mask (ndarray | Sequence[float] | None) – A 6 vector which assigns weights to Cartesian degrees-of-freedom error priority

  • joint_limits (bool) – Reject solutions with joint limit violations

  • seed (int | None) – A seed for the private RNG used to generate random joint coordinate vectors

  • pinv (bool) – If True, will use the pseudoinverse in the step method instead of the normal inverse

  • kq (float) – The gain for joint limit avoidance. Setting to 0.0 will remove this completely from the solution

  • km (float) – The gain for maximisation. Setting to 0.0 will remove this completely from the solution

  • ps (float) – The minimum angle/distance (in radians or metres) in which the joint is allowed to approach to its limit

  • pi (ndarray | float) – The influence angle/distance (in radians or metres) in null space motion becomes active

  • tool (ndarray | SE3 | None) – a static tool transformation matrix to apply to the end of end; defaults to the robot’s own self.tool if not given

Returns:

an IKSolution containing joint coordinates q, success flag, iterations, searches, residual error value, and reason string if applicable

Return type:

Any

If Tep is a trajectory (an SE3 with N poses, or an array with shape (N, 4, 4)) each pose is solved independently from the same q0, so consecutive solutions are not guaranteed to be on the same IK branch. q has shape (N, n), success is True only if every pose succeeded, and residual is the maximum over the poses. See solve().

Changed in version 1.5.0: For a trajectory, residual is 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.

Note

When using this method with redundant robots (>6 DoF), pinv must be set to True

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 a panda robot object, makes a goal pose Tep, and then solves for the joint coordinates which result in the pose Tep using the ikine_NR method.

>>> import roboticstoolbox as rtb
>>> panda = rtb.models.Panda()
>>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
>>> panda.ikine_NR(Tep)
IKSolution: q=[1.949, 0.7163, 1.07, -0.1702, -2.793, 2.411, -2.799], success=False, reason=iteration and search limit reached, 100 numpy.LinAlgError encountered, iterations=100, searches=100, residual=3.23

Notes

When using the 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

IK_NR

An IK Solver class which implements the Newton-Raphson optimisation technique

ikine_LM

Implements the IK_LM class as a method within the ETS class

ikine_GN

Implements the IK_GN class as a method within the ETS class

ikine_QP

Implements the IK_QP class as a method within the ETS class

ik_NR()

The fast, C++-backed equivalent of this method (requires the compiled extension)

Changed in version 1.0.4: Added the Newton-Raphson IK solver method on the Robot class

ikine_QP(Tep, end=None, start=None, 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, tool=None, **kwargs)

Quadratic Programming Numerical Inverse Kinematics Solver

Parameters:
  • Tep (ndarray | SE3) – The desired end-effector pose or pose trajectory

  • end (str | Link | Gripper | None) – the link considered as the end-effector

  • start (str | Link | Gripper | None) – the link considered as the base frame, defaults to the robots’s base frame

  • q0 (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) – How many iterations are allowed within a search before a new search is started

  • slimit (int) – How many searches are allowed before being deemed unsuccessful

  • tol (float) – Maximum allowed residual error E

  • mask (ndarray | Sequence[float] | None) – A 6 vector which assigns weights to Cartesian degrees-of-freedom error priority

  • joint_limits (bool) – Reject solutions with joint limit violations

  • seed (int | None) – A seed for the private RNG used to generate random joint coordinate vectors

  • kj (float) – A gain for joint velocity norm minimisation

  • ks (float) – A gain which adjusts the cost of slack (intentional error)

  • kq (float) – The gain for joint limit avoidance. Setting to 0.0 will remove this completely from the solution

  • km (float) – The gain for maximisation. Setting to 0.0 will remove this completely from the solution

  • ps (float) – The minimum angle/distance (in radians or metres) in which the joint is allowed to approach to its limit

  • pi (ndarray | float) – The influence angle/distance (in radians or metres) in null space motion becomes active

  • tool (ndarray | SE3 | None) – a static tool transformation matrix to apply to the end of end; defaults to the robot’s own self.tool if not given

Raises:

ImportError – If the package qpsolvers is not installed, see the note below

Returns:

an IKSolution containing joint coordinates q, success flag, iterations, searches, residual error value, and reason string if applicable

Return type:

Any

If Tep is a trajectory (an SE3 with N poses, or an array with shape (N, 4, 4)) each pose is solved independently from the same q0, so consecutive solutions are not guaranteed to be on the same IK branch. q has shape (N, n), success is True only if every pose succeeded, and residual is the maximum over the poses. See solve().

Changed in version 1.5.0: For a trajectory, residual is the maximum over the poses, it was the minimum.

A method that provides functionality to perform numerical inverse kinematics (IK) using a quadratic programming approach.

Note

This needs the packages qpsolvers and quadprog, which are not installed with the Toolbox by default. Install them with the qp extra: pip install roboticstoolbox-python[qp].

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 a panda robot object, makes a goal pose Tep, and then solves for the joint coordinates which result in the pose Tep using the ikine_QP method.

>>> import roboticstoolbox as rtb
>>> panda = rtb.models.Panda()
>>> Tep = panda.fkine([0, -0.3, 0, -2.2, 0, 2, 0.7854])
>>> panda.ikine_QP(Tep)
!! [RUNBLOCK-ERROR] robot/Robot.py:docstring of roboticstoolbox.robot.RobotKinematics.RobotKinematicsMixin.ikine_QP:3060
    Install them using 'pip install roboticstoolbox-python[qp]'

Notes

When using the 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

IK_QP

An IK Solver class which implements a quadratic programming approach

ikine_LM

Implements the IK_LM class as a method within the ETS class

ikine_GN

Implements the IK_GN class as a method within the ETS class

ikine_NR

Implements the IK_NR class as a method within the ETS class

Changed in version 1.0.4: Added the Quadratic Programming IK solver method on the Robot class

inertia(q)

Manipulator inertia matrix

Parameters:

q (ndarray) – Joint coordinates

Returns:

The inertia matrix

Return type:

ndarray

inertia(q) is the symmetric joint inertia matrix (n,n) which relates joint torque to joint acceleration for the robot at joint configuration q.

Trajectory operation

If q is a matrix (m,n), each row is interpreted as a joint state vector, and the result is a 3d-matrix (nxnxk) where each plane corresponds to the inertia for the corresponding row of q.

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.inertia(puma.qz)
array([[ 3.9611, -0.1627, -0.1389,  0.0016, -0.0004,  0.    ],
       [-0.1627,  4.4566,  0.3727,  0.    ,  0.0019,  0.    ],
       [-0.1389,  0.3727,  0.9387,  0.    ,  0.0019,  0.    ],
       [ 0.0016,  0.    ,  0.    ,  0.1924,  0.    ,  0.    ],
       [-0.0004,  0.0019,  0.0019,  0.    ,  0.1713,  0.    ],
       [ 0.    ,  0.    ,  0.    ,  0.    ,  0.    ,  0.1941]])

Notes

  • The diagonal elements M[j,j] are the inertia seen by joint

    actuator j.

  • The off-diagonal elements M[j,k] are coupling inertias that

    relate acceleration on joint j to force/torque on joint k.

  • The diagonal terms include the motor inertia reflected through

    the gear ratio.

See also

cinertia()

inertia_x(q=None, pinv=False, representation='rpy/xyz', Ji=None)

Operational space inertia matrix

Parameters:
  • q (Any) – Joint coordinates

  • pinv (bool) – use pseudo inverse rather than inverse (Default value = False)

  • representation (Literal['rpy/xyz', 'rpy/zyx', 'eul', 'exp']) – the type of analytical Jacobian to use, default is 'rpy/xyz'

  • Ji (Any) – The inverse analytical Jacobian (base-frame)

Returns:

The operational space inertia matrix

Return type:

Any

robot.inertia_x(q) is the operational space (Cartesian) inertia matrix which relates Cartesian force/torque to Cartesian acceleration at the joint configuration q.

\[\mathbf{M}_x = \mathbf{J}(q)^{-T} \mathbf{M}(q) \mathbf{J}(q)^{-1}\]

The transformation to operational space requires an analytical, rather than geometric, Jacobian. analytical can be one of:

Value

Rotational representation

'rpy/xyz'

RPY angular rates in XYZ order (default)

'rpy/zyx'

RPY angular rates in XYZ order

'eul'

Euler angular rates in ZYZ order

'exp'

exponential coordinate rates

Trajectory operation

If q is a matrix (m,n), each row is interpreted as a joint state vector, and the result is a 3d-matrix (m,n,n) where each plane corresponds to the Cartesian inertia for the corresponding row of q.

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.inertia_x(puma.qn)
array([[17.2954, -2.7542, -9.6233,  0.    ,  0.2795,  0.    ],
       [-2.7542, 11.6452,  1.2459,  0.0001, -0.0703,  0.0001],
       [-9.6233,  1.2459, 13.3348,  0.    ,  0.2767,  0.    ],
       [ 0.    ,  0.0001,  0.    ,  0.1941,  0.    ,  0.1941],
       [ 0.2795, -0.0703,  0.2767,  0.    ,  0.1713,  0.    ],
       [ 0.    ,  0.0001,  0.    ,  0.1941,  0.    ,  0.1941]])

Notes

  • If the robot is not 6 DOF the pinv option is set True.

  • pinv() is around 5x slower than inv()

Warning

Assumes that the operational space has 6 DOF.

See also

inertia()

isprismatic(j)

Check if joint is prismatic

Return type:

bool

Returns:

True if prismatic

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.prismaticjoints
[False, False, False, False, False, False]
>>> stanford = rtb.models.DH.Stanford()
>>> stanford.isprismatic(1)
False
isrevolute(j)

Check if joint is revolute

Return type:

bool

Returns:

True if revolute

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.revolutejoints
[True, True, True, True, True, True]
>>> stanford = rtb.models.DH.Stanford()
>>> stanford.isrevolute(1)
True
itorque(q, qdd)

Inertia torque

Parameters:
  • q (Any) – Joint coordinates

  • qdd (Any) – Joint acceleration

Returns:

The inertia torque vector

Return type:

Any

itorque(q, qdd) is the inertia force/torque vector (n) at the specified joint configuration q (n) and acceleration qdd (n), and n is the number of robot joints. It is \(\mathbf{I}(q) \ddot{q}\).

Trajectory operation

If q and qdd are matrices (m,n), each row is interpreted as a joint configuration, and the result is a matrix (m,n) where each row is the corresponding joint torques.

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.itorque(puma.qz, 0.5 * np.ones((6,)))
array([1.8304, 2.3343, 0.5872, 0.0971, 0.0873, 0.0971])

Notes

  • If the robot model contains non-zero motor inertia then this

    will be included in the result.

See also

inertia()

jacob0(q, end=None, start=None, tool=None)

Manipulator geometric Jacobian in the start frame

Parameters:
  • q (ndarray | Sequence[float]) – Joint coordinate vector

  • end (str | Link | Gripper | None) – the particular link or gripper whose velocity the Jacobian describes, defaults to the end-effector if only one is present

  • start (str | Link | Gripper | None) – the link considered as the base frame, defaults to the robots’s base frame

  • tool (ndarray | SE3 | None) – a static tool transformation matrix to apply to the end of end, defaults to None

Return type:

ndarray

Returns:

Manipulator Jacobian in the start frame

robot.jacobo(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 Puma560 robot object, and solves for the base-frame Jacobian at the zero joint angle configuration

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.Puma560()
>>> 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).

jacob0_analytical(q, representation='rpy/xyz', end=None, start=None, tool=None)

Manipulator analytical Jacobian in the start frame

Parameters:
  • q (ndarray | Sequence[float]) – Joint coordinate vector

  • representation (Literal['rpy/xyz', 'rpy/zyx', 'eul', 'exp']) – angular representation

  • end (str | Link | Gripper | None) – the particular link or gripper whose velocity the Jacobian describes, defaults to the base link

  • start (str | Link | Gripper | None) – the link considered as the end-effector, defaults to the robots’s end-effector

  • tool (ndarray | SE3 | None) – a static tool transformation matrix to apply to the end of end, defaults to None

Return type:

Any

Returns:

Manipulator Jacobian in the start frame

robot.jacob0_analytical(q) is the manipulator Jacobian matrix which maps joint velocity to end-effector spatial velocity expressed in the start 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}\).

representation

Rotational 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()
>>> 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.    ]])
jacobe(q, end=None, start=None, tool=None)

Manipulator geometric Jacobian in the end-effector frame

Parameters:
  • q (ndarray | Sequence[float]) – Joint coordinate vector

  • end (str | Link | Gripper | None) – the particular link or gripper whose velocity the Jacobian describes, defaults to the end-effector if only one is present

  • start (str | Link | Gripper | None) – the link considered as the base frame, defaults to the robots’s base frame

  • tool (ndarray | SE3 | None) – a static tool transformation matrix to apply to the end of end, defaults to None

Return type:

ndarray

Returns:

Manipulator Jacobian in the end frame

robot.jacobe(q) is the manipulator Jacobian matrix which maps joint velocity to end-effector spatial velocity expressed in the end 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 Puma560 robot object, and solves for the end-effector frame Jacobian at the zero joint angle configuration

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.Puma560()
>>> 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).

jointdynamics(q, qd=None)

Transfer function of joint actuator

Parameters:
  • q (Any) – Joint coordinates

  • qd (Any) – Joint velocity

Returns:

transfer function denominators

Return type:

Any

tf = jointdynamics(qd, q) calculates a vector of n continuous-time transfer functions that represent the transfer function 1/(Js+B) for each joint based on the dynamic parameters of the robot and the configuration q (n). n is the number of robot joints. The result is a list of tuples (J, B) for each joint.

tf = jointdynamics(q, qd) as above but include the linearized effects of Coulomb friction when operating at joint velocity QD (1xN).

property keywords: list[str]

Keywords that describe the robot

Returns:

the keywords, which the model catalog can filter on

linkcolormap(linkcolors='viridis')

Create a colormap for robot joints.

Parameters:

linkcolors (list[Any] | str) – list of colors or colormap name, defaults to "viridis"

Return type:

Any

Returns:

the color map

  • cm = robot.linkcolormap() is an n-element colormap that gives a unique color for every link. The RGBA colors for link j are cm(j).

  • cm = robot.linkcolormap(cmap) as above but cmap is the name of a valid matplotlib colormap. The default, example above, is the viridis colormap.

  • cm = robot.linkcolormap(list of colors) as above but a colormap is created from a list of n color names given as strings, tuples or hexstrings.


>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> cm = robot.linkcolormap("inferno")
>>> print(cm(range(6))) # cm(i) is 3rd color in colormap
>>> cm = robot.linkcolormap(
...     ['red', 'g', (0,0.5,0), '#0f8040', 'yellow', 'cyan'])
>>> print(cm(range(6)))

Notes

  • Colormaps have 4-elements: red, green, blue, alpha (RGBA)

  • Names of supported colors and colormaps are defined in the matplotlib documentation.

Robot links

Returns:

A list of link objects

Notes

It is probably more concise to index the robot object rather than the list of links, ie. the following are equivalent: - robot.links[i] - robot[i]

property manufacturer: Any

Get/set robot manufacturer’s name

  • robot.manufacturer is the robot manufacturer’s name

  • robot.manufacturer = ... checks and sets the manufacturer’s name

Returns:

robot manufacturer’s name

property n: int

Number of joints

Returns:

Number of joints

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> robot.n
6
property name: str

Get/set robot name

  • robot.name is the robot name

  • robot.name = ... checks and sets the robot name

Parameters:

name – the new robot name

Returns:

the current robot name

property nbranches: int

Number of branches

Number of branches in this robot. Computed as the number of links with zero children

Returns:

number of branches in the robot’s kinematic tree

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.ETS.Panda()
>>> robot.nbranches
1

See also

n() nlinks()

Number of links

The returned number is the total of both variable joints and static links

Returns:

Number of links

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> robot.nlinks
6

See also

n() nbranches()

nofriction(coulomb=True, viscous=False)

Remove manipulator joint friction

Parameters:
  • coulomb (bool) – set the Coulomb friction to 0

  • viscous (bool) – set the viscous friction to 0

Return type:

Any

Returns:

A copy of the robot with dynamic parameters perturbed

nofriction() copies the robot and returns a robot with the same link parameters except the Coulomb and/or viscous friction parameter are set to zero.

partial_fkine0(q, n=3, end=None, start=None)

Manipulator Forward Kinematics nth Partial Derivative

Parameters:
  • q (ndarray | Sequence[float]) – The joint angles/configuration of the robot (Optional, if not supplied will use the stored q values).

  • n (int) – The derivative order, must be >= 3

  • end (str | Link | Gripper | None) – the final link/Gripper which the Hessian represents

  • start (str | Link | Gripper | None) – the first link which the Hessian represents

Return type:

Any

Returns:

The nth Partial Derivative of the forward kinematics

This method computes the nth derivative of the forward kinematics where n is 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 Panda robot object, and solves for the base-effector frame 4th defivative of the forward kinematics at the given joint angle configuration

>>> import roboticstoolbox as rtb
>>> panda = rtb.models.Panda()
>>> panda.partial_fkine0([0, -0.3, 0, -2.2, 0, 2, 0.7854], n=4)
array([[[[[ 0.484 ,  0.    ,  0.486 , ...,  0.1547, -0.    ,  0.    ],
          [-0.    , -0.0796, -0.    , ..., -0.    , -0.2006,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  1.    ,  0.    , ..., -0.    , -1.    , -0.    ],
          [ 0.    ,  0.    ,  0.2955, ..., -0.9463,  0.    , -0.0998],
          [ 0.    , -0.    ,  0.    , ..., -0.    ,  0.    , -0.    ]],

         [[ 0.    ,  0.484 ,  0.    , ...,  0.    , -0.1086,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    , -0.    , -0.    , ..., -0.    ,  0.    ,  0.    ],
          [-1.    ,  0.    , -0.9553, ...,  0.3233, -0.    ,  0.995 ],
          [-0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ]],

         [[ 0.4624,  0.    ,  0.4643, ...,  0.1478, -0.    ,  0.    ],
          [-0.    ,  0.067 , -0.    , ..., -0.    , -0.2237,  0.    ],
          [-0.    ,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    ,  0.9553,  0.    , ..., -0.    , -0.9553, -0.    ],
          [-0.2955, -0.    ,  0.    , ..., -0.8085,  0.    ,  0.1987],
          [-0.    , -0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ]],

         ...,

         [[-0.1565, -0.    , -0.1571, ..., -0.05  ,  0.    ,  0.    ],
          [ 0.    , -0.4323,  0.    , ..., -0.    ,  0.1676,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    , -0.3233,  0.    , ...,  0.    ,  0.3233, -0.    ],
          [ 0.9463,  0.    ,  0.8085, ...,  0.    ,  0.    , -0.9093],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ]],

         [[ 0.    , -0.484 ,  0.    , ..., -0.    ,  0.1086,  0.    ],
          [-0.    ,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    , -0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 1.    ,  0.    ,  0.9553, ..., -0.3233,  0.    , -0.995 ],
          [-0.    , -0.    , -0.    , ..., -0.    ,  0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[-0.4816, -0.    , -0.4835, ..., -0.1539,  0.    ,  0.    ],
          [ 0.    ,  0.0309,  0.    , ...,  0.    ,  0.2104,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    , -0.995 ,  0.    , ...,  0.    ,  0.995 ,  0.    ],
          [ 0.0998,  0.    , -0.1987, ...,  0.9093, -0.    ,  0.    ],
          [ 0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ]]],


        [[[ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    , -0.0796, -0.    , ..., -0.    , -0.2006,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ],
          [ 0.    , -0.    ,  0.2955, ..., -0.9463,  0.    , -0.0998]],

         [[-0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    , -0.0796, -0.    , ..., -0.    , -0.2006,  0.    ],
          [-0.0796, -0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.    ,  0.    ,  0.2955, ..., -0.9463,  0.    , -0.0998],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ]],

         [[ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.143 , -0.    , -0.1436, ..., -0.0457, -0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.    , -0.2955,  0.    , ..., -0.    ,  0.2955,  0.    ],
          [-0.2955, -0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ]],

         ...,

         [[ 0.    ,  0.    , -0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.4581,  0.    ,  0.4599, ...,  0.1464,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.9463,  0.    , ...,  0.    , -0.9463, -0.    ],
          [ 0.9463,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ]],

         [[ 0.    , -0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [-0.    ,  0.0796,  0.    , ...,  0.    ,  0.2006,  0.    ],
          [ 0.0796,  0.    , -0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ],
          [-0.    , -0.    , -0.2955, ...,  0.9463,  0.    ,  0.0998],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[-0.    ,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.0483,  0.    ,  0.0485, ...,  0.0154,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    , -0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.0998, -0.    , ...,  0.    , -0.0998,  0.    ],
          [ 0.0998,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ]]],


        [[[ 0.4624,  0.    ,  0.4643, ...,  0.1478, -0.    ,  0.    ],
          [-0.    , -0.0761, -0.    , ..., -0.    , -0.1916,  0.    ],
          [-0.143 , -0.    , -0.1436, ..., -0.0457, -0.    ,  0.    ],
          [ 0.    ,  0.9553,  0.    , ..., -0.    , -0.9553, -0.    ],
          [ 0.    ,  0.    ,  0.2823, ..., -0.904 ,  0.    , -0.0954],
          [ 0.    , -0.2955,  0.    , ...,  0.    ,  0.2955,  0.    ]],

         [[ 0.    ,  0.4624,  0.    , ...,  0.    , -0.1037,  0.    ],
          [-0.    , -0.    , -0.1436, ..., -0.0457, -0.    ,  0.    ],
          [ 0.    ,  0.0091,  0.    , ...,  0.    ,  0.1916,  0.    ],
          [-0.9553,  0.    , -0.9127, ...,  0.3089, -0.    ,  0.9506],
          [-0.    ,  0.    ,  0.    , ..., -0.    ,  0.2955,  0.    ],
          [ 0.2955,  0.    , -0.2823, ...,  0.904 , -0.    ,  0.0954]],

         [[ 0.4418,  0.    ,  0.486 , ...,  0.1547, -0.    ,  0.    ],
          [-0.    ,  0.064 , -0.    , ..., -0.    , -0.2137,  0.    ],
          [-0.007 ,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    ,  0.9127,  0.    , ..., -0.    , -1.    , -0.    ],
          [-0.2823, -0.    ,  0.    , ..., -0.7724,  0.    ,  0.1898],
          [-0.    ,  0.2823,  0.    , ..., -0.    ,  0.    ,  0.    ]],

         ...,

         [[-0.1495, -0.    , -0.286 , ..., -0.091 ,  0.    ,  0.    ],
          [ 0.    , -0.413 ,  0.    , ..., -0.    ,  0.1601,  0.    ],
          [ 0.0223, -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    , -0.3089,  0.    , ..., -0.    ,  0.5885, -0.    ],
          [ 0.904 ,  0.    ,  0.7724, ...,  0.    ,  0.    , -0.8687],
          [-0.    , -0.904 ,  0.    , ...,  0.    , -0.    , -0.    ]],

         [[ 0.    , -0.486 ,  0.    , ..., -0.    ,  0.0444,  0.    ],
          [-0.143 ,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    ,  0.067 ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.9553,  0.    ,  1.    , ..., -0.5885,  0.    , -0.9801],
          [-0.    , -0.2955, -0.    , ..., -0.    ,  0.    ,  0.    ],
          [-0.2955,  0.    , -0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[-0.4601, -0.    , -0.4763, ..., -0.1516,  0.    ,  0.    ],
          [ 0.    ,  0.0295,  0.    , ...,  0.    ,  0.201 ,  0.    ],
          [ 0.0023,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    , -0.9506,  0.    , ...,  0.    ,  0.9801,  0.    ],
          [ 0.0954, -0.    , -0.1898, ...,  0.8687, -0.    ,  0.    ],
          [-0.    , -0.0954, -0.    , ...,  0.    , -0.    ,  0.    ]]],


        ...,


        [[[-0.1565, -0.    , -0.1571, ..., -0.05  ,  0.    ,  0.    ],
          [ 0.    ,  0.0257,  0.    , ...,  0.    ,  0.0648,  0.    ],
          [ 0.4581,  0.    ,  0.4599, ...,  0.1464,  0.    ,  0.    ],
          [ 0.    , -0.3233, -0.    , ...,  0.    ,  0.3233,  0.    ],
          [ 0.    , -0.    , -0.0955, ...,  0.3059, -0.    ,  0.0323],
          [ 0.    ,  0.9463, -0.    , ...,  0.    , -0.9463, -0.    ]],

         [[-0.    , -0.1565, -0.    , ..., -0.    ,  0.0351,  0.    ],
          [ 0.    , -0.    , -0.0457, ...,  0.1464,  0.    ,  0.    ],
          [-0.    ,  0.4066, -0.    , ...,  0.    , -0.0648,  0.    ],
          [ 0.3233,  0.    ,  0.3089, ..., -0.1045,  0.    , -0.3217],
          [ 0.    ,  0.    , -0.    , ...,  0.    , -0.9463, -0.    ],
          [-0.9463,  0.    , -0.713 , ..., -0.3059, -0.    , -0.0323]],

         [[-0.1495, -0.    , -0.1366, ..., -0.091 , -0.    ,  0.    ],
          [ 0.    , -0.0217,  0.    , ...,  0.    ,  0.0723,  0.    ],
          [ 0.2994,  0.    ,  0.3028, ...,  0.1251,  0.    ,  0.    ],
          [ 0.    , -0.3089,  0.    , ...,  0.    ,  0.5885,  0.    ],
          [ 0.0955,  0.    ,  0.    , ...,  0.2614, -0.    , -0.0642],
          [ 0.    ,  0.713 ,  0.    , ...,  0.    , -0.8085, -0.    ]],

         ...,

         [[ 0.0506,  0.    ,  0.0075, ...,  0.1547,  0.    ,  0.    ],
          [-0.    ,  0.1398, -0.    , ..., -0.    , -0.0542,  0.    ],
          [ 0.2945,  0.    ,  0.2885, ..., -0.    , -0.    ,  0.    ],
          [-0.    ,  0.1045, -0.    , ...,  0.    , -1.    , -0.    ],
          [-0.3059, -0.    , -0.2614, ...,  0.    ,  0.    ,  0.294 ],
          [-0.    ,  0.3059, -0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[ 0.    ,  0.2318,  0.    , ...,  0.    ,  0.1547,  0.    ],
          [ 0.4581,  0.    ,  0.5056, ..., -0.    , -0.    ,  0.    ],
          [ 0.    , -0.4323,  0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.3233, -0.    , -0.5885, ...,  1.    ,  0.    ,  0.4161],
          [ 0.    ,  0.9463,  0.    , ..., -0.    ,  0.    , -0.    ],
          [ 0.9463,  0.    ,  0.8085, ..., -0.    ,  0.    ,  0.    ]],

         [[ 0.1557,  0.    ,  0.1518, ...,  0.0644,  0.    ,  0.    ],
          [ 0.    , -0.01  ,  0.    , ..., -0.    , -0.068 ,  0.    ],
          [ 0.0311, -0.    ,  0.0304, ..., -0.    , -0.    ,  0.    ],
          [-0.    ,  0.3217, -0.    , ...,  0.    , -0.4161,  0.    ],
          [-0.0323,  0.    ,  0.0642, ..., -0.294 ,  0.    ,  0.    ],
          [ 0.    ,  0.0323,  0.    , ..., -0.    ,  0.    ,  0.    ]]],


        [[[ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.0796,  0.    , ...,  0.    ,  0.2006,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ],
          [ 0.    , -0.    , -0.2955, ...,  0.9463,  0.    ,  0.0998]],

         [[-0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    , -0.2006, -0.    , ...,  0.    ,  0.2006,  0.    ],
          [-0.2006, -0.    , -0.2237, ...,  0.1676,  0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ..., -0.    ,  0.    ,  0.0998],
          [ 0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ]],

         [[ 0.    ,  0.0593,  0.    , ...,  0.    , -0.0593,  0.    ],
          [-0.    ,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    , -0.0349,  0.    , ...,  0.    ,  0.1916,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    , -0.0295],
          [-0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.2955,  0.    ,  0.    , ...,  0.8085, -0.    ,  0.0954]],

         ...,

         [[-0.    , -0.1898, -0.    , ...,  0.    ,  0.1898,  0.    ],
          [ 0.    , -0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    ,  0.3296, -0.    , ..., -0.    , -0.0648,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.    ,  0.0945],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [-0.9463, -0.    , -0.8085, ...,  0.    ,  0.    , -0.0323]],

         [[ 0.    , -0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    ,  0.2006,  0.    , ..., -0.    , -0.2006,  0.    ],
          [ 0.2006,  0.    ,  0.2237, ..., -0.1676, -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ],
          [-0.    ,  0.    , -0.    , ..., -0.    ,  0.    , -0.0998],
          [-0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ]],

         [[-0.    , -0.028 , -0.    , ..., -0.    ,  0.    ,  0.    ],
          [-0.0483,  0.    , -0.0485, ..., -0.0154, -0.    ,  0.    ],
          [ 0.    ,  0.0375,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.    , -0.    ,  0.0295, ..., -0.0945,  0.    ,  0.    ],
          [ 0.    , -0.0998, -0.    , ...,  0.    ,  0.0998,  0.    ],
          [-0.0998, -0.    , -0.0954, ...,  0.0323,  0.    ,  0.    ]]],


        [[[-0.4816, -0.    , -0.4835, ..., -0.1539,  0.    ,  0.    ],
          [ 0.    ,  0.0792,  0.    , ...,  0.    ,  0.1996,  0.    ],
          [ 0.0483,  0.    ,  0.0485, ...,  0.0154,  0.    ,  0.    ],
          [ 0.    , -0.995 , -0.    , ...,  0.    ,  0.995 ,  0.    ],
          [ 0.    , -0.    , -0.294 , ...,  0.9416, -0.    ,  0.0993],
          [ 0.    ,  0.0998, -0.    , ...,  0.    , -0.0998,  0.    ]],

         [[-0.    , -0.4816, -0.    , ..., -0.    ,  0.108 ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.    , -0.1101, -0.    , ..., -0.    , -0.41  ,  0.    ],
          [ 0.995 ,  0.    ,  0.9506, ..., -0.3217,  0.    , -0.99  ],
          [ 0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.0998,  0.    ,  0.4927, ..., -1.8509,  0.    , -0.0993]],

         [[-0.4601, -0.    , -0.4619, ..., -0.147 ,  0.    ,  0.    ],
          [ 0.    , -0.0666,  0.    , ...,  0.    ,  0.2226,  0.    ],
          [-0.2385, -0.    , -0.2394, ..., -0.0762,  0.    ,  0.    ],
          [ 0.    , -0.9506,  0.    , ...,  0.    ,  0.9506,  0.    ],
          [ 0.294 ,  0.    ,  0.    , ...,  0.8045, -0.    , -0.1977],
          [ 0.    , -0.4927,  0.    , ...,  0.    ,  0.4927,  0.    ]],

         ...,

         [[ 0.1557,  0.    ,  0.1563, ...,  0.0498, -0.    ,  0.    ],
          [-0.    ,  0.4302, -0.    , ...,  0.    , -0.1667,  0.    ],
          [ 0.8959,  0.    ,  0.8994, ...,  0.2863,  0.    ,  0.    ],
          [-0.    ,  0.3217, -0.    , ...,  0.    , -0.3217,  0.    ],
          [-0.9416, -0.    , -0.8045, ...,  0.    , -0.    ,  0.9048],
          [-0.    ,  1.8509, -0.    , ...,  0.    , -1.8509, -0.    ]],

         [[-0.    ,  0.4816, -0.    , ...,  0.    , -0.108 ,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.1101,  0.    , ...,  0.    ,  0.41  ,  0.    ],
          [-0.995 , -0.    , -0.9506, ...,  0.3217,  0.    ,  0.99  ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.0998, -0.    , -0.4927, ...,  1.8509,  0.    ,  0.0993]],

         [[ 0.4792,  0.    ,  0.4811, ...,  0.1532, -0.    ,  0.    ],
          [-0.    , -0.0308, -0.    , ..., -0.    , -0.2093,  0.    ],
          [ 0.0481,  0.    ,  0.0483, ...,  0.0154,  0.    ,  0.    ],
          [-0.    ,  0.99  , -0.    , ..., -0.    , -0.99  ,  0.    ],
          [-0.0993, -0.    ,  0.1977, ..., -0.9048,  0.    ,  0.    ],
          [-0.    ,  0.0993, -0.    , ...,  0.    , -0.0993,  0.    ]]]],



       [[[[ 0.    ,  0.484 ,  0.    , ...,  0.    , -0.1086,  0.    ],
          [-0.0796, -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    , -0.9553, ...,  0.3233, -0.    ,  0.995 ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ]],

         [[ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.    , -0.0796, -0.    , ..., -0.    , -0.2006,  0.    ],
          [ 0.    , -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.2955, ..., -0.9463,  0.    , -0.0998],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ]],

         [[ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.2191, -0.    , -0.1436, ..., -0.0457, -0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.9553,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    , -0.2955,  0.    , ..., -0.    ,  0.2955,  0.    ],
          [-0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         ...,

         [[ 0.    , -0.    , -0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.4838,  0.    ,  0.4599, ...,  0.1464,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.3233, -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.9463,  0.    , ...,  0.    , -0.9463, -0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ]],

         [[-0.    , -0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [-0.    ,  0.0796,  0.    , ...,  0.    ,  0.2006,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ],
          [-0.    , -0.    , -0.2955, ...,  0.9463,  0.    ,  0.0998],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[-0.    ,  0.    , -0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.1276,  0.    ,  0.0485, ...,  0.0154,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.995 , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.0998, -0.    , ...,  0.    , -0.0998,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ]]],


        [[[ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.    , -0.0796, -0.    , ..., -0.    , -0.2006,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.2955, ..., -0.9463,  0.    , -0.0998],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ]],

         [[ 0.    ,  0.484 ,  0.    , ...,  0.    , -0.1086,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.0796,  0.    , ...,  0.    ,  0.2006,  0.    ],
          [ 0.    ,  0.    , -0.9553, ...,  0.3233, -0.    ,  0.995 ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    , -0.2955, ...,  0.9463, -0.    ,  0.0998]],

         [[ 0.4154,  0.    ,  0.4643, ...,  0.1478, -0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.2952,  0.    ,  0.1436, ...,  0.0457,  0.    ,  0.    ],
          [ 0.    ,  0.9553,  0.    , ..., -0.    , -0.9553, -0.    ],
          [-0.2955, -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.    ,  0.2955,  0.    , ...,  0.    , -0.2955, -0.    ]],

         ...,

         [[-0.0058, -0.    , -0.1571, ..., -0.05  ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.5095, -0.    , -0.4599, ..., -0.1464, -0.    ,  0.    ],
          [-0.    , -0.3233,  0.    , ...,  0.    ,  0.3233, -0.    ],
          [ 0.9463,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    , -0.9463, -0.    , ...,  0.    ,  0.9463,  0.    ]],

         [[ 0.    , -0.484 ,  0.    , ..., -0.    ,  0.1086,  0.    ],
          [-0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    , -0.0796, -0.    , ..., -0.    , -0.2006,  0.    ],
          [ 0.    ,  0.    ,  0.9553, ..., -0.3233,  0.    , -0.995 ],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.    ,  0.    ,  0.2955, ..., -0.9463,  0.    , -0.0998]],

         [[-0.4657, -0.    , -0.4835, ..., -0.1539,  0.    ,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.2068, -0.    , -0.0485, ..., -0.0154, -0.    ,  0.    ],
          [-0.    , -0.995 ,  0.    , ...,  0.    ,  0.995 ,  0.    ],
          [ 0.0998,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    , -0.0998,  0.    , ..., -0.    ,  0.0998,  0.    ]]],


        [[[ 0.    ,  0.4624,  0.    , ...,  0.    , -0.1037,  0.    ],
          [-0.2191, -0.    , -0.1436, ..., -0.0457, -0.    ,  0.    ],
          [ 0.    ,  0.0761,  0.    , ...,  0.    ,  0.1916,  0.    ],
          [ 0.    ,  0.    , -0.9127, ...,  0.3089, -0.    ,  0.9506],
          [ 0.    , -0.2955,  0.    , ..., -0.    ,  0.2955,  0.    ],
          [ 0.    , -0.    , -0.2823, ...,  0.904 , -0.    ,  0.0954]],

         [[-0.0235,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    , -0.067 ,  0.    , ...,  0.    ,  0.2237,  0.    ],
          [ 0.0761,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.2955,  0.    ,  0.    , ...,  0.8085, -0.    , -0.1987],
          [ 0.    ,  0.    , -0.    , ...,  0.    ,  0.    , -0.    ]],

         [[-0.    ,  0.    ,  0.    , ...,  0.    , -0.0661,  0.    ],
          [-0.2232,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.2137,  0.    ],
          [ 0.9127,  0.    ,  0.    , ..., -0.2389, -0.    ,  0.0587],
          [-0.    , -0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.2823,  0.    ,  0.    , ...,  0.7724, -0.    , -0.1898]],

         ...,

         [[ 0.    , -0.0644, -0.    , ..., -0.    ,  0.0495,  0.    ],
          [ 0.1154, -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.3914, -0.    , ...,  0.    , -0.1601,  0.    ],
          [-0.3089, -0.    ,  0.2389, ...,  0.    ,  0.    , -0.2687],
          [ 0.    , -0.8085,  0.    , ...,  0.    ,  0.    , -0.    ],
          [-0.904 , -0.    , -0.7724, ..., -0.    , -0.    ,  0.8687]],

         [[ 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.2955,  0.    , -0.    , ..., -0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ]],

         [[-0.    ,  0.0158, -0.    , ..., -0.    ,  0.0622,  0.    ],
          [ 0.2227, -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.    , -0.0962, -0.    , ..., -0.    , -0.201 ,  0.    ],
          [-0.9506, -0.    , -0.0587, ...,  0.2687,  0.    ,  0.    ],
          [-0.    ,  0.1987, -0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.0954,  0.    ,  0.1898, ..., -0.8687,  0.    ,  0.    ]]],


        ...,


        [[[ 0.    , -0.1565, -0.    , ..., -0.    ,  0.0351,  0.    ],
          [ 0.4838,  0.    ,  0.4599, ...,  0.1464,  0.    ,  0.    ],
          [ 0.    , -0.0257,  0.    , ...,  0.    , -0.0648,  0.    ],
          [ 0.    , -0.    ,  0.3089, ..., -0.1045,  0.    , -0.3217],
          [ 0.    ,  0.9463, -0.    , ...,  0.    , -0.9463, -0.    ],
          [ 0.    ,  0.    ,  0.0955, ..., -0.3059, -0.    , -0.0323]],

         [[ 0.0754, -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.4323,  0.    , ...,  0.    , -0.1676,  0.    ],
          [-0.0257,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ],
          [-0.9463,  0.    , -0.8085, ..., -0.    , -0.    ,  0.9093],
          [-0.    ,  0.    , -0.    , ..., -0.    ,  0.    ,  0.    ]],

         [[-0.    , -0.    , -0.    , ..., -0.    ,  0.0495,  0.    ],
          [ 0.3925,  0.    ,  0.3929, ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.1601,  0.    ],
          [-0.3089, -0.    ,  0.    , ...,  0.    ,  0.    , -0.2687],
          [ 0.    ,  0.8085,  0.    , ...,  0.    ,  0.    , -0.    ],
          [-0.0955,  0.    ,  0.    , ..., -0.    , -0.    ,  0.8687]],

         ...,

         [[ 0.    ,  0.    ,  0.    , ...,  0.    , -0.1586,  0.    ],
          [ 0.0668,  0.    ,  0.1251, ...,  0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.0542,  0.    ],
          [ 0.1045,  0.    , -0.    , ...,  0.    , -0.    ,  0.8605],
          [-0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.3059,  0.    ,  0.    , ...,  0.    , -0.    , -0.294 ]],

         [[-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.9463,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[ 0.    , -0.0724,  0.    , ...,  0.    , -0.1991,  0.    ],
          [-0.4578, -0.    , -0.4726, ...,  0.    , -0.    ,  0.    ],
          [-0.    ,  0.4401, -0.    , ...,  0.    ,  0.068 ,  0.    ],
          [ 0.3217,  0.    ,  0.2687, ..., -0.8605, -0.    ,  0.    ],
          [ 0.    , -0.9093,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.0323, -0.    , -0.8687, ...,  0.294 , -0.    , -0.    ]]],


        [[[-0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.    ,  0.0796,  0.    , ...,  0.    ,  0.2006,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    , -0.    , -0.2955, ...,  0.9463,  0.    ,  0.0998],
          [ 0.    , -0.    , -0.    , ...,  0.    , -0.    ,  0.    ]],

         [[-0.    , -0.484 , -0.    , ..., -0.    ,  0.1086,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    , -0.0796, -0.    , ..., -0.    , -0.2006,  0.    ],
          [-0.    ,  0.    ,  0.9553, ..., -0.3233,  0.    , -0.995 ],
          [ 0.    ,  0.    , -0.    , ...,  0.    , -0.    , -0.    ],
          [ 0.    ,  0.    ,  0.2955, ..., -0.9463,  0.    , -0.0998]],

         [[-0.5217, -0.    , -0.5304, ..., -0.0983, -0.    ,  0.    ],
          [ 0.    ,  0.0897,  0.    , ..., -0.    ,  0.2237,  0.    ],
          [ 0.0486,  0.    ,  0.0701, ..., -0.2058,  0.    ,  0.    ],
          [ 0.    , -0.9553,  0.    , ...,  0.    ,  0.9553,  0.    ],
          [ 0.2955,  0.    ,  0.    , ...,  1.617 , -0.    , -0.1987],
          [ 0.    , -0.2955,  0.    , ...,  0.    ,  0.2955,  0.    ]],

         ...,

         [[ 0.3463,  0.    ,  0.3688, ..., -0.1086,  0.    ,  0.    ],
          [-0.    ,  0.697 , -0.    , ...,  0.    , -0.1676,  0.    ],
          [ 0.3932,  0.    ,  0.3875, ...,  0.2006,  0.    ,  0.    ],
          [-0.    ,  0.3233, -0.    , ...,  0.    , -0.3233,  0.    ],
          [-0.9463, -0.    , -1.617 , ...,  0.    , -0.    ,  0.9093],
          [-0.    ,  0.9463, -0.    , ...,  0.    , -0.9463, -0.    ]],

         [[-0.    ,  0.484 , -0.    , ...,  0.    , -0.1086,  0.    ],
          [-0.    ,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.0796,  0.    , ..., -0.    ,  0.2006,  0.    ],
          [ 0.    , -0.    , -0.9553, ...,  0.3233,  0.    ,  0.995 ],
          [-0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    , -0.    , -0.2955, ...,  0.9463,  0.    ,  0.0998]],

         [[ 0.4937,  0.    ,  0.5059, ...,  0.1372, -0.    ,  0.    ],
          [-0.    , -0.2413, -0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.072 , -0.    , -0.1741, ...,  0.1822,  0.    ,  0.    ],
          [-0.    ,  0.995 , -0.    , ..., -0.    , -0.995 ,  0.    ],
          [-0.0998,  0.    ,  0.1987, ..., -0.9093,  0.    ,  0.    ],
          [-0.    ,  0.0998, -0.    , ...,  0.    , -0.0998,  0.    ]]],


        [[[-0.    , -0.4816, -0.    , ..., -0.    ,  0.108 ,  0.    ],
          [ 0.1276,  0.    ,  0.0485, ...,  0.0154,  0.    ,  0.    ],
          [-0.    , -0.0792, -0.    , ..., -0.    , -0.1996,  0.    ],
          [ 0.    , -0.    ,  0.9506, ..., -0.3217,  0.    , -0.99  ],
          [ 0.    ,  0.0998, -0.    , ...,  0.    , -0.0998,  0.    ],
          [ 0.    ,  0.    ,  0.294 , ..., -0.9416,  0.    , -0.0993]],

         [[ 0.0079, -0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [-0.    , -0.0309, -0.    , ..., -0.    , -0.2104,  0.    ],
          [-0.0792, -0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ],
          [-0.0998,  0.    ,  0.1987, ..., -0.9093,  0.    ,  0.    ],
          [-0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ]],

         [[-0.    , -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.0181, -0.    , -0.0965, ..., -0.0307,  0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.9506, -0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.    , -0.1987,  0.    , ...,  0.    ,  0.1987, -0.    ],
          [-0.294 , -0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ]],

         ...,

         [[ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.407 ,  0.    ,  0.4419, ...,  0.1407, -0.    ,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.3217,  0.    ,  0.    , ...,  0.    , -0.    , -0.    ],
          [-0.    ,  0.9093, -0.    , ...,  0.    , -0.9093,  0.    ],
          [ 0.9416,  0.    ,  0.    , ...,  0.    , -0.    , -0.    ]],

         [[-0.0079,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    ,  0.0309,  0.    , ...,  0.    ,  0.2104,  0.    ],
          [ 0.0792,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.0998, -0.    , -0.1987, ...,  0.9093,  0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.0796, -0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.99  ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.0993,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ]]]],



       [[[[ 0.486 ,  0.    ,  0.4643, ...,  0.1478, -0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.2237,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.9553, -0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.8085,  0.    ,  0.1987],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ]],

         [[ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.    , -0.    , -0.1436, ..., -0.0457, -0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.2955,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[ 0.4643,  0.    ,  0.486 , ...,  0.1547, -0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.2137,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -1.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.7724,  0.    ,  0.1898],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ]],

         ...,

         [[-0.1571, -0.    , -0.286 , ..., -0.091 ,  0.    ,  0.    ],
          [-0.    , -0.3914,  0.    , ..., -0.    ,  0.1601,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.5885, -0.    ],
          [ 0.8085,  0.    ,  0.7724, ...,  0.    ,  0.    , -0.8687],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ]],

         [[ 0.    , -0.486 ,  0.    , ..., -0.    ,  0.0444,  0.    ],
          [-0.143 ,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.9553,  0.    ,  1.    , ..., -0.5885, -0.    , -0.9801],
          [-0.    , -0.2955, -0.    , ..., -0.    ,  0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[-0.4835, -0.    , -0.4763, ..., -0.1516,  0.    ,  0.    ],
          [ 0.    ,  0.0962,  0.    , ...,  0.    ,  0.201 ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.9801,  0.    ],
          [-0.1987, -0.    , -0.1898, ...,  0.8687, -0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ]]],


        [[[ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.    , -0.    , -0.1436, ..., -0.0457, -0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.2955,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ]],

         [[ 0.486 ,  0.    ,  0.4643, ...,  0.1478, -0.    ,  0.    ],
          [ 0.    , -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    ,  0.    ,  0.1436, ...,  0.0457,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.9553, -0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.2955, -0.    ]],

         [[ 0.    ,  0.    ,  0.    , ...,  0.    , -0.0661,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.2137,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.2389, -0.    ,  0.0587],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.7724, -0.    , -0.1898]],

         ...,

         [[ 0.    , -0.0644, -0.    , ..., -0.    ,  0.0495,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.3914, -0.    , ...,  0.    , -0.1601,  0.    ],
          [ 0.    ,  0.    ,  0.2389, ...,  0.    ,  0.    , -0.2687],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ],
          [ 0.    , -0.    , -0.7724, ...,  0.    , -0.    ,  0.8687]],

         [[-0.0471, -0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.2191, -0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.9553,  0.    , ..., -0.    ,  0.    , -0.    ],
          [-0.2955, -0.    , -0.    , ..., -0.    ,  0.    , -0.    ],
          [-0.    ,  0.2955,  0.    , ...,  0.    ,  0.    , -0.    ]],

         [[-0.    ,  0.0158, -0.    , ..., -0.    ,  0.0622,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.    , -0.0962, -0.    , ..., -0.    , -0.201 ,  0.    ],
          [ 0.    ,  0.    , -0.0587, ...,  0.2687,  0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.    , -0.    ],
          [-0.    ,  0.    ,  0.1898, ..., -0.8687,  0.    ,  0.    ]]],


        [[[ 0.4643,  0.    ,  0.486 , ...,  0.1547, -0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.2137,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -1.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.7724,  0.    ,  0.1898],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ]],

         [[ 0.    ,  0.    ,  0.    , ...,  0.    , -0.0661,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.2137,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.2389, -0.    ,  0.0587],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.7724, -0.    , -0.1898]],

         [[ 0.4435,  0.    ,  0.4643, ...,  0.1478, -0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.2237,  0.    ],
          [ 0.1372,  0.    ,  0.1436, ...,  0.0457,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.9553, -0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.8085,  0.    ,  0.1987],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.2955, -0.    ]],

         ...,

         [[-0.0344, -0.    , -0.2732, ..., -0.087 ,  0.    ,  0.    ],
          [-0.    , -0.3929,  0.    , ..., -0.    ,  0.1676,  0.    ],
          [-0.0274, -0.    , -0.0845, ..., -0.0269,  0.    ,  0.    ],
          [ 0.    ,  0.2389,  0.    , ...,  0.    ,  0.5622, -0.    ],
          [ 0.7724,  0.    ,  0.8085, ...,  0.    ,  0.    , -0.9093],
          [ 0.    , -0.7724,  0.    , ...,  0.    ,  0.1739, -0.    ]],

         [[ 0.    , -0.484 ,  0.    , ..., -0.    ,  0.0425,  0.    ],
          [-0.2872,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    , -0.0796,  0.    , ..., -0.    ,  0.0131,  0.    ],
          [ 1.    ,  0.    ,  0.9553, ..., -0.5622,  0.    , -0.9363],
          [-0.    , -0.    , -0.    , ..., -0.    ,  0.    ,  0.    ],
          [-0.    ,  0.    ,  0.2955, ..., -0.1739,  0.    , -0.2896]],

         [[-0.4904, -0.    , -0.455 , ..., -0.1448,  0.    ,  0.    ],
          [ 0.    ,  0.0965,  0.    , ...,  0.    ,  0.2104,  0.    ],
          [-0.1476, -0.    , -0.1407, ..., -0.0448,  0.    ,  0.    ],
          [ 0.    , -0.0587,  0.    , ...,  0.    ,  0.9363,  0.    ],
          [-0.1898, -0.    , -0.1987, ...,  0.9093, -0.    ,  0.    ],
          [-0.    ,  0.1898,  0.    , ...,  0.    ,  0.2896,  0.    ]]],


        ...,


        [[[-0.1571, -0.    , -0.286 , ..., -0.091 , -0.    ,  0.    ],
          [-0.    ,  0.    ,  0.    , ...,  0.    ,  0.0723,  0.    ],
          [ 0.3914,  0.    ,  0.3929, ...,  0.1251,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.5885,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.2614, -0.    , -0.0642],
          [ 0.    ,  0.8085, -0.    , ...,  0.    , -0.8085, -0.    ]],

         [[-0.    , -0.0644, -0.    , ..., -0.    ,  0.0495,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.3914, -0.    , ...,  0.    , -0.1601,  0.    ],
          [-0.    ,  0.    ,  0.2389, ...,  0.    ,  0.    , -0.2687],
          [ 0.    ,  0.    , -0.    , ...,  0.    , -0.    , -0.    ],
          [-0.8085,  0.    , -0.7724, ...,  0.    , -0.    ,  0.8687]],

         [[-0.2657, -0.    , -0.3893, ..., -0.1239, -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.1316,  0.    ],
          [ 0.3274,  0.    ,  0.2908, ...,  0.0926,  0.    ,  0.    ],
          [-0.    , -0.2389,  0.    , ...,  0.    ,  0.8011,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.4758, -0.    , -0.1169],
          [ 0.    ,  0.7724,  0.    , ...,  0.    , -0.5985, -0.    ]],

         ...,

         [[ 0.0508,  0.    ,  0.0555, ...,  0.1478,  0.    ,  0.    ],
          [ 0.    ,  0.1874, -0.    , ..., -0.    , -0.0986,  0.    ],
          [ 0.2737,  0.    ,  0.3901, ...,  0.0457,  0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    , -0.9553, -0.    ],
          [-0.2614, -0.    , -0.4758, ...,  0.    ,  0.    ,  0.5351],
          [-0.    , -0.    , -0.    , ...,  0.    , -0.2955, -0.    ]],

         [[ 0.    ,  0.3492,  0.    , ...,  0.    ,  0.1478,  0.    ],
          [ 0.4141,  0.    ,  0.3929, ..., -0.    , -0.    ,  0.    ],
          [ 0.    , -0.3445,  0.    , ...,  0.    ,  0.0457,  0.    ],
          [-0.5885, -0.    , -0.8011, ...,  0.9553,  0.    ,  0.3976],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.8085,  0.    ,  0.5985, ...,  0.2955,  0.    ,  0.123 ]],

         [[ 0.2864,  0.    ,  0.2936, ...,  0.0615,  0.    ,  0.    ],
          [ 0.    , -0.0461,  0.    , ..., -0.    , -0.1238,  0.    ],
          [ 0.0063, -0.    , -0.0008, ...,  0.019 ,  0.    ,  0.    ],
          [-0.    ,  0.2687, -0.    , ...,  0.    , -0.3976,  0.    ],
          [ 0.0642,  0.    ,  0.1169, ..., -0.5351, -0.    ,  0.    ],
          [ 0.    , -0.8687,  0.    , ...,  0.    , -0.123 ,  0.    ]]],


        [[[ 0.    , -0.0235,  0.    , ...,  0.    , -0.0593,  0.    ],
          [-0.143 ,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.0761,  0.    , ...,  0.    ,  0.1916,  0.    ],
          [ 0.    ,  0.    ,  0.0873, ..., -0.2797, -0.    , -0.0295],
          [ 0.    , -0.2955, -0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.    , -0.    , -0.2823, ...,  0.904 , -0.    ,  0.0954]],

         [[-0.486 , -0.    , -0.4643, ..., -0.1478, -0.    ,  0.    ],
          [ 0.    , -0.067 ,  0.    , ...,  0.    ,  0.2237,  0.    ],
          [ 0.    , -0.    , -0.1436, ..., -0.0457,  0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ...,  0.    ,  0.9553,  0.    ],
          [ 0.2955,  0.    ,  0.    , ...,  0.8085, -0.    , -0.1987],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.2955,  0.    ]],

         [[ 0.    ,  0.0198,  0.    , ...,  0.    , -0.0661,  0.    ],
          [-0.1436,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    , -0.064 ,  0.    , ...,  0.    ,  0.2137,  0.    ],
          [-0.0873,  0.    ,  0.    , ..., -0.2389, -0.    ,  0.0587],
          [ 0.    , -0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.2823, -0.    ,  0.    , ...,  0.7724, -0.    , -0.1898]],

         ...,

         [[ 0.    , -0.2899, -0.    , ...,  0.    ,  0.2117,  0.    ],
          [ 0.0685, -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    ,  0.3252, -0.    , ..., -0.    , -0.0723,  0.    ],
          [ 0.2797, -0.    ,  0.2389, ...,  0.    ,  0.    , -0.188 ],
          [ 0.    , -0.8085,  0.    , ...,  0.    ,  0.    , -0.    ],
          [-0.904 , -0.    , -0.7724, ...,  0.    ,  0.    ,  0.0642]],

         [[-0.0357, -0.    , -0.0661, ...,  0.0495, -0.    ,  0.    ],
          [-0.    ,  0.2237,  0.    , ..., -0.    , -0.2237,  0.    ],
          [ 0.0486,  0.    ,  0.2137, ..., -0.1601,  0.    ,  0.    ],
          [ 0.    , -0.9553,  0.    , ..., -0.    ,  0.    , -0.    ],
          [-0.    ,  0.    , -0.    , ..., -0.    ,  0.    ,  0.1987],
          [ 0.    , -0.2955,  0.    , ..., -0.    ,  0.    , -0.    ]],

         [[-0.    ,  0.049 , -0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.0962,  0.    ,  0.0965, ...,  0.0307, -0.    ,  0.    ],
          [-0.    , -0.008 ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.0295, -0.    , -0.0587, ...,  0.188 ,  0.    ,  0.    ],
          [-0.    ,  0.1987, -0.    , ...,  0.    , -0.1987,  0.    ],
          [-0.0954, -0.    ,  0.1898, ..., -0.0642,  0.    ,  0.    ]]],


        [[[-0.4835, -0.    , -0.4763, ..., -0.1516, -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.2226,  0.    ],
          [-0.0962,  0.    , -0.0965, ..., -0.0307,  0.    ,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    ,  0.9801,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.8045, -0.    , -0.1977],
          [ 0.    , -0.1987, -0.    , ...,  0.    ,  0.1987,  0.    ]],

         [[-0.    ,  0.0158, -0.    , ..., -0.    ,  0.0622,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.    , -0.0962, -0.    , ..., -0.    , -0.201 ,  0.    ],
          [ 0.    ,  0.    , -0.0587, ...,  0.2687,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    , -0.    ],
          [ 0.1987,  0.    ,  0.1898, ..., -0.8687,  0.    ,  0.    ]],

         [[-0.4335, -0.    , -0.4265, ..., -0.1358, -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.2192,  0.    ],
          [-0.2348, -0.    , -0.233 , ..., -0.0742,  0.    ,  0.    ],
          [-0.    ,  0.0587,  0.    , ...,  0.    ,  0.8776,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.7924, -0.    , -0.1947],
          [ 0.    , -0.1898,  0.    , ...,  0.    ,  0.4794,  0.    ]],

         ...,

         [[ 0.0262,  0.    ,  0.0234, ...,  0.0074, -0.    ,  0.    ],
          [-0.    ,  0.3958, -0.    , ...,  0.    , -0.1642,  0.    ],
          [ 0.8781,  0.    ,  0.8728, ...,  0.2779,  0.    ,  0.    ],
          [-0.    , -0.2687, -0.    , ...,  0.    , -0.0481,  0.    ],
          [-0.8045, -0.    , -0.7924, ...,  0.    , -0.    ,  0.8912],
          [-0.    ,  0.8687, -0.    , ...,  0.    , -1.7961, -0.    ]],

         [[-0.    ,  0.4586, -0.    , ...,  0.    , -0.1686,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.1742,  0.    , ...,  0.    ,  0.3976,  0.    ],
          [-0.9801, -0.    , -0.8776, ...,  0.0481,  0.    ,  0.9752],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [-0.1987, -0.    , -0.4794, ...,  1.7961,  0.    ,  0.0978]],

         [[ 0.4811,  0.    ,  0.4739, ...,  0.1509, -0.    ,  0.    ],
          [-0.    , -0.0973, -0.    , ..., -0.    , -0.2062,  0.    ],
          [ 0.0483,  0.    ,  0.0475, ...,  0.0151,  0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.9752,  0.    ],
          [ 0.1977,  0.    ,  0.1947, ..., -0.8912,  0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    , -0.0978,  0.    ]]]],



       ...,



       [[[[ 0.1547,  0.    ,  0.1478, ..., -0.05  ,  0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    ,  0.1676,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.3233, -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.9093],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    , -0.    ]],

         [[ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [-0.    , -0.    , -0.0457, ...,  0.1464,  0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.9463, -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ]],

         [[ 0.1478,  0.    ,  0.1547, ..., -0.091 ,  0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    ,  0.1601,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.5885, -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.8687],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    , -0.    ]],

         ...,

         [[-0.05  , -0.    , -0.091 , ...,  0.1547,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.0542,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -1.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.294 ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[ 0.    ,  0.2318,  0.    , ...,  0.    ,  0.1547,  0.    ],
          [ 0.4581,  0.    ,  0.5056, ..., -0.    , -0.    ,  0.    ],
          [ 0.    , -0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.3233, -0.    , -0.5885, ...,  1.    ,  0.    ,  0.4161],
          [-0.    ,  0.9463, -0.    , ..., -0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ]],

         [[-0.1539, -0.    , -0.1516, ...,  0.0644,  0.    ,  0.    ],
          [ 0.    , -0.4401,  0.    , ..., -0.    , -0.068 ,  0.    ],
          [ 0.    , -0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.4161,  0.    ],
          [ 0.9093,  0.    ,  0.8687, ..., -0.294 ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ]]],


        [[[ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [-0.    , -0.    , -0.0457, ...,  0.1464,  0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.9463, -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    , -0.    ]],

         [[ 0.1547,  0.    ,  0.1478, ..., -0.05  ,  0.    ,  0.    ],
          [ 0.    , -0.    , -0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.    ,  0.    ,  0.0457, ..., -0.1464, -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.3233, -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.9463,  0.    ]],

         [[ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.0495,  0.    ],
          [ 0.    ,  0.    , -0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.1601,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.2687],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.8687]],

         ...,

         [[-0.    , -0.    , -0.    , ...,  0.    , -0.1586,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.0542,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.8605],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    , -0.294 ]],

         [[-0.2358, -0.    , -0.3049, ..., -0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.4838, -0.    , -0.5056, ...,  0.    ,  0.    ,  0.    ],
          [-0.    , -0.3233, -0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.9463,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    , -0.9463,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[ 0.    , -0.0724, -0.    , ...,  0.    , -0.1991,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.    ,  0.4401, -0.    , ...,  0.    ,  0.068 ,  0.    ],
          [ 0.    ,  0.    ,  0.2687, ..., -0.8605, -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    , -0.    , -0.8687, ...,  0.294 , -0.    , -0.    ]]],


        [[[ 0.1478,  0.    ,  0.1547, ..., -0.091 ,  0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    ,  0.1601,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.5885, -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.8687],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    , -0.    ]],

         [[ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.0495,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.1601,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.2687],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.8687]],

         [[ 0.1412,  0.    ,  0.1478, ..., -0.087 ,  0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    ,  0.1676,  0.    ],
          [ 0.0437,  0.    ,  0.0457, ..., -0.0269,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.5622, -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.9093],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.1739, -0.    ]],

         ...,

         [[-0.0478, -0.    , -0.087 , ...,  0.1478,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.0986,  0.    ],
          [-0.0148, -0.    , -0.0269, ...,  0.0457,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.9553, -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.5351],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.2955, -0.    ]],

         [[ 0.    ,  0.2849,  0.    , ...,  0.    ,  0.1478,  0.    ],
          [ 0.4141,  0.    ,  0.3929, ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.0469,  0.    , ...,  0.    ,  0.0457,  0.    ],
          [-0.5885, -0.    , -0.5622, ...,  0.9553,  0.    ,  0.3976],
          [-0.    , -0.    , -0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    , -0.1739, ...,  0.2955,  0.    ,  0.123 ]],

         [[-0.017 , -0.    , -0.1448, ...,  0.0615,  0.    ,  0.    ],
          [ 0.    , -0.4419,  0.    , ..., -0.    , -0.1238,  0.    ],
          [-0.0241, -0.    , -0.0448, ...,  0.019 ,  0.    ,  0.    ],
          [ 0.    ,  0.2687,  0.    , ...,  0.    , -0.3976,  0.    ],
          [ 0.8687,  0.    ,  0.9093, ..., -0.5351, -0.    ,  0.    ],
          [ 0.    , -0.8687,  0.    , ...,  0.    , -0.123 ,  0.    ]]],


        ...,


        [[[-0.05  , -0.    , -0.091 , ...,  0.1547,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.0542,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -1.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.294 ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[-0.    , -0.    , -0.    , ...,  0.    , -0.1586,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.0542,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.8605],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    , -0.294 ]],

         [[-0.0478, -0.    , -0.087 , ...,  0.1478,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.0986,  0.    ],
          [-0.0148, -0.    , -0.0269, ...,  0.0457,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.9553, -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.5351],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.2955, -0.    ]],

         ...,

         [[ 0.0162,  0.    ,  0.0294, ..., -0.05  ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.1676,  0.    ],
          [ 0.0473,  0.    ,  0.0861, ..., -0.1464, -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.3233, -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.9093],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.9463,  0.    ]],

         [[ 0.    , -0.484 ,  0.    , ..., -0.    , -0.05  ,  0.    ],
          [ 0.2928,  0.    ,  0.2501, ...,  0.    ,  0.    ,  0.    ],
          [-0.    , -0.0796, -0.    , ..., -0.    , -0.1464,  0.    ],
          [ 1.    ,  0.    ,  0.9553, ..., -0.3233,  0.    , -0.1345],
          [-0.    , -0.    , -0.    , ..., -0.    ,  0.    , -0.    ],
          [-0.    ,  0.    ,  0.2955, ..., -0.9463,  0.    , -0.3938]],

         [[-0.3667, -0.    , -0.4107, ..., -0.0208,  0.    ,  0.    ],
          [ 0.    ,  0.2108,  0.    , ..., -0.    ,  0.2104,  0.    ],
          [ 0.4286,  0.    ,  0.4207, ..., -0.0609, -0.    ,  0.    ],
          [ 0.    , -0.8605,  0.    , ...,  0.    ,  0.1345,  0.    ],
          [-0.294 , -0.    , -0.5351, ...,  0.9093,  0.    ,  0.    ],
          [-0.    ,  0.294 ,  0.    , ..., -0.    ,  0.3938,  0.    ]]],


        [[[ 0.    ,  0.0754,  0.    , ...,  0.    ,  0.1898,  0.    ],
          [ 0.4581,  0.    ,  0.5056, ..., -0.    , -0.    ,  0.    ],
          [-0.    , -0.0257, -0.    , ..., -0.    , -0.0648,  0.    ],
          [ 0.    , -0.    , -0.2797, ...,  0.8955,  0.    ,  0.0945],
          [ 0.    ,  0.9463,  0.    , ..., -0.    ,  0.    , -0.    ],
          [ 0.    , -0.    ,  0.0955, ..., -0.3059,  0.    , -0.0323]],

         [[-0.1547, -0.    , -0.1478, ...,  0.05  ,  0.    ,  0.    ],
          [ 0.    ,  0.4323,  0.    , ...,  0.    , -0.1676,  0.    ],
          [ 0.    , -0.    , -0.0457, ...,  0.1464,  0.    ,  0.    ],
          [ 0.    ,  0.    , -0.    , ...,  0.    , -0.3233,  0.    ],
          [-0.9463,  0.    , -0.8085, ..., -0.    , -0.    ,  0.9093],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.9463, -0.    ]],

         [[ 0.    , -0.0634,  0.    , ...,  0.    ,  0.2117,  0.    ],
          [ 0.3456,  0.    ,  0.3929, ..., -0.    , -0.    ,  0.    ],
          [-0.    ,  0.0217, -0.    , ..., -0.    , -0.0723,  0.    ],
          [ 0.2797,  0.    ,  0.    , ...,  0.7651,  0.    , -0.188 ],
          [-0.    ,  0.8085,  0.    , ..., -0.    ,  0.    , -0.    ],
          [-0.0955, -0.    ,  0.    , ..., -0.2614,  0.    ,  0.0642]],

         ...,

         [[-0.    ,  0.4091, -0.    , ..., -0.    , -0.1586,  0.    ],
          [ 0.1464, -0.    ,  0.1251, ...,  0.    ,  0.    ,  0.    ],
          [ 0.    , -0.1398,  0.    , ..., -0.    ,  0.0542,  0.    ],
          [-0.8955, -0.    , -0.7651, ...,  0.    ,  0.    ,  0.8605],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.3059,  0.    ,  0.2614, ...,  0.    ,  0.    , -0.294 ]],

         [[ 0.501 ,  0.    ,  0.5166, ..., -0.1586,  0.    ,  0.    ],
          [ 0.    , -0.1676,  0.    , ...,  0.    ,  0.1676,  0.    ],
          [ 0.3932,  0.    ,  0.4333, ...,  0.0542, -0.    ,  0.    ],
          [-0.    ,  0.3233, -0.    , ..., -0.    ,  0.    , -0.    ],
          [-0.    ,  0.    , -0.    , ..., -0.    ,  0.    , -0.9093],
          [-0.    ,  0.9463, -0.    , ..., -0.    ,  0.    ,  0.    ]],

         [[-0.    , -0.2116, -0.    , ..., -0.    ,  0.    ,  0.    ],
          [-0.4401, -0.    , -0.4419, ..., -0.1407,  0.    ,  0.    ],
          [ 0.    , -0.0887,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.0945, -0.    ,  0.188 , ..., -0.8605,  0.    ,  0.    ],
          [ 0.    , -0.9093,  0.    , ...,  0.    ,  0.9093, -0.    ],
          [ 0.0323,  0.    , -0.0642, ...,  0.294 , -0.    , -0.    ]]],


        [[[-0.1539, -0.    , -0.1516, ...,  0.0644,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.1667,  0.    ],
          [ 0.4401,  0.    ,  0.4419, ...,  0.1407,  0.    ,  0.    ],
          [ 0.    ,  0.    , -0.    , ...,  0.    , -0.4161,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.9048],
          [ 0.    ,  0.9093, -0.    , ..., -0.    , -0.9093, -0.    ]],

         [[-0.    , -0.0724, -0.    , ..., -0.    , -0.1991,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    ,  0.4401,  0.    , ...,  0.    ,  0.068 ,  0.    ],
          [-0.    ,  0.    ,  0.2687, ..., -0.8605, -0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.9093,  0.    , -0.8687, ...,  0.294 , -0.    , -0.    ]],

         [[-0.2771, -0.    , -0.2754, ...,  0.0199,  0.    ,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    , -0.1642,  0.    ],
          [ 0.375 ,  0.    ,  0.3773, ...,  0.1534,  0.    ,  0.    ],
          [ 0.    , -0.2687,  0.    , ...,  0.    , -0.1288,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.8912],
          [ 0.    ,  0.8687,  0.    , ..., -0.    , -0.9917, -0.    ]],

         ...,

         [[ 0.4663,  0.    ,  0.4672, ...,  0.1123,  0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ..., -0.    ,  0.0697,  0.    ],
          [ 0.0034, -0.    ,  0.0006, ..., -0.1064, -0.    ,  0.    ],
          [-0.    ,  0.8605, -0.    , ...,  0.    , -0.7259, -0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    , -0.3784],
          [ 0.    , -0.294 ,  0.    , ...,  0.    ,  0.6878,  0.    ]],

         [[ 0.    , -0.129 ,  0.    , ...,  0.    ,  0.2443,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    , -0.4733,  0.    , ..., -0.    , -0.1515,  0.    ],
          [ 0.4161,  0.    ,  0.1288, ...,  0.7259,  0.    , -0.4141],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.9093,  0.    ,  0.9917, ..., -0.6878,  0.    , -0.0415]],

         [[ 0.1532,  0.    ,  0.1509, ..., -0.0641,  0.    ,  0.    ],
          [-0.    ,  0.4452, -0.    , ...,  0.    ,  0.0876,  0.    ],
          [ 0.0154, -0.    ,  0.0151, ..., -0.0064, -0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.4141,  0.    ],
          [-0.9048, -0.    , -0.8912, ...,  0.3784, -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.0415,  0.    ]]]],



       [[[[-0.    , -0.1086, -0.    , ...,  0.    ,  0.1086,  0.    ],
          [-0.2006, -0.    , -0.2237, ...,  0.1676, -0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.995 ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.    , -0.2006, -0.    , ...,  0.    ,  0.2006,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.0998],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[-0.    , -0.0444, -0.    , ...,  0.    ,  0.0444,  0.    ],
          [-0.1916, -0.    , -0.2137, ...,  0.1601, -0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.9801],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         ...,

         [[ 0.    , -0.1547,  0.    , ...,  0.    ,  0.1547,  0.    ],
          [ 0.0648,  0.    ,  0.0723, ..., -0.0542, -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.4161],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[ 0.    ,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    ,  0.2006, -0.    , ..., -0.    , -0.2006,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.0998],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ]],

         [[-0.    , -0.4016,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.1512,  0.    ,  0.1741, ..., -0.1822, -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.995 ,  0.    ,  0.9801, ..., -0.4161,  0.    ,  0.    ],
          [-0.    , -0.0998, -0.    , ...,  0.    ,  0.0998,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.    ,  0.    ]]],


        [[[-0.    , -0.    , -0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.    , -0.2006, -0.    , ...,  0.    ,  0.2006,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.0998],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[-0.    , -0.1086, -0.    , ...,  0.    ,  0.1086,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.2006,  0.    , ..., -0.    , -0.2006,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.995 ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.0998]],

         [[-0.0593, -0.    , -0.0661, ...,  0.0495, -0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.1916,  0.    ,  0.2137, ..., -0.1601,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ]],

         ...,

         [[ 0.1898,  0.    ,  0.2117, ..., -0.1586,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [-0.0648, -0.    , -0.0723, ...,  0.0542,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[-0.    ,  0.1086, -0.    , ..., -0.    , -0.1086,  0.    ],
          [-0.    ,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    , -0.2006,  0.    , ...,  0.    ,  0.2006,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.995 ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.0998]],

         [[ 0.4937,  0.    ,  0.5059, ...,  0.1372, -0.    ,  0.    ],
          [-0.    , -0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [-0.072 , -0.    , -0.1741, ...,  0.1822,  0.    ,  0.    ],
          [ 0.    ,  0.995 ,  0.    , ..., -0.    , -0.995 ,  0.    ],
          [-0.0998, -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.    ,  0.0998,  0.    , ..., -0.    , -0.0998,  0.    ]]],


        [[[-0.    , -0.0444, -0.    , ...,  0.    ,  0.0444,  0.    ],
          [-0.1916, -0.    , -0.2137, ...,  0.1601, -0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.9801],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[-0.0593, -0.    , -0.0661, ...,  0.0495, -0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.1916,  0.    ,  0.2137, ..., -0.1601,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ]],

         [[-0.    , -0.0425, -0.    , ...,  0.    ,  0.0425,  0.    ],
          [-0.2006, -0.    , -0.2237, ...,  0.1676, -0.    ,  0.    ],
          [ 0.    , -0.0131,  0.    , ...,  0.    ,  0.0131,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.9363],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.2896]],

         ...,

         [[ 0.    , -0.1478,  0.    , ...,  0.    ,  0.1478,  0.    ],
          [ 0.118 ,  0.    ,  0.1316, ..., -0.0986, -0.    ,  0.    ],
          [-0.    , -0.0457, -0.    , ...,  0.    ,  0.0457,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.3976],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.123 ]],

         [[-0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.    ,  0.2237, -0.    , ..., -0.    , -0.2237,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.1987],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ]],

         [[-0.    , -0.3903,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [ 0.1481,  0.    ,  0.3158, ..., -0.1335, -0.    ,  0.    ],
          [-0.    , -0.052 ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.9801,  0.    ,  0.9363, ..., -0.3976,  0.    ,  0.    ],
          [-0.    , -0.    , -0.    , ..., -0.    , -0.1987,  0.    ],
          [-0.    ,  0.    ,  0.2896, ..., -0.123 ,  0.    ,  0.    ]]],


        ...,


        [[[ 0.    , -0.1547,  0.    , ...,  0.    ,  0.1547,  0.    ],
          [ 0.0648,  0.    ,  0.0723, ..., -0.0542, -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.4161],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ]],

         [[ 0.1898,  0.    ,  0.2117, ..., -0.1586,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.0648, -0.    , -0.0723, ...,  0.0542,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[ 0.    , -0.1478,  0.    , ...,  0.    ,  0.1478,  0.    ],
          [ 0.118 ,  0.    ,  0.1316, ..., -0.0986, -0.    ,  0.    ],
          [-0.    , -0.0457, -0.    , ...,  0.    ,  0.0457,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.3976],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.123 ]],

         ...,

         [[-0.    ,  0.05  , -0.    , ...,  0.    , -0.05  ,  0.    ],
          [-0.2006, -0.    , -0.2237, ...,  0.1676,  0.    ,  0.    ],
          [ 0.    ,  0.1464,  0.    , ..., -0.    , -0.1464,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.1345],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.3938]],

         [[ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    , -0.1676,  0.    , ...,  0.    ,  0.1676,  0.    ],
          [-0.    ,  0.    , -0.    , ...,  0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.9093],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[-0.    ,  0.173 , -0.    , ..., -0.    ,  0.    ,  0.    ],
          [-0.0989, -0.    , -0.0624, ..., -0.0709,  0.    ,  0.    ],
          [ 0.    , -0.0501,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [-0.4161, -0.    , -0.3976, ...,  0.1345,  0.    ,  0.    ],
          [ 0.    ,  0.    , -0.    , ...,  0.    ,  0.9093, -0.    ],
          [ 0.    , -0.    , -0.123 , ...,  0.3938, -0.    , -0.    ]]],


        [[[-0.    ,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    ,  0.2006, -0.    , ..., -0.    , -0.2006,  0.    ],
          [-0.    ,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.0998],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ]],

         [[-0.    ,  0.1086, -0.    , ..., -0.    , -0.1086,  0.    ],
          [-0.    ,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    , -0.2006,  0.    , ...,  0.    ,  0.2006,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.995 ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.0998]],

         [[-0.    ,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    ,  0.2237, -0.    , ..., -0.    , -0.2237,  0.    ],
          [ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.1987],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ]],

         ...,

         [[ 0.    , -0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    , -0.1676,  0.    , ...,  0.    ,  0.1676,  0.    ],
          [-0.    ,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.9093],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[ 0.    , -0.1086,  0.    , ...,  0.    ,  0.1086,  0.    ],
          [-0.    ,  0.    , -0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.    ,  0.2006, -0.    , ..., -0.    , -0.2006,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.995 ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    , -0.0998]],

         [[-0.5217, -0.    , -0.5282, ..., -0.1205,  0.    ,  0.    ],
          [ 0.    ,  0.2413,  0.    , ..., -0.    , -0.    ,  0.    ],
          [ 0.3508,  0.    ,  0.3966, ..., -0.3489, -0.    ,  0.    ],
          [ 0.    , -0.995 ,  0.    , ...,  0.    ,  0.995 ,  0.    ],
          [ 0.0998,  0.    , -0.1987, ...,  0.9093, -0.    ,  0.    ],
          [ 0.    , -0.0998,  0.    , ..., -0.    ,  0.0998,  0.    ]]],


        [[[-0.    ,  0.0801, -0.    , ..., -0.    , -0.108 ,  0.    ],
          [ 0.1512,  0.    ,  0.1741, ..., -0.1822, -0.    ,  0.    ],
          [ 0.    ,  0.0792,  0.    , ...,  0.    ,  0.1996,  0.    ],
          [ 0.    ,  0.    ,  0.0295, ..., -0.0945,  0.    ,  0.99  ],
          [ 0.    , -0.0998, -0.    , ...,  0.    ,  0.0998, -0.    ],
          [ 0.    , -0.    , -0.294 , ...,  0.9416, -0.    ,  0.0993]],

         [[ 0.02  ,  0.    ,  0.0223, ..., -0.0167, -0.    ,  0.    ],
          [ 0.    ,  0.0309,  0.    , ...,  0.    ,  0.2104,  0.    ],
          [-0.1996, -0.    , -0.2226, ...,  0.1667,  0.    ,  0.    ],
          [-0.    ,  0.    , -0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.0998,  0.    , -0.1987, ...,  0.9093, -0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]],

         [[-0.    ,  0.0908,  0.    , ..., -0.    , -0.1064,  0.    ],
          [ 0.2927,  0.    ,  0.3158, ..., -0.1335, -0.    ,  0.    ],
          [ 0.    , -0.0406,  0.    , ...,  0.    ,  0.1966,  0.    ],
          [-0.0295,  0.    ,  0.    , ..., -0.0807, -0.    ,  0.9752],
          [ 0.    ,  0.1987,  0.    , ..., -0.    , -0.1987, -0.    ],
          [ 0.294 , -0.    ,  0.    , ...,  0.8045,  0.    ,  0.0978]],

         ...,

         [[-0.    , -0.0716, -0.    , ..., -0.    ,  0.0452,  0.    ],
          [-0.5236, -0.    , -0.535 , ..., -0.0709, -0.    ,  0.    ],
          [ 0.    ,  0.3469,  0.    , ...,  0.    , -0.0835,  0.    ],
          [ 0.0945, -0.    ,  0.0807, ...,  0.    ,  0.    , -0.4141],
          [-0.    , -0.9093,  0.    , ...,  0.    ,  0.9093,  0.    ],
          [-0.9416, -0.    , -0.8045, ...,  0.    , -0.    , -0.0415]],

         [[-0.02  , -0.    , -0.0223, ...,  0.0167, -0.    ,  0.    ],
          [-0.    , -0.0309, -0.    , ..., -0.    , -0.2104,  0.    ],
          [ 0.1996,  0.    ,  0.2226, ..., -0.1667, -0.    ,  0.    ],
          [-0.    ,  0.    ,  0.    , ..., -0.    ,  0.    , -0.    ],
          [-0.0998,  0.    ,  0.1987, ..., -0.9093,  0.    ,  0.    ],
          [ 0.    ,  0.    , -0.    , ...,  0.    ,  0.    , -0.    ]],

         [[-0.    ,  0.3996, -0.    , ...,  0.    , -0.    ,  0.    ],
          [-0.2006, -0.    , -0.2237, ...,  0.1676,  0.    ,  0.    ],
          [ 0.    ,  0.0401,  0.    , ..., -0.    , -0.    ,  0.    ],
          [-0.99  , -0.    , -0.9752, ...,  0.4141,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ..., -0.    ,  0.    ,  0.    ],
          [-0.0993, -0.    , -0.0978, ...,  0.0415,  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.    ],
          [ 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.    ,  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.    ,  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.    ],
          [ 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.    ,  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.    ,  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.    ],
          [ 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.    ,  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.    ,  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.    ],
          [ 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.    ,  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.    ,  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.    ],
          [ 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.    ,  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.    ,  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.    ],
          [ 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.    ,  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.    ,  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.    ],
          [ 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.    ,  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.    ,  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.    ],
          [ 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.    ,  0.    , ...,  0.    ,  0.    ,  0.    ],
          [ 0.    ,  0.    ,  0.    , ...,  0.    ,  0.    ,  0.    ]]]]],
      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).

payload(m, p=None)

Add a payload to the end-effector

Parameters:
Return type:

None

payload(m, p) adds a payload with point mass m at position p in the end-effector coordinate frame.

payload(m) adds a payload with point mass m at the origin of the end-effector coordinate frame.

payload(0) removes added payload.

The point mass is combined with the mass, centre of mass and inertia of the end-effector link, and p is expressed in that link’s frame. The link’s own parameters are kept, so each call replaces the payload added by the previous one, and a payload of zero mass leaves the dynamics unchanged.

Note

The end-effector link is ee_links[0] when the robot has a single end-effector. A robot with several end-effectors has no single end-effector link, and the payload is added to links[n - 1] as in earlier releases.

payload_capacity(q, tau_m, w, frame='base')

Compute the payload capacity of the manipulator

Parameters:
  • q (ndarray | Sequence[float]) – Joint coordinates for trajectory

  • tau_m (ndarray | Sequence[float]) – actuator torque limits

  • w (ndarray | Sequence[float]) – External wrench applied to the end-effector

  • frame (Literal['base', 'ee']) – the frame in which w is expressed, "base" for the base frame (default) and "ee" for the end-effector frame, which includes the tool transform

Returns:

Payload capacity of the manipulator

Return type:

ndarray

For each configuration, row of q, compute the multiple of the applied external wrench w that can be applied to the end-effector without exceeding the actuator torque limits tau_m. If w is the weight of a 1 kg mass then the multiple is the capacity in kg. A load such as a weight is fixed in the world, so w is in the base frame by default; use frame="ee" for a wrench that is fixed to the end-effector, such as a force along the tool axis. This multiple is computed for each joint and can be

  • a positive real number

  • inf the joint has no role in determining the payload capacity

  • nan the gravity load already exceeds the joint torque limit

The joint with the lowest payload capacity is the one that determines the overall payload capacity for that configuration.

The result is a matrix of payload capacities for each joint and configuration.

The joint force/torque limits tau_m are given as an array of shape (n,) or (1,n) of maximum values, in which case the minimum is the negative of the maximum, or (2,n), in which case the first row is the minimum and the second row is the maximum.

Examples

In this example we compute the payload capacity of the Puma560 robot along a straight line trajectory in the x-direction, moving from tightly folded to almost straight. The end-effector is oriented with the tool frame pointing in the x-direction, and a tool offset is added so that the load causes a moment on the wrist. The external wrench is a downward force of 9.81 N, which is equivalent to a 1 kg mass. The torque limits are the motor fuse limits from Table 2.17 of “Visual Control of Robots”, Corke (1996). The payload capacity, as well as the limiting joint, is plotted as a function of the x-position of the end-effector. The minimum payload capacity is also plotted, along with the index of the joint that determines the payload capacity.

>>> from roboticstoolbox import models
>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> from spatialmath import SE3
>>> puma = models.DH.Puma560()
>>> puma.tool = SE3.Tz(0.05)
>>> T = SE3.Tx(np.arange(0.35, 0.85, 0.01)) * SE3.Tz(puma.links[0].d) * SE3.Ry(90, "deg")
>>> sol = puma.ikine_a(T)
>>> w = [0,0,-9.81,0,0,0]
>>> cap = puma.payload_capacity(sol.q, [56, 97, 52,10,10,10], w)
>>> plt.plot(T.x, [np.min(c) for c in cap])
>>> plt.plot(T.x, [np.argmin(c) for c in cap])

(Source code, png, hires.png, pdf)

_images/arm_superclass-1.png

Derived from the MATLAB functions pay and paycap originally contributed to the MATLAB Robotics Toolbox by Bryan Moutrie (@au-phiware). Ported to Python and adapted for robotics-toolbox-python with permission from the original author.

Added in version 1.5.0.

Seealso:

gravload() payload()

perturb(p=0.1)

Perturb robot parameters

Parameters:

p (float) – The percent (+/-) to be perturbed. Default 10%

Return type:

Any

Returns:

A copy of the robot with dynamic parameters perturbed

rp = perturb(p) is a new robot object in which the dynamic parameters (link mass and inertia) have been perturbed. The perturbation is multiplicative so that values are multiplied by random numbers in the interval (1-p) to (1+p). The name string of the perturbed robot is prefixed by ‘P/’.

Useful for investigating the robustness of various model-based control schemes. For example to vary parameters in the range +/- 10 percent is: r2 = puma.perturb(0.1)

plot(q, backend=None, block=False, dt=0.05, limits=None, vellipse=False, fellipse=False, fig=None, movie=None, loop=False, notebook=None, ax=None, env=None, view=None, **kwargs)

Graphical display and animation

robot.plot(q, 'pyplot') displays a graphical view of a robot based on the kinematic model and the joint configuration q. This is a stick figure polyline which joins the origins of the link coordinate frames. The plot will autoscale with an aspect ratio of 1.

If q (m,n) representing a joint-space trajectory it will create an animation with a pause of dt seconds between each frame.

Parameters:
  • q (ndarray | Sequence[float]) – The joint configuration of the robot.

  • backend (Optional[Literal['swift', 'pyplot', 'pyplot2']]) – The graphical backend to use, currently ‘swift’ and ‘pyplot’ are implemented. Defaults to ‘swift’ of a Robot and ‘pyplot` for a DHRobot

  • block (bool) – True waits until the window is closed; the PyPlot backend has already shown the figure, so False and None return at once, defaults to False

  • dt (float) – if q is a trajectory, this describes the delay in seconds between frames

  • limits (ndarray | Sequence[float] | None) – Custom view limits for the plot. If not supplied will autoscale, [x1, x2, y1, y2, z1, z2] (this option is for ‘pyplot’ only)

  • vellipse (bool) – (Plot Option) Plot the velocity ellipse at the end-effector (this option is for ‘pyplot’ only)

  • fellipse (bool) – (Plot Option) Plot the force ellipse at the end-effector (this option is for ‘pyplot’ only)

  • fig (str | None) – (Plot Option) The figure label to plot in (this option is for ‘pyplot’ only)

  • ax (Any) – (Plot Option) Existing Matplotlib 3D axes to draw the scene on, instead of making a figure (this option is for ‘pyplot’ only)

  • env (Connector | None) – The scene returned by an earlier plot, to add this robot to, instead of making a new scene; see Several configurations below. The backend of the scene is used, so backend is ignored, and the options that are set when a scene is made (limits, fig, ax, render_mode, inline_*, notebook and browser) cannot be given

  • color – (Plot Option) The color of the robot’s line, any Matplotlib color (this option is for ‘pyplot’ only)

  • view (str | None) – (Plot Option) "xy", "xz" or "yz" to start with a flat view of that plane, the first axis to the right and the second up, or None (default) for the usual three-dimensional view. The view is not locked, the plot can be rotated as usual. With env it changes the view of that scene (this option is for ‘pyplot’ only)

  • movie (str | None) – (Plot Option) The filename to save the movie to (this option is for ‘pyplot’ only)

  • loop (bool) – (Plot Option) Loop the movie (this option is for ‘pyplot’ only)

  • notebook (bool | None) – (Plot Option, Swift only) True shows Swift in a frame of the current notebook cell, False opens it in a browser window, and None (default) chooses the frame in a notebook, unless a browser is named, and a window otherwise, so the same call works in a script and in a notebook. The browser showing the notebook must be on the machine running the kernel, since the frame points at localhost

  • browser – (Plot Option, Swift only) the browser for the window, or None (default) for the system’s. This is a name known to Python’s webbrowser module, which depends on the operating system, for example "chrome", "firefox" or "safari" on macOS and "google-chrome" or "chromium" on Linux, or a command line with %s where the URL goes, for any other browser; webbrowser.get(name) tells you whether a name works. Naming a browser means a window, not the notebook frame. browser="notebook" is deprecated, use notebook=True. See swift.Swift.Swift.launch()

  • realtime – (Plot Option) Pace the steps of a trajectory in real time, one each dt, defaults to True for a trajectory (this option is for ‘swift’ only)

  • jointaxes – (Plot Option) Plot an arrow indicating the axes in which the joint revolves around(revolute joint) or translates along (prosmatic joint) (this option is for ‘pyplot’ only)

  • eeframe – (Plot Option) Plot the end-effector coordinate frame at the location of the end-effector. Uses three arrows, red, green and blue to indicate the x, y, and z-axes. (this option is for ‘pyplot’ only)

  • shadow – (Plot Option) Plot a shadow of the robot in the x-y plane. (this option is for ‘pyplot’ only)

  • name – (Plot Option) Plot the name of the robot near its base (this option is for ‘pyplot’ only)

  • render_mode – (Plot Option) Rendering mode for matplotlib backends: 'window', 'notebook-widget', or 'notebook-inline'. If omitted, a mode is chosen from the environment, so the same call works for any %matplotlib setting: for the interactive ipympl backend a single pose is a widget that can be rotated, but a trajectory uses 'notebook-inline', since a widget cannot update while the cell is running.

  • inline_every_n – (Plot Option) In notebook-inline mode, push one rendered frame every N simulation steps. Larger N reduces output load.

  • inline_format – (Plot Option) In notebook-inline mode, frame format: 'svg' (default) or 'png'.

  • inline_dpi – (Plot Option) DPI for PNG inline frames only; ignored when inline_format='svg'.

Return type:

Connector

Returns:

A reference to the environment object which controls the figure

Note

Python’s webbrowser module cannot tell whether a browser is installed, so a browser that cannot be opened is not reported as such. On macOS the names "chrome", "firefox" and "safari" are always accepted, whether or not the app is installed. If it is not, no window opens and there is no error: Swift waits about 10 seconds for the page to connect and then reports Could not connect to the Swift simulator. If you see that, check that the browser named by browser is installed, or leave it as None to use the system’s default browser. See swift.Swift.Swift.launch().

Several configurations

plot returns the scene it made, and passing that as env to another plot adds a robot to it instead of making a new scene. The robot is the same model, and each plot of it holds the pose it was given, so the robot is shown in two configurations at once, here the initial and the final. Give each a color, and turn off what would be drawn twice.

import roboticstoolbox as rtb

puma = rtb.models.DH.Puma560()
env = puma.plot(puma.qr, color="gray", block=False)
puma.plot(puma.qn, env=env, color="red", name=False, block=False)

(Source code, png, hires.png, pdf)

_images/arm_superclass-2.png

The scene can be given a pose to draw directly, handle = env.add(puma, q=q), and handle.q = q moves only that drawing. A robot that is added without a q follows puma.q, as it always has. A trajectory can be plotted on top of an earlier plot in the same way; the earlier plot stays where it was. In a notebook, an animation needs the scene to have been made with render_mode="notebook-inline".

Notes

  • By default this method will block until the figure is dismissed.

    To avoid this set block=False.

  • For PyPlot, the polyline joins the origins of the link frames,

    but for some Denavit-Hartenberg models those frames may not actually be on the robot, ie. the lines to not necessarily represent the links of the robot.

See also

teach()

plot_ellipse(ellipse, block=True, limits=None, jointaxes=True, eeframe=True, shadow=True, name=True)

Plot an ellipsoid.

Parameters:
  • ellipse (EllipsePlot) – the ellipsoid to plot

  • block (bool) – True waits until the window is closed; the PyPlot backend has already shown the figure, so False and None return at once, defaults to True

  • limits (ndarray | Sequence[float] | None) – custom view limits [x1, x2, y1, y2, z1, z2]; autoscales if not supplied

  • jointaxes (bool) – plot an arrow indicating the joint axis

  • eeframe (bool) – plot the end-effector coordinate frame

  • shadow (bool) – plot a shadow of the robot in the x-y plane

  • name (bool) – plot the name of the robot near its base

Returns:

a reference to the PyPlot object controlling the matplotlib figure

Return type:

PyPlot

robot.plot_ellipse(ellipsoid) displays the ellipsoid.

plot_fellipse(q, block=True, fellipse=None, limits=None, opt='trans', centre='ee', jointaxes=True, eeframe=True, shadow=True, name=True)

Plot the force ellipsoid for a manipulator.

Parameters:
  • q (ndarray | Sequence[float] | None) – the joint configuration of the robot

  • block (bool) – True waits until the window is closed; the PyPlot backend has already shown the figure, so False and None return at once, defaults to True

  • fellipse (EllipsePlot | None) – a pre-built force ellipsoid to plot

  • limits (ndarray | Sequence[float] | None) – custom view limits [x1, x2, y1, y2, z1, z2]; autoscales if not supplied

  • opt (Literal['trans', 'rot']) – 'trans' or 'rot' — plot the translational or rotational force ellipsoid

  • centre (Union[Literal['ee'], ndarray, Sequence[float]]) – coordinates to plot the ellipse — [x, y, z] or "ee"

  • jointaxes (bool) – plot an arrow indicating the joint axis

  • eeframe (bool) – plot the end-effector coordinate frame

  • shadow (bool) – plot a shadow of the robot in the x-y plane

  • name (bool) – plot the name of the robot near its base

Raises:

ValueError – if neither q nor fellipse is supplied

Returns:

a reference to the PyPlot object controlling the matplotlib figure

Return type:

PyPlot

robot.plot_fellipse(q) displays the force ellipsoid for the robot at pose q. The plot will autoscale with an aspect ratio of 1.

robot.plot_fellipse(vellipse=ell) uses a pre-built ellipse object.

Notes

  • By default the ellipsoid related to translational motion is drawn. Use opt='rot' to draw the rotational velocity ellipsoid.

  • By default the ellipsoid is drawn at the origin. Use centre to specify a 3-vector, or "ee" to draw at the end-effector.

plot_vellipse(q, block=True, vellipse=None, limits=None, opt='trans', centre='ee', jointaxes=True, eeframe=True, shadow=True, name=True)

Plot the velocity ellipsoid for a manipulator.

Parameters:
  • q (ndarray | Sequence[float] | None) – the joint configuration of the robot

  • block (bool) – True waits until the window is closed; the PyPlot backend has already shown the figure, so False and None return at once, defaults to True

  • vellipse (EllipsePlot | None) – a pre-built velocity ellipsoid to plot

  • limits (ndarray | Sequence[float] | None) – custom view limits [x1, x2, y1, y2, z1, z2]; autoscales if not supplied

  • opt (Literal['trans', 'rot']) – 'trans' or 'rot' — plot the translational or rotational velocity ellipsoid

  • centre (Union[Literal['ee'], ndarray, Sequence[float]]) – coordinates to plot the ellipse — [x, y, z] or "ee"

  • jointaxes (bool) – plot an arrow indicating the joint axis

  • eeframe (bool) – plot the end-effector coordinate frame

  • shadow (bool) – plot a shadow of the robot in the x-y plane

  • name (bool) – plot the name of the robot near its base

Raises:

ValueError – if neither q nor vellipse is supplied

Returns:

a reference to the PyPlot object controlling the matplotlib figure

Return type:

PyPlot

robot.plot_vellipse(q) displays the velocity ellipsoid for the robot at pose q. The plot will autoscale with an aspect ratio of 1.

robot.plot_vellipse(vellipse=ell) uses a pre-built ellipse object.

Notes

  • By default the ellipsoid related to translational motion is drawn. Use opt='rot' to draw the rotational velocity ellipsoid.

  • By default the ellipsoid is drawn at the origin. Use centre to specify a 3-vector, or "ee" to draw at the end-effector.

property prismaticjoints: list[bool]

Prismatic joints as bool array

Returns:

array of joint type, True if prismatic

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.prismaticjoints
[False, False, False, False, False, False]
>>> stanford = rtb.models.DH.Stanford()
>>> stanford.prismaticjoints
[False, False, True, False, False, False]

Notes

Fixed joints, that maintain a constant link relative pose, are not included.

property q: ndarray

Get/set robot joint configuration

  • robot.q is the robot joint configuration

  • robot.q = ... checks and sets the joint configuration

Parameters:

q – the new robot joint configuration

Returns:

robot joint configuration

Setter accepts:

ndarray | Sequence[float]

property qd: ndarray

Get/set robot joint velocity

  • robot.qd is the robot joint velocity

  • robot.qd = ... checks and sets the joint velocity

Returns:

robot joint velocity

Setter accepts:

ndarray | Sequence[float]

property qdd: ndarray

Get/set robot joint acceleration

  • robot.qdd is the robot joint acceleration

  • robot.qdd = ... checks and sets the robot joint acceleration

Returns:

robot joint acceleration

Setter accepts:

ndarray | Sequence[float]

property qlim: ndarray

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:

qlim – An array of joints limits (2, n)

Raises:

ValueError – unset limits for a prismatic joint

Returns:

Array of joint limit values

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]])
Setter accepts:

ndarray | Sequence[float]

random_q()

Return a random joint configuration

The value for each joint is uniform randomly distributed between the limits set for the robot.

Notes

The joint limit for all joints must be set.

Return type:

Any

Returns:

Random joint configuration :rtype: ndarray(n)

See also

qlim() qlim()

property revolutejoints: list[bool]

Revolute joints as bool array

Returns:

array of joint type, True if revolute

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.revolutejoints
[True, True, True, True, True, True]
>>> stanford = rtb.models.DH.Stanford()
>>> stanford.revolutejoints
[True, True, False, True, True, True]

Notes

Fixed joints, that maintain a constant link relative pose, are not included.

property scene_children: list[SceneNode]

Return the child nodes of this object in the scene graph.

Setting a new list of children updates each child’s scene_parent to this object, but does not remove this object from any previous parent’s scene_children.

This is a read/write property.

Return type:

list(SceneNode)

Seealso:

scene_parent() attach() attach_to()

property scene_parent: SceneNode | None

Return the parent node of this object in the scene graph.

Setting a new parent adds this object to the new parent’s scene_children.

This is a read/write property.

Return type:

SceneNode | None

Seealso:

scene_children() attach() attach_to()

Setter accepts:

SceneNode

segments()

Segments of branched robot

For a single-chain robot with structure:

L1 - L2 - L3

the return is [[None, L1, L2, L3]]

For a robot with structure:

L1 - L2 +-  L3 - L4
        +- L5 - L6

the return is [[None, L1, L2], [L2, L3, L4], [L2, L5, L6]]

Return type:

list[list[Optional[Link]]]

Returns:

Segment list

Notes

  • the length of the list is the number of segments in the robot

  • the first segment always starts with None which represents

    the base transform (since there is no base link)

  • the last link of one segment is also the first link of subsequent

    segments

classmethod set_default_backend(be)

Set the default graphical backend for all robots

Parameters:

be (Any) – backend name, for example "swift", or None to clear

Return type:

None

Robot.set_default_backend("swift") sets the backend used by plot() for every robot, existing or created later, that has not been given one of its own by robot.default_backend = .... The robot’s own value takes precedence.

See also

default_backend

showgraph(display_graph=True, **kwargs)

Display a link transform graph in browser

robot.showgraph() displays a graph of the robot’s link frames and the ETS between them. It uses GraphViz dot.

The nodes are:
  • Base is shown as a grey square. This is the world frame origin, but can be changed using the base attribute of the robot.

  • Link frames are indicated by circles

  • ETS transforms are indicated by rounded boxes

The edges are:
  • an arrow if jtype is False or the joint is fixed

  • an arrow with a round head if jtype is True and the joint is revolute

  • an arrow with a box head if jtype is True and the joint is prismatic

Edge labels or nodes in blue have a fixed transformation to the preceding link.

Parameters:
  • display_graph (bool) – Open the graph in a browser if True. Otherwise will return the file path

  • etsbox – Put the link ETS in a box, otherwise an edge label

  • jtype – Arrowhead to node indicates revolute or prismatic type

  • static – Show static joints in blue and bold

Return type:

str | None

Examples

>>> import roboticstoolbox as rtb
>>> panda = rtb.models.URDF.Panda()
>>> panda.showgraph()
_images/panda-graph.svg

See also

dotfile() graph()

property structure: str

Return the joint structure string

A string with one letter per joint: R for a revolute joint, and P for a prismatic joint.

Returns:

joint configuration string

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.structure
'RRRRRR'
>>> stanford = rtb.models.DH.Stanford()
>>> stanford.structure
'RRPRRR'

Notes

Fixed joints, that maintain a constant link relative pose, are not included. len(self.structure) == self.n.

property symbolic: bool
teach(q, block=True, limits=None, vellipse=False, fellipse=False, backend=None, view=None)

Graphical teach pendant

robot.teach(q) opens a graphical view (PyPlot or Swift – see backend) which allows the user to “drive” a graphical robot using a graphical slider panel. The robot’s initial joint configuration is q.

robot.teach() as above except the robot’s stored value of q is used.

Parameters:
  • q (ndarray | Sequence[float] | None) – The joint configuration of the robot (Optional, if not supplied will use the stored q values).

  • block (bool) – True waits until the window is closed; the PyPlot backend has already shown the figure, so False and None return at once, defaults to True

  • limits (ndarray | Sequence[float] | None) – Custom view limits for the plot. If not supplied will autoscale, [x1, x2, y1, y2, z1, z2] (this option is for ‘pyplot’/’pyplot2’ only)

  • vellipse (bool) – (Plot Option) Plot the velocity ellipse at the end-effector (this option is for ‘pyplot’ only)

  • fellipse (bool) – (Plot Option) Plot the force ellipse at the end-effector (this option is for ‘pyplot’ only)

  • backend (Optional[Literal['swift', 'pyplot', 'pyplot2']]) – The graphical backend to use – ‘swift’, ‘pyplot’, or ‘pyplot2’. Defaults to whatever plot() would pick for this robot (see its own backend for the resolution rule).

  • view (str | None) – "xy", "xz" or "yz" to start with a flat view of that plane, the first axis to the right and the second up, or None (default) for the usual three-dimensional view. The view is not locked, the plot can be rotated as usual (this option is for ‘pyplot’ only)

Return type:

Connector

Returns:

A reference to the environment object which controls the figure/view

Notes

  • Program execution is blocked until the teach window is dismissed. If block=False the method is non-blocking but you need to poll the window manager (PyPlot) or keep calling env.step() yourself (Swift) to ensure the window/panel remains responsive.

  • Once teach() returns (block=True), robot.q holds the final pose the sliders were left at – true for every backend, even though Swift’s own live joint state during the session lives on the returned environment’s handle (env.swift_objects[0].q), not robot.q itself, to keep the robot model plain and shareable while teaching is in progress (see swift’s AssemblyHandle).

  • The slider limits are derived from the joint limit properties. If not set then:

    • For revolute joints they are assumed to be [-pi, +pi]

    • For prismatic joint they are assumed unknown and an error occurs.

todegrees(q)

Convert joint angles to degrees

Parameters:

q (Any) – The joint configuration of the robot

Return type:

ndarray

Returns:

a vector of joint coordinates in degrees and metres

Returns:

robot.todegrees(q) converts joint coordinates q to degrees

Returns:

taking into account whether elements of q correspond to revolute

Returns:

or prismatic joints, ie. prismatic joint values are not converted.

Returns:

If q is a matrix, with one column per joint, the conversion is

Returns:

performed columnwise.

Examples

>>> import roboticstoolbox as rtb
>>> from math import pi
>>> stanford = rtb.models.DH.Stanford()
>>> stanford.todegrees([pi/4, pi/8, 2, -pi/4, pi/6, pi/3])
array([ 45. ,  22.5,   2. , -45. ,  30. ,  60. ])
property tool: SE3

Get/set robot tool transform

  • robot.tool is the robot tool transform as an SE3 object

  • robot._tool is the robot tool transform as a numpy array

  • robot.tool = ... checks and sets the robot tool transform

Parameters:

tool – the new robot tool transform (as an SE(3))

Returns:

robot tool transform

Setter accepts:

SE3 | ndarray

toradians(q)

Convert joint angles to radians

robot.toradians(q) converts joint coordinates q to radians taking into account whether elements of q correspond to revolute or prismatic joints, ie. prismatic joint values are not converted.

If q is a matrix, with one column per joint, the conversion is performed columnwise.

Parameters:

q (Any) – The joint configuration of the robot

Return type:

ndarray

Returns:

a vector of joint coordinates in radians and metres

Examples

>>> import roboticstoolbox as rtb
>>> stanford = rtb.models.DH.Stanford()
>>> stanford.toradians([10, 20, 2, 30, 40, 50])
array([0.1745, 0.3491, 2.    , 0.5236, 0.6981, 0.8727])
tree()

Render the whole tree this node lives in as indented text – walks up to the root first (the same root-finding as update()), then renders down from there, with this node marked with a trailing <== so its position in the tree is visible.

Return type:

str

tree_children()

Render this node’s own subtree as indented text (one repr() per line), not walking through parents – the same “not through parents” scope as _propagate_scene_children().

Nodes have no .name in this package, so each line is that node’s own repr() (type, constructor params, color, pose) – usually enough to tell siblings apart, since it’s rare for two distinct nodes to share an identical pose as well as everything else.

Return type:

str

update()

Recompute the world transform of every node in the scene graph this node belongs to, starting from the root and working down.

Call this after changing any node’s T/pose (or its scene_parent) – nothing propagates automatically. It doesn’t matter which node in the graph you call it on: this always walks up to the root first, then pushes fresh world transforms down through the whole tree, not just this node’s own subtree.

Return type:

None

property urdf_filepath: str
property urdf_string: str
vellipse(q, opt='trans', unit='rad', centre='ee', scale=0.1, add=True)

Create a velocity ellipsoid object for plotting with PyPlot.

Parameters:
  • q (ndarray | Sequence[float]) – the joint configuration of the robot

  • opt (Literal['trans', 'rot']) – 'trans' or 'rot' — plot the translational or rotational velocity ellipsoid

  • unit (Literal['rad', 'deg']) – 'rad' or 'deg'

  • centre (Union[Literal['ee'], ndarray, Sequence[float]]) – centre of the ellipsoid — 'ee' for the end-effector or a 3-vector [x, y, z] in the world frame

  • scale (float) – scale factor for the ellipsoid

  • add (bool) – if True, add the ellipsoid to the active plot environment

Returns:

an EllipsePlot object

Return type:

EllipsePlot

robot.vellipse(q) creates a velocity ellipsoid for the robot at pose q. By default the ellipsoid is centered at the end-effector.

Notes

  • By default the ellipsoid related to translational motion is drawn. Use opt='rot' to draw the rotational velocity ellipsoid.

  • By default the ellipsoid is drawn at the end-effector. The option centre allows its origin to be set to the specified 3-vector, or the string "ee" ensures it is drawn at the end-effector position.

class Robot2(arg, **kwargs)[source]

Bases: BaseRobot[Link2]

property T: ndarray

Pose of the shape relative to its parent frame in the scene graph (or the world frame if it has no parent), as a 4x4 homogeneous transformation matrix. Set via the pose argument of the constructor.

This is a read/write property. The getter always returns a plain ndarray; the setter also accepts an SE3.

Warning

Because the getter returns an ndarray, in-place operators like shape.T *= delta do an elementwise multiply, not a pose composition, even when delta is an SE3 – use shape.T = shape.T * delta (or shape.T @= delta.A) instead.

Return type:

ndarray(4,4)

Setter accepts:

ndarray | SE3

__getitem__(i)

Get link

This also supports iterating over each link in the robot object, from the base to the tool.

Parameters:

i (int | str) – link number or name

Return type:

Link2

Returns:

i’th link or named link

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> print(robot[1]) # print the 2nd link
RevoluteDH:   θ=q,  d=0,  a=0.4318,  ⍺=0.0
>>> print([link.a for link in robot])  # print all the a_j values
[0, 0.4318, 0.0203, 0, 0, 0]

Notes

Robot supports link lookup by name,

eg. robot['link1']

__str__()

Pretty prints the ETS Model of the robot.

Return type:

str

Returns:

Pretty print of the robot model

Notes

  • Constant links are shown in blue.

  • End-effector links are prefixed with an @

  • Angles in degrees

  • The robot base frame is denoted as BASE and is equal to the

    robot’s base attribute.

accel(q, qd, torque, gravity=None)

Compute acceleration due to applied torque

Parameters:
  • q (Any) – Joint coordinates

  • qd (Any) – Joint velocity

  • torque (Any) – Joint torques of the robot

  • gravity (Any) – gravitational acceleration in the world frame, downwards gravitational force is equivalent to robot base acceleration upwards (positive); if not supplied, uses the gravity attribute of self

Returns:

Joint accelerations

Return type:

Any

qdd = accel(q, qd, torque) calculates a vector (n) of joint accelerations that result from applying the actuator force/torque (n) to the manipulator in state q (n) and qd (n), and n is the number of robot joints.

\[\ddot{q} = \mathbf{M}^{-1} \left(\tau - \mathbf{C}(q)\dot{q} - \mathbf{g}(q)\right)\]

Trajectory operation

If q, qd, torque are matrices (m,n) then qdd is a matrix (m,n) where each row is the acceleration corresponding to the equivalent rows of q, qd, torque.

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.accel(puma.qz, 0.5 * np.ones(6), np.zeros(6))
array([ -7.5544, -12.22  ,  -6.4022,  -5.4303,  -4.9518,  -2.1178])

Notes

  • Useful for simulation of manipulator dynamics, in

    conjunction with a numerical integration function.

  • Uses the method 1 of Walker and Orin to compute the forward

    dynamics.

  • Featherstone’s method is more efficient for robots with large

    numbers of joints.

  • Joint friction is considered.

References

  • Efficient dynamic computer simulation of robotic mechanisms,

    M. W. Walker and D. E. Orin, ASME Journal of Dynamic Systems, Measurement and Control, vol. 104, no. 3, pp. 205-211, 1982.

accel_x(q, xd, wrench, gravity=None, pinv=False, representation='rpy/xyz')

Operational space acceleration due to applied wrench

Parameters:
  • q (Any) – Joint coordinates

  • xd (Any) – Operational space velocity of the end-effector

  • wrench (Any) – Wrench applied to the end-effector

  • gravity (Any) – gravitational acceleration in the world frame, downwards gravitational force is equivalent to robot base acceleration upwards (positive); if not supplied, uses the gravity attribute of self

  • pinv (bool) – use pseudo inverse rather than inverse

  • representation (Literal['rpy/xyz', 'rpy/zyx', 'eul', 'exp']) – the type of analytical Jacobian to use, default is 'rpy/xyz'

Returns:

Operational space accelerations of the end-effector

Return type:

Any

xdd = accel_x(q, xd, wrench) is the operational space acceleration due to wrench applied to the end-effector of a robot in joint configuration q and operational space velocity xd.

\[\ddot{x} = \dot{\mathbf{J}}_a(q, \dot{q})\dot{q} + \mathbf{J}_a(q) \mathbf{M}(q)^{-1} \left( \mathbf{J}_a(q)^T w - \mathbf{C}(q)\dot{q} - \mathbf{g}(q) \right)\]

Trajectory operation

If q is a matrix (m,n), and xd and wrench are matrices (m,6), then xdd is a matrix (m,6) where each row is the acceleration corresponding to the equivalent rows of q, xd, and wrench.

Notes

  • Useful for simulation of manipulator dynamics, in

    conjunction with a numerical integration function.

  • Uses the method 1 of Walker and Orin to compute the forward

    dynamics.

  • Featherstone’s method is more efficient for robots with large

    numbers of joints.

  • Joint friction is considered.

See also

accel()

addconfiguration(name, q)

Add a named joint configuration

Add a named configuration to the robot instance’s dictionary of named configurations.

Parameters:
Return type:

None

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> robot.addconfiguration_attr("mypos", [0.1, 0.2, 0.3, 0.4, 0.5, 0.6])
>>> robot.configs["mypos"]
array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6])
addconfiguration_attr(name, q, unit='rad')

Add a named joint configuration as an attribute

Parameters:
Return type:

None

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> robot.addconfiguration_attr("mypos", [0.1, 0.2, 0.3, 0.4, 0.5, 0.6])
>>> robot.mypos
array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6])
>>> robot.configs["mypos"]
array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6])

Notes

  • Used in robot model init method to store the qr configuration

  • Dynamically adding attributes to objects can cause issues with

    Python type checking.

  • Configuration is also added to the robot instance’s dictionary of

    named configurations.

attach(object)

Attach a child node

Parameters:

object (SceneNode) – the node to attach as a child of this node

Seealso:

attach_to() scene_children()

Return type:

None

attach_to(object)

Attach this node to a parent node

Parameters:

object (SceneNode) – the node to attach this node to, this node will become a child of the parent

Seealso:

attach() scene_parent()

Return type:

None

Get the robot base link

  • robot.base_link is the robot base link

Returns:

the first link in the robot tree

cinertia(q)

Deprecated, use inertia_x

Return type:

None

property comment: str

Get/set robot comment

  • robot.comment is the robot comment

  • robot.comment = ... checks and sets the robot comment

Parameters:

name – the new robot comment

Returns:

robot comment

property configs: dict[str, ndarray]

Named joint configurations

Returns:

dictionary of joint configurations, such as qr and qz, indexed by name

configurations_str(border='thin')
Return type:

Any

property control_mode: str

Get/set robot control mode

  • robot.control_type is the robot control mode

  • robot.control_type = ... checks and sets the robot control mode

Parameters:

control_mode – the new robot control mode

Returns:

the current robot control mode

copy()

Make a copy of the robot

Return type:

Any

Returns:

a deep copy, which shares no state with the original

coriolis(q, qd)

Coriolis and centripetal term

Parameters:
  • q (Any) – Joint coordinates

  • qd (Any) – Joint velocity

Returns:

Coriolis/centripetal velocity matrix

Return type:

Any

coriolis(q, qd) calculates the Coriolis/centripetal matrix (n,n) for the robot in configuration q and velocity qd, where n is the number of joints.

The product \(\mathbf{C} \dot{q}\) is the vector of joint force/torque due to velocity coupling. The diagonal elements are due to centripetal effects and the off-diagonal elements are due to Coriolis effects. This matrix is also known as the velocity coupling matrix, since it describes the disturbance forces on any joint due to velocity of all other joints.

Trajectory operation

If q and qd are matrices (m,n), each row is interpreted as a joint configuration, and the result (n,n,m) is a 3d-matrix where each plane corresponds to a row of q and qd.

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.coriolis(puma.qz, 0.5 * np.ones((6,)))
array([[-0.4017, -0.5513, -0.2025, -0.0007, -0.0013,  0.    ],
       [ 0.2023, -0.1937, -0.3868, -0.    , -0.002 ,  0.    ],
       [ 0.1987,  0.193 , -0.    ,  0.    , -0.0001,  0.    ],
       [ 0.    ,  0.    ,  0.    ,  0.    ,  0.    ,  0.    ],
       [ 0.0007,  0.0007,  0.0001,  0.    ,  0.    ,  0.    ],
       [ 0.    ,  0.    ,  0.    ,  0.    ,  0.    ,  0.    ]])

Notes

  • Joint viscous friction is also a joint force proportional to

    velocity but it is eliminated in the computation of this value.

  • Computationally slow, involves \(n^2/2\) invocations of RNE.

coriolis_x(q, qd, pinv=False, representation='rpy/xyz', J=None, Ji=None, Jd=None, C=None, Mx=None)

Operational space Coriolis and centripetal term

Parameters:
  • q (Any) – Joint coordinates

  • qd (Any) – Joint velocity

  • pinv (bool) – use pseudo inverse rather than inverse (Default value = False)

  • representation (Literal['rpy/xyz', 'rpy/zyx', 'eul', 'exp']) – the type of analytical Jacobian to use, default is 'rpy/xyz'

  • J (Any) – pre-computed analytical Jacobian (optional)

  • Ji (Any) – pre-computed inverse analytical Jacobian (optional)

  • Jd (Any) – pre-computed time-derivative of analytical Jacobian (optional)

  • C (Any) – pre-computed joint-space Coriolis matrix (optional)

  • Mx (Any) – pre-computed operational-space inertia matrix (optional)

Returns:

Operational space velocity matrix

Return type:

Any

coriolis_x(q, qd) is the Coriolis/centripetal matrix (m,m) in operational space for the robot in configuration q and velocity qd, where n is the number of joints.

\[\mathbf{C}_x = \mathbf{J}(q)^{-T} \mathbf{C}(q, \dot{q}) \mathbf{J}(q)^{-1} - \mathbf{M}_x(q) \dot{\mathbf{J}}(q, \dot{q}) \mathbf{J}(q)^{-1}\]

The product \(\mathbf{C} \dot{x}\) is the operational space wrench due to joint velocity coupling. This matrix is also known as the velocity coupling matrix, since it describes the disturbance forces on any joint due to velocity of all other joints.

The transformation to operational space requires an analytical, rather than geometric, Jacobian. analytical can be one of:

Value

Rotational representation

'rpy/xyz'

RPY angular rates in XYZ order (default)

'rpy/zyx'

RPY angular rates in XYZ order

'eul'

Euler angular rates in ZYZ order

'exp'

exponential coordinate rates

Trajectory operation

If q and qd are matrices (m,n), each row is interpreted as a joint configuration, and the result is an array (m,6,6) where each matrix corresponds to a row of q and qd.

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.coriolis_x(puma.qn, 0.5 * np.ones((6,)))
array([[     12.3365,       4.6387,      13.7633,      -0.0409,
              0.0043,      -0.0409],
       [     -4.788 ,  -31430.2949,      -3.4675,       0.3301,
             -0.3188,       0.3301],
       [    -11.5011,      -1.7324,     -10.0545,      -0.0405,
              0.    ,      -0.0405],
       [     -0.0165, 4869725.6671,      -0.0165,      -0.1245,
              0.0278,      -0.1245],
       [     -0.1112,       0.0531,       0.1332,      -0.0251,
             -0.    ,      -0.0251],
       [     -0.0165, 4869725.6671,      -0.0165,      -0.1245,
              0.0278,      -0.1245]])

Notes

  • Joint viscous friction is also a joint force proportional to

    velocity but it is eliminated in the computation of this value.

  • Computationally slow, involves \(n^2/2\) invocations of RNE.

  • If the robot is not 6 DOF the pinv option is set True.

  • pinv() is around 5x slower than inv()

Warning

Assumes that the operational space has 6 DOF.

property default_backend: Any

Get default graphical backend

  • robot.default_backend Get the default graphical backend, used when

    no explicit backend is passed to Robot.plot. This is the value set for the robot, otherwise the value set for all robots by set_default_backend(), otherwise None.

  • robot.default_backend = ... Set the default graphical backend, used when

    no explicit backend is passed to Robot.plot. The default set here will be overridden if the particular Robot subclass cannot support it.

Returns:

backend name

A link search method

Visit all links from start in depth-first order and will apply func to each visited link

Parameters:
Return type:

list[Link2]

Returns:

A list of links

dotfile(filename, etsbox=False, ets='full', jtype=False, static=True)

Write a link transform graph as a GraphViz dot file

The file can be processed using dot:

% dot -Tpng -o out.png dotfile.dot

The nodes are:

  • Base is shown as a grey square. This is the world frame origin, but can be changed using the base attribute of the robot.

  • Link frames are indicated by circles

  • ETS transforms are indicated by rounded boxes

The edges are:

  • an arrow if jtype is False or the joint is fixed

  • an arrow with a round head if jtype is True and the joint is revolute

  • an arrow with a box head if jtype is True and the joint is prismatic

Edge labels or nodes in blue have a fixed transformation to the preceding link.

Notes

If filename is a file object then the file will not be closed after the GraphViz model is written.

Parameters:
  • file – Name of file to write to

  • etsbox (bool) – Put the link ETS in a box, otherwise an edge label

  • ets (Literal['full', 'brief']) – Display the full ets with “full” or a brief version with “brief”

  • jtype (bool) – Arrowhead to node indicates revolute or prismatic type

  • static (bool) – Show static joints in blue and bold

Return type:

None

See also

showgraph() graph()

dynamics()

Pretty print the dynamic parameters

The dynamic parameters (inertial and friction) are printed in a table, with one row per link.

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> robot.dynamics()
┌───────┬───────┬─────────────────────────┬────────────────────────────────────────┬──────────┬───────────┬───────────────────┬───────┐
│   j   │   m   │            r            │                   I                    │    Jm    │     B     │        Tc         │   G   │
├───────┼───────┼─────────────────────────┼────────────────────────────────────────┼──────────┼───────────┼───────────────────┼───────┤
│ link1 │  0    │  0,  0,  0              │  0,  0.35,  0,  0,  0,  0              │  0.0002  │  0.00148  │  0.395, -0.435    │ -62.6 │
│ link2 │  17.4 │ -0.364,  0.006,  0.228  │  0.13,  0.524,  0.539,  0,  0,  0      │  0.0002  │  0.000817 │  0.126, -0.071    │  108  │
│ link3 │  4.8  │ -0.0203, -0.0141,  0.07 │  0.066,  0.086,  0.0125,  0,  0,  0    │  0.0002  │  0.00138  │  0.132, -0.105    │ -53.7 │
│ link4 │  0.82 │  0,  0.019,  0          │  0.0018,  0.0013,  0.0018,  0,  0,  0  │  3.3e-05 │  7.12e-05 │  0.0112, -0.0169  │  76   │
│ link5 │  0.34 │  0,  0,  0              │  0.0003,  0.0004,  0.0003,  0,  0,  0  │  3.3e-05 │  8.26e-05 │  0.00926, -0.0145 │  71.9 │
│ link6 │  0.09 │  0,  0,  0.032          │  0.00015,  0.00015,  4e-05,  0,  0,  0 │  3.3e-05 │  3.67e-05 │  0.00396, -0.0105 │  76.7 │
└───────┴───────┴─────────────────────────┴────────────────────────────────────────┴──────────┴───────────┴───────────────────┴───────┘
Return type:

None

dynamics_list()

Print dynamic parameters

Display the kinematic and dynamic parameters to the console in reable format

Return type:

None

dynchanged(what=None)

Dynamic parameters have changed

Called from a property setter to inform the robot that the cache of dynamic parameters is invalid.

See also

roboticstoolbox.Link._dirties_frne()

Return type:

None

ets(start=None, end=None)

Robot to ETS

robot.ets() is an ETS representing the kinematics from base to end-effector.

robot.ets(end=link) is an ETS representing the kinematics from base to the link link specified as a Link reference or a name.

robot.ets(start=l1, end=l2) is an ETS representing the kinematics from link l1 to link l2.

Parameters:
  • start (:param) – start of path, defaults to base_link:

  • end (:param) – end of path, defaults to end-effector:

Raises:
Return type:

ETS

Returns:

elementary transform sequence

Examples

>>> import roboticstoolbox as rtb
>>> panda = rtb.models.ETS.Panda()
>>> panda.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)]
fdyn(T, q0, Q=None, Q_args=None, qd0=None, solver='RK45', solver_args=None, dt=None, progress=False)

Integrate forward dynamics

Parameters:
  • T (float) – integration time

  • q0 (ndarray | Sequence[float]) – initial joint coordinates

  • Q (Callable[[Any, float, ndarray, ndarray], ndarray] | None) – a function that computes generalized joint force as a function of time and/or state

  • Q_args (dict | None) – positional arguments passed to torque

  • qd0 (ndarray | Sequence[float] | None) – initial joint velocities, assumed zero if not given

  • solver (str) – name of SciPy integrator to use, default 'RK45'

  • solver_args (dict | None) – optional arguments passed to the SciPy integrator

  • dt (float | None) – if given, interpolate the results to this timestep

  • progress (bool) – show progress bar, default False

Returns:

robot trajectory

Return type:

Any

tg = R.fdyn(T, q) integrates the dynamics of the robot with zero input torques over the time interval 0 to T and returns the trajectory as a namedtuple with elements:

  • t the time vector (M,)

  • q the joint coordinates (M,n)

  • qd the joint velocities (M,n)

tg = R.fdyn(T, q, torqfun) as above but the torque applied to the joints is given by the provided function:

tau = function(robot, t, q, qd, **args)

where the inputs are:

  • the robot object

  • current time

  • current joint coordinates (n,)

  • current joint velocity (n,)

  • args, optional keyword arguments can be specified, these are passed in from the targs keyword argument.

The function must return a Numpy array (n,) of joint forces/torques.

Examples

To apply zero joint torque to the robot without Coulomb friction:

>>> def myfunc(robot, t, q, qd):
>>>     return np.zeros((robot.n,))
>>> tg = robot.nofriction().fdyn(5, q0, myfunc)
>>> plt.figure()
>>> plt.plot(tg.t, tg.q)
>>> plt.show()

We could also use a lambda function:

>>> tg = robot.nofriction().fdyn(
>>>     5, q0, lambda r, t, q, qd: np.zeros((r.n,)))

The robot is controlled by a PD controller. We first define a function to compute the control which has additional parameters for the setpoint and control gains (qstar, P, D):

>>> def myfunc(robot, t, q, qd, qstar, P, D):
>>>     return (qstar - q) * P + qd * D  # P, D are (6,)
>>> tg = robot.fdyn(10, q0, myfunc, torque_args=(qstar, P, D))

Many integrators have variable step length which is problematic if we want to animate the result. If dt is specified then the solver results are interpolated in time steps of dt.

Notes

  • This function performs poorly with non-linear joint friction,

    such as Coulomb friction. The R.nofriction() method can be used to set this friction to zero.

  • If the function is not specified then zero force/torque is

    applied to the manipulator joints.

  • Interpolation is performed using SciPy integrate.ode

  • The SciPy RK45 integrator is used by default

  • Interpolation is performed using SciPy interp1d

fellipse(q, opt='trans', unit='rad', centre='ee', add=True)

Create a force ellipsoid object for plotting with PyPlot.

Parameters:
  • q (ndarray | Sequence[float]) – the joint configuration of the robot

  • opt (Literal['trans', 'rot']) – 'trans' or 'rot' — plot the translational or rotational force ellipsoid

  • unit (Literal['rad', 'deg']) – 'rad' or 'deg'

  • centre (Union[Literal['ee'], ndarray, Sequence[float]]) – centre of the ellipsoid — 'ee' for the end-effector or a 3-vector [x, y, z] in the world frame

  • add (bool) – if True, add the ellipsoid to the active plot environment

Returns:

an EllipsePlot object

Return type:

EllipsePlot

robot.fellipse(q) creates a force ellipsoid for the robot at pose q. By default the ellipsoid is centered at the end-effector.

Notes

  • By default the ellipsoid related to translational motion is drawn. Use opt='rot' to draw the rotational velocity ellipsoid.

  • By default the ellipsoid is drawn at the end-effector. The option centre allows its origin to be set to the specified 3-vector, or the string "ee" ensures it is drawn at the end-effector position.

friction(qd)

Manipulator joint friction

Parameters:

qd (ndarray) – The joint velocities of the robot

Returns:

The joint friction forces/torques for the robot

Return type:

ndarray

robot.friction(qd) is a vector of joint friction forces/torques for the robot moving with joint velocities qd.

The friction model includes:

  • Viscous friction which is a linear function of velocity.

  • Coulomb friction which is proportional to sign(qd).

\[\begin{split}\tau_j = G^2 B \dot{q}_j + |G_j| \left\{ \begin{array}{ll} \tau_{C,j}^+ & \mbox{if $\dot{q}_j > 0$} \\ \tau_{C,j}^- & \mbox{if $\dot{q}_j < 0$} \end{array} \right.\end{split}\]

Notes

  • The friction value should be added to the motor output torque to

    determine the nett torque. It has a negative value when qd > 0.

  • The returned friction value is referred to the output of the

    gearbox.

  • The friction parameters in the Link object are referred to the

    motor.

  • Motor viscous friction is scaled up by \(G^2\).

  • Motor Coulomb friction is scaled up by \(G\).

  • The appropriate Coulomb friction value to use in the

    non-symmetric case depends on the sign of the joint velocity, not the motor velocity.

  • Coulomb friction is zero for zero joint velocity, stiction is

    not modeled.

  • The absolute value of the gear ratio is used. Negative gear

    ratios are tricky: the Puma560 robot has negative gear ratio for joints 1 and 3.

get_path(end=None, start=None)

Find a path from start to end

Parameters:
  • end (Union[Gripper, Link2, str, None]) – end-effector or gripper to compute forward kinematics to

  • start (Union[Gripper, Link2, str, None]) – name or reference to a base link, defaults to None

Raises:

ValueError – link not known or ambiguous

Return type:

tuple[list[Link2], int, SE3]

Returns:

the path from start to end

Returns:

the number of joints in the path

Returns:

the tool transform present after end

graph(format='dot', filename=None, **kwargs)

Render a link transform graph as text

Parameters:
  • format (Literal['dot', 'mermaid', 'mermaid_fenced']) – graph output format: "dot", "mermaid" or "mermaid_fenced", defaults to "dot"

  • filename (Union[str, IO[str], None]) – destination path or open text stream, defaults to None

  • kwargs (Any) – for format="dot", forwarded to dotfile() (etsbox, ets, jtype, static); ignored otherwise

Return type:

str

Returns:

rendered graph text

Creates graph text representing the robot’s link transform graph – the same structure dotfile()/showgraph() render, in a choice of formats. If filename is provided, the rendered text is also written to it.

"dot" produces the same GraphViz output as dotfile(), just returned as a string rather than requiring a real file – etsbox/ets/jtype/static behave exactly as they do there.

"mermaid"/"mermaid_fenced" render a simplified Mermaid flowchart: one node per link (a double circle for end-effectors, a hexagon for gripper links), edges labelled with the joint type (R/P) and joint index for actuated joints. Mermaid has no equivalent of DOT’s per-edge arrowhead/colour styling, so jtype/static/etsbox only affect "dot" output. "mermaid_fenced" wraps the same text in a fenced mermaid code block, ready to paste into Markdown or render directly in a Jupyter cell:

from IPython.display import Markdown, display
display(Markdown(robot.graph(format="mermaid_fenced")))
property gravity: ndarray

Get/set default gravitational acceleration

  • robot.gravity is the default gravitational acceleration

  • robot.gravity = ... checks and sets default gravitational

    acceleration

Parameters:

gravity – gravitational acceleration in the world frame, downwards gravitational force is equivalent to robot base acceleration upwards (positive)

Returns:

gravitational acceleration

Setter accepts:

ndarray | Sequence[float]

gravload(q=None, gravity=None)

Compute gravity load

Parameters:
  • q (ndarray | Sequence[float] | None) – Joint coordinates

  • gravity (ndarray | Sequence[float] | None) – gravitational acceleration in the world frame, downwards gravitational force is equivalent to robot base acceleration upwards (positive); if not supplied, uses the stored gravity values

Returns:

The generalised joint force/torques due to gravity

Return type:

Any

robot.gravload(q) calculates the joint gravity loading (n) for the robot in the joint configuration q and using the default gravitational acceleration specified in the DHRobot object.

robot.gravload(q, gravity=g) as above except the gravitational acceleration is explicitly specified as g.

The return value is referenced to the load, not the motor, the gear ratio is not taken into account.

Trajectory operation

If q is a matrix (nxm) each column is interpreted as a joint configuration vector, and the result is a matrix (nxm) each column being the corresponding joint torques.

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.gravload(puma.qz)
array([ 0.    , 37.4837,  0.2489,  0.    ,  0.    ,  0.    ])
gravload_x(q=None, gravity=None, pinv=False, representation='rpy/xyz', Ji=None)

Operational space gravity load

Parameters:
  • q (Any) – Joint coordinates

  • gravity (Any) – gravitational acceleration in the world frame, downwards gravitational force is equivalent to robot base acceleration upwards (positive); if not supplied, uses the gravity attribute of self

  • pinv (bool) – use pseudo inverse rather than inverse (Default value = False)

  • representation (Literal['rpy/xyz', 'rpy/zyx', 'eul', 'exp']) – the type of analytical Jacobian to use, default is 'rpy/xyz'

  • Ji (Any) – pre-computed inverse analytical Jacobian (optional)

Returns:

The operational space gravity wrench

Return type:

Any

robot.gravload_x(q) calculates the gravity wrench for the robot in the joint configuration q and using the default gravitational acceleration specified in the robot object.

robot.gravload_x(q, gravity=g) as above except the gravitational acceleration is explicitly specified as g.

\[\mathbf{G}_x = \mathbf{J}(q)^{-T} \mathbf{G}(q)\]

The transformation to operational space requires an analytical, rather than geometric, Jacobian. analytical can be one of:

Value

Rotational representation

'rpy/xyz'

RPY angular rates in XYZ order (default)

'rpy/zyx'

RPY angular rates in XYZ order

'eul'

Euler angular rates in ZYZ order

'exp'

exponential coordinate rates

Trajectory operation

If q is a matrix (m,n), each row is interpreted as a joint configuration vector, and the result is a matrix (m,6) with one gravity wrench per row.

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.gravload_x(puma.qn)
array([-30.1218,   7.5797,  53.7378,  -0.    ,  -0.0283,  -0.    ])

Notes

  • If the robot is not 6 DOF the pinv option is set True.

  • pinv() is around 5x slower than inv()

Warning

Assumes that the operational space has 6 DOF.

See also

gravload()

property grippers: list[Gripper]

Grippers attached to the robot

Returns:

A list of grippers

property hascollision: Any

Robot has collision model

Returns:

Robot has collision model

Returns:

At least one link has associated collision model.

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> robot.hascollision
False

See also

hasgeometry()

property hasdynamics: bool

Robot has dynamic parameters

Returns:

True if at least one link has a non-zero mass or motor inertia

These are the parameters that the inertial dynamics need. It is false for a model of the kinematics only, such as the default rtb.models.Panda, and the dynamics methods gravload, inertia, coriolis, accel, fdyn, itorque and rne raise ValueError for such a model, rather than return zeros or a confusing error. It is any link and not all, since the first link of the DH Puma560 has a mass of zero.

The answer is cached, and recomputed only when the mass or motor inertia of a link has been changed, so it costs nothing to ask.

Changed in version 1.5.0: This was true if any dynamic parameter had been assigned, even to zero, and was not reset when the parameters were set back to zero. A robot made from DH links with no masses reported True. The dynamics methods now raise ValueError if it is False, where they returned zeros or raised LinAlgError.

Warning

Behaviour change. Scripts that call the dynamics methods on a kinematics-only model, and accept the zeros, now get a ValueError.

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> robot.hasdynamics
True
property hasgeometry: Any

Robot has geometry model

At least one link has associated mesh to describe its shape.

Returns:

Robot has geometry model

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> robot.hasgeometry
True

See also

hascollision()

hierarchy()

Pretty print the robot link hierarchy

Return type:

None

Returns:

Pretty print of the robot model

Examples

Makes a robot and prints the hierarchy

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.URDF.Panda()
>>> robot.hierarchy()
 panda_link0
   panda_link1
     panda_link2
       panda_link3
         panda_link4
           panda_link5
             panda_link6
               panda_link7
                 panda_link8
                   panda_hand
                     panda_leftfinger
                     panda_rightfinger
inertia(q)

Manipulator inertia matrix

Parameters:

q (ndarray) – Joint coordinates

Returns:

The inertia matrix

Return type:

ndarray

inertia(q) is the symmetric joint inertia matrix (n,n) which relates joint torque to joint acceleration for the robot at joint configuration q.

Trajectory operation

If q is a matrix (m,n), each row is interpreted as a joint state vector, and the result is a 3d-matrix (nxnxk) where each plane corresponds to the inertia for the corresponding row of q.

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.inertia(puma.qz)
array([[ 3.9611, -0.1627, -0.1389,  0.0016, -0.0004,  0.    ],
       [-0.1627,  4.4566,  0.3727,  0.    ,  0.0019,  0.    ],
       [-0.1389,  0.3727,  0.9387,  0.    ,  0.0019,  0.    ],
       [ 0.0016,  0.    ,  0.    ,  0.1924,  0.    ,  0.    ],
       [-0.0004,  0.0019,  0.0019,  0.    ,  0.1713,  0.    ],
       [ 0.    ,  0.    ,  0.    ,  0.    ,  0.    ,  0.1941]])

Notes

  • The diagonal elements M[j,j] are the inertia seen by joint

    actuator j.

  • The off-diagonal elements M[j,k] are coupling inertias that

    relate acceleration on joint j to force/torque on joint k.

  • The diagonal terms include the motor inertia reflected through

    the gear ratio.

See also

cinertia()

inertia_x(q=None, pinv=False, representation='rpy/xyz', Ji=None)

Operational space inertia matrix

Parameters:
  • q (Any) – Joint coordinates

  • pinv (bool) – use pseudo inverse rather than inverse (Default value = False)

  • representation (Literal['rpy/xyz', 'rpy/zyx', 'eul', 'exp']) – the type of analytical Jacobian to use, default is 'rpy/xyz'

  • Ji (Any) – The inverse analytical Jacobian (base-frame)

Returns:

The operational space inertia matrix

Return type:

Any

robot.inertia_x(q) is the operational space (Cartesian) inertia matrix which relates Cartesian force/torque to Cartesian acceleration at the joint configuration q.

\[\mathbf{M}_x = \mathbf{J}(q)^{-T} \mathbf{M}(q) \mathbf{J}(q)^{-1}\]

The transformation to operational space requires an analytical, rather than geometric, Jacobian. analytical can be one of:

Value

Rotational representation

'rpy/xyz'

RPY angular rates in XYZ order (default)

'rpy/zyx'

RPY angular rates in XYZ order

'eul'

Euler angular rates in ZYZ order

'exp'

exponential coordinate rates

Trajectory operation

If q is a matrix (m,n), each row is interpreted as a joint state vector, and the result is a 3d-matrix (m,n,n) where each plane corresponds to the Cartesian inertia for the corresponding row of q.

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.inertia_x(puma.qn)
array([[17.2954, -2.7542, -9.6233,  0.    ,  0.2795,  0.    ],
       [-2.7542, 11.6452,  1.2459,  0.0001, -0.0703,  0.0001],
       [-9.6233,  1.2459, 13.3348,  0.    ,  0.2767,  0.    ],
       [ 0.    ,  0.0001,  0.    ,  0.1941,  0.    ,  0.1941],
       [ 0.2795, -0.0703,  0.2767,  0.    ,  0.1713,  0.    ],
       [ 0.    ,  0.0001,  0.    ,  0.1941,  0.    ,  0.1941]])

Notes

  • If the robot is not 6 DOF the pinv option is set True.

  • pinv() is around 5x slower than inv()

Warning

Assumes that the operational space has 6 DOF.

See also

inertia()

isprismatic(j)

Check if joint is prismatic

Return type:

bool

Returns:

True if prismatic

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.prismaticjoints
[False, False, False, False, False, False]
>>> stanford = rtb.models.DH.Stanford()
>>> stanford.isprismatic(1)
False
isrevolute(j)

Check if joint is revolute

Return type:

bool

Returns:

True if revolute

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.revolutejoints
[True, True, True, True, True, True]
>>> stanford = rtb.models.DH.Stanford()
>>> stanford.isrevolute(1)
True
itorque(q, qdd)

Inertia torque

Parameters:
  • q (Any) – Joint coordinates

  • qdd (Any) – Joint acceleration

Returns:

The inertia torque vector

Return type:

Any

itorque(q, qdd) is the inertia force/torque vector (n) at the specified joint configuration q (n) and acceleration qdd (n), and n is the number of robot joints. It is \(\mathbf{I}(q) \ddot{q}\).

Trajectory operation

If q and qdd are matrices (m,n), each row is interpreted as a joint configuration, and the result is a matrix (m,n) where each row is the corresponding joint torques.

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.itorque(puma.qz, 0.5 * np.ones((6,)))
array([1.8304, 2.3343, 0.5872, 0.0971, 0.0873, 0.0971])

Notes

  • If the robot model contains non-zero motor inertia then this

    will be included in the result.

See also

inertia()

jointdynamics(q, qd=None)

Transfer function of joint actuator

Parameters:
  • q (Any) – Joint coordinates

  • qd (Any) – Joint velocity

Returns:

transfer function denominators

Return type:

Any

tf = jointdynamics(qd, q) calculates a vector of n continuous-time transfer functions that represent the transfer function 1/(Js+B) for each joint based on the dynamic parameters of the robot and the configuration q (n). n is the number of robot joints. The result is a list of tuples (J, B) for each joint.

tf = jointdynamics(q, qd) as above but include the linearized effects of Coulomb friction when operating at joint velocity QD (1xN).

property keywords: list[str]

Keywords that describe the robot

Returns:

the keywords, which the model catalog can filter on

linkcolormap(linkcolors='viridis')

Create a colormap for robot joints.

Parameters:

linkcolors (list[Any] | str) – list of colors or colormap name, defaults to "viridis"

Return type:

Any

Returns:

the color map

  • cm = robot.linkcolormap() is an n-element colormap that gives a unique color for every link. The RGBA colors for link j are cm(j).

  • cm = robot.linkcolormap(cmap) as above but cmap is the name of a valid matplotlib colormap. The default, example above, is the viridis colormap.

  • cm = robot.linkcolormap(list of colors) as above but a colormap is created from a list of n color names given as strings, tuples or hexstrings.


>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> cm = robot.linkcolormap("inferno")
>>> print(cm(range(6))) # cm(i) is 3rd color in colormap
>>> cm = robot.linkcolormap(
...     ['red', 'g', (0,0.5,0), '#0f8040', 'yellow', 'cyan'])
>>> print(cm(range(6)))

Notes

  • Colormaps have 4-elements: red, green, blue, alpha (RGBA)

  • Names of supported colors and colormaps are defined in the matplotlib documentation.

Robot links

Returns:

A list of link objects

Notes

It is probably more concise to index the robot object rather than the list of links, ie. the following are equivalent: - robot.links[i] - robot[i]

property manufacturer: Any

Get/set robot manufacturer’s name

  • robot.manufacturer is the robot manufacturer’s name

  • robot.manufacturer = ... checks and sets the manufacturer’s name

Returns:

robot manufacturer’s name

property n: int

Number of joints

Returns:

Number of joints

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> robot.n
6
property name: str

Get/set robot name

  • robot.name is the robot name

  • robot.name = ... checks and sets the robot name

Parameters:

name – the new robot name

Returns:

the current robot name

property nbranches: int

Number of branches

Number of branches in this robot. Computed as the number of links with zero children

Returns:

number of branches in the robot’s kinematic tree

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.ETS.Panda()
>>> robot.nbranches
1

See also

n() nlinks()

Number of links

The returned number is the total of both variable joints and static links

Returns:

Number of links

Examples

>>> import roboticstoolbox as rtb
>>> robot = rtb.models.DH.Puma560()
>>> robot.nlinks
6

See also

n() nbranches()

nofriction(coulomb=True, viscous=False)

Remove manipulator joint friction

Parameters:
  • coulomb (bool) – set the Coulomb friction to 0

  • viscous (bool) – set the viscous friction to 0

Return type:

Any

Returns:

A copy of the robot with dynamic parameters perturbed

nofriction() copies the robot and returns a robot with the same link parameters except the Coulomb and/or viscous friction parameter are set to zero.

payload(m, p=None)

Add a payload to the end-effector

Parameters:
Return type:

None

payload(m, p) adds a payload with point mass m at position p in the end-effector coordinate frame.

payload(m) adds a payload with point mass m at the origin of the end-effector coordinate frame.

payload(0) removes added payload.

The point mass is combined with the mass, centre of mass and inertia of the end-effector link, and p is expressed in that link’s frame. The link’s own parameters are kept, so each call replaces the payload added by the previous one, and a payload of zero mass leaves the dynamics unchanged.

Note

The end-effector link is ee_links[0] when the robot has a single end-effector. A robot with several end-effectors has no single end-effector link, and the payload is added to links[n - 1] as in earlier releases.

payload_capacity(q, tau_m, w, frame='base')

Compute the payload capacity of the manipulator

Parameters:
  • q (ndarray | Sequence[float]) – Joint coordinates for trajectory

  • tau_m (ndarray | Sequence[float]) – actuator torque limits

  • w (ndarray | Sequence[float]) – External wrench applied to the end-effector

  • frame (Literal['base', 'ee']) – the frame in which w is expressed, "base" for the base frame (default) and "ee" for the end-effector frame, which includes the tool transform

Returns:

Payload capacity of the manipulator

Return type:

ndarray

For each configuration, row of q, compute the multiple of the applied external wrench w that can be applied to the end-effector without exceeding the actuator torque limits tau_m. If w is the weight of a 1 kg mass then the multiple is the capacity in kg. A load such as a weight is fixed in the world, so w is in the base frame by default; use frame="ee" for a wrench that is fixed to the end-effector, such as a force along the tool axis. This multiple is computed for each joint and can be

  • a positive real number

  • inf the joint has no role in determining the payload capacity

  • nan the gravity load already exceeds the joint torque limit

The joint with the lowest payload capacity is the one that determines the overall payload capacity for that configuration.

The result is a matrix of payload capacities for each joint and configuration.

The joint force/torque limits tau_m are given as an array of shape (n,) or (1,n) of maximum values, in which case the minimum is the negative of the maximum, or (2,n), in which case the first row is the minimum and the second row is the maximum.

Examples

In this example we compute the payload capacity of the Puma560 robot along a straight line trajectory in the x-direction, moving from tightly folded to almost straight. The end-effector is oriented with the tool frame pointing in the x-direction, and a tool offset is added so that the load causes a moment on the wrist. The external wrench is a downward force of 9.81 N, which is equivalent to a 1 kg mass. The torque limits are the motor fuse limits from Table 2.17 of “Visual Control of Robots”, Corke (1996). The payload capacity, as well as the limiting joint, is plotted as a function of the x-position of the end-effector. The minimum payload capacity is also plotted, along with the index of the joint that determines the payload capacity.

>>> from roboticstoolbox import models
>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> from spatialmath import SE3
>>> puma = models.DH.Puma560()
>>> puma.tool = SE3.Tz(0.05)
>>> T = SE3.Tx(np.arange(0.35, 0.85, 0.01)) * SE3.Tz(puma.links[0].d) * SE3.Ry(90, "deg")
>>> sol = puma.ikine_a(T)
>>> w = [0,0,-9.81,0,0,0]
>>> cap = puma.payload_capacity(sol.q, [56, 97, 52,10,10,10], w)
>>> plt.plot(T.x, [np.min(c) for c in cap])
>>> plt.plot(T.x, [np.argmin(c) for c in cap])

(Source code, png, hires.png, pdf)

_images/arm_superclass-3.png

Derived from the MATLAB functions pay and paycap originally contributed to the MATLAB Robotics Toolbox by Bryan Moutrie (@au-phiware). Ported to Python and adapted for robotics-toolbox-python with permission from the original author.

Added in version 1.5.0.

Seealso:

gravload() payload()

perturb(p=0.1)

Perturb robot parameters

Parameters:

p (float) – The percent (+/-) to be perturbed. Default 10%

Return type:

Any

Returns:

A copy of the robot with dynamic parameters perturbed

rp = perturb(p) is a new robot object in which the dynamic parameters (link mass and inertia) have been perturbed. The perturbation is multiplicative so that values are multiplied by random numbers in the interval (1-p) to (1+p). The name string of the perturbed robot is prefixed by ‘P/’.

Useful for investigating the robustness of various model-based control schemes. For example to vary parameters in the range +/- 10 percent is: r2 = puma.perturb(0.1)

plot(q, backend=None, block=False, dt=0.05, limits=None, vellipse=False, fellipse=False, fig=None, movie=None, loop=False, notebook=None, ax=None, env=None, view=None, **kwargs)

Graphical display and animation

robot.plot(q, 'pyplot') displays a graphical view of a robot based on the kinematic model and the joint configuration q. This is a stick figure polyline which joins the origins of the link coordinate frames. The plot will autoscale with an aspect ratio of 1.

If q (m,n) representing a joint-space trajectory it will create an animation with a pause of dt seconds between each frame.

Parameters:
  • q (ndarray | Sequence[float]) – The joint configuration of the robot.

  • backend (Optional[Literal['swift', 'pyplot', 'pyplot2']]) – The graphical backend to use, currently ‘swift’ and ‘pyplot’ are implemented. Defaults to ‘swift’ of a Robot and ‘pyplot` for a DHRobot

  • block (bool) – True waits until the window is closed; the PyPlot backend has already shown the figure, so False and None return at once, defaults to False

  • dt (float) – if q is a trajectory, this describes the delay in seconds between frames

  • limits (ndarray | Sequence[float] | None) – Custom view limits for the plot. If not supplied will autoscale, [x1, x2, y1, y2, z1, z2] (this option is for ‘pyplot’ only)

  • vellipse (bool) – (Plot Option) Plot the velocity ellipse at the end-effector (this option is for ‘pyplot’ only)

  • fellipse (bool) – (Plot Option) Plot the force ellipse at the end-effector (this option is for ‘pyplot’ only)

  • fig (str | None) – (Plot Option) The figure label to plot in (this option is for ‘pyplot’ only)

  • ax (Any) – (Plot Option) Existing Matplotlib 3D axes to draw the scene on, instead of making a figure (this option is for ‘pyplot’ only)

  • env (Connector | None) – The scene returned by an earlier plot, to add this robot to, instead of making a new scene; see Several configurations below. The backend of the scene is used, so backend is ignored, and the options that are set when a scene is made (limits, fig, ax, render_mode, inline_*, notebook and browser) cannot be given

  • color – (Plot Option) The color of the robot’s line, any Matplotlib color (this option is for ‘pyplot’ only)

  • view (str | None) – (Plot Option) "xy", "xz" or "yz" to start with a flat view of that plane, the first axis to the right and the second up, or None (default) for the usual three-dimensional view. The view is not locked, the plot can be rotated as usual. With env it changes the view of that scene (this option is for ‘pyplot’ only)

  • movie (str | None) – (Plot Option) The filename to save the movie to (this option is for ‘pyplot’ only)

  • loop (bool) – (Plot Option) Loop the movie (this option is for ‘pyplot’ only)

  • notebook (bool | None) – (Plot Option, Swift only) True shows Swift in a frame of the current notebook cell, False opens it in a browser window, and None (default) chooses the frame in a notebook, unless a browser is named, and a window otherwise, so the same call works in a script and in a notebook. The browser showing the notebook must be on the machine running the kernel, since the frame points at localhost

  • browser – (Plot Option, Swift only) the browser for the window, or None (default) for the system’s. This is a name known to Python’s webbrowser module, which depends on the operating system, for example "chrome", "firefox" or "safari" on macOS and "google-chrome" or "chromium" on Linux, or a command line with %s where the URL goes, for any other browser; webbrowser.get(name) tells you whether a name works. Naming a browser means a window, not the notebook frame. browser="notebook" is deprecated, use notebook=True. See swift.Swift.Swift.launch()

  • realtime – (Plot Option) Pace the steps of a trajectory in real time, one each dt, defaults to True for a trajectory (this option is for ‘swift’ only)

  • jointaxes – (Plot Option) Plot an arrow indicating the axes in which the joint revolves around(revolute joint) or translates along (prosmatic joint) (this option is for ‘pyplot’ only)

  • eeframe – (Plot Option) Plot the end-effector coordinate frame at the location of the end-effector. Uses three arrows, red, green and blue to indicate the x, y, and z-axes. (this option is for ‘pyplot’ only)

  • shadow – (Plot Option) Plot a shadow of the robot in the x-y plane. (this option is for ‘pyplot’ only)

  • name – (Plot Option) Plot the name of the robot near its base (this option is for ‘pyplot’ only)

  • render_mode – (Plot Option) Rendering mode for matplotlib backends: 'window', 'notebook-widget', or 'notebook-inline'. If omitted, a mode is chosen from the environment, so the same call works for any %matplotlib setting: for the interactive ipympl backend a single pose is a widget that can be rotated, but a trajectory uses 'notebook-inline', since a widget cannot update while the cell is running.

  • inline_every_n – (Plot Option) In notebook-inline mode, push one rendered frame every N simulation steps. Larger N reduces output load.

  • inline_format – (Plot Option) In notebook-inline mode, frame format: 'svg' (default) or 'png'.

  • inline_dpi – (Plot Option) DPI for PNG inline frames only; ignored when inline_format='svg'.

Return type:

Connector

Returns:

A reference to the environment object which controls the figure

Note

Python’s webbrowser module cannot tell whether a browser is installed, so a browser that cannot be opened is not reported as such. On macOS the names "chrome", "firefox" and "safari" are always accepted, whether or not the app is installed. If it is not, no window opens and there is no error: Swift waits about 10 seconds for the page to connect and then reports Could not connect to the Swift simulator. If you see that, check that the browser named by browser is installed, or leave it as None to use the system’s default browser. See swift.Swift.Swift.launch().

Several configurations

plot returns the scene it made, and passing that as env to another plot adds a robot to it instead of making a new scene. The robot is the same model, and each plot of it holds the pose it was given, so the robot is shown in two configurations at once, here the initial and the final. Give each a color, and turn off what would be drawn twice.

import roboticstoolbox as rtb

puma = rtb.models.DH.Puma560()
env = puma.plot(puma.qr, color="gray", block=False)
puma.plot(puma.qn, env=env, color="red", name=False, block=False)

(Source code, png, hires.png, pdf)

_images/arm_superclass-4.png

The scene can be given a pose to draw directly, handle = env.add(puma, q=q), and handle.q = q moves only that drawing. A robot that is added without a q follows puma.q, as it always has. A trajectory can be plotted on top of an earlier plot in the same way; the earlier plot stays where it was. In a notebook, an animation needs the scene to have been made with render_mode="notebook-inline".

Notes

  • By default this method will block until the figure is dismissed.

    To avoid this set block=False.

  • For PyPlot, the polyline joins the origins of the link frames,

    but for some Denavit-Hartenberg models those frames may not actually be on the robot, ie. the lines to not necessarily represent the links of the robot.

See also

teach()

plot_ellipse(ellipse, block=True, limits=None, jointaxes=True, eeframe=True, shadow=True, name=True)

Plot an ellipsoid.

Parameters:
  • ellipse (EllipsePlot) – the ellipsoid to plot

  • block (bool) – True waits until the window is closed; the PyPlot backend has already shown the figure, so False and None return at once, defaults to True

  • limits (ndarray | Sequence[float] | None) – custom view limits [x1, x2, y1, y2, z1, z2]; autoscales if not supplied

  • jointaxes (bool) – plot an arrow indicating the joint axis

  • eeframe (bool) – plot the end-effector coordinate frame

  • shadow (bool) – plot a shadow of the robot in the x-y plane

  • name (bool) – plot the name of the robot near its base

Returns:

a reference to the PyPlot object controlling the matplotlib figure

Return type:

PyPlot

robot.plot_ellipse(ellipsoid) displays the ellipsoid.

plot_fellipse(q, block=True, fellipse=None, limits=None, opt='trans', centre='ee', jointaxes=True, eeframe=True, shadow=True, name=True)

Plot the force ellipsoid for a manipulator.

Parameters:
  • q (ndarray | Sequence[float] | None) – the joint configuration of the robot

  • block (bool) – True waits until the window is closed; the PyPlot backend has already shown the figure, so False and None return at once, defaults to True

  • fellipse (EllipsePlot | None) – a pre-built force ellipsoid to plot

  • limits (ndarray | Sequence[float] | None) – custom view limits [x1, x2, y1, y2, z1, z2]; autoscales if not supplied

  • opt (Literal['trans', 'rot']) – 'trans' or 'rot' — plot the translational or rotational force ellipsoid

  • centre (Union[Literal['ee'], ndarray, Sequence[float]]) – coordinates to plot the ellipse — [x, y, z] or "ee"

  • jointaxes (bool) – plot an arrow indicating the joint axis

  • eeframe (bool) – plot the end-effector coordinate frame

  • shadow (bool) – plot a shadow of the robot in the x-y plane

  • name (bool) – plot the name of the robot near its base

Raises:

ValueError – if neither q nor fellipse is supplied

Returns:

a reference to the PyPlot object controlling the matplotlib figure

Return type:

PyPlot

robot.plot_fellipse(q) displays the force ellipsoid for the robot at pose q. The plot will autoscale with an aspect ratio of 1.

robot.plot_fellipse(vellipse=ell) uses a pre-built ellipse object.

Notes

  • By default the ellipsoid related to translational motion is drawn. Use opt='rot' to draw the rotational velocity ellipsoid.

  • By default the ellipsoid is drawn at the origin. Use centre to specify a 3-vector, or "ee" to draw at the end-effector.

plot_vellipse(q, block=True, vellipse=None, limits=None, opt='trans', centre='ee', jointaxes=True, eeframe=True, shadow=True, name=True)

Plot the velocity ellipsoid for a manipulator.

Parameters:
  • q (ndarray | Sequence[float] | None) – the joint configuration of the robot

  • block (bool) – True waits until the window is closed; the PyPlot backend has already shown the figure, so False and None return at once, defaults to True

  • vellipse (EllipsePlot | None) – a pre-built velocity ellipsoid to plot

  • limits (ndarray | Sequence[float] | None) – custom view limits [x1, x2, y1, y2, z1, z2]; autoscales if not supplied

  • opt (Literal['trans', 'rot']) – 'trans' or 'rot' — plot the translational or rotational velocity ellipsoid

  • centre (Union[Literal['ee'], ndarray, Sequence[float]]) – coordinates to plot the ellipse — [x, y, z] or "ee"

  • jointaxes (bool) – plot an arrow indicating the joint axis

  • eeframe (bool) – plot the end-effector coordinate frame

  • shadow (bool) – plot a shadow of the robot in the x-y plane

  • name (bool) – plot the name of the robot near its base

Raises:

ValueError – if neither q nor vellipse is supplied

Returns:

a reference to the PyPlot object controlling the matplotlib figure

Return type:

PyPlot

robot.plot_vellipse(q) displays the velocity ellipsoid for the robot at pose q. The plot will autoscale with an aspect ratio of 1.

robot.plot_vellipse(vellipse=ell) uses a pre-built ellipse object.

Notes

  • By default the ellipsoid related to translational motion is drawn. Use opt='rot' to draw the rotational velocity ellipsoid.

  • By default the ellipsoid is drawn at the origin. Use centre to specify a 3-vector, or "ee" to draw at the end-effector.

property prismaticjoints: list[bool]

Prismatic joints as bool array

Returns:

array of joint type, True if prismatic

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.prismaticjoints
[False, False, False, False, False, False]
>>> stanford = rtb.models.DH.Stanford()
>>> stanford.prismaticjoints
[False, False, True, False, False, False]

Notes

Fixed joints, that maintain a constant link relative pose, are not included.

property q: ndarray

Get/set robot joint configuration

  • robot.q is the robot joint configuration

  • robot.q = ... checks and sets the joint configuration

Parameters:

q – the new robot joint configuration

Returns:

robot joint configuration

Setter accepts:

ndarray | Sequence[float]

property qd: ndarray

Get/set robot joint velocity

  • robot.qd is the robot joint velocity

  • robot.qd = ... checks and sets the joint velocity

Returns:

robot joint velocity

Setter accepts:

ndarray | Sequence[float]

property qdd: ndarray

Get/set robot joint acceleration

  • robot.qdd is the robot joint acceleration

  • robot.qdd = ... checks and sets the robot joint acceleration

Returns:

robot joint acceleration

Setter accepts:

ndarray | Sequence[float]

property qlim: ndarray

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:

qlim – An array of joints limits (2, n)

Raises:

ValueError – unset limits for a prismatic joint

Returns:

Array of joint limit values

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]])
Setter accepts:

ndarray | Sequence[float]

random_q()

Return a random joint configuration

The value for each joint is uniform randomly distributed between the limits set for the robot.

Notes

The joint limit for all joints must be set.

Return type:

Any

Returns:

Random joint configuration :rtype: ndarray(n)

See also

qlim() qlim()

property revolutejoints: list[bool]

Revolute joints as bool array

Returns:

array of joint type, True if revolute

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.revolutejoints
[True, True, True, True, True, True]
>>> stanford = rtb.models.DH.Stanford()
>>> stanford.revolutejoints
[True, True, False, True, True, True]

Notes

Fixed joints, that maintain a constant link relative pose, are not included.

property scene_children: list[SceneNode]

Return the child nodes of this object in the scene graph.

Setting a new list of children updates each child’s scene_parent to this object, but does not remove this object from any previous parent’s scene_children.

This is a read/write property.

Return type:

list(SceneNode)

Seealso:

scene_parent() attach() attach_to()

property scene_parent: SceneNode | None

Return the parent node of this object in the scene graph.

Setting a new parent adds this object to the new parent’s scene_children.

This is a read/write property.

Return type:

SceneNode | None

Seealso:

scene_children() attach() attach_to()

Setter accepts:

SceneNode

segments()

Segments of branched robot

For a single-chain robot with structure:

L1 - L2 - L3

the return is [[None, L1, L2, L3]]

For a robot with structure:

L1 - L2 +-  L3 - L4
        +- L5 - L6

the return is [[None, L1, L2], [L2, L3, L4], [L2, L5, L6]]

Return type:

list[list[Optional[Link2]]]

Returns:

Segment list

Notes

  • the length of the list is the number of segments in the robot

  • the first segment always starts with None which represents

    the base transform (since there is no base link)

  • the last link of one segment is also the first link of subsequent

    segments

classmethod set_default_backend(be)

Set the default graphical backend for all robots

Parameters:

be (Any) – backend name, for example "swift", or None to clear

Return type:

None

Robot.set_default_backend("swift") sets the backend used by plot() for every robot, existing or created later, that has not been given one of its own by robot.default_backend = .... The robot’s own value takes precedence.

See also

default_backend

showgraph(display_graph=True, **kwargs)

Display a link transform graph in browser

robot.showgraph() displays a graph of the robot’s link frames and the ETS between them. It uses GraphViz dot.

The nodes are:
  • Base is shown as a grey square. This is the world frame origin, but can be changed using the base attribute of the robot.

  • Link frames are indicated by circles

  • ETS transforms are indicated by rounded boxes

The edges are:
  • an arrow if jtype is False or the joint is fixed

  • an arrow with a round head if jtype is True and the joint is revolute

  • an arrow with a box head if jtype is True and the joint is prismatic

Edge labels or nodes in blue have a fixed transformation to the preceding link.

Parameters:
  • display_graph (bool) – Open the graph in a browser if True. Otherwise will return the file path

  • etsbox – Put the link ETS in a box, otherwise an edge label

  • jtype – Arrowhead to node indicates revolute or prismatic type

  • static – Show static joints in blue and bold

Return type:

str | None

Examples

>>> import roboticstoolbox as rtb
>>> panda = rtb.models.URDF.Panda()
>>> panda.showgraph()
_images/panda-graph.svg

See also

dotfile() graph()

property structure: str

Return the joint structure string

A string with one letter per joint: R for a revolute joint, and P for a prismatic joint.

Returns:

joint configuration string

Examples

>>> import roboticstoolbox as rtb
>>> puma = rtb.models.DH.Puma560()
>>> puma.structure
'RRRRRR'
>>> stanford = rtb.models.DH.Stanford()
>>> stanford.structure
'RRPRRR'

Notes

Fixed joints, that maintain a constant link relative pose, are not included. len(self.structure) == self.n.

property symbolic: bool
teach(q, block=True, limits=None, vellipse=False, fellipse=False, backend=None, view=None)

Graphical teach pendant

robot.teach(q) opens a graphical view (PyPlot or Swift – see backend) which allows the user to “drive” a graphical robot using a graphical slider panel. The robot’s initial joint configuration is q.

robot.teach() as above except the robot’s stored value of q is used.

Parameters:
  • q (ndarray | Sequence[float] | None) – The joint configuration of the robot (Optional, if not supplied will use the stored q values).

  • block (bool) – True waits until the window is closed; the PyPlot backend has already shown the figure, so False and None return at once, defaults to True

  • limits (ndarray | Sequence[float] | None) – Custom view limits for the plot. If not supplied will autoscale, [x1, x2, y1, y2, z1, z2] (this option is for ‘pyplot’/’pyplot2’ only)

  • vellipse (bool) – (Plot Option) Plot the velocity ellipse at the end-effector (this option is for ‘pyplot’ only)

  • fellipse (bool) – (Plot Option) Plot the force ellipse at the end-effector (this option is for ‘pyplot’ only)

  • backend (Optional[Literal['swift', 'pyplot', 'pyplot2']]) – The graphical backend to use – ‘swift’, ‘pyplot’, or ‘pyplot2’. Defaults to whatever plot() would pick for this robot (see its own backend for the resolution rule).

  • view (str | None) – "xy", "xz" or "yz" to start with a flat view of that plane, the first axis to the right and the second up, or None (default) for the usual three-dimensional view. The view is not locked, the plot can be rotated as usual (this option is for ‘pyplot’ only)

Return type:

Connector

Returns:

A reference to the environment object which controls the figure/view

Notes

  • Program execution is blocked until the teach window is dismissed. If block=False the method is non-blocking but you need to poll the window manager (PyPlot) or keep calling env.step() yourself (Swift) to ensure the window/panel remains responsive.

  • Once teach() returns (block=True), robot.q holds the final pose the sliders were left at – true for every backend, even though Swift’s own live joint state during the session lives on the returned environment’s handle (env.swift_objects[0].q), not robot.q itself, to keep the robot model plain and shareable while teaching is in progress (see swift’s AssemblyHandle).

  • The slider limits are derived from the joint limit properties. If not set then:

    • For revolute joints they are assumed to be [-pi, +pi]

    • For prismatic joint they are assumed unknown and an error occurs.

todegrees(q)

Convert joint angles to degrees

Parameters:

q (Any) – The joint configuration of the robot

Return type:

ndarray

Returns:

a vector of joint coordinates in degrees and metres

Returns:

robot.todegrees(q) converts joint coordinates q to degrees

Returns:

taking into account whether elements of q correspond to revolute

Returns:

or prismatic joints, ie. prismatic joint values are not converted.

Returns:

If q is a matrix, with one column per joint, the conversion is

Returns:

performed columnwise.

Examples

>>> import roboticstoolbox as rtb
>>> from math import pi
>>> stanford = rtb.models.DH.Stanford()
>>> stanford.todegrees([pi/4, pi/8, 2, -pi/4, pi/6, pi/3])
array([ 45. ,  22.5,   2. , -45. ,  30. ,  60. ])
property tool: SE3

Get/set robot tool transform

  • robot.tool is the robot tool transform as an SE3 object

  • robot._tool is the robot tool transform as a numpy array

  • robot.tool = ... checks and sets the robot tool transform

Parameters:

tool – the new robot tool transform (as an SE(3))

Returns:

robot tool transform

Setter accepts:

SE3 | ndarray

toradians(q)

Convert joint angles to radians

robot.toradians(q) converts joint coordinates q to radians taking into account whether elements of q correspond to revolute or prismatic joints, ie. prismatic joint values are not converted.

If q is a matrix, with one column per joint, the conversion is performed columnwise.

Parameters:

q (Any) – The joint configuration of the robot

Return type:

ndarray

Returns:

a vector of joint coordinates in radians and metres

Examples

>>> import roboticstoolbox as rtb
>>> stanford = rtb.models.DH.Stanford()
>>> stanford.toradians([10, 20, 2, 30, 40, 50])
array([0.1745, 0.3491, 2.    , 0.5236, 0.6981, 0.8727])
tree()

Render the whole tree this node lives in as indented text – walks up to the root first (the same root-finding as update()), then renders down from there, with this node marked with a trailing <== so its position in the tree is visible.

Return type:

str

tree_children()

Render this node’s own subtree as indented text (one repr() per line), not walking through parents – the same “not through parents” scope as _propagate_scene_children().

Nodes have no .name in this package, so each line is that node’s own repr() (type, constructor params, color, pose) – usually enough to tell siblings apart, since it’s rare for two distinct nodes to share an identical pose as well as everything else.

Return type:

str

update()

Recompute the world transform of every node in the scene graph this node belongs to, starting from the root and working down.

Call this after changing any node’s T/pose (or its scene_parent) – nothing propagates automatically. It doesn’t matter which node in the graph you call it on: this always walks up to the root first, then pushes fresh world transforms down through the whole tree, not just this node’s own subtree.

Return type:

None

property urdf_filepath: str
property urdf_string: str
vellipse(q, opt='trans', unit='rad', centre='ee', scale=0.1, add=True)

Create a velocity ellipsoid object for plotting with PyPlot.

Parameters:
  • q (ndarray | Sequence[float]) – the joint configuration of the robot

  • opt (Literal['trans', 'rot']) – 'trans' or 'rot' — plot the translational or rotational velocity ellipsoid

  • unit (Literal['rad', 'deg']) – 'rad' or 'deg'

  • centre (Union[Literal['ee'], ndarray, Sequence[float]]) – centre of the ellipsoid — 'ee' for the end-effector or a 3-vector [x, y, z] in the world frame

  • scale (float) – scale factor for the ellipsoid

  • add (bool) – if True, add the ellipsoid to the active plot environment

Returns:

an EllipsePlot object

Return type:

EllipsePlot

robot.vellipse(q) creates a velocity ellipsoid for the robot at pose q. By default the ellipsoid is centered at the end-effector.

Notes

  • By default the ellipsoid related to translational motion is drawn. Use opt='rot' to draw the rotational velocity ellipsoid.

  • By default the ellipsoid is drawn at the end-effector. The option centre allows its origin to be set to the specified 3-vector, or the string "ee" ensures it is drawn at the end-effector position.

property base: SE2

Get/set robot base transform

Returns:

robot tool transform

robot.base is the robot base transform

  • robot.base = ... checks and sets the robot base transform

Notes

  • The private attribute _base will be None in the case of

    no base transform, but this property will return SE3() which is an identity matrix.

Setter accepts:

Any

jacob0(q, start=None, end=None)[source]
Return type:

Any

jacobe(q, start=None, end=None)[source]
Return type:

Any

fkine(q, end=None, start=None)[source]
Return type:

Any

property reach: float

Reach of the robot

Returns:

Maximum reach of the robot

Return type:

float

A conservative estimate of the reach of the robot. It is computed as the sum of the translational ETs that define the link transform.

Computed on the first access. If kinematic parameters subsequently change this will not be reflected.

Notes

  • Probably an overestimate of reach

  • Used by numerical inverse kinematics to scale translational error.

  • For a prismatic joint, uses qlim if it is set

fkine_all(q)[source]

Compute the pose of every link frame

Parameters:

q (ndarray | Sequence[float]) – The joint configuration

Return type:

SE2

Returns:

Pose of all links

T = robot.fkine_all(q) is an SE3 instance with robot.nlinks + 1 values:

  • T[0] is the base transform

  • T[i] is the pose of link whose number is i

References

  • J. Haviland, and P. Corke. “Manipulator Differential Kinematics Part I: Kinematics, Velocity, and Applications.” arXiv preprint arXiv:2207.01796 (2022).