Skip to content

Tasks

EmbodiK supports various task types for multi-task inverse kinematics.

Task Types

FrameTask

Control end-effector pose (position + orientation).

frame_task = solver.add_frame_task("ee_task", "panda_hand")
frame_task.priority = 0
frame_task.weight = 1.0

PostureTask

Maintain desired joint configuration.

posture_task = solver.add_posture_task("posture")
posture_task.priority = 1
posture_task.set_target_configuration(q_default)

ManipulabilityTask

Improve frame-Jacobian conditioning with the analytic gradient of a regularized log-determinant score:

conditioning = solver.add_manipulability_task(
    "ee_conditioning",
    "panda_hand",
    embodik.TaskType.FRAME_POSITION,
)
conditioning.priority = 1
conditioning.weight = 10.0
conditioning.solve_mode = embodik.TaskSolveMode.MIN_ERROR
conditioning.set_controlled_joint_indices(arm_velocity_indices)
conditioning.set_regularization(0.03)
conditioning.set_joint_limit_penalty(0.002, epsilon=0.04)

The regularization keeps the score and gradient finite at singular configurations. The gradient magnitude is smoothly bounded below 1 before the task weight is applied. At an exactly symmetric singularity the first-order gradient can be zero; use a deterministic nominal PostureTask at a lower priority to select a bend direction when the robot has that symmetry.

The frame task type selects the Jacobian whose conditioning is optimized. Use FRAME_POSITION when translational reach and Cartesian position tracking are the primary concern. Use FRAME_POSE only when improving the combined linear and angular Jacobian is intentional; on a limited-range arm, its rotational gradient can otherwise consume nullspace motion without improving position tracking.

The optional joint-limit penalty uses the descent direction of EmbodiK's normalized joint-limit distance metric. Before adding that inward direction, EmbodiK projects away any component of the frame-manipulability gradient that would worsen the limit metric to first order. The remaining tangential manipulability component can still improve conditioning without trading away hard-limit recovery. The projection is evaluated only for controlled scalar joints and does not add another hierarchy level. The penalty defaults to 0, preserving the frame-only metric; epsilon regularizes the normalized distance close to either hard limit.

JointLimitAvoidanceTask

Move selected scalar joints inward before they become pinned at a hard limit:

limit_avoidance = solver.add_joint_limit_avoidance_task(
    "arm_limit_avoidance",
    controlled_joint_indices=[elbow_velocity_index],
)
limit_avoidance.priority = 1
limit_avoidance.weight = 0.012
limit_avoidance.solve_mode = embodik.TaskSolveMode.MIN_ERROR
limit_avoidance.set_activation_margin(0.002)

The task uses a signed cubic smoothstep. It is exactly zero outside the activation margin, rises continuously toward either limit, and never replaces the solver's hard position or velocity constraints. The margin uses each joint's configuration units (rad for revolute joints, m for prismatic joints).

For limited-range arms, a useful hierarchy is:

  1. Position tracking at priority 0.
  2. Joint-limit avoidance at priority 1.
  3. Orientation recovery and manipulability conditioning at priority 2.

This split permits a continuous bend away from a fully extended limit while position continues to make progress. For these recovery objectives, near-limit Jacobian clamping evaluates the requested task direction so safe inward rows remain available. Ordinary tasks keep the historical row-sign clamp, and all hard position and velocity constraints remain enforced by the solver.

COMTask

Control center of mass position. Most current examples use the support-polygon constraint API instead of a standalone CoM task:

solver.configure_com_constraint(
    support_polygon=polygon_xy,
    margin=0.05,
    frame_name="world",
)

JointTask

Control individual joint position.

joint_task = solver.add_joint_task("joint_bias", "panda_joint4")
joint_task.set_target_value(0.5)

MultiJointTask

Control multiple joints simultaneously.

Use a PostureTask with selected controlled joints when you want a compact multi-joint bias.

Units Conventions

Use these units consistently across task targets, limits, and tolerances:

  • Translation (x, y, z): m
  • Rotation (rx, ry, rz, roll/pitch/yaw, angle errors): rad
  • Linear velocity: m/s
  • Angular velocity: rad/s
  • Linear acceleration: m/s^2
  • Angular acceleration: rad/s^2

For 6D torso pose vectors in PositionIKOptions.torso_constraint, the ordering is [x, y, z, rx, ry, rz] with units [m, m, m, rad, rad, rad]. Pose bounds are measured relative to torso_constraint.pose_bounds_reference_pose when set, else relative to the torso frame at the solve_position seed configuration for that call.

Task Hierarchy

Tasks are solved in priority order (0 = highest).

ee_task.priority = 0
torso_task.priority = 1
posture_task.priority = 2

Typical use:

  • Priority 0: end-effector tracking (FrameTask)
  • Priority 1: secondary balance/posture frame objective (for example torso upright)
  • Priority 2: nullspace posture bias (PostureTask)

Task Solve Modes

