newton.controllers.ControllerOperationalSpaceModelFree#

class newton.controllers.ControllerOperationalSpaceModelFree(*, controlled_dofs_per_robot, motion_stiffness, motion_damping, operational_frame_pose_world=_IDENTITY_TRANSFORM, use_inertia_decoupling=True, use_partial_inertia_decoupling=False, use_gravity_compensation=True, use_wrench_feedforward=False, use_wrench_feedback=False, motion_selection_axes=None, wrench_selection_axes=None, wrench_stiffness=None, linear_selection_frame_operational=_IDENTITY_QUAT, angular_selection_frame_operational=_IDENTITY_QUAT, use_null_space_control=False, null_space_stiffness=None, null_space_damping=None, device=None, requires_grad=False)[source]#

Bases: ControllerBase

Task-space (operational-space) impedance controller with caller-supplied kinematics and dynamics.

Implements the operational-space motion-control law. This model-free variant expects the tool pose, tool twist, tool-point Jacobian, and (when use_inertia_decoupling=True) the controlled-DOF mass matrix to be computed externally — it is the caller’s responsibility to compute these correctly and write them into the input struct before every step().

Every port is per-robot: a 1-D array with one entry per robot, ordered to match controlled_dofs_per_robot — except outputs.joint_f, which is compact: one entry per controlled DOF, robot 0’s DOFs first, then robot 1’s.

Every port, of any dtype, may be bound either to a plain array or to an indexed view of a simulation-sized array.

Array shapes and devices are validated on each direct call to step(), but not when a captured graph is replayed, since the checks run in Python at capture time only.

Supports heterogeneous robot fleets — robots may have different controlled-DOF counts. Only the Jacobian and mass matrix are padded, to max_controlled_dofs; every other buffer is compact or per-robot.

Allocate input and output structs via input() and output(). All field names on those structs are fixed — see Inputs and Outputs for the typed schema. Fields for disabled features (e.g. mass_matrix when use_inertia_decoupling=False) are allocated as None and must not be written.

