The hand, center-of-mass, and posture tasks can each compute a valid acceleration request and still disagree about how the robot should move. They all depend on the same generalized acceleration a=v˙a=\dot v:

Jcoma≈bcom,Jhanda≈bhand,Jposturea≈bposture.J_{\mathrm{com}}a\approx b_{\mathrm{com}},\qquad J_{\mathrm{hand}}a\approx b_{\mathrm{hand}},\qquad J_{\mathrm{posture}}a\approx b_{\mathrm{posture}}.

WBC 03 built a TaskRequest(J, b) from a reference and model data. This post combines those requests. The task computes what it wants; the controller decides which requests may compromise and which requirements must hold. Null-space projection first shows how to preserve a primary output. Weighted QP adds physical constraints and trades tracking errors; HQP combines those constraints with explicit task levels.

Reach with the hand while keeping support

Talos starts in the half-sitting pose from WBC 01, with zero velocity and both feet fixed. A right-hand target 0.30 m forward with Kp=100K_p=100 s−2^{-2} requests bh=[30,0,0]Tb_h=[30,0,0]^T m/s². The CoM reference and joint posture reference remain at their current values, so bcom=0b_{\rm com}=0 and bposture=0b_{\rm posture}=0.

Loading Talos meshes…

One frozen Talos state: half-sitting, v = 0, both soles fixed. A hand target 0.30 m forward with Kp = 100 s⁻² requests 30 m/s². Mesh pose is fixed; support arrows show the weighted-QP result. This is one control update, not a trajectory or a stability demonstration.

The controller must reconcile the forward hand request with the stationary CoM and feet. The Talos examples below compare one offline control update at this state.

Null-space projection preserves the primary output

Null-space projection (NP) restricts a lower task to motion directions that leave the achieved primary output unchanged.

See the remaining motion on a small robot

A three-link planar arm has three joint velocities but only two endpoint position outputs. Away from singularities, it can change posture while keeping that endpoint fixed. The primary task is J(q)q˙=0J(q)\dot q=0; the secondary request bends the third joint toward a posture reference.

1 / 5 · Start with the full 3D command space3-link planar arm · position task
Without projectionq1q2q3q₃ = -91.7°Endpoint error: 0.000 mmWith null-space projectionq1q2q3q₃ = -91.7°Endpoint error: 0.000 mmBlue crosshair: fixed primary target · faint links: starting posture
Null-space projection in joint-velocity spaceq̇₁, q̇₂, q̇₃ [rad/s] · Euclidean metric
Loading joint-velocity space…
Orange: request zGreen: projected lattice / allowed spaceFaint cube: original spaceRed: (I − N)z

Task outputs below use z and Nz before the common timing envelope c(t).

Task 1 · hold endpoint heightUnfiltered height velocity: -0.597 m/sBefore projection: -0.597 m/s
Task 2 · change postureRequested q̇₃: -1.000 rad/sAllowed q̇₃: -1.000 rad/sLower task yields the component that would change Task 1.

The same 3D samples map into a plane under one constraint, then a line under two. The last two stages use the moving robot's current Jacobian. These axes are joint velocities, not Cartesian position.

p(q)∈R2,J(q)∈R2×3,J(q)q˙=0⏟hold endpoint positionp(q)\in\mathbb R^2,\quad J(q)\in\mathbb R^{2\times3},\quad \underbrace{J(q)\dot q=0}_{\text{hold endpoint position}}
Computed time0.00 / 3.0 sProjected endpoint speed0.000000 m/sProjected q₃ goal error28.6°
A planar arm has three joint velocities and a two-coordinate endpoint task. Away from singularities, one local motion direction remains available while the endpoint stays fixed. The secondary task bends joint 3 toward −120.3°. A smooth speed envelope starts and ends the motion at rest.

The direct request zz moves the endpoint because Jz≠0Jz\ne0. Projecting it gives q˙=(I−J†J)z\dot q=(I-J^\dagger J)z, so Jq˙=0J\dot q=0. Several joints now move together to cancel their effects on the endpoint. The endpoint orientation is free; only its position is held.

