Skip to content

Repository files navigation

waldoctl

Shared interface definitions for robot arm control. waldoctl defines the contract between robot arm backends (hardware communication, motion planning) and frontend applications (control interfaces, scripting, visualization).

Named after Robert A. Heinlein's 1942 short story Waldo, in which the protagonist invents remote manipulator arms -- the origin of the real-world term "waldo" for teleoperated mechanical hands.

Installation

pip install "waldoctl @ git+https://github.com/Jepson2k/waldoctl.git"

Key abstractions

Robot

The single entry point for a backend. One object gives the frontend access to everything: joint configuration (limits, home position), tool definitions, forward/inverse kinematics, URDF paths for 3D rendering, capability flags, and factories for creating clients.

RobotClient

Async control interface spanning motion (moveJ, moveL, home), streaming position targets (servoJ, servoL), velocity jog (jogJ, jogL), queries, I/O, and synchronization. Async keeps operations like jogging, status streaming, and motion commands concurrent. For simple automation scripts where async/await would be unnecessary ceremony, backends also provide a synchronous client.

Control operations are @abstractmethod: every backend implements them. What varies by hardware is exposed as a has_* flag on Robot (has_force_torque, has_freedrive, has_collision_checking), and the handful of methods those gate have defaults that raise NotImplementedError.

Every method carries a @command(kind) marker and command_table() reads them back: MOTION and QUEUED calls enter the controller's queue and return an index a program may wait_command; SYSTEM calls apply at once and return 1/0/negative; CONTROL acts on the queue (stop and estop cancel it); QUERY reads state a plan knows; OBSERVATION reads live state only a running controller can answer; SYNC waits. A program runs unchanged against a live client or a preview because every wrapper that stands in for a client, the stepping wrapper, the path preview, a backend's dry run, reads its behaviour for a call from this table instead of its own list, and the conformance test refuses an unclassified method.

DryRunClient

The offline client a program runs against for a preview. It takes the same calls as a live client and answers them the same way -- a queue index, a code, a refusal -- and gives two tick-indexed records for the program so far. plan() is the commanded record, the planner's answer, fast enough to run behind a keystroke; simulate() is the predicted one, the same commands through the backend's control loop and plant. A backend with no plant returns the plan from simulate() too. Both are a TickIndex on one row axis with a TickBlock per command, and following_error(commanded, predicted) is the gap between them, compared by command so a run that settles longer than its plan still lines up.

is_dry_run(client) tells a skill whether the client it was handed previews or drives; it resolves the protocol's members the way a call would, so a wrapper that forwards attribute access counts where isinstance would not.

World

A Shape (Box, Sphere, Cylinder, Capsule, Cone, Ellipsoid) is one thing in the robot's world, in metres and radians. What it is follows from what it declares: collision=False is a visual marker, a plain shape is a keep-out, and a shape carrying physics=Physical(...) is also a body in a backend's contact simulation -- a static fixture without mass, a free object with one. ShapeWorld is a backend's applied world as read back: the installation layer from its robot config, the program layer the last set_shapes applied, and floor_z_m, the installation floor the backend enforces and rests objects on. waldoctl.world is the one JSON codec for a saved world, a library object or an import/export document. ObjectTicks on a predicted record reports where a physical object went during a previewed program, and SceneHandle is a plugin's window into the host's 3D scene, including proposing shapes for the installation layer.

Tools

A ToolSpec describes an end-of-arm tool: TCP offset, 3D mesh descriptors for visualization, motion descriptors (linear jaws, rotary spindles) for animation, UI button configuration, process data channels, and named variants for swapping configurations (e.g. different jaw sets). The typed hierarchy (ToolSpecGripperToolPneumaticGripperTool / ElectricGripperTool) lets frontends render tool controls and animate tool parts generically without hard-coding knowledge of specific tools.

Modules

Module Contents
robot Robot ABC -- identity, joints, tools, kinematics, lifecycle, client factories
client RobotClient ABC -- async control interface
dry_run DryRunClient protocol -- the offline client whose plan() and simulate() return the commanded and predicted records
tools Tool hierarchy, mesh/motion descriptors, enums, ToolStatus
joints Frozen dataclasses for joint configuration and limits
status StatusBuffer protocol for real-time state, query result types
recordings Immutable joint/tool observations, capture termination reasons and explicit gap/span inspection
results IKResult protocol and its concrete dataclass
shapes Shape kinds, Physical, ShapeWorld, the wire form and the reporting vocabulary
world JSON codec for a ShapeWorld -- saved worlds, library entries, import/export
scene SceneHandle protocol -- a plugin's window into the host's 3D scene
dry_run_state PathSegment, ToolAction and the other dry-run records a host keeps
ticks TickIndex, TickBlock, ObjectTicks, align_rows and following_error -- the records a dry run returns and how the two compare
types Frame and Axis type aliases
sync_tools Sync wrappers for async tool methods

For guides on implementing a backend or building scripts, see the PAROL Web Commander documentation.

TCP calibration

SetupSnapshot.tcp_calibrations stores named TcpCalibration values, tool/variant bindings and measurement provenance. The setup codec validates one versioned schema; snapshots and exports retain their fixed values. The pivot solve and orientation teaching that produce a calibration belong to the host application.

Backends implement set_tcp_transform and tcp_transform: six values in millimetres and intrinsic XYZ degrees, composed as T_registered_tool @ T_user. Wait for the setter's returned command index before readback. The legacy set_tcp_offset(x, y, z) clears user rotation; failed readback raises instead of substituting a zero transform. Physical tool meshes and inertial frames remain attached to their registered links.

License

Apache-2.0. See NOTICE for the attribution notices redistributors must preserve.

SetupSnapshot.signals maps names to immutable DigitalSignal values: backend, input/output bank, zero-based channel, expected bank sizes, and active-high or active-low polarity. Decoding refuses a different controller layout. The E-stop status bit is excluded from the channel banks.

RobotClient.io(timeout=...) bounds the entire query and returns None without a reply. write_io(..., timeout=...) bounds acceptance and raises TimeoutError when it remains unconfirmed. Both retain their configured client timeouts when omitted. Backends implementing this contract advertise io.digital; preview clients additionally advertise execution.preview. SignalObservation and SignalWaitResult carry logical levels, host receipt timestamps, and distinct matched/timeout outcomes. The I/O skills live in waldo_commander.skills.

SetupSnapshot.cameras stores CameraCalibration values from waldoctl.camera, with immutable pinhole intrinsics, measurement quality and provenance. A tool camera binds its camera→TCP pose to the backend, tool variant and full TCP transform. A fixed camera binds its pose to a named static frame and a snapshot of that frame's WRF transform. validate checks current acquisition and setup bindings; world_pose additionally resolves the camera to WRF, using an explicit observed TCP pose for tool cameras. Both reject changed relevant bindings. These helpers perform no capture, storage or robot I/O. Acquisition must supply fresh observations and account for physical camera/lens/mount changes that software cannot detect. Camera data is included in explicit setup snapshot serialization and export.

About

Shared interface definitions for robot arm control

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages