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.

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.
| as authored | after retime | |
|---|---|---|
| verdict | BLOCKED — 1 failure | READY — 0 warnings |
| peak joint velocity | 820.5 deg/s (J4) | 166.7 deg/s of 180 |
| frames | 150 | 162 |
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.
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°.
- 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