MIME-VER-124 — RobotArmNode Inverse-Dynamics + PD Trajectory Tracking#
Date: 2026-04-30
Node under test: mime.nodes.actuation.robot_arm.RobotArmNode
Algorithm ID: MIME-NODE-102
Benchmark type: Analytical (Mode 2 independent)
Test file: tests/verification/test_robot_arm.py::test_ver124_pd_tracking
Acceptance: max-per-joint RMS tracking error $< 0.5°$ over 2 s of a 0.5 Hz sinusoid
Goal#
Track a sinusoidal joint-space trajectory using the standard manipulator-control law (Sciavicco–Siciliano §6.6):
$$ \tau = M(q),\ddot q_{\mathrm{des}} + c(q,\dot q) + g(q) + K_p,e + K_d,\dot e, $$
with $e = q_{\mathrm{des}} - q$, and assert that the tracking RMS error stays below $0.5°$ across all 3 joints over a 2 s integration.
This benchmark stresses the full dynamics path: $M(q)$ from CRBA,
$c+g$ from RNEA, and the forward-dynamics solve in update. A bug in
any of those would manifest as drift or oscillation.
Configuration#
Parameter |
Value |
|---|---|
URDF |
|
Trajectory |
$q_{\mathrm{des},i}(t) = A_i \sin(\omega t)$ |
Amplitudes |
$A = (0.3, 0.2, 0.4)$ rad |
Frequency |
$\omega = 2\pi \cdot 0.5$ rad/s (0.5 Hz) |
$K_p$ (per joint) |
$(200, 200, 80)$ N·m/rad |
$K_d$ (per joint) |
$(20, 20, 8)$ N·m·s/rad |
Joint friction |
$0$ (overridden in test fixture) |
Timestep |
$10^{-3}$ s |
Steps |
2000 (2 s of simulated time) |
JAX precision |
x64 enabled at module load |
Hot loop |
|
The PD gains were chosen for a closed-loop natural frequency well above the 0.5 Hz disturbance band. The inverse-dynamics feed-forward is the principal contributor — without it, residual tracking error is $\approx 7°$ (verified during V&V development); with it, error drops below the $0.5°$ acceptance.
Procedure#
Initialise $(q_0, \dot q_0)$ to the desired trajectory at $t=0$.
JIT-compile a step closure that, given $(q, \dot q, t)$, computes $M(q), c+g, \tau_{\mathrm{ff}} = M\ddot q_{\mathrm{des}}+c+g$, the PD term $K_p e + K_d \dot e$, and calls
arm.update.Run 2000 jitted steps, accumulating $\sum e^2$.
Compute per-joint RMS = $\sqrt{\overline{e^2}}$ in degrees and assert the maximum component is below $0.5°$.
Result#
PASS. Per-joint RMS error stays within the acceptance.
Scope and Limitations#
One trajectory shape (single-frequency sinusoid). Higher-frequency components or non-smooth trajectories would test the integrator’s CFL-like stability boundary, which is not in scope here.
Joint friction is disabled in this benchmark to isolate the dynamics. With realistic friction, additional gain tuning would be required — that’s an experiment-folder concern, not a node-level V&V concern.
The inverse-dynamics feed-forward is computed at the current state rather than the desired state — both are valid approaches, but the current-state form is what the test uses.
Reproducibility#
Run:
JAX_PLATFORMS=cpu .venv/bin/python -m pytest tests/verification/test_robot_arm.py::test_ver124_pd_tracking -x -q.