Sensor rendering · Rust → WebAssembly

The verified browser sensor renderer

Synthetic depth, segmentation, and lidar — the sim-to-real currency — rendered by a pure-Rust signed-distance ray marcher compiled to WebAssembly, running right here. Sensor simulation that renders and proves itself, in the browser, on your own hardware — no cloud GPU.

FERROMOTION · SENSORSLoading the renderer (WebAssembly)…
The same renderer, on your GPU

Route the work to the best local accelerator

The renderer above ran on your CPU, in WebAssembly. Ray marching is embarrassingly parallel — one independent ray per pixel — so it belongs on a GPU. Here the identical sphere-tracer runs as a WGSL compute shader on whatever local GPU your browser exposes: tens of thousands of rays at once, on your own hardware, no cloud. Then it reads the depth back and checks it against the verified CPU render — so "it ran on your GPU" arrives with "and it matches, to the last few decimals." No local GPU? The same code runs on the CPU. That is the whole thesis: use the best accelerator in front of you, and prove the answer.

FERROMOTION · GPU SENSORRendering on your local GPU (WebGPU)…
The sensor, closing a loop

Perception → action, in one page

The renderer above is a sensor. Here it becomes a robot. A free-flying eye sees a labelled target only through its own raytraced depth and segmentation image — it segments the target out and rebuilds its position from the range channel — then visual-servos to face it and close to a fixed standoff, ignoring the unlabelled distractors. Toggle the target into motion and the eye tracks it. Nothing reads the scene's ground truth; perception is earned from the image, and every step is the same loop verified in the crate. And that is the reality gap for a certificate: you can only certify the state you can SEE — when the image degrades, an observability-aware controller widens its margin and slows down, safe because it knows it cannot see.

FERROMOTION · SENSORIMOTORLoading the perception→action loop (WebAssembly)…
The loop, on an arm

A robot that reaches for what it sees

Now put the loop on a manipulator. A six-jointed arm carries the camera on its wrist; it sees the target only through that raytraced image and drives its joints — differential inverse kinematics on two look-at tasks — until the wrist faces the target at a standoff. The left panel is the arm reaching; the right is the wrist camera's own view, centering the target. When it arrives, it picks a new one. Perception, kinematics, and control, closed end to end in the browser.

FERROMOTION · EYE-IN-HANDLoading the reaching arm (WebAssembly)…
Reaching around obstacles

The arm plans its own way past a wall

A wall stands between the arm and a target behind it. A naive reach — interpolating straight to the inverse-kinematics solution — would drive the arm clean through the wall. Instead it plans: a sampling planner (RRT*) searches the joint space, checking the whole arm's swept geometry against the obstacle, and returns a collision-free path the arm then follows. The dashed line is the route it found; the receipt is the minimum clearance it holds to the wall, against the penetration a straight reach would incur.

FERROMOTION · OBSTACLE-REACHPlanning the path (WebAssembly)…
The planner's hot loop, on your GPU

One thread per candidate config

The RRT* above builds its tree one node at a time — that part is sequential and stays on the CPU. But its inner question — does this candidate joint configuration drive the arm through the obstacle? — is asked thousands of times and is embarrassingly parallel. Here a fixed cloud of 4,096 candidate configurations is collision-checked all at once: one GPU thread per config runs the arm's forward kinematics, places its swept collision spheres, and takes their signed distance to the obstacle — the exact clearance test the planner uses, in a single WebGPU pass. Gold configs are collision-free (what the planner would keep); red are rejected. The obstacle sweeps through so you can watch the whole batch re-decide in real time — every result checked against the CPU core. No local GPU? The identical check routes to the CPU.

FERROMOTION · WEBGPUBringing up the batch collision-checker…
Catching a moving object

The arm matches speed to grasp on the move

Static objects are the easy case. Here a soft block glides across a frictionless floor; the arm waits at an interception point, and as the block arrives it descends and closes on it while matching its velocity — so the jaws meet the block at near-zero relative speed and don't bat it away — then lifts it, carrying it along. Grabbing a moving thing cleanly is a velocity problem before it is a contact problem.

FERROMOTION · DYNAMIC-GRASPLoading the moving-object catch (WebAssembly)…
Two arms, one object

Bimanual — a lift too big for one hand

Some objects are too long for a single grasp. Here two arms each take an end of a soft beam, close across it, and lift in coordination — the beam rises held at both ends while its ungripped middle sags between them, deforming under its own weight. Two independent kinematic chains and two grippers acting on one shared deformable body; the finite jaw pads keep each arm to its own end.

FERROMOTION · BIMANUALLoading the two-arm lift (WebAssembly)…
Planning around an obstacle

Reach around the wall, then grasp

A wall stands between the arm and a soft block — a straight reach would drive the arm through it. So the arm plans a collision-free joint-space path around the wall (an RRT* over the arm's own swept geometry, avoiding both the wall and the block), follows that detour to a pre-grasp pose, then descends, closes on the block, and lifts it away. The gold dashed line is the route the planner found. Planning and the deformable grasp, in one loop.

FERROMOTION · PLANNED-GRASPLoading the plan-around-obstacle grasp (WebAssembly)…
The whole loop, on one arm

See, reach, grasp — closed end to end

The culmination. A fixed camera perceives the scene through its raytraced image and segments the labelled target out of the clutter — ignoring the larger decoy beside it; the arm drives its joints to bring its gripper over the chosen object; the jaws close on the soft, deformable block; and the arm lifts it away, held by friction. Perception, kinematics, and deformable contact — three verified solvers — running as a single loop, in the browser, on the device in front of you. This is what it means for the stack to be a robot.

FERROMOTION · SEE·REACH·GRASPLoading the full loop (WebAssembly)…
Why this page exists

Sensor sim, on your own hardware and accountable

The field's dominant axis — training embodied policies on synthetic depth, lidar, and segmentation — has been CUDA-only. This is the browser-native, verification-first counterpart.

Depth, segmentation, lidar

One signed-distance sphere marcher renders all three synthetic modalities the way sim-to-real training consumes them — a depth image, a per-object segmentation mask, and a lidar point cloud — over the same analytic scene.

Rendered, and verified

Every 2026 browser fluid or 3-D demo renders without accountability; every verified sensor sim is CUDA-bound and install-only. This checks the tracked sphere's depth against the closed-form ray–sphere intersection every frame — a physics receipt on the image.

The exact surface normal, free

The signed-distance field's gradient is the eikonal surface normal, so the renderer returns normals to machine precision without a mesh — the geometry the collision, planning, and control layers already query.