Skip to content
Husain Bootwala
01Active R&D

Mobile Particle Forensics Robot

A cobot that reaches inside semiconductor equipment to find where contamination starts

Video · Stow, traverse, deploy: the arm crosses folded, then extends
Channel
01
Period
2026 —
Domain
Hardware
Role
Sole engineer: concept, mechanical design, simulation and motion stack, agent architecture

Stack

  • UR5e / URScript
  • ROS 2 Jazzy
  • MoveIt 2
  • URSim (PolyScope)
  • Gazebo
  • ros2_control
  • TRAC-IK
  • Python
  • URDF / xacro
  • OpenSCAD
  • LLM agents
Planning group
7 DOF
Rail travel
2.0 m
Motion modes
3
Rail hold tolerance
5 mm
  1. A flashlight beam searches a cutaway wafer inspector, missing a particle source hidden under a side moduleInspectorOpticsSource ??Flashlight
    BeforeParticle sources inside a wafer inspector are hunted with a flashlight.
  2. A rail-mounted robot arm reaches into the tool and points a UV head at the particle source, after a human confirmsRailConfirmUR5eUV head
    AfterDesigned: an arm on a rail reaches in. Today, its motion runs in simulation.

Designed, not built

  1. An inspection head with two camera cones: a narrow UV view onto particles and a wide depth view onto obstacle voxelsDepthsteer clearUV-Afind particles
    designUV-A finds particles; a depth camera keeps the arm off the optics.
  2. Agent proposes, a human confirms, then the arm moves; the direct path from agent to arm is crossed outNo bypassAgentproposesHumanconfirmsArmmovesEvidence
    designThe agent proposes each step. A human confirms before anything moves.
Arm reach alone
0.85 m
Distance to target
1.581 m
Rail slide needed
0.763 m

Running in simulation

  1. A rail carriage and six arm joints drawn as one numbered chain of seven, feeding one exported URScript fileRail12345677 joints1 trajectory.scriptURScript
    FixRail and arm solved as one seven-joint chain, exported as URScript.
  2. Three rows reach the same target: arm only is refused, arm plus rail slides and reaches, stow-traverse-deploy folds, slides, then extendsArm onlyRefusedArm + rail0.76 mStowtraversedeploy
    ResultOne target, three ways: arm only refuses; arm plus rail; stow-traverse-deploy.

A bug, and a limit

  1. Left, an arm laid flat along the rail is crossed out as singular; right, the same arm folded upright is marked as solvingLaid flatsingularIK stallsStoweduprightIK solves
    FixThe extended transit pose was singular. Stowing the arm upright let IK solve.
  2. Top-down oval rail around a tool: the front straight is driven, the curved ends and back straight are dashed as not drivenToolCurves: plugin needed5–12 weeks, declined2.0 m
    limitThe carriage drives the straight only. Curves need a plugin I declined.
Read the engineering detail5 min read

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, partially enclosed volume full of expensive optics, and diagnosis today depends on an experienced engineer with a flashlight, a swab and a hypothesis. That is slow, hard to repeat, and the knowledge stays in individual heads.

What I’m building

A collaborative arm on a rail base carrying a custom inspection head, which reaches into the equipment, images fine particle distributions under UV, and maps them back onto a reference frame.

Two perception jobs run at once, 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.

A bounded action executor with human gates is the only responsible way to let an LLM drive real actuators near expensive hardware. 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, and the motion stack now runs.

Universal Robots ships URSim as a container running the PolyScope controller itself: the same interpreter as a physical UR5e, not a mock. URScript sent to it over TCP executes for real. Alongside it, Gazebo carries the full cell: the UR5e 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 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 exports MoveIt’s planned path as a standalone URScript file that replays directly on the UR controller, keeping 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

  • Arm only. A path constraint pins the rail where it is. If the target is out of reach, planning fails rather than sliding the base to compensate. This is the “rail locked out for maintenance” mode, and a clean failure is the reason it exists. With the rail held this way, carriage drift stays within 5 mm.
  • 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, and only then does the arm extend. Nothing should cross a floor with its arm out.

Building the third 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 sweeps a smaller volume as well. The reasoning sits in the code next to the constant, because the next person to “simplify” that pose would 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 for “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 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

A 3D render of stadium_rail.stl, the oval rail generated by stadium.scad: two straight 60 mm tubes joined by semicircular ends, 3.06 m by 1.06 m overall. The front straight is highlighted and dimensioned as the carriage's travel, 2.0 m from rail_joint 0 to rail_joint 2.0. A label marks the curved ends and back straight as silhouette only.
CAD · The oval rail as modelled: the carriage drives the front straight only
Video · Three motion modes for the same target point
Two-lane architecture diagram. The upper lane, inspection eyes, runs from UV-A and dark-field optics through per-channel detection and classification to a particle map in the equipment's own frame. The lower lane, guiding eyes, runs from a wrist depth camera through a voxel map and a planning scene to one motion plan across seven joints. Every box is drawn dashed, meaning specified but not built, except the motion plan, which is solid because it runs in simulation today.
Diagram · Two perception paths, and what runs today

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

  • A planning agent took the concept to a full critical design review: competitor teardown, platform comparison, comms trade study, deck.
  • Research and design ran as separate agent passes, so sourcing could not rewrite decisions.

The discipline around it

  • Product claims trace to a public source, or are labelled unverified.
  • Rationale lives in numbered working documents.
  • An audit pass hunted unsupported claims.

What stayed human

  • The agent proposes, a human confirms, and only then does the robot move. The gate is architecture, not a setting.
  • Motion is proven in simulation first.
  • Scope stayed human: the full-oval plugin was costed at 5–12 weeks and declined; reopen conditions are recorded.

Process artifacts in the repo

02b_OvalRail_Custom_Kinematics_Plugin.md
Spec of the declined feature and its reopen conditions
02_Phase2_Linear_Rail.md
The rail as a seventh joint, with each failure and fix
moveit_to_urscript.py
Exports a MoveIt plan as URScript, keeping per-segment timing
phase2_tools/lib.py
The three motion modes, singularity finding commented in place