Curvature¶
This tool tells you how far one value is from a target value, as a score from 0 (right on the target) towards 1 (far away). You give it the current value and the target; it measures the distance in the units of your problem.
curvature(x, ref, scale) answers one question with one number in [0, 1): how far is
x from ref, in the physical units of the problem? It is not an anomaly detector;
it is a bounded proximity score, useful when "getting close" is itself the thing you
want to measure.
Orca's input shield uses it internally to size the current deviation.
1. Basic use¶
A joint should turn at its nominal 0.5 rad/s; right now it turns at 2.5 rad/s.
import jax.numpy as jnp
from dense_armor.utility.anomaly.curvature import curvature
print(float(curvature(jnp.array([2.5]), jnp.array([0.5]))))
At the default scale = 1.0 the score is 0.97, close to 1: two rad/s away from the reference is
"far" at that scale.
2. With the right scale¶
The default scale = 1.0 is a place-holder. Set scale to the width of the zone you
actually care about, in the same units as the input. For a joint velocity where "close"
means "within 2 rad/s of nominal":
import jax.numpy as jnp
from dense_armor.utility.anomaly.curvature import curvature
print(float(curvature(jnp.array([2.5]), jnp.array([0.5]), scale=2.0)))
The same two rad/s, measured against a 2-unit zone, scores 0.89 instead of 0.97: still far, but no longer saturated. The plot shows the whole curve for scale 1 and scale 15.

3. The formula, symbol by symbol¶
Let d = x − ref and let scale be the width of the zone. Define
g = 2·d / scale, then:
with δ a small positive constant (default 1e-6, a numerical guard). κ is
almost 0 at d = 0 (exactly $\sqrt{\delta}/\sqrt{1+\delta} \approx 0.001$), increases smoothly as |d| grows, and saturates to 1 for
|d| ≫ scale. δ keeps the function away from exactly 0 and 1 so gradients stay finite.
4. Hand cases¶
Distance d = 0.5 from the reference.
- At
scale = 1.0:g = 2·0.5 / 1 = 1,κ = √(1) / √(2) = 0.7071. - At
scale = 15.0:g = 2·0.5 / 15 = 0.0667,κ = √(0.00444) / √(1.00444) = 0.0665.
At the default scale = 1.0, a distance of half a unit already gives 0.71 — nearly
saturated. At scale = 15.0, the same distance gives 0.07 — the zone extends 15 units,
so half a unit is barely into it. The scale argument is what makes the score mean
something in the units of the problem.
API reference¶
curvature ¶
curvature ¶
curvature(
x_current: ndarray,
x_reference: ndarray,
scale: float = 1.0,
delta: float = 1e-06,
) -> jnp.ndarray
Calcola la curvatura geometrica (κ) calcolando direttamente il gradiente analitico. Elimina l'overhead di tracciamento di jax.grad mantenendo l'invarianza numerica.
scale fissa l'ampiezza reale (nelle stesse unità di x_current/x_reference) alla
quale la funzione satura verso 1. Con lo scale di default (1.0, comportamento
identico alle versioni precedenti) qualunque distanza reale oltre ~5 unità è
già indistinguibile da "lontanissimo" -- verificato su dati reali SO-101
(episodio pick-place, gradi reali): per elbow_flex, la cui distanza dal
limite reale varia tra 0.1° e 66.9°, la correlazione tra curvature() e la
distanza grezza è solo 0.235 (59% dei frame già saturi a >0.99) con scale=1.0,
contro 0.932 (41% saturi) con scale=15.0 -- la stessa funzione, senza scale, non
distingue "vicino al limite" da "lontano dal limite" in unità fisiche reali
(gradi), è un indicatore quasi binario. Per un uso reale come segnale di
prossimità a un limite articolare, passare uno scale reale (es. l'ampiezza in
gradi della "zona di allerta" desiderata), non lasciare il default.
Source code in dense_armor/utility/anomaly/curvature.py
Details¶
scale defaults to 1.0 so the function is backward compatible: Orca's existing call
site (orca.py, curvature(fh, c_chunk)) is unaffected.
This parameter was added after checking a claim that curvature could work as a
joint-limit-feasibility check, against real SO-101 joint data. The real robot does press
against its physical limits during real pick-place episodes (elbow_flex, 120/303 real
frames at its true hard-stop, a few degrees past the reference URDF's declared limit,
consistent with normal manufacturing tolerance on that one unit). But at the default
scale, the raw formula saturated to ≈ 1 within about 5 raw units of any reference
regardless of the caller's physical units: as a joint-limit signal in real degrees it was
a near-binary near/far indicator, not a graded one. Correlation with raw distance was
only 0.235 on elbow_flex's real 0.1–66.9 degree range, rising to 0.932 at scale=15.0.
See also: Rate limiter and CBF filter — if the real goal is bounding or correcting a command near a limit, not just scoring proximity to one, those modules are the right tool.