Houdini Robot Toolkit

A Houdini digital asset that animates a 6-axis arm along a drawn curve, measures what the move would do to the hardware, and blocks export until it is safe.

Role
Creator and sole author
Year
2026 · active
Type
Robotics · Tool · Generative
Tools
Houdini · VEX · Python · KineFX · UF850 · Fairino FR20

Draw a curve, get a robot move. A Houdini asset that solves a 6-axis arm along the curve, measures what the move would do to the hardware, and will not export it until it is safe. It is the authoring end of the Robot Darkroom: the show's clip library comes out of it.

The solve

Three inputs: a goal curve, fused, decimated and fit to a spline; a goal point to reach instead; and the tool geometry, from which the TCP is read. The result is coloured by whatever you are worried about. Here that is joint velocity, blue at 0 and red at the profile's 180 deg/s limit.

Houdini viewport showing a robot arm with its goal curve, achieved path coloured by joint velocity, and magenta markers on the frames that fail validation
The analysis overlay, with the flagged frames clustered around the wrist.

The gate

A pre-flight check runs the whole clip: joint limits, continuity, velocity, wrist flips, tracking residual, and whether the cache still matches the live solve. With the gate on, a clip that fails cannot be written out.

READY - 0 warningsOK    Joint limits         all samples within profile limitsOK    Angle continuity     no step exceeds 180 degOK    Unwrap               continuous anglesOK    Joint velocity       peak 166.7 deg/s of 180 allowedOK    Wrist branch         resolved at 131 frames (tool pose unchanged)OK    Frame range          1-162, matches playbarOK    Tracking residual    peak 248.33 mmOK    Solve cache          matches the live solve

What clears it is a joint CSV: frame, time_s, j1_deg through j6_deg, and speed_pct. TD Robot Control's Go worker plays it directly and Motion-Core imports it.

Posing and retiming

One menu picks how the arm is posed: FK, IK, an imported CSV, or a baked solve. Everything downstream is the same. Baking IK to FK resolves wrist flips without moving the tool, 285 of them on a 354-frame clip, and a clip imported from anywhere is measured by the same validator as one drawn here.

Most first drafts are too fast. Retime slows only the stretches that are over budget, then the gate runs again.

Before and after retiming. The rejected frames, in magenta, are gone.
as authoredafter retime
verdictBLOCKED — 1 failureREADY — 0 warnings
peak joint velocity820.5 deg/s (J4)166.7 deg/s of 180
frames150162

Retime cannot move the curve, though: a curve that goes where the arm cannot reach has to be redrawn.

The clip factory

PDG wedges the asset into whole libraries: motion primitives, and dance phrases generated from Laban's efforts. Every clip is rendered in the room, labelled by what it measures as against what it was asked to be, and checked against the arm and the room before it is kept. All 48 dance phrases passed.

The PDG review: intended action against measured, per clip.

On the real arm

The asset builds an arm from its URDF. For the Fairino FR20 the IK is a closed-form solve, so every frame takes the branch nearest the frame before. Streamed to the real arm at 125 Hz, the clip below was tracked within 0.85°.

The same clip on the FR20 and in the asset.
Role
Creator and sole author; operated the robot
Built with
Houdini · VEX · Python · KineFX
Asset
wenyi::robot_arm::1.0, six tabs in workflow order
Robot
UF850 and Fairino FR20; other arms from a URDF and a profile JSON
Hardware
The FR20 and the lab, Volvox Labs
Used on
Robot Darkroom, whose clip library it generates
Feeds
TD Robot Control plays the exported joint CSV directly and Motion-Core imports it; on the FR20, the toolkit's own ServoJ player
Sibling
xArm Blender Animation, the keyframed route to the same file
Source
github.com/wzhang1998/houdini-robot-toolkit