---
kind: concept
slug: inverse-dynamics-control
title: Inverse dynamics control
summary: >-
  Uses the robot's dynamics model to map a commanded acceleration to joint torques. Two cards: a quadruped controller that enforces the exact friction cone and splits joint tracking into a null space, and a GPU planner that evaluates inverse dynamics inside trajectory optimisation to respect torque limits. Both results are author-reported.
tags: [robot-control, torque-control, legged-locomotion, contact-force, trajectory-optimization]
papers: ["2412.09816", "2603.05493"]
related: [quadratic-programming, constraint-satisfaction, impedance-control, virtual-model-control, model-predictive-control, inverse-kinematics]
status: draft
updated_at: 2026-11-01
---

## Overview

Inverse dynamics control treats the robot as if every joint were actuated. It
asks which generalised force would produce a commanded acceleration, using the
robot's dynamics model [arxiv:2412.09816 §3] [arxiv:2412.09816 eq. 5].

The two cards use this computation in different places. In
[arxiv:2412.09816 §3] it is the core of a feedback controller for a legged
robot. In [arxiv:2603.05493 §6.3] the same kind of pass runs for each candidate
trajectory inside an optimiser, and its output is checked against torque
limits. The second use is a feasibility check, not a feedback loop.

A legged robot is not fully actuated, since the body is only moved through the
contact forces of the feet. The feedback controller therefore has two further
jobs: pick contact forces that can be realised, and map the rest of the command
onto the joints. The 2412 card covers both jobs for a quadruped
[arxiv:2412.09816 §3].

The 2412 design rests on three assumptions. Each foot in contact does not
slip [arxiv:2412.09816 §2.1]. At least two feet are in contact at any time, so
the base map has full row rank [arxiv:2412.09816 §3]. The gait and step length
are chosen so that the Jacobians do not become rank-deficient
[arxiv:2412.09816 §3]. The experiments are on flat ground with a trotting gait
[arxiv:2412.09816 §6].

The 2603 torque check rests on a payload model. Its headline result uses a 3 kg
payload at the end effector, but the paper does not describe how that payload
enters the inertial model [arxiv:2603.05493 §7.1].

## Variants

The first three variants come from one paper. The last comes from the second
card, and it is a constraint on a planner, not a controller.

### Exact friction cone with a projected-gradient solver

The contact forces come from a regularised least-squares problem. It penalises
the base-wrench error, the size of the forces and their change from the
previous step, and it keeps the friction cone exactly rather than a linear
pyramid [arxiv:2412.09816 eq. 12] [arxiv:2412.09816 eq. 14]. The paper solves
it with its own method, GPGD, which takes a Newton-type step and then projects
each foot's force onto the bounds and the cone [arxiv:2412.09816 alg. 1]
[arxiv:2412.09816 §4]. Card:
[Distributed Inverse Dynamics Control for Quadruped Robots using Geometric Optimization](/papers/2412.09816).

### Null-space split of joint tracking

The joint torques are projected into the null space of the map from joint
torques to base wrench. The paper argues that this leaves the base motion
unchanged, so the base task has priority over the joint task
[arxiv:2412.09816 eq. 16] [arxiv:2412.09816 eq. 18] [arxiv:2412.09816 eq. 19].
The projector is printed in a form that does not multiply out, so the proof
form is the one to implement [arxiv:2412.09816 §3]; see the sketch below. This
split is separate from the force solver and can be used with any force
distribution that gives the base wrench.

### Baselines in the same paper

The card compares against two controllers that run on the same robot.
Null-space inverse dynamics control, NSPIDC, does not enforce the friction
constraints, so its contact forces can slip [arxiv:2412.09816 §2.2]. QP balance
control adds the joint torques directly to the base torques, which changes the
base motion [arxiv:2412.09816 §2.3].

### Inverse dynamics as a torque constraint in trajectory optimisation

