API Reference¶
The interfaces below are defined in waldoctl, the abstraction layer that all backends implement. When you write from parol6 import RobotClient in a script, that RobotClient is a concrete subclass of waldoctl.RobotClient — it inherits the same methods documented here, plus any backend-specific extras. The same applies to Robot, tool specs, and status types.
In short: this reference covers everything available to your scripts regardless of which backend you're using.
Robot¶
waldoctl.Robot
¶
Bases: ABC
Unified robot interface — the single entry point for any backend.
Combines identity, joint configuration, tool definitions, kinematics, lifecycle management, and client factories into one ABC.
Required methods are marked with @abstractmethod. Optional
capabilities have concrete defaults that backends override as needed.
name: str
abstractmethod
property
¶
Human-readable robot name, e.g. "PAROL6".
joints: JointsSpec
abstractmethod
property
¶
Joint configuration: count, names, limits, home position.
tools: ToolsSpec
property
¶
Backend-native tools composed with plugins registered via
waldoctl.tools. Cached per instance (entry points are static).
native_tools: ToolsSpec
abstractmethod
property
¶
The backend's own tools; composed with plugin tools by :attr:tools.
Backends implement this; consumers read :attr:tools (which adds plugin
tools).
cartesian_limits: CartesianKinodynamicLimits
abstractmethod
property
¶
Jog-mode Cartesian velocity and acceleration limits.
position_unit: Literal['mm', 'm']
abstractmethod
property
¶
How this robot's users think about distance (display hint).
has_force_torque: bool
property
¶
Whether force / torque readout is available.
has_freedrive: bool
property
¶
Whether a freedrive / teach mode is available.
digital_outputs: int
abstractmethod
property
¶
Number of digital output pins.
digital_inputs: int
abstractmethod
property
¶
Number of digital input pins.
urdf_path: str
abstractmethod
property
¶
Path to the URDF file for 3-D rendering.
mesh_dir: str
abstractmethod
property
¶
Directory containing STL / mesh files referenced by the URDF.
joint_index_mapping: tuple[int, ...]
abstractmethod
property
¶
Maps URDF joint indices to control joint indices.
motion_profiles: tuple[str, ...]
property
¶
Available motion profile names.
At least one profile is required. The default is ("linear",)
which backends should override with their actual profiles.
cartesian_frames: tuple[str, ...]
property
¶
Available Cartesian reference frames for jogging.
Default includes both WRF and TRF which are required.
backend_package: str
abstractmethod
property
¶
Python package used by user scripts and subprocess workers.
sync_client_class: type
abstractmethod
property
¶
The synchronous client class (e.g. RobotClient).
Used for editor autocomplete discovery and stepping wrapper. Convention: backends export this class at their package level.
async_client_class: type
abstractmethod
property
¶
The asynchronous client class (e.g. AsyncRobotClient).
Used for editor command discovery (introspecting available methods). Convention: backends export this class at their package level.
has_collision_checking: bool
property
¶
Whether collision checking (self + workspace shapes) is available.
fk(q_rad: NDArray[np.float64], out: NDArray[np.float64]) -> NDArray[np.float64]
abstractmethod
¶
Forward kinematics.
q_rad: joint angles in radians (num_joints,).
out: pre-allocated (6,) buffer to write the result into.
Returns out filled with [x, y, z, rx, ry, rz] in meters + radians.
ik(pose: NDArray[np.float64], q_seed_rad: NDArray[np.float64]) -> IKResult
abstractmethod
¶
Inverse kinematics.
pose: [x, y, z, rx, ry, rz] — meters + radians.
q_seed_rad: current joint angles in radians (seed).
Returns an IKResult with q in radians.
set_active_tool(tool_key: str, tcp_offset_m: tuple[float, float, float] | None = None, variant_key: str | None = None) -> None
abstractmethod
¶
Apply tool transform to the local FK/IK model.
When set, fk() returns TCP position instead of flange position.
tcp_offset_m: optional (x, y, z) user offset in meters, composed on top of the tool's registered transform. variant_key: optional variant whose TCP overrides the tool default.
check_limits(q_rad: NDArray[np.float64]) -> bool
abstractmethod
¶
Return True if all joints are within limits.
fk_batch(joint_path_rad: NDArray[np.float64]) -> NDArray[np.float64]
abstractmethod
¶
Batch FK: (N, num_joints) radians -> (N, 6) poses (m + rad).
ik_batch(poses: NDArray[np.float64], q_start_rad: NDArray[np.float64]) -> list[IKResult]
abstractmethod
¶
Batch IK: (N, 6) poses -> list of IKResult (radians).
in_collision(q_rad: NDArray[np.float64]) -> bool
¶
Whether q_rad (radians) collides — with itself, the attached
tool, or a workspace keep-out shape.
colliding_pairs(q_rad: NDArray[np.float64]) -> list[tuple[str, str]]
¶
Colliding (name, name) geometry/link pairs at q_rad.
check_trajectory(q_path_rad: NDArray[np.float64]) -> int
¶
First colliding row index in (N, num_joints) path, or -1 if clear.
min_distance(q_rad: NDArray[np.float64]) -> float
¶
Min clearance at q_rad (signed; negative = penetration).
apply_shapes(shapes: list[Shape]) -> None
¶
Apply workspace keep-out shapes to this process's local checker.
Local-only twin of RobotClient.set_shapes (which updates the
backend's checkers) — feeds client-side preview / editing-pose
collision queries. No-op on backends without collision checking.
start(**kwargs: Any) -> None
abstractmethod
¶
Start the backend process / connection (blocking).
What "start" means is backend-specific: spawn a subprocess, connect to a remote server, launch a ROS node, etc.
stop() -> None
abstractmethod
¶
Stop the backend process and release resources.
is_available(**kwargs: Any) -> bool
abstractmethod
¶
Check if the backend is reachable / ready.
create_async_client(**kwargs: Any) -> RobotClient
abstractmethod
¶
Create an async client connected to this backend.
create_sync_client(**kwargs: Any) -> object
abstractmethod
¶
Create a synchronous client. Returns backend-specific type.
create_dry_run_client(**kwargs: Any) -> DryRunClient | None
¶
Create an offline simulation client, or None if unsupported.
RobotClient¶
waldoctl.RobotClient
¶
Bases: ABC
Generic async robot control interface.
Backends inherit from this ABC and implement the required abstract
methods. Optional methods have concrete defaults that raise
NotImplementedError.
Command palette integration: Methods that should appear in the editor's
command palette must include Category: and Example: sections in
their docstrings. The editor parses these at startup to build the palette.
Category: <name>— groups the command in the palette UI.Example:— the first indented line becomes the insertion snippet.
Command return codes: Command methods declared -> int follow one
convention, which backends MUST honor:
- Queued motion commands (Category: Motion) return the command's queue
index (
>= 0) once the backend acknowledges it;< 0when the command could not be confirmed or was rejected. - Every other command returns
1when the backend confirmed it applied the command,0when unconfirmed (unreachable, or no reply in time — the command may or may not have been applied), and< 0on rejection. A backend may raise instead of returning a negative code on active rejection; callers must treat both as failure.
A backend that cannot confirm application must never report success.
Success is >= 0 for queued motion, > 0 for everything else.
tool: ToolSpec
property
¶
The active bound tool.
Raises RuntimeError if no tool has been set.
close() -> None
abstractmethod
async
¶
Release resources and disconnect.
ping() -> PingResult | None
abstractmethod
async
¶
Check connectivity. Returns None if unreachable.
Category: Query
Example
rbt.ping()
wait_ready(timeout: float = 5.0, interval: float = 0.05) -> bool
abstractmethod
async
¶
Block until the robot backend is reachable or timeout expires.
stream_status() -> AsyncIterator[StatusBuffer]
abstractmethod
¶
Async iterator of real-time status snapshots (yields copies, safe to store).
stream_status_shared() -> AsyncIterator[StatusBuffer]
abstractmethod
¶
Async iterator of real-time status snapshots (shared buffer, zero-copy).
move_j(angles: list[float] | None = None, *, pose: list[float] | None = None, duration: float = 0.0, speed: float = 0.0, accel: float = 1.0, r: float = 0.0, rel: bool = False, wait: bool = False, timeout: float = 10.0, **wait_kwargs: Any) -> int
abstractmethod
async
¶
Joint-space move. angles: joint angles in degrees.
If pose is given, performs joint-interpolated move to Cartesian target. Returns the command index (>= 0) on success, -1 on failure.
Category: Motion
Example
rbt.move_j(
move_l(pose: list[float], *, frame: Frame = 'WRF', duration: float = 0.0, speed: float = 0.0, accel: float = 1.0, r: float = 0, rel: bool = False, wait: bool = False, **wait_kwargs: Any) -> int
abstractmethod
async
¶
Linear Cartesian move to [x, y, z, rx, ry, rz].
Returns the command index (>= 0) on success, -1 on failure.
Category: Motion
Example
rbt.move_l(
home(wait: bool = False, **wait_kwargs: Any) -> int
abstractmethod
async
¶
Move to the robot's home position.
Returns the command index (>= 0) on success, -1 on failure.
Category: Motion
Example
rbt.home()
move_c(via: list[float], end: list[float], *, frame: Frame = 'WRF', duration: float | None = None, speed: float | None = None, accel: float = 1.0, r: float = 0, wait: bool = False, **wait_kwargs: Any) -> int
async
¶
Circular arc move through via to end.
Category: Motion
Example
rbt.move_c(
move_s(waypoints: list[list[float]], *, frame: Frame = 'WRF', duration: float | None = None, speed: float | None = None, accel: float = 1.0, wait: bool = False, **wait_kwargs: Any) -> int
async
¶
Cubic spline move through waypoints.
Category: Motion
Example
rbt.move_s(
move_p(waypoints: list[list[float]], *, frame: Frame = 'WRF', duration: float | None = None, speed: float | None = None, accel: float = 1.0, wait: bool = False, **wait_kwargs: Any) -> int
async
¶
Process move with auto-blending through waypoints.
Category: Motion
Example
rbt.move_p(
servo_j(angles: list[float], *, pose: list[float] | None = None, speed: float = 1.0, accel: float = 1.0) -> int
abstractmethod
async
¶
Streaming joint position target (fire-and-forget).
angles: joint angles in degrees (ignored if pose is set). If pose is given, dispatches to Cartesian target via IK.
Category: Streaming
Example
rbt.servo_j(
servo_l(pose: list[float], *, speed: float = 1.0, accel: float = 1.0) -> int
abstractmethod
async
¶
Streaming linear Cartesian position target (fire-and-forget).
pose: [x, y, z, rx, ry, rz] in mm and degrees.
Category: Streaming
Example
rbt.servo_l(
jog_j(joint: int, speed: float = 0.0, duration: float = 0.1, *, joints: list[int] | None = None, speeds: list[float] | None = None, accel: float = 1.0) -> int
abstractmethod
async
¶
Joint velocity jog. Single-joint or multi-joint.
Single joint: jog_j(0, 0.5, 1.0)
Multi joint: jog_j(joints=[0, 1], speeds=[0.5, -0.3], duration=1.0)
Category: Jog
Example
rbt.jog_j(
jog_l(frame: Frame, axis: Axis | None = None, speed: float = 0.0, duration: float = 0.1, *, axes: list[Axis] | None = None, speeds_list: list[float] | None = None, accel: float = 1.0) -> int
abstractmethod
async
¶
Cartesian velocity jog. Single-axis or multi-axis.
Single axis: jog_l("WRF", "X", 0.5, 1.0)
Multi axis: jog_l("WRF", axes=["X", "Y"], speeds_list=[0.5, -0.3])
Category: Jog
Example
rbt.jog_l("WRF", "X", speed=0.5, duration=1.0)
wait_motion(timeout: float = 10.0, **kwargs: Any) -> bool
abstractmethod
async
¶
Block until the robot has stopped moving or timeout expires.
Category: Synchronization
Example
rbt.wait_motion()
wait_command(command_index: int, timeout: float = 10.0) -> bool
abstractmethod
async
¶
Block until a specific command index has completed.
Category: Synchronization
Example
rbt.wait_command(
wait_status(predicate: Callable[[StatusBuffer], bool], timeout: float = 5.0) -> bool
async
¶
Block until predicate returns True for a status snapshot.
wait_checkpoint(label: str, timeout: float = 30.0) -> bool
async
¶
Block until a checkpoint with label is reached.
stop() -> int
abstractmethod
async
¶
Stop all motion — cancel the active move and clear the queue.
The controller stays enabled and holding position; the next motion command is accepted immediately.
Category: Control
Example
rbt.stop()
estop() -> int
abstractmethod
async
¶
Protective stop: stop all motion and latch the controller
disabled until reset().
Category: Control
Example
rbt.estop()
reset() -> int
abstractmethod
async
¶
Clear a latched protective stop, re-enabling motion.
Category: Control
Example
rbt.reset()
simulator(enabled: bool) -> int
async
¶
Enable or disable simulator mode.
Category: Control
Example
rbt.simulator(True)
is_simulator() -> bool
async
¶
Query whether simulator mode is active.
Category: Query
Example
active = rbt.is_simulator()
teleport(angles_deg: list[float], tool_positions: list[float] | None = None) -> int
async
¶
Instantly set joint angles and optional tool positions (simulator only).
Category: Control
Example
rbt.teleport([0, -90, 0, 0, 0, 0]) rbt.teleport([0, -90, 0, 0, 0, 0], tool_positions=[1.0])
freedrive(enabled: bool) -> int
async
¶
Enable or disable freedrive / teach mode.
is_freedrive() -> bool
async
¶
Query whether freedrive / teach mode is active.
set_shapes(shapes: list[Shape]) -> int
async
¶
Replace the program-layer keep-out / marker shapes (the collision world).
Collision-enabled shapes are added to the backend's collision checkers so motion is blocked against them; an empty list clears all program-layer shapes. Installation-layer shapes (declared in the backend's robot config) are unaffected — programs inherit them and cannot remove them.
The change also invalidates committed motion: the backend re-guards the currently-streaming trajectory's remaining path and every queued trajectory before it starts, halting with a collision error rather than driving into a keep-out declared after the motion was planned.
Returns 1 only after the backend confirms the world was applied;
0 if unconfirmed, < 0 if the backend rejected the shapes (see
the class docstring's return-code convention).
Category: Configuration
Example
rbt.set_shapes([Box(name="table", x=0.6, y=0.4, z=0.02, pose=(0.3, 0, -0.01, 0, 0, 0))])
shapes() -> ShapeWorld | None
async
¶
The collision world the backend is currently enforcing, by layer.
Readback truth: displays should render this — not a locally stored
copy — re-querying whenever StatusBuffer.scene_epoch changes.
Returns None if the backend is unreachable.
Category: Query
Example
world = rbt.shapes()
angles() -> list[float] | None
abstractmethod
async
¶
Current joint angles in degrees.
Category: Query
Example
angles = rbt.angles()
pose(frame: Frame = 'WRF') -> list[float] | None
abstractmethod
async
¶
Current TCP pose as [x, y, z, rx, ry, rz] in mm and degrees.
Category: Query
Example
pose = rbt.pose()
joint_speeds() -> list[float] | None
async
¶
Current joint velocities.
Category: Query
Example
speeds = rbt.joint_speeds()
io() -> list[int] | None
async
¶
Digital I/O state.
Category: Query
Example
io = rbt.io()
status() -> object | None
async
¶
Aggregate status snapshot.
Category: Query
Example
status = rbt.status()
queue() -> list[str] | None
async
¶
Queued command list.
Category: Query
Example
queue = rbt.queue()
tools() -> ToolResult | None
async
¶
Current tool and available tools.
Category: Query
Example
tools = rbt.tools()
activity() -> ActivityResult | None
async
¶
What the robot is currently doing.
Returns state (idle/executing/error), current command name, parameters, and error description if applicable.
Category: Query
Example
act = rbt.activity()
reachable() -> object | None
async
¶
Remaining freedom of movement per joint/axis before hitting limits.
Category: Query
Example
en = rbt.reachable()
error() -> object | None
async
¶
Current error state, or None if no error.
Category: Query
Example
err = rbt.error()
profile() -> str | None
async
¶
Current motion profile name.
Category: Query
Example
profile = rbt.profile()
tcp_speed() -> float | None
async
¶
TCP linear velocity in mm/s.
Category: Query
Example
speed = rbt.tcp_speed()
connect_hardware(port_str: str) -> int
async
¶
Connect to robot hardware via serial port.
Category: Configuration
Example
rbt.connect_hardware("/dev/ttyUSB0")
select_profile(profile: str) -> int
async
¶
Set the motion profile (e.g. "TOPPRA").
Category: Configuration
Example
rbt.select_profile("TOPPRA")
select_tool(tool_name: str, variant_key: str = '') -> int
async
¶
Set the active end-effector tool on the controller.
Category: Configuration
Example
rbt.select_tool("PNEUMATIC")
set_tcp_offset(x: float = 0, y: float = 0, z: float = 0) -> int
async
¶
Set TCP offset in mm, composed on top of the current tool transform.
The offset shifts the effective TCP point in the tool's local frame. Subsequent motion (especially TRF relative moves) will use the new TCP. Call with (0, 0, 0) to reset. Changing tools resets the offset.
Category: Configuration
Example
rbt.set_tcp_offset(0, 0, -190)
tcp_offset() -> list[float]
async
¶
Query current TCP offset in mm [x, y, z].
Category: Configuration
Example
offset = rbt.tcp_offset()
write_io(index: int, value: int) -> int
async
¶
Set digital output by logical index (0 = first output pin).
Category: I/O
Example
rbt.write_io(0, 1) # Set first output HIGH
tool_action(tool_key: str, action: str, params: list[Any] | None = None, *, wait: bool = False, timeout: float = 10.0) -> int
async
¶
Invoke a tool-specific action by key.
tool_key: identifier of the attached tool (e.g. "ELECTRIC").
action: action name understood by the tool (e.g. "calibrate", "move").
params: optional positional parameters for the action.
Category: I/O
Example
rbt.tool_action("ELECTRIC", "calibrate")
reset_state() -> int
async
¶
Reset controller state (world shapes, tool selection, errors).
Category: Control
Example
rbt.reset_state()
checkpoint(label: str) -> int
async
¶
Insert a checkpoint marker in the command queue.
Category: Synchronization
Example
rbt.checkpoint("pick_done")
delay(seconds: float) -> int
async
¶
Insert a non-blocking delay in the command queue.
Category: Synchronization
Example
rbt.delay(1.0)
DryRunClient¶
waldoctl.DryRunClient
¶
Bases: Protocol
Offline motion client for path preview / dry-run simulation.
Concrete implementations run the real command pipeline against a
simulated controller state without hardware. Each motion method
returns a DryRunResult containing the TCP trajectory and final
joint state.
Required methods: home(), move_j(), move_l(),
angles(), pose(), flush().
Joint Configuration¶
waldoctl.JointsSpec(count: int, names: tuple[str, ...], limits: JointLimits, home: HomePosition)
dataclass
¶
Complete joint configuration for a robot.
All array properties have their first dimension equal to count.
waldoctl.JointLimits(position: PositionLimits, hard: KinodynamicLimits, jog: KinodynamicLimits)
dataclass
¶
All joint limits — position and kinodynamic.
waldoctl.PositionLimits(deg: NDArray[np.float64], rad: NDArray[np.float64])
dataclass
¶
waldoctl.KinodynamicLimits(velocity: NDArray[np.float64], acceleration: NDArray[np.float64], jerk: NDArray[np.float64] | None = None)
dataclass
¶
Per-joint velocity, acceleration, and jerk limits.
All arrays have shape (num_joints,) in SI units (rad/s family).
velocity: NDArray[np.float64]
instance-attribute
¶
(N,) — max joint velocities in rad/s.
acceleration: NDArray[np.float64]
instance-attribute
¶
(N,) — max joint accelerations in rad/s².
jerk: NDArray[np.float64] | None = None
class-attribute
instance-attribute
¶
(N,) — max joint jerks in rad/s³, or None.
waldoctl.HomePosition(deg: NDArray[np.float64], rad: NDArray[np.float64])
dataclass
¶
waldoctl.CartesianKinodynamicLimits(velocity: LinearAngularLimits, acceleration: LinearAngularLimits)
dataclass
¶
waldoctl.LinearAngularLimits(linear: float, angular: float)
dataclass
¶
Results¶
waldoctl.IKResult
¶
waldoctl.DryRunResult
¶
Bases: Protocol
Result from a dry-run motion command (path preview).
tcp_poses: NDArray[np.float64]
instance-attribute
¶
(N, 6) — TCP trajectory [x, y, z, rx, ry, rz] in meters + radians.
end_joints_rad: NDArray[np.float64]
instance-attribute
¶
(num_joints,) — final joint angles in radians.
duration: float
instance-attribute
¶
Trajectory duration in seconds.
error: object | None
instance-attribute
¶
Structured error (e.g. RobotError), or None on success.
valid: NDArray[np.bool_] | None
instance-attribute
¶
(N,) per-pose IK validity; None means all poses are valid.
joint_trajectory_rad: NDArray[np.float64] | None
instance-attribute
¶
(N, num_joints) — full joint trajectory in radians, aligned with tcp_poses rows. None if unavailable.
waldoctl.IKResultData(q: NDArray[np.float64], success: bool, violations: str | None = None)
dataclass
¶
Concrete IKResult for use in tests and adapters.
waldoctl.DryRunResultData(tcp_poses: NDArray[np.float64], end_joints_rad: NDArray[np.float64], duration: float, error: object | None = None, valid: NDArray[np.bool_] | None = None, joint_trajectory_rad: NDArray[np.float64] | None = None)
dataclass
¶
Concrete DryRunResult for use in tests and adapters.
Status¶
waldoctl.StatusBuffer
¶
Bases: Protocol
Status snapshot yielded by status_stream_shared().
Each field is a numpy array for zero-copy access in the hot path.
pose: np.ndarray
instance-attribute
¶
(16,) float64 — flattened 4x4 homogeneous transform.
angles: np.ndarray
instance-attribute
¶
(N,) float64 — joint angles in degrees.
speeds: np.ndarray
instance-attribute
¶
(N,) float64 — joint velocities in rad/s.
io: np.ndarray
instance-attribute
¶
(5,) int32 — [in1, in2, out1, out2, estop].
tool_status: ToolStatus
instance-attribute
¶
Universal EOAT status (key, state, positions, etc.).
joint_en: np.ndarray
instance-attribute
¶
(12,) int32 — joint enable envelope.
cart_en: dict[str, np.ndarray]
instance-attribute
¶
Frame name -> (12,) int32 Cartesian enable envelope.
action_current: str
instance-attribute
¶
Currently executing action name.
action_params: str
instance-attribute
¶
Brief serialization of current action parameters.
action_state: ActionState
instance-attribute
¶
State of the current action.
executing_index: int
instance-attribute
¶
Index of the command currently being executed (-1 if idle).
completed_index: int
instance-attribute
¶
Index of the last completed command (-1 if none).
last_checkpoint: str
instance-attribute
¶
Label of the last checkpoint reached (empty if none).
tcp_speed: float
instance-attribute
¶
TCP linear velocity in mm/s.
simulator_active: bool
instance-attribute
¶
Whether the controller is in simulator mode.
collision_active: bool
instance-attribute
¶
Whether a motion was blocked/stopped by a predicted collision.
collision_pairs: list[tuple[str, str]]
instance-attribute
¶
Colliding pairs at the predicted colliding config. Names are URDF link
names, shape:<name> (program keep-out), install:<name>
(installation keep-out), or tool:<key>:<part> (attached tool geometry)
— never backend-internal geometry identifiers.
scene_epoch: int
instance-attribute
¶
Monotonic counter bumped on every collision-world change; displays
re-query RobotClient.shapes() when it moves.
homed: bool
instance-attribute
¶
All joints homed. Until homing, reported joint positions are unreferenced and backends refuse planned motion; frontends seed dry-run previews with this so previews mirror that gate.
waldoctl.PingResult(hardware_connected: bool)
dataclass
¶
Result of a connectivity check.
hardware_connected: bool
instance-attribute
¶
Whether the controller has a live link to robot hardware (serial, socket, CAN, PLC, etc.).
waldoctl.ToolResult(tool: str, available: list[str])
dataclass
¶
waldoctl.ActionState
¶
Bases: IntEnum
State of the currently executing action on the controller.
Tools¶
waldoctl.ToolSpec(*, key: str, display_name: str, tool_type: str | ToolType, tcp_origin: tuple[float, float, float], tcp_rpy: tuple[float, float, float], description: str = '', meshes: tuple[MeshSpec, ...] = (), motions: tuple[PartMotion, ...] = (), variants: tuple[ToolVariant, ...] = (), activation_type: ActivationType = ActivationType.PROGRESSIVE, action_l_labels: tuple[str, str] | None = None, action_l_icons: tuple[str, str] | None = None, action_l_mode: ToggleMode = ToggleMode.TOGGLE, adjust_step: int | None = None, adjust_labels: tuple[str, str] | None = None, adjust_icons: tuple[str, str] | None = None, action_r_labels: tuple[str, str] | None = None, action_r_icons: tuple[str, str] | None = None, action_r_mode: ToggleMode = ToggleMode.TRIGGER, camera_spec: CameraSpec | None = None)
¶
Bases: ABC
Base contract every tool must satisfy.
key is unique per tool instance (e.g. "pneumatic_left").
tool_type determines which GUI panel category the tool belongs to.
Immutable spec fields are stored privately and exposed via read-only
properties. :attr:runtime_settings is the mutable, bindable layer for
user overrides (currently camera device; tools can extend it).
key: str
property
¶
Unique instance identifier.
display_name: str
property
¶
Human-readable name for UI display.
tool_type: str
property
¶
GUI category — determines which panel (if any) is shown.
Returns a str so third-party tools can introduce new categories
beyond the built-in :class:ToolType values. Comparison with
ToolType.GRIPPER etc. still works because ToolType is a
StrEnum.
tcp_origin: tuple[float, float, float]
property
¶
(x, y, z) translation from flange to TCP in meters.
tcp_rpy: tuple[float, float, float]
property
¶
(roll, pitch, yaw) orientation from flange to TCP in radians.
activation_type: ActivationType
property
¶
How the tool is activated — binary (on/off) or progressive (continuous).
description: str
property
¶
Short description of the tool.
meshes: tuple[MeshSpec, ...]
property
¶
Mesh descriptors for 3D visualization.
motions: tuple[PartMotion, ...]
property
¶
Physical motion descriptors for movable tool parts.
variants: tuple[ToolVariant, ...]
property
¶
Named mesh/motion variants (e.g. different jaw sets).
action_l_labels: tuple[str, str] | None
property
¶
(off_label, on_label) tooltip text for the left action button.
action_l_icons: tuple[str, str] | None
property
¶
(off_icon, on_icon) Material Icon names for the left action button.
action_l_mode: ToggleMode
property
¶
How the left action button behaves — stateful on/off or one-shot trigger.
adjust_step: int | None
property
¶
Step size for the +/- adjust buttons, or None if not supported.
adjust_labels: tuple[str, str] | None
property
¶
(decrease_label, increase_label) tooltip text for adjust buttons.
adjust_icons: tuple[str, str] | None
property
¶
(decrease_icon, increase_icon) Material Icon names for adjust buttons.
action_r_labels: tuple[str, str] | None
property
¶
(off_label, on_label) tooltip text for the right action button.
action_r_icons: tuple[str, str] | None
property
¶
(off_icon, on_icon) Material Icon names for the right action button.
action_r_mode: ToggleMode
property
¶
How the right action button behaves — stateful on/off or one-shot trigger.
channel_descriptors: tuple[ChannelDescriptor, ...]
property
¶
Descriptors for tool-specific process data channels.
camera_spec: CameraSpec | None
property
¶
Spec-time default camera attached to this tool, if any.
Returns None when the tool has no camera. The user can still
override via :attr:runtime_settings; consumers should resolve the
effective device via :attr:effective_camera_device.
runtime_settings: 'ToolRuntimeSettings'
property
¶
User-tweakable runtime overrides for this tool.
Bindable. The host application persists these per tool key to
:attr:nicegui.app.storage.general so user choices survive restarts.
effective_camera_device: int | str | None
property
¶
Resolved camera device after applying any runtime override.
Resolution order: runtime_settings.camera_device if set, else
camera_spec.device if a camera_spec exists, else None.
Two values mean "no camera": None (no spec or override supplies a
device) and -1 (a spec is present but set to CameraSpec.device's
no-camera sentinel). Callers must treat both as absent.
action_l(engaged: bool) -> None
async
¶
Left action button handler.
Override in subclasses to define tool-specific behavior.
action_r(engaged: bool) -> None
async
¶
Right action button handler.
Override in subclasses to define tool-specific behavior.
status() -> ToolStatus
async
¶
Query current tool status from the controller.
Returns the live tool status (state, engaged, positions, channels).
The base ToolSpec raises NotImplementedError; client-bound
tool subclasses override it against the controller.
waldoctl.ToolsSpec
¶
Bases: ABC
Collection of available tools for a robot.
Supports membership testing by ToolType (category) or str (key).
available: tuple[ToolSpec, ...]
abstractmethod
property
¶
All available tool specifications, ordered for display.
default: ToolSpec
abstractmethod
property
¶
Default tool (typically bare flange / "NONE").
__getitem__(key: str) -> ToolSpec
abstractmethod
¶
Look up a tool by its key. Raises KeyError if not found.
__contains__(item: object) -> bool
abstractmethod
¶
Test membership by ToolType (any tool of that category?)
or str (specific key exists?).
by_type(tool_type: str | ToolType) -> tuple[ToolSpec, ...]
abstractmethod
¶
Return all tools matching the given category.
Accepts a plain str so third-party tool categories work without
extending the built-in :class:ToolType enum.
waldoctl.GripperTool(**kwargs: Any)
¶
Bases: ToolSpec
Base for all grippers.
All grippers support set_position() as the universal control method.
Position is normalized: 0.0 = fully open, 1.0 = fully closed.
Action methods are abstract — backends provide concrete implementations.
gripper_type: GripperType
abstractmethod
property
¶
Gripper sub-type.
set_position(position: float, **kwargs: float | int) -> int
abstractmethod
async
¶
Set gripper position. 0.0 = fully open, 1.0 = fully closed.
Category: Tool
Example
rbt.tool.set_position(0.5)
calibrate(**kwargs: object) -> int
async
¶
Calibrate the gripper. Not all grippers support this.
Category: Tool
Example
rbt.tool.calibrate()
is_open(position: float) -> bool
¶
Infer open/closed from normalized position. True = open.
action_l(engaged: bool) -> None
async
¶
Left action: open if engaged, close if not.
open(**kwargs: float | int) -> int
abstractmethod
async
¶
Open the gripper.
Category: Tool
Example
rbt.tool.open()
close(**kwargs: float | int) -> int
abstractmethod
async
¶
Close the gripper.
Category: Tool
Example
rbt.tool.close()
waldoctl.PneumaticGripperTool(*, io_port: int, **kwargs: Any)
¶
Bases: GripperTool
Pneumatic gripper — binary open/close.
Action methods are abstract — backends provide concrete implementations.
io_port: int
property
¶
Digital I/O port number for open/close control.
waldoctl.ElectricGripperTool(*, position_range: tuple[float, float], speed_range: tuple[float, float], current_range: tuple[int, int], **kwargs: Any)
¶
Bases: GripperTool
Electric gripper — continuous position with speed and current control.
Action methods and computed properties (adjust_step,
channel_descriptors) are abstract — backends provide concrete
implementations.
waldoctl.ToolType
¶
Bases: StrEnum
Tool categories the web commander has GUI support for.
StrEnum so third-party tools can pass arbitrary category strings
via waldoctl.tools entry points while ToolType.GRIPPER == "gripper"
keeps existing equality checks working.
waldoctl.GripperType
¶
Bases: Enum
Gripper sub-types — each gets different UI controls.
waldoctl.ActivationType
¶
Bases: Enum
How a tool is activated / controlled.
On/off only — no intermediate position feedback from hardware.
Tools with motion descriptors need estimated_speed fields
so the simulator can animate transitions.
PROGRESSIVE: Continuous position control with real-time position feedback.
waldoctl.ToggleMode
¶
waldoctl.ToolState
¶
Bases: IntEnum
State of an end-of-arm tool.
waldoctl.ToolStatus
¶
Universal end-of-arm tool status — the bindable surface exposed at
commander.status.tool.
Populated by the host application's status loop at the controller's
broadcast rate. Consumers combine positions[i] with
ToolSpec.motions[i] to reconstruct the physical state of each DOF
without knowing the tool type. Tool-specific process data is in
channels, described by the tool's channel_descriptors.
Decorated with @bindable_dataclass so UI elements can bind to leaf
fields directly: bind_text_from(commander.status.tool, "key"),
bind_value_from(commander.status.tool, "engaged"), etc. Field
reassignment by the status loop fires bindings synchronously.
Mutate-in-place invariant: this is a sub-object of RobotStatus —
its fields are written individually by the status loop. The instance
itself is never swapped.
key: str = 'NONE'
class-attribute
instance-attribute
¶
Attached tool key.
variant_key: str = ''
class-attribute
instance-attribute
¶
Active variant within the attached tool (empty if the tool has no variants).
state: ToolState = ToolState.OFF
class-attribute
instance-attribute
¶
Tool operational state.
engaged: bool = False
class-attribute
instance-attribute
¶
Actively doing work (welding, gripping, dispensing).
part_detected: bool = False
class-attribute
instance-attribute
¶
EOAT part/object presence confirmed.
fault_code: int = 0
class-attribute
instance-attribute
¶
0=no fault, nonzero=tool-specific error.
positions: tuple[float, ...] = ()
class-attribute
instance-attribute
¶
DOF positions 0..1, one per PartMotion.
channels: tuple[float, ...] = ()
class-attribute
instance-attribute
¶
Tool-specific process data, described by ChannelDescriptor.
position: float
property
¶
Primary DOF position (positions[0] if any, else 0.0).
Convenience accessor for the common single-DOF case (gripper open/
close, etc.). Not bindable — bind to positions and use a backward
function if reactive display of the primary value is needed.
current: float
property
¶
Primary process-channel value (channels[0] if any, else 0.0).
Convenience accessor for the common case (e.g. gripper motor current).
Not bindable — bind to channels with a backward function for
reactive display.
waldoctl.ToolVariant(key: str, display_name: str, meshes: tuple[MeshSpec, ...] = (), motions: tuple[PartMotion, ...] = (), tcp_origin: tuple[float, float, float] | None = None, tcp_rpy: tuple[float, float, float] | None = None)
dataclass
¶
Named variant that replaces a tool's meshes and motions.
Each variant is self-contained — it provides a complete set of meshes and motions, so the scene swaps them wholesale without merge logic.
key: str
instance-attribute
¶
Unique identifier within the tool (e.g. "finger", "pinch").
display_name: str
instance-attribute
¶
Human-readable name for the UI dropdown.
meshes: tuple[MeshSpec, ...] = ()
class-attribute
instance-attribute
¶
Complete mesh set for this variant.
motions: tuple[PartMotion, ...] = ()
class-attribute
instance-attribute
¶
Complete motion descriptors for this variant.
tcp_origin: tuple[float, float, float] | None = None
class-attribute
instance-attribute
¶
(x, y, z) TCP translation in meters, or None to use tool default.
tcp_rpy: tuple[float, float, float] | None = None
class-attribute
instance-attribute
¶
(roll, pitch, yaw) TCP orientation in radians, or None to use tool default.
waldoctl.MeshSpec(file: str, origin: tuple[float, float, float] = (0.0, 0.0, 0.0), rpy: tuple[float, float, float] = (0.0, 0.0, 0.0), role: MeshRole = MeshRole.BODY)
dataclass
¶
Immutable descriptor for a single STL mesh in a tool assembly.
file: str
instance-attribute
¶
Filename of the STL mesh.
origin: tuple[float, float, float] = (0.0, 0.0, 0.0)
class-attribute
instance-attribute
¶
(x, y, z) offset in meters.
rpy: tuple[float, float, float] = (0.0, 0.0, 0.0)
class-attribute
instance-attribute
¶
(roll, pitch, yaw) orientation in radians.
role: MeshRole = MeshRole.BODY
class-attribute
instance-attribute
¶
Which mesh group this belongs to.
waldoctl.MeshRole
¶
Bases: Enum
Well-defined roles for tool mesh groups.
waldoctl.LinearMotion(role: MeshRole, axis: tuple[float, float, float], travel_m: float, symmetric: bool = True, estimated_speed_m_s: float | None = None, estimated_accel_m_s2: float | None = None)
dataclass
¶
Linear motion of tool parts (gripper jaws, press-fit rams).
role: MeshRole
instance-attribute
¶
Which mesh group moves.
axis: tuple[float, float, float]
instance-attribute
¶
Unit vector along which the motion occurs.
travel_m: float
instance-attribute
¶
Max displacement per side in meters.
symmetric: bool = True
class-attribute
instance-attribute
¶
If True, paired parts (left/right) move in opposite directions.
estimated_speed_m_s: float | None = None
class-attribute
instance-attribute
¶
Estimated travel speed in m/s (for binary-activation tools without position feedback).
estimated_accel_m_s2: float | None = None
class-attribute
instance-attribute
¶
Estimated acceleration in m/s² (for binary-activation tools).
waldoctl.RotaryMotion(role: MeshRole, axis: tuple[float, float, float], travel_rad: float, symmetric: bool = True, estimated_speed_rad_s: float | None = None, estimated_accel_rad_s2: float | None = None)
dataclass
¶
Rotary motion of tool parts (spindle bits, drill chucks).
role: MeshRole
instance-attribute
¶
Which mesh group moves.
axis: tuple[float, float, float]
instance-attribute
¶
Unit vector for the rotation axis.
travel_rad: float
instance-attribute
¶
Max rotation in radians.
symmetric: bool = True
class-attribute
instance-attribute
¶
If True, paired parts rotate in opposite directions.
estimated_speed_rad_s: float | None = None
class-attribute
instance-attribute
¶
Estimated angular speed in rad/s (for binary-activation tools).
estimated_accel_rad_s2: float | None = None
class-attribute
instance-attribute
¶
Estimated angular acceleration in rad/s² (for binary-activation tools).
waldoctl.ChannelDescriptor(name: str, unit: str, min: float = 0.0, max: float = 0.0)
dataclass
¶
Describes one process data channel reported by a tool.
The controller populates ToolStatus.channels positionally — index i
in the channels tuple corresponds to channel_descriptors[i].
name: str
instance-attribute
¶
Human-readable name (e.g. "Force", "Current").
unit: str
instance-attribute
¶
SI unit symbol (e.g. "N", "mA", "bar").
min: float = 0.0
class-attribute
instance-attribute
¶
Minimum expected value (0 = auto-scale).
max: float = 0.0
class-attribute
instance-attribute
¶
Maximum expected value (0 = auto-scale).