Parameters:
  • controlled_dofs_per_robot (wp.array[wp.int32]) – Controlled-DOF count for each robot. Its length sets controlled_robot_count (the length of every per-robot port), its sum sets total_controlled_dofs (the length of outputs.joint_f), and its maximum sets max_controlled_dofs (the padded width of the Jacobian and mass matrix). Every entry must be positive, and — when use_inertia_decoupling=True — at least 6, since the operational-space mass matrix is only invertible for a robot whose Jacobian can span all 6 task dimensions.

  • motion_stiffness (wp.array[wp.spatial_vector] | wp.spatial_vector | float | None) – Task-space position/orientation-error gain Kp, per-axis in the operational frame (e.g. “stiff along the insertion axis” stays meaningful as that frame reorients). Units depend on use_inertia_decoupling: [1/s²] when enabled, since the spring-damper term is then a task-space acceleration premultiplied by Lambda; otherwise [N/m] on the position axes and [N·m/rad] on the orientation axes. Pass a scalar to apply the same gain to every axis of every robot, a wp.spatial_vector to apply the same 6 per-axis gains to every robot, an array of shape [controlled_robot_count] to set them individually (one wp.spatial_vector of 6 gains per robot), or None to read inputs.motion_stiffness each step.

  • motion_damping (wp.array[wp.spatial_vector] | wp.spatial_vector | float | None) – Task-space velocity-error gain Kd, operational-frame- local like motion_stiffness, [1/s] when use_inertia_decoupling is enabled, otherwise [N·s/m] on the position axes and [N·m·s/rad] on the orientation axes. Same format as motion_stiffness.

  • operational_frame_pose_world (wp.array[wp.transform] | wp.transform | None) – World pose of the operational frame — the frame inputs.desired_tool_pose_operational/ inputs.desired_twist_operational are expressed relative to, and that motion_stiffness/motion_damping/ wrench_stiffness are interpreted in. Need not coincide with the tool’s own current orientation (e.g. a frame aligned to a work surface, tracked independently of how the tool is oriented). Pass a wp.transform to apply the same fixed pose to every robot, an array of shape [controlled_robot_count] to set them individually (fixed for the controller’s lifetime), or None to read inputs.operational_frame_pose_world each step for a time-varying frame. Defaults to identity (coincides with world frame).

  • use_inertia_decoupling (bool) – Premultiply the task-space spring-damper term by Lambda, the operational-space mass matrix. Note that if inputs.mass_matrix omits a DOF that is both free and dynamically coupled to the controlled set, then there is not sufficient information to fully dynamically decouple the system. No error is raised, as omitting certain joints is often a useful approximation. It is the user’s responsibility to provide the needed information.

  • use_partial_inertia_decoupling (bool) – Compute Lambda ignoring the coupling between translational and rotational inertia. Only meaningful when use_inertia_decoupling=True.

  • use_gravity_compensation (bool) – Add inputs.gravity_force directly to the summed joint torque.

  • use_wrench_feedforward (bool) – Command the desired wrench directly, as a feedforward term in the wrench law, combined with motion control through Khatib’s generalized selection matrix Omega (see linear_selection_frame_operational/ angular_selection_frame_operational below). When both this and use_wrench_feedback are False, every axis is motion-controlled and motion_selection_axes/ wrench_selection_axes/wrench_stiffness must be left unset, and linear_selection_frame_operational/ angular_selection_frame_operational must be left at their identity default.

  • use_wrench_feedback (bool) – Correct the wrench command by Kp · (desired - measured) using inputs.measured_wrench_world each step, as a feedback term in the wrench law. May be enabled with or without use_wrench_feedforward: without it, the command is the feedback correction alone, regulating the measured wrench toward the desired setpoint with no separate feedforward term.

  • motion_selection_axes (wp.array[wp.spatial_vector] | wp.spatial_vector | None) – Diagonal selection weight per task axis (0/1, or any scalar weight): (linear x, y, z, angular x, y, z), the linear half interpreted in linear_selection_frame_operational (S_f) and the angular half in angular_selection_frame_operational (S_tau). Pass a wp.spatial_vector to apply the same weights to every robot, or an array of shape [controlled_robot_count] to set them individually. Only meaningful when wrench control is enabled; defaults to every axis motion-controlled, wp.spatial_vector(1, 1, 1, 1, 1, 1). Usually the complement of wrench_selection_axes — each axis under motion control, not force control, and vice versa — but that is not enforced: nothing here requires the two to partition the 6 axes.

  • wrench_selection_axes (wp.array[wp.spatial_vector] | wp.spatial_vector | None) – Diagonal selection weight per task axis, same format and selection frames as motion_selection_axes, applied to the wrench term. Required when wrench control is enabled. Usually the complement of motion_selection_axes, but that is not enforced — see its docstring above.

  • wrench_stiffness (wp.array[wp.spatial_vector] | wp.spatial_vector | float | None) – Contact-wrench proportional feedback gain Kp, operational-frame-local like motion_stiffness, dimensionless (multiplies a wrench error directly, not a pose error) on both the force and moment axes. Same format as motion_stiffness. Only meaningful when use_wrench_feedback=True.

  • linear_selection_frame_operational (wp.array[wp.quat] | wp.quat | None) – Orientation of S_f, the frame motion_selection_axes/wrench_selection_axes’s linear (force) half is interpreted in, relative to the operational frame — e.g. aligned to a contact surface’s normal. Independent of angular_selection_frame_operational (S_tau); the two need not agree. Pass a wp.quat to apply the same fixed orientation to every robot, an array of shape [controlled_robot_count] to set them individually, or None to read inputs.linear_selection_frame_operational each step for a time-varying frame. Defaults to identity.

  • angular_selection_frame_operational (wp.array[wp.quat] | wp.quat | None) – Orientation of S_tau, the frame motion_selection_axes/wrench_selection_axes’s angular (moment) half is interpreted in, relative to the operational frame — e.g. a compliant rotation axis. Same format as linear_selection_frame_operational.

  • use_null_space_control (bool) – Pursue a secondary joint-space posture task in the null space of the primary task, so it does not disturb task-space motion. Requires every robot to have more than 6 controlled DOFs (redundant relative to the 6D task). The null-space projector is dynamically consistent (accounts for the robot’s own inertia) when use_inertia_decoupling=True and use_partial_inertia_decoupling=False, or a kinematics-only (Moore-Penrose) projector otherwise.

  • null_space_stiffness (wp.array[wp.float32] | float | None) – Joint-space posture position-error gain Kp. Units depend on use_inertia_decoupling: [1/s²] when enabled, since the posture PD term is then premultiplied by the mass matrix; otherwise [N/m or N·m/rad]. Pass a scalar to apply the same gain to every controlled DOF, an array of shape [total_controlled_dofs] to set them individually, or None to read inputs.null_space_stiffness each step. Only meaningful when use_null_space_control=True.

  • null_space_damping (wp.array[wp.float32] | float | None) – Joint-space posture velocity-error gain Kd, [1/s] when use_inertia_decoupling is enabled, otherwise [N·s/m or N·m·s/rad]. Same format as null_space_stiffness.

  • device (Any) – Warp device.

  • requires_grad (bool) – Whether internal buffers need gradient support.

