Φferromotion · textbook · chapter 14 rust → wasm · on-device

Planning through contact

The moment a robot touches something, its equations of motion develop a kink: nothing happens as the gap closes, then a force switches on. Gradient-based planners need a slope to follow, and a kink has none. This page shows the fix — smooth the contact, then step only as far as the smooth model stays honest — running the real Rust pusher-slider on your device.

01 — the kinkContact is nondifferentiable

Rigid contact is a switch: while a gap remains the contact force is exactly zero; the instant the gap closes the force turns on. That corner — λ = k·max(0, d) — is where planning through contact breaks. An optimizer linearizes the dynamics to decide its next move, but a linearization needs a derivative, and at the corner there isn't one. Worse, on the flat "no contact yet" side the gradient is zero: the plan has no signal that a push is even available.

02 — smooth itA force with a slope everywhere

The remedy is to replace the hard corner with a smooth surrogate — a softplus of penetration, λ = (k/κ)·log(1 + e^{κd}). It is positive and differentiable everywhere, so a planner always has a gradient to follow; and as the sharpness κ grows it converges back to true rigid contact. Drag κ and watch the smooth curve sharpen toward the corner.

low κ: soft and easy to optimize · high κ: nearly rigid but the gradient collapses back into a corner

03 — the trapA step that jumps the boundary

Smoothing alone is not enough. The smooth model is only accurate near where it was linearized — and a plain trust region (a ball, ‖Δu‖ ≤ ρ) knows nothing about where the contact turns on. A large ball-shaped step can leap clean across the contact boundary, into a region where the linearization it was based on is meaningless. The plan then trusts a prediction that is simply wrong.

Below, at a contact transition, the gold curve is the true next slider position as a function of the control step Δu; the dashed line is the linear model the planner uses. The green band is the contact trust region. Drag left–right to move the step.

step Δu
trust radius 1/(κh)
linear-model error

inside the band the red error bar is tiny; drag past it and the linear model peels away from the truth

04 — the trust region, shaped by contact

The contact trust region sizes the step so the contact configuration changes by no more than the model's smoothing bandwidth — Δd ≤ 1/κ, i.e. Δu ≤ 1/(κh). Inside it the penetration never moves far enough to leave the region the linearization describes, so the model's prediction stays trustworthy; outside it, all bets are off. It is a trust region whose shape comes from the physics of the contact rather than from a generic ball.

This is the whole idea. Smoothing gives you a gradient; the contact trust region tells you how far you are allowed to believe it. Together they turn a nondifferentiable, gradient-free contact problem into one an ordinary optimizer can march through — which is what lets a plan discover a push, a grasp, or a foothold that only exists through contact.

05 — the checkThe step you can trust vs the one you can't

On load, this page linearized the smoothed pusher–slider right at contact onset and measured the model's error at a trust-region-sized step against a step six times larger:

linear-model error at the trust-region step
linear-model error at a 6× step
the big step is this much worse
trust-region planner reaches a contact-only target
verdict

The trust-region step's prediction is off by a small fraction of the oversized step's — and a planner that caps every move to that region discovers, from a standoff, exactly the push that drives the unactuated slider to its target. The slider has no motor of its own; it moves only through contact, and the plan found the contact.

06 — the pointBelieve the model only where it holds

Smooth the contact; step only as far as the smoothing lets you.

Contact-rich planning is not defeated by the kink but by trusting a linearization past where it is valid. Smooth the force so a gradient exists, then bound the step to the contact's own bandwidth — a trust region shaped by the physics — and the optimizer can plan straight through the touch.

This chapter is the companion to the consensus-complementarity method a chapter earlier: both make contact plannable, one by consensus over the complementarity constraints, this one by smoothing plus a physically-shaped trust region. The pattern is the same the book keeps returning to — reshape the problem until the answer is one an ordinary solver can reach.

What you just drove: the PusherSlider and SmoothedContact from ferromotion-control, compiled to WebAssembly — the same code the native tools link against. The force curve, the linearization, the trust radius, and the planner are all evaluated live; nothing precomputed.

Verified in the library: the smoothed force converges to rigid k·max(0,d) as κ→∞; the analytic contact-force gradient matches finite differences; a trust-region-sized step keeps the linearization more than 5× more valid than an oversized step; and the trust-region planner drives the unactuated slider to a contact-only target. Each is a test in cargo test, not a claim in prose. See also ch.12 — closing the loop · the full textbook.

Institute for Physical AI · the Rust library · crates.io