newton.controllers.ControllerOperationalSpace#

class newton.controllers.ControllerOperationalSpace(model, *, articulations=None, joints=None, tool_sites, 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)[source]#

Bases: ControllerBase

Task-space (operational-space) impedance controller with internally computed dynamics.

Implements the operational-space control law. This model-based variant computes the tool pose/twist, tool-point Jacobian, and (when enabled) the mass matrix and gravity term itself: it evaluates forward kinematics and the enabled dynamics terms from model on every step(), so the caller supplies only joint positions and velocities plus task-space targets.

model is borrowed, not owned — it is never written to, and changes to it are visible to the controller immediately.

Joint selection. articulations and joints select 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 against articulation_label and the leaf component of joint_label respectively. Only joints spanning a single coordinate and a single DOF can be controlled.

Tool selection. tool_sites selects one Newton site per robot that ends up with controlled joints — the point on the robot whose pose/twist is controlled. This need not be the same frame commands are specified in — see operational_frame_pose_world. It follows the same list[index/pattern] | index | pattern shape as joints, matched against the leaf component of each site’s label. Every controlled robot must match exactly one site.

Each articulation in model is one robot. Supports heterogeneous robot fleets — robots may have different controlled-DOF counts, and a robot may be left uncontrolled entirely by omitting it from articulations.

See also ControllerOperationalSpaceModelFree, which takes the tool pose/twist, Jacobian, mass matrix, and gravity term as inputs instead of computing them from a Model.

Parameters:
  • model (Model) – Model whose articulations are the robots.

  • 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. None selects every articulation in model.

  • 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. None selects 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 raises ValueError if 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.

  • 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. 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, computed each step from model’s own mass matrix (via newton.eval_mass_matrix()) and the resolved tool Jacobian. Note that if the joints/articulations selection 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 the model’s own gravity generalized forces — computed each step via eval_inverse_dynamics_passive() on model — 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 the generalized selection matrix Omega from Khatib, O. (1987), “A unified approach for motion and force control of robot manipulators: The operational space formulation,” IEEE Journal of Robotics and Automation, 3(1), 43-53 (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.

class Inputs#

Bases: object

Input struct returned by input().

joint_q/joint_qd cover the whole model, since forward kinematics depends on uncontrolled joints too; every other field is per-robot, shape [controlled_robot_count]. 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]. None unless wrench control is enabled.

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

Current joint positions [m or rad], shape [model.joint_coord_count].

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]#

Current joint velocities [m/s or rad/s], shape [model.joint_dof_count].

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.

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]. 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]. None when 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]. None when 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.

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], compact, shape [total_controlled_dofs].

__init__(model, *, articulations=None, joints=None, tool_sites, 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)#
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)#

Run one operational-space control step.

Computes forward kinematics and the enabled dynamics terms from model, resolves the tool pose/twist/Jacobian from each robot’s tool site, then delegates the control law to the inner ControllerOperationalSpaceModelFree.

Parameters:
  • inputs (Inputs) – Populated Inputs struct.

  • 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 with at least one controlled DOF.

property max_controlled_dofs: int#

Largest controlled-DOF count over the controlled robots.

property model_robot_count: int#

Number of articulations in model, controlled or not.

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 of each controlled robot’s tool site as of the latest step() [m, unitless quaternion], shape [controlled_robot_count].

property tool_transform_body: wp.array[wp.transformf]#

Tool site’s transform relative to its body [m, unitless quaternion], shape [controlled_robot_count].

property tool_twist_world: wp.array[wp.spatial_vectorf]#

World twist (linear, angular) of each controlled robot’s tool site as of the latest step() [m/s, rad/s], shape [controlled_robot_count].

property total_controlled_dofs: int#

Total controlled-DOF count across all robots, the length of every compact port.