- Planning group
- 7 DOF
- Rail travel
- 2.0 m
- Motion modes
- 3
- Rail hold tolerance
- 5 mm
Rail plus six arm joints solved as one kinematic chain, one trajectory
Prismatic carriage travel along the front straight segment
Arm only, arm and rail combined, and stow-traverse-deploy
Measured carriage drift ceiling when the rail is constrained
The problem
A wafer inspector is the tool a fab trusts to tell it whether its process is clean. When the inspector itself starts shedding particles, that trust inverts. The instrument becomes the contaminant, and every measurement it produces is suspect until someone finds the source.
Finding it is hard. The contamination is sub-micron, the interior is a tight and partially enclosed volume full of expensive optics, and the diagnosis today depends on an experienced engineer with a flashlight, a swab and a hypothesis. That process is slow, hard to repeat, and the knowledge stays in individual heads.
What I’m building
A mobile particle-forensics robot: a collaborative arm on a rail base carrying a custom inspection head, which navigates around and reaches into the equipment, images fine particle distributions under UV, and maps them back onto a reference frame.
Two distinct perception jobs run at the same time, and separating them is the core architectural decision:
- Inspection eyes: high-magnification UV and 2D imaging feeding particle detection, size distribution, and spatial mapping.
- Guiding eyes: a wrist-mounted depth camera building a voxel map for collision-aware motion planning into tight spaces.
Conflating the two is the obvious mistake: the optics that resolve a sub-micron particle are useless for knowing whether the elbow is about to hit a bracket.
How the agent fits in
An engineer describes a symptom in plain language. The agent proposes an inspection sequence, executes it behind confirm-gates, presents the image evidence it gathered, and iterates with the human on what to look at next.
That shape is deliberate. A bounded action executor with human gates is the only responsible way to let an LLM drive real actuators near expensive hardware, and it is the same pattern behind the action layer in Nexop.
The simulation runs on the real controller
The design review is complete and audited. More usefully, the motion stack now runs.
Universal Robots ships URSim as a container running the PolyScope controller itself, the same interpreter as a physical UR5e rather than a mock. URScript sent to it over TCP executes for real. Alongside it, Gazebo carries the full cell: the UR5e mounted on a carriage riding a 3 m oval rail, with the rail declared as a seventh joint in the same kinematic chain as the arm.
That last detail carries the design. The rail is not a second robot choreographed against the first: MoveIt plans one trajectory across all seven joints and a single controller executes it. Ask for a point the arm alone cannot reach, and the carriage slides while the arm articulates, as one motion.
A companion node subscribes to MoveIt’s planned path and exports it as a standalone URScript file that replays directly on the UR controller, preserving MoveIt’s per-segment timing rather than flattening it to a constant speed. The planner is a development convenience; the exported script is what would travel to real hardware.
Three ways to reach the same point
The same target coordinate can be reached three different ways, and choosing between them is an engineering decision:
- Arm only. A path constraint pins the rail at its current position. If the target is out of reach, planning fails rather than sliding the base to compensate. This is the “rail is locked out for maintenance” mode, and a clean failure is the whole reason it exists.
- Arm and rail together. The planner is free to use both and decides for itself whether the rail is needed.
- Stow, traverse, deploy. The arm folds into a vertical column above the carriage, the rail traverses to the position that puts the target at a comfortable reach distance, and only then does the arm extend. This is how real mobile manipulators move; nothing crosses a floor with its arm out.
Building the third one turned up a problem you only find by running it. The obvious transit pose, arm fully extended along the rail, sits at a kinematic singularity. The IK solver could not iterate away from it and the deploy stage aborted every time. Stowing vertically fixed that, and it sweeps a smaller volume as well. The reasoning sits in the code next to the constant, because the next person to “simplify” that pose will otherwise put the bug straight back.
What does not work yet
The carriage traverses the straight section of the oval. It cannot go around the curved ends.
That is a scoping decision. URDF has no joint type that expresses “position is arc length along a closed curve”; every joint it offers is linear in its variable along a fixed axis. Doing it properly means writing a custom MoveIt kinematics plugin that owns the ellipse math: arc-length parameterisation through an elliptic integral, carriage yaw along the tangent, and a hand-derived Jacobian column for the rail. I specced it fully, estimated 5–12 weeks, and stopped there. The payoff is almost entirely visual, and it would only transfer to a real cell if the procured rail were itself a closed loop with a vendor controller using the same parameterisation.
So the loop is presentational for now. The silhouette shows how a rail would wrap a tool, while the motion is what a straight rail does. The spec for the harder version is written down and waiting for a reason to build it.
Perception, the inspection-tool mockup, and the agent driving motion end to end come after this, and none of them are built.
Media

How this was built
The spec sheet above lists the stack. This section covers how the work was run, which a screenshot cannot show you.
Where AI did the work
- Used a planning agent to work the concept from problem statement to a full critical design review: competitor teardown, robot lineup comparison, protocol trade study (ROS 2 vs native UR comms), then the deck itself.
- Kept research and design in separate agent passes, so a sourcing pass could not rewrite design decisions that were already committed.
The discipline around it
- Every claim about a real product line traces to a public source, and anything I could not verify is labelled as unverified.
- Design rationale lives in numbered working documents, so the reasoning outlives the decision.
- Ran a dedicated audit pass over the finished deck to hunt for unsupported claims before it went in front of anyone.
What stayed human
- The robot never acts on the agent's plan directly. The agent proposes an inspection sequence, a human confirms, and only then does motion execute. The confirm-gate is built into the architecture, so it cannot be switched off in a settings panel.
- All motion planning is validated in simulation before any hardware moves.
- Scope calls stayed human. Full traversal of the oval loop needs a custom MoveIt kinematics plugin; I costed it at 5–12 weeks, wrote down why it does not transfer to real hardware, and declined it. Three conditions that would reverse the decision are recorded, so it can be re-opened when one of them is met.
Process artifacts in the repo
- 02b_OvalRail_Custom_Kinematics_Plugin.md
- The full engineering spec for the feature I chose not to build: curve math, Jacobian, IK strategy, effort breakdown, and the trigger conditions that would justify it
- 13_Final_Audit_Findings.md
- A self-audit of the design review looking for claims the evidence did not support
- 04_Robot_Comparison_Sheet.md
- Side-by-side platform trade study behind the UR5e selection
- phase2_tools/lib.py
- Shared geometry and MoveIt client behind the three motion modes, with the IK seeding and singularity findings written into the code as comments