Robot model

Tatbot uses a pair of Trossen WidowX AI arms in a leader/follower research configuration. The public repository includes the model and software interfaces; deployment-specific addresses and calibration records are private.

Model

The URDF at urdf/tatbot.urdf is consumed by vision replay and visualization tools. Treat it as a shared interface: when geometry changes, rebuild consumers and record the model revision with the run.

The fitted visual model has a Lutin ballpoint on the pink-taped right arm and a mirrored laser attachment on left, with one D405 on each wrist. Left/right are persistent physical identities; their positions on the screen depend on the viewing direction. Leader/follower are control assignments. The old left handle and finger links retain frames only, without geometry. The left laser uses the V5 CAD assembly, whose meshes are authored in left/carriage_right but which is bolted to left/carriage_left rolled half a turn about the carriage axis — the placement the measured wrist fiducials and the palette contact holds agree on. The pen is rendered from its datasheet on the tool datum carried through that placement, with its lens face at the 2026-09-16 touch-off. Nothing there establishes a laser focus or collision clearance.

Left and right are the robot’s own sides, looking forward through the fixed cameras: +X forward, +Y left, +Z up. root and rig_center coincide at the arm-pair midpoint. A registration must associate the observed wrist with that same arm’s measured joints; similar leader/follower poses do not prove identity. A changed whole-URDF digest requires fresh source bindings wherever an acquisition binds that digest.

The control path is joint-space. It keeps the mapping from a leader arm to a follower explicit instead of hiding a separate inverse-kinematics service in the public API.

Control layers

  • cpp/teleop/ provides low-latency leader/follower teleoperation.

  • python/lerobot_robot_tatbot/ adapts the robot to LeRobot episode and policy interfaces.

  • rust/visiond/ records camera data and can replay a run with the URDF.

  • python/tatbot_sim/ provides hardware-independent development and tests.

See teleoperation, vision, and simulation for the public entry points.

Hardware profiles: tatbot profile

Which arms, addresses and e-stop a checkout may drive is a profile (config/profiles/), resolved before any motion verb connects. tatbot profile show [name] prints the resolved one (backend, arms, e-stop, provenance) and says whether it may drive hardware; tatbot profile list lists the profiles this checkout carries and marks each hardware or synthetic/incomplete; tatbot profile check [name] runs exactly the validation the motion gate runs and exits 3 when it would refuse, without starting anything. A public clone carries only gate-incapable profiles.

Recovery after a controller fault

tatbot arm recover lands the follower first and starts leader recovery only after the follower succeeds. Failure, interruption or timeout stops the sequence. An explicit leader or follower argument selects one arm. Each single-arm attempt retains an arm-recover run log.

Recovery automatically terminates existing processes holding the shared arm driver lease, including teleop, LeRobot and stuck recovery children. It sends SIGTERM, allows up to 10 seconds for cleanup, then sends SIGKILL to remaining holders and waits up to two seconds for the lock. This also stops a workflow using both arms when recovering an explicit single role. Only actual lease holders are signaled; unrelated processes are left running. Recovery retains the lock file and must acquire its exclusive lock before connecting to an arm. If ownership cannot be obtained, it refuses with exit 6.

The landing runs on the C++ arm stack: cpp/teleop/arm_recover, a small program on the vendor SDK that the teleop executor also uses, built by scripts/check cpp and staged on the arm node by tatbot deploy. No Python environment is involved. It opens a fresh driver session with the controller’s error state cleared, pushes the arm’s golden when the controller boots faulted or with measured feedback outside its admitted tolerance, takes position control softly at the measured pose, then moves staged → sleep → idle and verifies the sleep pose was actually reached. An arm joint measured past its limits by more than that tolerance is refused instead, before any command (exit 7): a power cycle can leave a joint counted a full turn off, and clamping it into its limits would snap the arm. Power the controller off, turn that joint by hand to near 0, and power it on before recovering again. The carriage stays at its measured position through the staged sweep, then returns to its configured rest position (0 m in the Tatbot profile) during the sleep phase; recovery fails if that return is not measured. The e-stop device is mandatory: a latched or silent button refuses the landing before any command (exit 3), and a press mid-move freezes the arm where it is until the button is released. Each attempt runs in its own child process, because the vendor driver cannot be reused after a failed connection; a controller that never answers exits 5 with nothing commanded. The LeRobot plugins keep their own copy of this ritual for a failed in-session disconnect.

The standalone launcher enforces a 45-second budget around that process, including termination of the previous owners, with a two-second termination grace. The SDK’s connection timeout alone does not bound later TCP reads in older drivers. Expiry terminates the driver and reports unknown arm state, never a successful landing or release. Landing verification and Ctrl+C shielding remain in the recovery process while it runs. This outer timeout does not repair controller communication or establish that a blocked driver can handle an e-stop.

Before any controller power cycle, support both arms and stop all existing recovery/teleop processes. A pending recovery could otherwise reconnect and start a landing when the controller returns. Do not force a stiff arm or start another driver alongside a hung one. Trossen documents controller and driver hangs in older versions; see the vendor troubleshooting guide.

Hardware boundary

The public model is not a calibration or an operating procedure. Do not infer joint limits, tool offsets, contact behavior, or permission for human use from the example files. Those values belong to the private acceptance contract.