class Inputs#

Bases: object

Input struct returned by input().

Every field is per-robot, shape [controlled_robot_count], except jacobian_tool_world and mass_matrix, which are padded to [controlled_robot_count, …, max_controlled_dofs]. Optional fields are None when the corresponding feature is disabled at construction.

angular_selection_frame_operational: wp.array[wp.quatf] | wp.indexedarray[wp.quatf] | None#

Orientation of S_tau, relative to the operational frame, shape [controlled_robot_count]. None when fixed at construction, or when wrench control is disabled.

desired_tool_pose_operational: wp.array[wp.transformf] | wp.indexedarray[wp.transformf]#

Desired tool pose, relative to the operational frame, shape [controlled_robot_count].

desired_twist_operational: wp.array[wp.spatial_vectorf] | wp.indexedarray[wp.spatial_vectorf]#

Desired tool twist (linear, angular), components expressed in the operational frame [m/s, rad/s], shape [controlled_robot_count].

desired_wrench_world: wp.array[wp.spatial_vectorf] | wp.indexedarray[wp.spatial_vectorf] | None#

Desired contact wrench (force, moment) in world coordinates [N, N·m], shape [controlled_robot_count] — the feedforward term, and/or the feedback setpoint. None unless wrench control is enabled.

gravity_force: wp.array[wp.float32] | wp.indexedarray[wp.float32] | None#

Gravity generalized forces [N or N·m], compact, shape [total_controlled_dofs]. None unless use_gravity_compensation=True.

jacobian_tool_world: wp.array3d[wp.float32] | <warp._src.types.indexedarray object>#

Tool-point Jacobian in world coordinates, shape [controlled_robot_count, 6, max_controlled_dofs]. Rows 0-2 map a controlled DOF’s velocity to the tool point’s linear velocity [1 or m], rows 3-5 to its angular velocity [1/m or 1], depending on whether that DOF is revolute or prismatic.

joint_q: wp.array[wp.float32] | wp.indexedarray[wp.float32] | None#

Current joint positions [m or rad], compact, shape [total_controlled_dofs]. None unless use_null_space_control=True.

joint_q_des_null: wp.array[wp.float32] | wp.indexedarray[wp.float32] | None#

Desired joint positions for the null-space posture task [m or rad], compact, shape [total_controlled_dofs]. None unless use_null_space_control=True.

joint_qd: wp.array[wp.float32] | wp.indexedarray[wp.float32] | None#

Current joint velocities [m/s or rad/s], compact, shape [total_controlled_dofs]. None unless use_null_space_control=True.

joint_qd_des_null: wp.array[wp.float32] | wp.indexedarray[wp.float32] | None#

Desired joint velocities for the null-space posture task [m/s or rad/s], compact, shape [total_controlled_dofs]. None unless use_null_space_control=True.

linear_selection_frame_operational: wp.array[wp.quatf] | wp.indexedarray[wp.quatf] | None#

Orientation of S_f, relative to the operational frame, shape [controlled_robot_count]. None when fixed at construction, or when wrench control is disabled.

mass_matrix: wp.array3d[wp.float32] | <warp._src.types.indexedarray object> | None#

[kg] translational, [kg·m] mixed, [kg·m²] rotational. None unless use_inertia_decoupling=True.

Type:

Joint-space mass matrix over the controlled DOFs, shape [controlled_robot_count, max_controlled_dofs, max_controlled_dofs]; a robot with fewer than max_controlled_dofs DOFs leaves the trailing rows and columns unread. Units by row/column DOF type

measured_wrench_world: wp.array[wp.spatial_vectorf] | wp.indexedarray[wp.spatial_vectorf] | None#