The planner represents each joint's trajectory as a uniform cubic B-spline and
optimises its control points [arxiv:2603.05493 §4]. Torque limits are
constraints in that optimisation. Each candidate is passed through an RNEA
(inverse dynamics) pass, so a trajectory that asks for too much torque under
the given payload is penalised [arxiv:2603.05493 §3] [arxiv:2603.05493 §6.3].
The gradient through this pass is computed with an adjoint RNEA, which costs
O(n) and avoids forming an n-by-n Jacobian [arxiv:2603.05493 alg. 5]
[arxiv:2603.05493 §6.3]. The adjoint's selector `s_k` is not defined in the
paper, so check its index and sign conventions against a reference RNEA; the
authors used Pinocchio in their own tests [arxiv:2603.05493 alg. 5]
[arxiv:2603.05493 §8].

The reported effect is on the whole planner. On a Franka benchmark of 2600
problems with a 3 kg payload, success was 99.7%, against 77.1% for cuRobo
[arxiv:2603.05493 §7.1] [arxiv:2603.05493 fig. 11]. The comparison includes
the spline, collision and energy terms, so it does not isolate the torque
term. The cost of the dynamics term is reported separately: with dynamics on,
the time per trajectory-optimisation iteration rose from 97.7 us to 132.8 us,
and end-to-end time from 35 ms to 42 ms [arxiv:2603.05493 §7.2]
[arxiv:2603.05493 tab. 3]. Card:
[cuRoboV2: Dynamics-Aware Motion Generation with Depth-Fused Distance Fields for High-DoF Robots](/papers/2603.05493).

## When to use which

| Situation | Use | Why |
|---|---|---|
| Foot slip is the main failure and the friction limit is close | Exact cone with GPGD | In simulation, NSPIDC slipped about 32% more than the paper's controller, but only with softer NSPIDC gains, which are not given [arxiv:2412.09816 §6.1.1] [arxiv:2412.09816 fig. 6] |
| Joint tracking must not disturb body motion | Null-space split | The paper proves the orthogonality [arxiv:2412.09816 §3]. The whole controller gave a hardware base orientation error of 0.0156 rad, against 0.0234 rad for QP balance control, at ±0.5 m/s [arxiv:2412.09816 §6.2] [arxiv:2412.09816 fig. 14]. The split alone was not tested |
| A solver is the bottleneck and a standard QP solver is already in place | Benchmark both on your hardware first | In simulation GPGD solved in 9.3e-3 ms and qpOASES in 2.3e-2 ms [arxiv:2412.09816 tab. 1]. The paper calls its GPGD implementation naive and qpOASES optimised, so the ratio is not like for like [arxiv:2412.09816 §6.1.2] |
| Friction coefficient or normal-force limits are unknown | Not settled by this card | The friction coefficient and force limits are named but not valued [arxiv:2412.09816 eq. 13] [arxiv:2412.09816 eq. 14] |
| Fewer than two feet can be in contact, or the terrain is rough | Not tested | The base map needs at least two stance feet [arxiv:2412.09816 §3], and the experiments are on flat ground [arxiv:2412.09816 §6] |
| Planned arm or humanoid trajectories must stay within torque limits under payload | Torque constraint in trajectory optimisation | 99.7% success at 3 kg against 77.1% for cuRobo, but the comparison covers the whole planner [arxiv:2603.05493 §7.1] [arxiv:2603.05493 fig. 11]. Time per iteration rises by about 36% with dynamics on [arxiv:2603.05493 §7.2] |
| One 7-DoF arm, large batches of inverse dynamics on a GPU | Check GRiD first | At batch 256, the paper's table has GRiD at 18.8 us and its own RNEA at 29.3 us. Its RNEA is faster only on the 48-DoF humanoid, where GRiD fails on shared memory [arxiv:2603.05493 §7.3] [arxiv:2603.05493 fig. 13] |
| Torque limits must hold in a reactive loop at high rate | Not tested | The 2603 numbers are batched solves on an RTX 4090 with CUDA graphs and torch.compile. Single-problem latency on other hardware was not reported [arxiv:2603.05493 §7] |

