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:
ControllerBaseTask-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 everystep().Every port is per-robot: a 1-D array with one entry per robot, ordered to match
controlled_dofs_per_robot— exceptoutputs.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()andoutput(). All field names on those structs are fixed — seeInputsandOutputsfor the typed schema. Fields for disabled features (e.g.mass_matrixwhenuse_inertia_decoupling=False) are allocated asNoneand 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 setstotal_controlled_dofs(the length ofoutputs.joint_f), and its maximum setsmax_controlled_dofs(the padded width of the Jacobian and mass matrix). Every entry must be positive, and — whenuse_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, awp.spatial_vectorto apply the same 6 per-axis gains to every robot, an array of shape [controlled_robot_count] to set them individually (onewp.spatial_vectorof 6 gains per robot), orNoneto readinputs.motion_stiffnesseach 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] whenuse_inertia_decouplingis enabled, otherwise [N·s/m] on the position axes and [N·m·s/rad] on the orientation axes. Same format asmotion_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_operationalare expressed relative to, and thatmotion_stiffness/motion_damping/wrench_stiffnessare 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 awp.transformto 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), orNoneto readinputs.operational_frame_pose_worldeach 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_matrixomits 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_forcedirectly 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_operationalbelow). When both this anduse_wrench_feedbackareFalse, every axis is motion-controlled andmotion_selection_axes/wrench_selection_axes/wrench_stiffnessmust be left unset, andlinear_selection_frame_operational/angular_selection_frame_operationalmust be left at their identity default.use_wrench_feedback (bool) – Correct the wrench command by
Kp · (desired - measured)usinginputs.measured_wrench_worldeach step, as a feedback term in the wrench law. May be enabled with or withoutuse_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 inangular_selection_frame_operational(S_tau). Pass awp.spatial_vectorto 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 ofwrench_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 ofmotion_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 asmotion_stiffness. Only meaningful whenuse_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 ofangular_selection_frame_operational(S_tau); the two need not agree. Pass awp.quatto apply the same fixed orientation to every robot, an array of shape [controlled_robot_count] to set them individually, orNoneto readinputs.linear_selection_frame_operationaleach 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 aslinear_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=Trueanduse_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, orNoneto readinputs.null_space_stiffnesseach step. Only meaningful whenuse_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_decouplingis enabled, otherwise [N·s/m or N·m·s/rad]. Same format asnull_space_stiffness.device (Any) – Warp device.
requires_grad (bool) – Whether internal buffers need gradient support.
- class Inputs#
Bases:
objectInput struct returned by
input().Every field is per-robot, shape [controlled_robot_count], except
jacobian_tool_worldandmass_matrix, which are padded to [controlled_robot_count, …, max_controlled_dofs]. Optional fields areNonewhen 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].
Nonewhen 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.
Noneunless 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].
Noneunlessuse_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].
Noneunlessuse_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].
Noneunlessuse_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].
Noneunlessuse_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].
Noneunlessuse_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].
Nonewhen 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.
Noneunlessuse_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_dofsDOFs 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.
Noneunlessuse_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_decouplingis enabled, otherwise [N·s/m] / [N·m·s/rad].Nonewhen 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_decouplingis enabled, otherwise [N/m] / [N·m/rad].Nonewhen 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_decouplingis enabled, otherwise [N·s/m or N·m·s/rad].Nonewhen gains are baked at construction, or whenuse_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_decouplingis enabled, otherwise [N/m or N·m/rad].Nonewhen gains are baked at construction, or whenuse_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].
Nonewhen 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.
Nonewhen gains are baked at construction, or whenuse_wrench_feedback=False.
- class Outputs#
Bases:
objectOutput 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)#
- is_graphable()#
- step(*, inputs, outputs, dt)#
Compute one operational-space motion-control step and write joint torques.
- property controlled_robot_count: int#
Number of robots, i.e. the length of
controlled_dofs_per_robot.