newton.controllers.ControllerDifferentialIK#
- class newton.controllers.ControllerDifferentialIK(model, *, articulations=None, joints=None, tool_sites, axis_weight=None, bandwidth, damping, ik_method=DifferentialIKMethod.DAMPED_LEAST_SQUARES, adaptive_damping_min=None, adaptive_damping_max=None, adaptive_damping_threshold=None, truncated_svd_threshold=None, use_joint_limit_avoidance=False, joint_limit_avoidance_gain=0.0, joint_limit_avoidance_margin=0.0, joint_pos_lower=None, joint_pos_upper=None, use_null_space_posture_control=False, null_space_stiffness=None, null_space_damping=None, null_space_axes=None)[source]#
Bases:
ControllerBaseDifferential-kinematics (Jacobian-based) controller with internally computed kinematics.
Implements a differential-kinematics control law, selectable per instance via
DifferentialIKMethod(damped least squares by default). This model-based variant computes the tool pose and tool-point Jacobian itself: it evaluates forward kinematics andnewton.eval_jacobian()frommodelon everystep(), so the caller supplies only joint positions/velocities plus the desired tool pose.modelis borrowed, not owned — it is never written to, and changes to it are visible to the controller immediately.Joint selection.
articulationsandjointsselect which DOFs become the tool Jacobian’s columns, following Label Matching: each is a list of model indices and/or label patterns (or a single pattern), matched againstarticulation_labeland the leaf component ofjoint_labelrespectively. Only joints spanning a single coordinate and a single DOF can be controlled.Tool selection.
tool_sitesselects one Newton site per robot that ends up with controlled joints — the point on the robot whose pose is controlled. It follows the samelist[index/pattern] | index | patternshape asjoints, matched against the leaf component of each site’s label. Every controlled robot must match exactly one site.Each articulation in
modelis one robot. Supports heterogeneous robot fleets — robots may have different controlled-DOF counts, and a robot may be left uncontrolled entirely by omitting it fromarticulations.See also
ControllerDifferentialIKModelFree, which takes the tool pose and Jacobian as inputs instead of computing them from aModel.- Parameters:
model (Model) –
Modelwhose articulations are the robots.model.requires_grad=Trueis not supported at this time.articulations (list[int | str | re.Pattern[str]] | str | re.Pattern[str] | None) – Articulation indices or label patterns to control, as a list or as a single pattern.
Noneselects every articulation inmodel.joints (list[int | str | re.Pattern[str]] | str | re.Pattern[str] | None) – Model joint indices or label patterns whose DOFs become the tool Jacobian’s columns, within the selected articulations, as a list or as a single pattern.
Noneselects every joint spanning exactly one coordinate and one DOF in each selected articulation; any other joint is left uncontrolled instead of rejected. A joint named explicitly is not filtered this way and still raisesValueErrorif it is not 1-coordinate/1-DOF.tool_sites (list[int | str | re.Pattern[str]] | str | re.Pattern[str]) – Site indices or label patterns selecting each controlled robot’s controlled point, as a list or as a single pattern. Required — there is no default tool site. Raises if a controlled robot matches zero or more than one site.
axis_weight (wp.array[wp.spatial_vector] | wp.spatial_vector | None) – Non-negative per-axis weight for each of the 6 canonical task axes (position x, y, z, then orientation x, y, z),
diag(w)applied to both the Jacobian and the pose error for that axis before the solve (J_w = diag(w) @ J,e_w = diag(w) @ e) — a genuine soft weight for any nonzero value. An axis weighted exactly0is different in kind, not just degree: it is excluded from the solve structurally (its error and Jacobian rows never enter it at all), not merely driven toward zero by a very small weight — this also shrinks the task’s own dimension, so a robot with fewer than 6 controlled DOFs can still be redundant if enough axes are zeroed. Any combination of active axes is allowed, not just a leading prefix. Pass a singlewp.spatial_vectorto apply the same weights to every robot, or an array of shape [controlled_robot_count] to set them per robot.None(the default) means every axis is weighted1for every robot — full, equally-trusted 6D pose.bandwidth (wp.array[wp.float32] | float | None) – Output velocity scale gain, applied per controlled DOF after the Jacobian solve. Must be non-negative, since a negative value would flip the output velocity’s direction. Pass a scalar to apply the same gain to every controlled DOF, an array of shape [total_controlled_dofs] to set them individually, or
Noneto readinputs.bandwidtheach step.damping (wp.array[wp.float32] | float | None) – Damped-least-squares regularization λ, applied per robot to the task-space normal-equations matrix. Pass a scalar to apply the same damping to every robot, an array of shape [controlled_robot_count] to set them individually, or
Noneto readinputs.dampingeach step. Only meaningful whenik_method=DifferentialIKMethod.DAMPED_LEAST_SQUARES(the default); must beNonefor every otherDifferentialIKMethod, which has no λ to set.ik_method (DifferentialIKMethod) – Inverse-Jacobian solve method, a
DifferentialIKMethod. Defaults toDifferentialIKMethod.DAMPED_LEAST_SQUARES.adaptive_damping_min (float | None) – λ used when the smallest singular value of the task Jacobian is at or above
adaptive_damping_threshold. Required (and must be non-negative) whenik_method=DifferentialIKMethod.ADAPTIVE_DAMPING; must beNoneotherwise.adaptive_damping_max (float | None) – λ used at a full singularity (smallest singular value zero), ramping down to
adaptive_damping_minas the smallest singular value rises toadaptive_damping_threshold. Required (and must exceedadaptive_damping_min) whenik_method=DifferentialIKMethod.ADAPTIVE_DAMPING; must beNoneotherwise.adaptive_damping_threshold (float | None) – Smallest-singular-value threshold below which damping starts ramping from
adaptive_damping_mintowardadaptive_damping_max. Required (and must be positive) whenik_method=DifferentialIKMethod.ADAPTIVE_DAMPING; must beNoneotherwise.truncated_svd_threshold (float | None) – Per-direction singular-value threshold — a task-space direction with singular value above this is inverted exactly, one at or below it is dropped from the solve entirely. Required (and must be positive) when
ik_method=DifferentialIKMethod.TRUNCATED_SVD; must beNoneotherwise.use_joint_limit_avoidance (bool) – Project a joint-limit-avoidance bias through the null-space projector. Requires
joint_limit_avoidance_gain,joint_limit_avoidance_margin,joint_pos_lower, andjoint_pos_upper.joint_limit_avoidance_gain (float) – Joint-centering gain, applied once a DOF comes within
joint_limit_avoidance_marginof either limit. Required (and must be positive) whenuse_joint_limit_avoidance=True.joint_limit_avoidance_margin (float) – Distance from either limit at which the avoidance bias starts ramping in [m or rad], same units as
joint_pos_lower/joint_pos_upper. Required (and must be positive) whenuse_joint_limit_avoidance=True.joint_pos_lower (wp.array[wp.float32] | None) – Lower joint position limit per controlled DOF [m or rad], shape [total_controlled_dofs]. Required when
use_joint_limit_avoidance=True; baked at construction, not a live port.joint_pos_upper (wp.array[wp.float32] | None) – Upper joint position limit per controlled DOF [m or rad], shape [total_controlled_dofs]. Required when
use_joint_limit_avoidance=True; baked at construction, not a live port.use_null_space_posture_control (bool) – Project a proportional pull toward
inputs.q_des_nullthrough the null-space projector. Enablesnull_space_stiffness.null_space_stiffness (wp.array[wp.float32] | float | None) – Posture-control proportional gain, applied per controlled DOF. Must be non-negative. Pass a scalar to apply the same gain to every controlled DOF, an array of shape [total_controlled_dofs] to set them individually, or
Noneto readinputs.null_space_stiffnesseach step. Must beNonewhenuse_null_space_posture_control=False.null_space_damping (wp.array[wp.float32] | float | None) – Damping λ_null for the null-space projector’s own
(JJᵀ + λ_null²I)⁻¹, independent of the primary task’sdamping. Must be non-negative. Only meaningful whenuse_joint_limit_avoidanceoruse_null_space_posture_controlis enabled — pass a scalar or an array of shape [controlled_robot_count] to bake a value, or leave itNoneto readinputs.null_space_dampingeach step (the default, and the only valid value when both are disabled). Unlike the primarydamping,λ_null = 0is only safe when every robot has at least as many controlled DOFs as its own task dimension (the number of nonzeronull_space_axesentries) — otherwise the projector’s ownJJᵀis rank-deficient. That stronger, per-robot requirement is checked at construction only when baked; a live value is the caller’s responsibility there.null_space_axes (wp.array[wp.spatial_vector] | wp.spatial_vector | None) – Which of the 6 canonical axes the null-space projector guarantees the secondary objective (joint-limit avoidance/posture control) won’t disturb — zero leaves that axis unprotected, nonzero protects it; only the sign matters, unlike
axis_weight’s own soft magnitude. Defaults toaxis_weight(every solved axis protected), but the two are independent: an axis can be softly solved for yet left unprotected, e.g. an under-actuated arm with too few DOFs to protect every solved axis and still have a usable null space left over. Unlikeaxis_weight, an all-zero row is legal — it protects no axes, so the secondary objective is free to move all of them. Only meaningful whenuse_joint_limit_avoidanceoruse_null_space_posture_controlis enabled.
- class Inputs#
Bases:
objectInput struct returned by
input().joint_q/joint_qdcover the whole model, since forward kinematics depends on uncontrolled joints too; every other field is either per-robot or compact (one entry per controlled DOF). Optional fields areNonewhen the corresponding feature is disabled at construction.- bandwidth: wp.array[wp.float32] | wp.indexedarray[wp.float32] | None#
Output velocity scale gain, shape [total_controlled_dofs].
Nonewhen baked at construction.
- damping: wp.array[wp.float32] | wp.indexedarray[wp.float32] | None#
Damped-least-squares regularization λ, shape [controlled_robot_count].
Nonewhen baked at construction.
- desired_tool_pose_world: wp.array[wp.transformf] | wp.indexedarray[wp.transformf]#
Desired tool pose [m, unitless quaternion], world frame, shape [controlled_robot_count].
- joint_q: wp.array[wp.float32] | wp.indexedarray[wp.float32]#
Current joint positions [m or rad], shape [model.joint_coord_count].
- joint_qd: wp.array[wp.float32] | wp.indexedarray[wp.float32]#
Current joint velocities [m/s or rad/s], shape [model.joint_dof_count].
- null_space_damping: wp.array[wp.float32] | wp.indexedarray[wp.float32] | None#
Null-space projector damping λ_null, shape [controlled_robot_count].
Nonewhen both secondary objectives are disabled, or when baked at construction.
- class Outputs#
Bases:
objectOutput struct returned by
output().- joint_q_target: wp.array[wp.float32] | wp.indexedarray[wp.float32]#
One-step-ahead target joint position [m or rad], shape [total_controlled_dofs] =
joint_q + joint_qd_target * dt.
- joint_qd_target: wp.array[wp.float32] | wp.indexedarray[wp.float32]#
Target joint velocity [m/s or rad/s], shape [total_controlled_dofs].
- __init__(model, *, articulations=None, joints=None, tool_sites, axis_weight=None, bandwidth, damping, ik_method=DifferentialIKMethod.DAMPED_LEAST_SQUARES, adaptive_damping_min=None, adaptive_damping_max=None, adaptive_damping_threshold=None, truncated_svd_threshold=None, use_joint_limit_avoidance=False, joint_limit_avoidance_gain=0.0, joint_limit_avoidance_margin=0.0, joint_pos_lower=None, joint_pos_upper=None, use_null_space_posture_control=False, null_space_stiffness=None, null_space_damping=None, null_space_axes=None)#
- is_graphable()#
- set_joint_limits(*, joint_pos_lower, joint_pos_upper)#
Update the joint position limits used by joint-limit avoidance, in place.
- Parameters:
joint_pos_lower (wp.array[wp.float32]) – Lower joint position limit per controlled DOF [m or rad], shape [total_controlled_dofs].
joint_pos_upper (wp.array[wp.float32]) – Upper joint position limit per controlled DOF [m or rad], shape [total_controlled_dofs].
- step(*, inputs, outputs, dt)#
Run one differential-kinematics step.
Computes forward kinematics and the tool-point Jacobian from
model, then delegates the control law to the innerControllerDifferentialIKModelFree.
- property q_start: wp.array[wp.int32]#
Model coordinate index of each controlled joint, shape [total_controlled_dofs].
- property qd_start: wp.array[wp.int32]#
Model DOF index of each controlled joint, shape [total_controlled_dofs].
- property tool_body: wp.array[wp.int32]#
Body index of each controlled robot’s tool site, shape [controlled_robot_count].
- property tool_pose_world: wp.array[wp.transformf]#
World pose [m, unitless quaternion] of each controlled robot’s tool site as of the latest
step(), shape [controlled_robot_count].
- property tool_transform_body: wp.array[wp.transformf]#
Tool site’s transform [m, unitless quaternion] relative to its body, shape [controlled_robot_count].