The 3D view transforms a whole lattice in joint-velocity coordinates (q˙1,q˙2,q˙3)(\dot q_1,\dot q_2,\dot q_3), not just one arrow. First impose height alone:

Jyq˙=0,Ny=I−Jy†Jy.J_y\dot q=0,\qquad N_y=I-J_y^\dagger J_y.

A rank-one Jy∈R1×3J_y\in\mathbb R^{1\times3} removes one motion direction. Every sample maps into the two-dimensional plane ker⁡Jy\ker J_y. Adding the independent x-position requirement gives J=[Jx;Jy]J=[J_x;J_y] with rank two. Applying N=I−J†JN=I-J^\dagger J then collapses that plane onto the line ker⁡J\ker J. Since ker⁡J⊂ker⁡Jy\ker J\subset\ker J_y, this second projection preserves the height requirement.

The faint cube marks the original 3D sample region. The green plane and line are allowed command spaces, not Cartesian surfaces. The height-only step explains the geometry; the robot trajectory holds both endpoint coordinates. Interpolated frames illustrate the transformation; the exact projector relation holds at each completed stage.

The second task asks for a posture velocity zz. Its request can change, but its contribution to the first task is always zero after projection:

q˙=q˙primary+N1z,J1q˙=J1q˙primary+J1N1⏟0z=b1.\dot q=\dot q_{\rm primary}+N_1z,\qquad J_1\dot q=J_1\dot q_{\rm primary}+\underbrace{J_1N_1}_{0}z=b_1.

Here the primary target is stationary, so b1=0b_1=0 and q˙primary=0\dot q_{\rm primary}=0. The two task panels show the changing posture request and its allowed component alongside the unchanged primary output. The allowed joint-3 velocity need not equal the requested one: the lower task gives up the component that would disturb the higher task.

This example uses velocity-level kinematics to show the null-space idea. The Jacobian and projector are recomputed during integration. Keeping only the initial projector would preserve the task at that initial configuration, not throughout a finite motion.

In software, the task supplies its Jacobian and target. The NP backend computes the remaining motion space and solves the lower task through its projected Jacobian. The task itself does not decide its priority.

Separate physical feasibility from tracking error

The arm example preserves an endpoint using joint velocities, without checking torque or contact-force limits. For the Talos acceleration tasks, the controller must also find compatible joint torques and ground contact forces. Its decision vector can include all three:

y=[aτλ].y=\begin{bmatrix}a\\\tau\\\lambda\end{bmatrix}.

For the generic formulation, λ\lambda stacks contact wrenches in the same frames and order as the rows of JcJ_c. A motion task becomes a residual over this larger vector:

ri(y)=Aiy−bi,Ai=[Ji00].r_i(y)=A_i y-b_i,\qquad A_i=\begin{bmatrix}J_i&0&0\end{bmatrix}.

Dynamics and maintained stationary contacts supply hard equalities:

[M−ST−JcT]⏟Edyny=−h,[Jc00]⏟Econtacty=−J˙cv.\underbrace{\begin{bmatrix}M&-S^T&-J_c^T\end{bmatrix}}_{E_{\mathrm{dyn}}}y=-h, \qquad \underbrace{\begin{bmatrix}J_c&0&0\end{bmatrix}}_{E_{\mathrm{contact}}}y=-\dot J_c v.

SS selects actuated velocity coordinates. Torque bounds and admissible contact wrenches further restrict the feasible set. A contact model can impose unilateral force, friction, and center-of-pressure limits. A QP uses linear inequalities, including a friction-pyramid approximation to the circular Coulomb cone.

Talos model dimensions and contact coordinates
Model blockSize and convention
q,v,aq,v,a39 configuration entries; 38 velocity and acceleration entries
SS32×3832\times38, selecting actuated coordinates
JcJ_c12×3812\times38, two sole-origin spatial Jacobians in world-aligned axes
Jcom,JhJ_{\rm com},J_hEach 3×383\times38, world-axis translational acceleration tasks
ff24 sole-local point-force components, four points per foot
λ=Ff\lambda=Ff12 world-aligned sole-origin wrench components