Measured contact wrench (force, moment) in world coordinates [N, N·m], shape [controlled_robot_count], e.g. from a 6-axis force/torque sensor. None unless use_wrench_feedback=True.

motion_damping: wp.array[wp.spatial_vectorf] | wp.indexedarray[wp.spatial_vectorf] | None#

Task-space velocity-error gain Kd, operational-frame-local, shape [controlled_robot_count]. [1/s] when use_inertia_decoupling is enabled, otherwise [N·s/m] / [N·m·s/rad]. None when gains are baked at construction.

motion_stiffness: wp.array[wp.spatial_vectorf] | wp.indexedarray[wp.spatial_vectorf] | None#

Task-space position/orientation-error gain Kp, operational-frame-local, shape [controlled_robot_count]. [1/s²] when use_inertia_decoupling is enabled, otherwise [N/m] / [N·m/rad]. None when gains are baked at construction.

null_space_damping: wp.array[wp.float32] | wp.indexedarray[wp.float32] | None#

Joint-space posture velocity-error gain Kd, compact, shape [total_controlled_dofs]. [1/s] when use_inertia_decoupling is enabled, otherwise [N·s/m or N·m·s/rad]. None when gains are baked at construction, or when use_null_space_control=False.

null_space_stiffness: wp.array[wp.float32] | wp.indexedarray[wp.float32] | None#

Joint-space posture position-error gain Kp, compact, shape [total_controlled_dofs]. [1/s²] when use_inertia_decoupling is enabled, otherwise [N/m or N·m/rad]. None when gains are baked at construction, or when use_null_space_control=False.

operational_frame_pose_world: wp.array[wp.transformf] | wp.indexedarray[wp.transformf] | None#

World pose of the operational frame, shape [controlled_robot_count]. None when fixed at construction.

tool_pose_world: wp.array[wp.transformf] | wp.indexedarray[wp.transformf]#

Current world pose of the tool frame [m, unitless quaternion], shape [controlled_robot_count].

tool_twist_world: wp.array[wp.spatial_vectorf] | wp.indexedarray[wp.spatial_vectorf]#

Current tool twist (linear, angular) in world coordinates [m/s, rad/s], shape [controlled_robot_count].

wrench_stiffness: wp.array[wp.spatial_vectorf] | wp.indexedarray[wp.spatial_vectorf] | None#

Contact-wrench proportional feedback gain Kp, operational-frame-local, shape [controlled_robot_count]. Dimensionless – multiplies a wrench error directly, not a pose error. None when gains are baked at construction, or when use_wrench_feedback=False.

class Outputs#

Bases: object

Output struct returned by output().

joint_f: wp.array[wp.float32] | wp.indexedarray[wp.float32]#

Joint torque command [N or N·m], shape [total_controlled_dofs].

__init__(*, controlled_dofs_per_robot, motion_stiffness, motion_damping, operational_frame_pose_world=_IDENTITY_TRANSFORM, use_inertia_decoupling=True, use_partial_inertia_decoupling=False, use_gravity_compensation=True, use_wrench_feedforward=False, use_wrench_feedback=False, motion_selection_axes=None, wrench_selection_axes=None, wrench_stiffness=None, linear_selection_frame_operational=_IDENTITY_QUAT, angular_selection_frame_operational=_IDENTITY_QUAT, use_null_space_control=False, null_space_stiffness=None, null_space_damping=None, device=None, requires_grad=False)#
input()#

Return a pre-allocated Inputs with zero-initialised arrays.

is_graphable()#
output()#

Return a pre-allocated Outputs with a compact torque array.

step(*, inputs, outputs, dt)#

Compute one operational-space motion-control step and write joint torques.

Parameters:
  • inputs (Inputs) – Populated Inputs struct. Kinematic and dynamics fields must be filled by the caller before each call.

  • outputs (Outputs) – Outputs struct to write torques into.

  • dt (float | wp.array[wp.float32]) – Unused. Accepted for API compatibility.

property controlled_robot_count: int#

Number of robots, i.e. the length of controlled_dofs_per_robot.

property max_controlled_dofs: int#

Largest controlled-DOF count over the robots, the padded width of the Jacobian and mass matrix.

property total_controlled_dofs: int#

Total controlled-DOF count across all robots, the length of outputs.joint_f.