## Implementation sketch

The sketch follows the equations cited on each line. It is our arrangement,
not a listing from the paper. The model estimates `M_hat` and `eta_hat` come
from the caller, since the paper does not say where they are obtained
[arxiv:2412.09816 eq. 5]. It covers the 2412 feedback controller. The RNEA used
for torque limits in [arxiv:2603.05493 alg. 4] is a different routine and is
not sketched here.

```pseudocode
# One inverse-dynamics step for a legged robot  [§3; eqs. 5, 9, 12-19]
# Output: tau (12,) joint torques

def inverse_dynamics_step(q, dq, desired, stance, params):
    # Commanded acceleration: PD per DOF around the desired motion  [eq. 9]
    err = space_minus(desired.q, q)
    acc_cmd = desired.acc + Kp @ err + Kd @ (desired.dq - dq)
    # Generalised force from the estimated model  [eq. 5]
    tau_full = M_hat @ acc_cmd + eta_hat
    tau_base, tau_joint = tau_full[:6], tau_full[6:]
    # Contact Jacobians, rows for stance feet only  [eqs. 10, 11]
    J_ab, J_aa = contact_jacobians(q, stance)
    # Contact forces: base-wrench fit with the exact cone  [eqs. 12-14]
    forces = solve_cone_qp(J_ab, tau_base, prev_forces, stance, params)
    # Stance-leg torques that produce those forces  [eq. 15]
    tau_stance = -J_aa.T @ forces
    # Joint torque to base wrench map, and its null-space projector  [eqs. 16, 18]
    J_base = -J_aa.T @ pinv(J_ab.T)
    N = eye(12) - J_base @ inv(J_base.T @ J_base) @ J_base.T
    # Joint tracking acts only in the null space  [eq. 19]
    return tau_stance + N @ tau_joint
```

The printed projector in [arxiv:2412.09816 eq. 18] does not multiply out, so
the sketch uses the transposed form that the paper's proof uses
[arxiv:2412.09816 §3]. The force solver needs one correction to be
implementable. As printed, [arxiv:2412.09816 alg. 1] never copies the new
iterate back into the current one, so a literal reading repeats the same step.
The paper does not say how the warm start `prev_forces` relates to the
solver's starting point [arxiv:2412.09816 alg. 1] [arxiv:2412.09816 §3]. The
stop test is an absolute tolerance of 1e-2 with no unit given
[arxiv:2412.09816 alg. 1].

## Contradictions

No claim is contradicted across the two cards, because they use inverse
dynamics for different purposes [arxiv:2412.09816 §3] [arxiv:2603.05493 §6.3].
Within the 2412 paper, the printed force-solver algorithm does not match the
text it describes: its iterate is never updated, although its stop test assumes
that it is [arxiv:2412.09816 alg. 1] [arxiv:2412.09816 §4]. The text also calls
the orientation study in §6.1.1 an experiment, while its figure caption says
simulation [arxiv:2412.09816 §6.1.1] [arxiv:2412.09816 fig. 10].

## Papers

- [Distributed Inverse Dynamics Control for Quadruped Robots using Geometric Optimization](/papers/2412.09816): an inverse dynamics controller for an 18-DOF quadruped, with an exact-cone force solver (GPGD), a null-space joint split and a gait and estimation stack; author-reported in simulation and on a Unitree Go2.
- [cuRoboV2: Dynamics-Aware Motion Generation with Depth-Fused Distance Fields for High-DoF Robots](/papers/2603.05493): a GPU motion stack whose trajectory optimiser evaluates RNEA and its adjoint to enforce torque limits; author-reported against cuRobo and other planners, with the dynamics term not isolated.