In the computed comparison, the solver uses y=[a;τ;f]∈R94y=[a;\tau;f]\in\mathbb R^{94} and substitutes λ=Ff\lambda=Ff. Each sole has four support points at (±0.10,±0.065,0)(\pm0.10,\pm0.065,0) m. The common feasible set F\mathcal F imposes:

  • All 38 rigid-body dynamics rows and 12 stationary-contact acceleration rows.
  • Unscaled URDF torque bounds and actuated acceleration bounds ∣Sa∣≤10|Sa|\le10 rad/s².
  • At each support point, fz≥0f_z\ge0, ∣fx∣≤0.3fz|f_x|\le0.3f_z, and ∣fy∣≤0.3fz|f_y|\le0.3f_z in sole-local axes.
  • Total normal force between 5 and 1000 N per foot.

These friction-pyramid inequalities are a model approximation. Joint position prediction, collisions, contact changes, and future feasibility are outside this single-state comparison. Because v=0v=0, the acceleration drift terms vanish at this snapshot.

Tracking a hand reference can remain a soft cost. Keeping a contact stationary is a hard requirement for this chosen contact mode. A CoM request may be hard, soft, or prioritized depending on the controller design. Its name alone does not determine how it enters the solver.

Joint limits also need a constraint on the decision variables. At a fixed state, qq is already known; writing qmin⁡≤q≤qmax⁡q_{\min}\le q\le q_{\max} does not constrain the current acceleration solve. One approach bounds predicted joint position and velocity using aa and the control period. These bounds require a chosen prediction model and do not by themselves guarantee safety for all future motion.

Weighted QP trades task errors within physical limits

A weighted controller minimizes tracking residuals inside the feasible set:

min⁡y  12∑iwi∥Aiy−bi∥2,Ey=e,Gy≤g,wi≥0.\min_y\;\frac12\sum_i w_i\lVert A_i y-b_i\rVert^2, \qquad Ey=e,\quad Gy\le g,\quad w_i\ge0.

E,eE,e collect hard equalities; G,gG,g collect linear inequality bounds. The solver can trade one soft task’s error against another’s. Increasing the CoM weight makes CoM error more expensive, but does not give it strict priority over the hand task.

The same expression takes the standard QP form:

min⁡y  12yTHy+cTy,H=∑iwiAiTAi,c=−∑iwiAiTbi.\min_y\;\frac12 y^THy+c^Ty, \qquad H=\sum_i w_i A_i^TA_i,\quad c=-\sum_i w_i A_i^Tb_i.

Each task contributes a matrix and a vector to the shared problem. Because H⪰0H\succeq0, the cost is convex. The affine constraints define a convex feasible set. Any local minimum is global, although a feasible minimizer need not be unique or even exist for every convex QP. See Boyd and Vandenberghe, §4.4.

The Talos weighted objective is

12(100∥Jcoma∥2+∥Jha−bh∥2+0.01∥Sa/10∥2).\frac12\left(100\lVert J_{\rm com}a\rVert^2 +\lVert J_ha-b_h\rVert^2 +0.01\lVert Sa/10\rVert^2\right).

For this example, translation residuals use a 1 m/s² scale and the posture residual uses a 10 rad/s² scale. These scales and weights are illustrative controller settings.

1 / 3 · Talos tracking costTalos · one computed control update
u · slice coordinatev · slice coordinate-0.4-0.4000.50.5111.41.41.81.8staticQP optimumsame coston each curve
12(100∥Jcoma∥2+∥Jha−bh∥2+0.01∥Sa/10∥2)\frac12\left(100\|J_{\rm com}a\|^2+\|J_ha-b_h\|^2+0.01\|Sa/10\|^2\right)
‖CoM acceleration‖ 0.083 m/s²Hand-x acceleration 17.946 / 30 m/s²Peak torque / URDF limit100.0%
These are contours of the actual Talos tracking cost on an affine two-dimensional slice of the 94-variable problem. The axes are slice coordinates u and v, not Cartesian robot coordinates. Curves connect commands with the same tracking cost. Displayed values are rounded; calculations use full precision.