Each task can be solved in one of two modes:

  • TaskSolveMode.SCALE (default): classic SNS/eSNS behavior that preserves task direction with a scale factor in [0, 1].
  • TaskSolveMode.MIN_ERROR: clamped minimum-error behavior that computes the best feasible residual motion under active constraints.

Automatic fallback from SCALE to MIN_ERROR when scale collapses is disabled by default for SCALE tasks. Enable it explicitly when needed:

task = solver.add_frame_task("ee", "panda_hand", embodik.TaskType.FRAME_POSE)
task.solve_mode = embodik.TaskSolveMode.SCALE
task.allow_min_error_fallback = True

After a solve, inspect effective diagnostics:

result = solver.solve_position_step(q, target_pose, "ee_task", step_opts)
print(result.task_modes_effective)
print(result.task_used_fallback)

Notes:

  • User-created tasks default to SCALE.
  • User-created tasks default to allow_min_error_fallback = False.
  • Internal nullspace-bias posture tasks used by solve_position() run in MIN_ERROR mode and are placed after the optional internal torso objective.

PostureTask Joint Selection and Weights

PostureTask supports explicit selection and per-joint weighting:

posture = solver.add_posture_task("posture")
posture.set_controlled_joint_indices([0, 1, 2])
posture.set_controlled_joint_weights(np.array([2.0, 1.0, 0.5]))

This behavior is consistent with a diagonal selection/weighting matrix:

  • selected joints contribute to the nullspace objective
  • unselected joints are not driven by the posture objective

API Reference

FrameTask

Bases: Task

Attributes

current_orientation property

current_orientation

Current frame orientation

current_position property

current_position

Current frame position

Functions

__init__

__init__(name, model, frame_name, task_type=TaskType.FRAME_POSE, priority=0, weight=1.0)

Create a frame tracking task

set_orientation_mask

set_orientation_mask(mask)

Set orientation mask (which axes to control)

set_position_mask

set_position_mask(mask)

Set position mask (which axes to control)

set_target_angular_velocity

set_target_angular_velocity(omega)

Set target angular velocity (3D)

set_target_orientation

set_target_orientation(rotation)

Set desired orientation as rotation matrix

set_target_pose

set_target_pose(position, rotation)

Set desired pose (position + orientation)

set_target_position

set_target_position(position)

Set desired position

set_target_position_velocity

set_target_position_velocity(velocity)

Set target linear velocity (3D)

set_target_velocity

set_target_velocity(velocity)

Set full spatial velocity (linear + angular)

PostureTask

Bases: Task

Attributes

controlled_joint_indices property

controlled_joint_indices

Get controlled joint indices

Functions

set_controlled_joint_indices

set_controlled_joint_indices(indices)

Set controlled joint indices

set_controlled_joint_targets

set_controlled_joint_targets(target_values)

Set target values for controlled joints only

set_controlled_joint_weights

set_controlled_joint_weights(weights)

Set weights for controlled joints only

set_joint_mask

set_joint_mask(mask)

Set joint mask (which joints to control)

set_joint_weights

set_joint_weights(weights)

Set per-joint weights

set_reference_configuration

set_reference_configuration(q_reference)

Update a moving regularization reference without declaring a new posture command

set_target_configuration

set_target_configuration(q_target)

Set target joint configuration

ManipulabilityTask

Bases: Task

Functions

__init__

__init__(name, model, frame_name, frame_task_type=TaskType.FRAME_POSITION, priority=10, weight=1.0)

Create a regularized frame manipulability gradient task

set_controlled_joint_indices

set_controlled_joint_indices(indices)

Set controlled velocity-space joint indices

set_joint_limit_penalty

set_joint_limit_penalty(penalty, epsilon=0.04)

Penalize normalized proximity to controlled scalar joint limits

set_regularization

set_regularization(regularization)

Set the positive log-determinant regularization epsilon

JointLimitAvoidanceTask

Bases: Task

Functions

__init__

__init__(name, model, controlled_joint_indices=[], priority=10, weight=0.01)

Create a smooth joint-limit avoidance task

set_activation_margin

set_activation_margin(activation_margin)

Set the smooth activation margin in joint configuration units

set_controlled_joint_indices

set_controlled_joint_indices(indices)

Set controlled velocity-space indices

COMTask

Bases: Task

Attributes

current_position property

current_position

Current COM position

Functions

__init__

__init__(name, model, priority=0, weight=1.0)

Create a center of mass tracking task

set_position_mask

set_position_mask(mask)

Set position mask (which axes to control)

set_target_position

set_target_position(position)

Set desired COM position

JointTask

Bases: Task

Functions

set_target_value

set_target_value(value)

Set target joint value

MultiJointTask

Bases: Task

Attributes

joint_indices property

joint_indices

Get controlled joint indices

target_values property

target_values

Get target values

Functions

set_joint_weights

set_joint_weights(weights)

Set per-joint weights

set_target_value

set_target_value(idx, value)

Set target value for a specific controlled joint

set_target_values

set_target_values(values)

Set target values for all controlled joints