The plot shows the cost on a two-dimensional slice of the actual 94-variable problem. Its coordinates u,vu,v combine two directions du,dvd_u,d_v from a static-reference solution ysy_s:

y(u,v)=ys+udu+vdv.y(u,v)=y_s+u d_u+v d_v.

Every point in this plane satisfies the hard equalities. The polygon adds the inequalities; the contours connect points with the same tracking cost. The weighted solution lies at (u,v)=(1,0)(u,v)=(1,0). The solver searches all 94 variables, while the plot shows this one slice.

For implementation, each task contributes wiAiTAiw_iA_i^TA_i to HH and −wiAiTbi-w_iA_i^Tb_i to cc. The assembler adds those contributions and passes one cost and the hard constraints to the QP backend.

The weighted result requests 17.946 m/s² of forward hand acceleration and leaves a 0.083 m/s² CoM acceleration norm. A torque bound is active. The hand’s full three-component acceleration residual is 12.506 m/s².

Gains, weights, and priority levels act at different stages:

SettingWhat it changes
Task gains Kp,KdK_p,K_dThe requested task acceleration and therefore bib_i
Cost weight wiw_iThe tradeoff among residuals in one weighted objective
Priority levelWhich task results lower levels must preserve

Weights also depend on scaling. A metre of position error and a radian of orientation error are different quantities. Choose residual scales before interpreting weight ratios; increasing weights across many orders of magnitude can worsen numerical conditioning.

HQP preserves task results across optimization levels

Weighted QP allows soft tasks to compromise. Hierarchical quadratic programming (HQP) preserves higher-level results through successive optimization levels. Each level improves its own objective while preserving higher-level results and the common hard constraints. It can handle both equality and inequality objectives; see Escande, Mansard, and Wieber (2014).

For the equality least-squares tasks used here, a simplified two-level construction is

y1∈arg⁡min⁡y∈F12∥A1y−b1∥2,y2∈arg⁡min⁡y∈F12∥A2y−b2∥2subject to A1y=A1y1.\begin{aligned} y_1&\in\arg\min_{y\in\mathcal F}\frac12\lVert A_1y-b_1\rVert^2,\\ y_2&\in\arg\min_{y\in\mathcal F}\frac12\lVert A_2y-b_2\rVert^2 \quad\text{subject to }A_1y=A_1y_1. \end{aligned}

F\mathcal F is the common feasible set. Preserving A1y1A_1y_1 preserves the optimal first-level residual, including when it is nonzero. Fixing the entire vector y=y1y=y_1 would remove the remaining freedom needed by the second task. Hierarchical inequality objectives need their own slack and active-constraint treatment; the equality formula above does not cover that case.

This preserves the same quantity as NP: the achieved primary output. NP restricts the correction to a null space; HQP constrains the next solution to keep A1yA_1y unchanged.

For this Talos snapshot, the three levels minimize CoM acceleration, hand acceleration error, and scaled posture acceleration, respectively. All levels retain the same F\mathcal F used by the weighted QP.

1 / 3 · Level 1 · hold CoM accelerationTalos · one computed control update
Level 1 · CoMCoM residual: ≈ 0 m/s²Hand residual: 30.001 m/s²Common physical constraints
Level 2 · HandCoM residual: ≈ 0 m/s²Hand residual: 12.562 m/s²Preserve all 3 CoM outputs
Level 3 · PostureCoM residual: ≈ 0 m/s²Hand residual: 12.562 m/s²Preserve CoM + all 3 hand outputs
y1∈arg⁡min⁡y∈F∥Jcoma∥2y_1\in\arg\min_{y\in\mathcal F}\|J_{\rm com}a\|^2
‖CoM acceleration‖ ≈ 0 m/s²Hand-x acceleration -0.001 / 30 m/s²Peak torque / URDF limit24.1%
First minimize the three-component CoM acceleration residual under the same dynamics and inequalities as QP. The hand is not an objective at this level. The displayed snapshot has zero initial velocity, so acceleration drift is zero. Displayed values are rounded; calculations use full precision.

The posture level preserves all three achieved CoM and hand outputs. It cannot materially improve posture in this saturated snapshot. The two constrained formulations produce:

Talos formulationCoM acceleration normHand-x accelerationFull hand residualPhysical constraints
Weighted QP0.083 m/s²17.946 m/s²12.506 m/s²Satisfied
HQPApproximately zero17.893 m/s²12.562 m/s²Satisfied

HQP preserves the first level’s CoM output within numerical tolerance. Weighted QP accepts a small CoM error to reduce hand error. The planar NP example illustrates output preservation with a different robot and velocity-level model; its numerical results are not part of this Talos comparison.

An HQP backend consumes tasks grouped by level. After each solve, it records the achieved task outputs and adds their preservation equalities to subsequent levels. The task evaluation code remains unchanged.

Several tasks can share a level and use weights within it. The distinction is between tradeoffs within a level and preservation between levels. Solver names alone do not establish which hierarchy is implemented.

In particular, the TSID recordings in WBC 01 use hard constraints and one weighted soft level. Their hand and posture costs trade off within that level. They do not demonstrate a separate strict priority level for every task.

Assemble the problem outside the task

Keep the TaskRequest(J, b) from 03 unchanged. The task owns its reference, gains, and selected axes. The controller configuration assigns its request a weight, a priority level, or hard-constraint treatment. The problem assembler maps it into solver coordinates.

The same request enters a different assembly operation depending on the configured policy:

BackendWhat the assembler or backend constructs
NPRemaining basis or projector, then the lower task’s projected Jacobian
Weighted QPOne accumulated H,cH,c and common hard constraints
HQPCosts grouped by level and constraints preserving achieved higher-level outputs

The following illustrative Python function assembles the tracking cost for one weighted level. Its input is a list of (TaskRequest, weight) pairs; the task objects do not own those weights.

import numpy as np

def tracking_cost(weighted_requests, nv, na, nlambda):
    ny = nv + na + nlambda
    H = np.zeros((ny, ny))
    c = np.zeros(ny)
    for request, weight in weighted_requests:
        A = np.zeros((request.J.shape[0], ny))
        A[:, :nv] = request.J
        H += weight * (A.T @ A)
        c -= weight * (A.T @ request.b)
    return H, c

This assumes nonnegative validated weights and matching request dimensions. The contact representation determines nlambda. For the stacked wrench convention above, it is six times the number of contacts. A point-force parameterization needs the corresponding force-generator mapping instead.

One control update then follows this sequence:

one state snapshot
    → update model once
    → evaluate active tasks and contacts
    → assign configured weights, priority levels, and hard requirements
    → assemble and solve with the selected backend
    → obtain motion commands (and torques / contact forces for inverse dynamics)
    → accept a valid feasible result or enter the chosen failure path

For a weighted backend, the assembler passes H,c,E,e,G,gH,c,E,e,G,g to one QP. An HQP backend also needs explicit level grouping and preservation of higher-level results. The equality-only null-space method works with projected task Jacobians and needs additional machinery for physical inequalities.

The assembly contract must also specify the solver’s objective convention. The code above assumes 12yTHy+cTy\frac12y^THy+c^Ty; omitting the half changes the required Hessian scaling. Frames, variable ordering, and constraint signs must agree across every block.

A solver status, finite outputs, and constraint residuals determine whether the controller accepts a result. If the hard feasible set is empty, changing a tracking weight cannot repair it. The application needs an explicit failure response and a deliberate policy for which requirements, if any, may be relaxed.