Work in progress: this documentation is still being written and reviewed. Check details against the source code.

Task orchestrator

Validate task scripts and coordinate tool setup, motion batches, child actions, cached replay, pause, and cancellation.

Only a goal containing one batch is eligible for trajectory replay. Pause and cancellation are checked at execution boundaries. Vacuum monitoring is disabled.

beambot.action_servers.orchestrator Β· Source

Task execution Β· Guide Β· Symbol index

How it is used

This is the main execution path for task JSON submitted through MTCExecution. Read _execute() first: it parses the document, starts the selected tool model, groups tasks, then dispatches batches or individual actions. _execute_batch() handles combined motion planning and eligible cached replay; _execute_step() routes other operations.

The class owns task state, pause/resume services, and child action clients. Clients submit goals and service requests; the underscore methods explain the execution flow and are not a separate client API. Cache identity uses expanded tasks and resolved pose values, not just the submitted JSON text.

Start here

Callable

Purpose

main

Run MTCOrchestratorServer using the shared multithreaded ROS runner.

MTCOrchestratorServer._execute

Run the task document from parsing through completion. Select the start tool, initialize MoveIt, group tasks, and dispatch with boundary pause/cancel checks. Eligible single-batch goals use expanded tasks, resolved poses, model revision, and start joints for cache identity. Dry runs plan/preview but still perform lifecycle startup.

MTCOrchestratorServer._execute_batch

Plan or replay one motion/gripper batch. Replay failure can trigger fresh planning, but REPLAY_TIMEOUT never starts a second trajectory. Fresh plans may be previewed and retained for caching.

MTCOrchestratorServer._execute_step

Dispatch a single task to motion, gripper, tool-exchange, vision, scan or pipettor handlers. Pause tasks are handled by the main loop before this method.

Functions

main()

Run MTCOrchestratorServer using the shared multithreaded ROS runner.

Entry point Β· Source

main(args=None)

Parameter

Meaning

args

Optional ROS initialization arguments.

Returns: None after server shutdown.

Errors: Runner construction/spin errors propagate except a handled KeyboardInterrupt or external shutdown.

Side effects: Initializes ROS, creates/spins the orchestrator and, on spin exit, destroys the node (which stops MoveIt) and shuts down the context.

MTCOrchestratorServer

Top-level ROS node for multi-step execution. It coordinates MoveIt lifecycle, tools, child actions, feedback, and cached plans. It uses its own admission and fault handling rather than inheriting BaseActionServer.

Inherits from: Node.

MTCOrchestratorServer._execute()

Run the task document from parsing through completion. Select the start tool, initialize MoveIt, group tasks, and dispatch with boundary pause/cancel checks. Eligible single-batch goals use expanded tasks, resolved poses, model revision, and start joints for cache identity. Dry runs plan/preview but still perform lifecycle startup.

Method Β· Source

_execute(self, goal_handle: ServerGoalHandle) -> MTCExecution.Result

Parameter

Meaning

goal_handle

MTCExecution handle carrying full_json and optional dry_run.

Returns: MTCExecution.Result with expanded total/completed counts, success/error and any retained detected pose.

Errors: Parser ValueError aborts cleanly. Handled launch/dispatch failures abort; TIMEOUT/REPLAY_TIMEOUT or cancellation during a failed unit can fault the server. Unexpected exceptions reach _execute_callback and fault it.

Side effects: Can change reported gripper, launch/configure hardware, plan/preview/execute tasks, cache serialized plans and publish feedback/state. Vacuum checks and bookkeeping are disabled; eligible end-effector actions may share a batch with motion.

Referenced in source (1)

MTCOrchestratorServer._execute_batch()

Plan or replay one motion/gripper batch. Replay failure can trigger fresh planning, but REPLAY_TIMEOUT never starts a second trajectory. Fresh plans may be previewed and retained for caching.

Method Β· Source

_execute_batch(
    self,
    batch_tasks: list[dict[str, Any]],
    poses_json: str,
    dry_run: bool = False,
    cached_plan = None,
) -> bool

Parameter

Meaning

batch_tasks

Ordered moveto/end_effector task dictionaries.

poses_json

Serialized named pose mapping.

dry_run

Plan and preview without executing fresh task motion when true.

cached_plan

Optional serialized MTC solution message itself, not a wrapper dictionary. The caller normally supplies it only for live execution.

Returns: True for empty input or successful replay/plan/execution; False with _last_error for handled failures.

Errors: Unknown batch types and helper errors return False; construction/JSON exceptions propagate. A supplied cached_plan is replayed before checking dry_run.

Side effects: Creates/plans/executes MTC tasks, may publish preview and set _last_planned_sol_msg; always closes the constructed MoveToStages TF listener in finally.

Referenced in source (1)

MTCOrchestratorServer._execute_step()

Dispatch a single task to motion, gripper, tool-exchange, vision, scan or pipettor handlers. Pause tasks are handled by the main loop before this method.

Method Β· Source

_execute_step(self, task_type: str, step: dict[str, Any], poses_json: str) -> bool

Parameter

Meaning

task_type

Task type string.

step

Task dictionary passed to its handler.

poses_json

Serialized named joint poses.

Returns: Delegated boolean success, or False for unknown types.

Errors: Unknown type sets _last_error; handler exceptions propagate.

Side effects: Logs and may execute child hardware actions or lifecycle changes.

Referenced in source (1)

MTCOrchestratorServer.__init__()

Create the task coordinator and its ROS endpoints. Load beamline/tool/pose settings, initialize pause, fault, and cache state, and construct lifecycle and tool-exchange managers. Vacuum monitoring is not instantiated.

Lifecycle Β· Source

__init__(self)

Errors: Missing required configuration keys, configuration resolution and ROS resource initialization errors propagate.

Side effects: Creates beambot_execution and seven child-action clients, tool exchange clients, pause/resume services and state/gripper publishers; publishes IDLE and unknown. Does not launch MoveIt until a goal executes.

MTCOrchestratorServer.destroy_node()

Stop the MoveIt launch session, then destroy the ROS node.

Lifecycle Β· Source

destroy_node(self)

Returns: None.

Errors: An error while stopping MoveIt propagates before the node’s ROS entities are destroyed.

Side effects: Calls kill_current_process(drain=False) while rclpy is still running, which clears the model revision and stops MoveIt’s process group. Skips the discovery drain because no launch follows. Then destroys the node’s publishers, services and action endpoints.

Used by: run_server() during shutdown.

Internal callbacks and helpers

MTCOrchestratorServer._goal_callback()

Reserve the orchestrator under a lock only when neither faulted nor executing. Script validation happens later.

Callback Β· Source

_goal_callback(self, goal_request) -> GoalResponse

Parameter

Meaning

goal_request

Incoming MTCExecution request; its contents are unused here.

Returns: ACCEPT after reservation, otherwise REJECT.

Errors: No payload validation or exception conversion.

Side effects: Sets _executing on acceptance; logs rejections.

Referenced in source (1)

MTCOrchestratorServer._cancel_callback()

Accept cancellation and announce CANCELING; the execution loop checks the request after the active batch or single action completes.

Callback Β· Source

_cancel_callback(self, goal_handle: ServerGoalHandle) -> CancelResponse

Parameter

Meaning

goal_handle

Goal handle; unused by this callback.

Returns: CancelResponse.ACCEPT.

Errors: Publication errors propagate.

Side effects: Publishes CANCELING and logs; does not directly stop a trajectory or cancel an active child.

Referenced in source (1)

MTCOrchestratorServer._pause_callback()

Under the execution lock, accept a new pause request only while executing and neither paused nor already pending.

Callback Β· Source

_pause_callback(self, request, response)

Parameter

Meaning

request

Trigger request; unused.

response

Response object to populate.

Returns: Same response, with success and a reason describing accepted or rejected pause.

Errors: No exception conversion.

Side effects: Sets _pause_requested, publishes COMPLETING_TASK and logs when accepted.

Referenced in source (1)

MTCOrchestratorServer._resume_callback()

Resume only an actively paused execution by clearing the paused flag and setting its event. A merely pending pause cannot be resumed here.

Callback Β· Source

_resume_callback(self, request, response)

Parameter

Meaning

request

Trigger request; unused.

response

Response object to populate.

Returns: Same response with success=True when resumed, otherwise Not currently paused.

Errors: No exception conversion.

Side effects: Changes _is_paused/_pause_event and logs; the waiting execution thread publishes RUNNING.

Referenced in source (1)

MTCOrchestratorServer._handle_pause()

Enter paused state, publish completed-step feedback and wait in 0.5 s intervals for resume or cancellation. Explicit pause tasks can identify the active uncompleted step separately.

Internal helper Β· Source

_handle_pause(
    self,
    feedback: MTCExecution.Feedback,
    goal_handle: ServerGoalHandle,
    completed_steps: int,
    total_steps: int,
    active_step: int | None = None,
)

Parameter

Meaning

feedback

Mutable execution feedback object.

goal_handle

Goal handle used for feedback and cancel checks.

completed_steps

Count of fully completed tasks.

total_steps

Total expanded task count; zero yields 0% progress.

active_step

Optional one-based explicit pause-task number.

Returns: None when resumed or a cancel request is observed.

Errors: Feedback/publication errors propagate.

Side effects: Clears pending pause, updates pause event/flags, publishes PAUSED and repeated feedback, then RUNNING on resume; cancellation exits without publishing RUNNING.

Referenced in source (1)

MTCOrchestratorServer._execute_callback()

Run the orchestration loop, permanently fault on an uncaught exception, then publish FAULTED or IDLE. Only a nonfaulted exit releases the executing reservation.

Callback Β· Source

_execute_callback(self, goal_handle: ServerGoalHandle)

Parameter

Meaning

goal_handle

Accepted MTCExecution handle.

Returns: Result returned by _execute.

Errors: Uncaught execution exceptions are re-raised after setting _faulted; no failed result is synthesized here.

Side effects: Updates fault/busy state and publishes final execution state.

Referenced in source (1)

MTCOrchestratorServer._create_moveto_goal()

Copy MoveTo selectors, convert travel/Cartesian values to floats, attach pose JSON and serialize optional constraints. Missing frame_id defaults to base_link.

Internal helper Β· Source

_create_moveto_goal(self, step: dict[str, Any], poses_json: str) -> MoveToAction.Goal

Parameter

Meaning

step

Task dictionary with target/planning_type/direction/distance/cartesian_target and optional frame/constraints.

poses_json

Resolved pose registry JSON.

Returns: MoveToAction.Goal; model revision is populated later by _send_and_wait for child actions.

Errors: Float conversion, malformed iterables, JSON serialization and message assignment errors propagate.

Side effects: Allocates a goal without planning or sending it.

Referenced in source (2)

MTCOrchestratorServer._create_endeffector_goal()

Select the explicit end_effector_type or current gripper, look up its SRDF group, and copy the requested end-effector state.

Internal helper Β· Source

_create_endeffector_goal(self, step: dict[str, Any]) -> EndEffectorAction.Goal

Parameter

Meaning

step

Task dictionary; unknown gripper types yield an empty group.

Returns: EndEffectorAction.Goal.

Errors: Malformed mapping/message values can raise; unknown gripper names are not rejected here.

Side effects: Allocates a goal. Empty group becomes a downstream no-op.

Referenced in source (2)

MTCOrchestratorServer._send_and_wait()

Reset the last error, attach the active model revision when the goal supports it, send the child goal and wait without spinning. Success follows result.success, not the action wrapper status.

Internal helper Β· Source

_send_and_wait(self, client: ActionClient, goal, name: str, timeout: float) -> bool

Parameter

Meaning

client

ActionClient for the operation.

goal

Mutable goal message.

name

Operation label used in logs/errors.

timeout

Result wait limit in seconds, excluding 5 s discovery and 10 s acceptance waits.

Returns: Child result.success on completion; False for missing revision, unavailable server, rejection, timeout or failed child result.

Errors: Acceptance/result timeouts set _faulted; result timeout requests cancellation without waiting for acknowledgement. Future/transport exceptions propagate. _last_result is replaced only after receiving a result, so earlier failures can leave it stale.

Side effects: Mutates goal revision and orchestrator error/result/fault fields, sends hardware actions and may request cancellation.

Referenced in source (8)

MTCOrchestratorServer._call_moveto()

Build a MoveTo goal and send it with the configured moveto result timeout.

Internal helper Β· Source

_call_moveto(self, step: dict[str, Any], poses_json: str) -> bool

Parameter

Meaning

step

Task dictionary consumed by _create_moveto_goal.

poses_json

Named pose JSON forwarded to the goal.

Returns: Boolean child success.

Errors: Builder/transport exceptions propagate; handled child failures update _last_error.

Side effects: Sends a motion action and may fault on timeout.

Referenced in source (1)

MTCOrchestratorServer._call_endeffector()

Build an SRDF gripper-state goal and send it with the configured end_effector timeout.

Internal helper Β· Source

_call_endeffector(self, step: dict[str, Any], poses_json: str) -> bool

Parameter

Meaning

step

Task dictionary consumed by _create_endeffector_goal.

poses_json

Accepted for dispatcher compatibility; unused.

Returns: Boolean child success.

Errors: Builder/transport exceptions propagate; handled child failures update _last_error.

Side effects: Sends a gripper action and may fault on timeout.

Referenced in source (1)

MTCOrchestratorServer._handle_tool_exchange()

Delegate exchange using the current gripper and configured timeout, copying a nonempty manager error on failure.

Internal helper Β· Source

_handle_tool_exchange(self, step: dict[str, Any], poses_json: str) -> bool

Parameter

Meaning

step

Validated tool-exchange task fields.

poses_json

Named pose JSON for approach motion.

Returns: Boolean exchange/synchronization success.

Errors: Manager exceptions propagate; last_error is copied only when supplied by the manager.

Side effects: May change voltage, move/dock/load tools, update current gripper, relaunch MoveIt and reset vision TF.

Referenced in source (1)

MTCOrchestratorServer._call_pipettor()

Build a pipettor goal, convert volume and optional RGB values to floats, force supplied color alpha to 1.0 and send with the configured timeout.

Internal helper Β· Source

_call_pipettor(self, step: dict[str, Any], poses_json: str) -> bool

Parameter

Meaning

step

Task with operation, optional volume_pct (default 0.0) and optional led_color RGB mapping.

poses_json

Pose JSON forwarded although the pipettor stage does not use it.

Returns: Boolean child success.

Errors: Numeric/shape/message/transport errors propagate; values are not range-checked here.

Side effects: Sends a pipettor/LED command and records child result/error.

Referenced in source (1)

MTCOrchestratorServer._call_vision_scan()

Resolve scan_positions names from pose JSON, convert each available pose’s degrees to radians, flatten and send a scan goal; missing names are skipped.

Internal helper Β· Source

_call_vision_scan(self, step: dict[str, Any], poses_json: str) -> bool

Parameter

Meaning

step

Task containing nonempty scan_positions plus scans_per_position (default 3) and timeout (default 10 s).

poses_json

Named joint-pose JSON in degrees.

Returns: False with an error if no names/no resolved positions; otherwise child scan success.

Errors: JSON/numeric errors propagate; pose lengths are not checked here and are checked by the scan server.

Side effects: Logs missing names and dispatches multi-position robot scanning that populates the scan server’s cache.

Referenced in source (1)

MTCOrchestratorServer._call_vision_task()

Route nonvision pick/place to legacy sample handlers; otherwise merge preset and explicit fields, map legacy detection_type unless detector is explicit, wait up to 10 s of requested settling, build/send a generic vision goal and retain returned position/orientation arrays.

Internal helper Β· Source

_call_vision_task(self, task_type: str, step: dict[str, Any], poses_json: str) -> bool

Parameter

Meaning

task_type

Canonical vision_task or recognized legacy/preset task type.

step

Task overrides; explicit fields take precedence over preset fields.

poses_json

Named pose JSON.

Returns: Boolean child success.

Errors: Conversion/build/transport errors propagate. Negative settle values skip the delay; no general finite-value validation is performed here.

Side effects: May sleep before sending, execute vision/motion and replace retained detected pose; vacuum bookkeeping is disabled.

Referenced in source (1)

MTCOrchestratorServer._build_vision_goal()

Translate merged task settings into a VisionTaskAction goal. Resolve target-pose precedence, tool states, retreat behavior, and degree-to-radian scan arrays. Group/state selection honors cfg.gripper; default vertical offset and IK frame use the current gripper.

Internal helper Β· Source

_build_vision_goal(self, cfg: dict[str, Any], poses_json: str)

Parameter

Meaning

cfg

Merged task/preset mapping with detector, goal-computer, target and execution settings.

poses_json

Named six-joint degree poses serialized as JSON.

Returns: VisionTaskAction.Goal with perception/geometry/execution fields.

Errors: Numeric conversion, JSON serialization/decoding and message assignment errors propagate; unknown grippers yield an empty group/state map.

Side effects: Allocates a goal, reads current gripper configuration, and logs skipped/multi-position scan names.

Referenced in source (1)

MTCOrchestratorServer._gripper_ik_frame()

Resolve the current gripper’s configured tip frame through the shared configuration helper.

Internal helper Β· Source

_gripper_ik_frame(self) -> str

Returns: Tip frame, falling back to flange on absent/unreadable configuration.

Errors: Configuration helper suppresses lookup failures.

Side effects: May initialize shared configuration cache.

Referenced in source (1)

MTCOrchestratorServer._gripper_z_offset()

Read the current gripper z_offset and convert it to float.

Internal helper Β· Source

_gripper_z_offset(self) -> float

Returns: Configured offset in metres, or 0.0 if the gripper/key is absent.

Errors: Malformed mapping or nonnumeric configured value raises.

Referenced in source (1)

MTCOrchestratorServer._call_pick_sample_hardcoded()

Build a legacy pick sample goal with use_vision=False, named approach/target poses and selected gripper states, then send it using the operation-specific timeout.

Internal helper Β· Source

_call_pick_sample_hardcoded(self, step: dict[str, Any], poses_json: str) -> bool

Parameter

Meaning

step

Task dictionary with optional gripper override, approach_pose, target_pose and constraints.

poses_json

Named joint-pose JSON in degrees.

Returns: Boolean child success.

Errors: JSON serialization, message assignment and transport errors propagate; unknown gripper gives an empty group/states.

Side effects: Executes named-pose sample pick through its child action; no vacuum bookkeeping is performed.

Referenced in source (1)

MTCOrchestratorServer._call_place_sample_hardcoded()

Build a legacy place sample goal with use_vision=False, named approach/target poses and selected gripper states, then send it using the operation-specific timeout.

Internal helper Β· Source

_call_place_sample_hardcoded(self, step: dict[str, Any], poses_json: str) -> bool

Parameter

Meaning

step

Task dictionary with optional gripper override, approach_pose, target_pose and constraints.

poses_json

Named joint-pose JSON in degrees.

Returns: Boolean child success.

Errors: JSON serialization, message assignment and transport errors propagate; unknown gripper gives an empty group/states.

Side effects: Executes named-pose sample place through its child action; no vacuum bookkeeping is performed.

Referenced in source (1)

MTCOrchestratorServer._publish_state()

Publish an execution-state string on the transient-local state publisher.

Internal helper Β· Source

_publish_state(self, state: str)

Parameter

Meaning

state

State text, such as IDLE, RUNNING, PAUSED, CANCELING or FAULTED.

Returns: None.

Errors: ROS message/publication errors propagate; state vocabulary is not validated here.

Side effects: Publishes beambot/execution_state.

Referenced in source (6)

MTCOrchestratorServer._publish_gripper()

Publish the supplied attached-gripper label on the transient-local gripper publisher.

Internal helper Β· Source

_publish_gripper(self, gripper: str)

Parameter

Meaning

gripper

Gripper name or initialization label such as unknown.

Returns: None.

Errors: ROS message/publication errors propagate.

Side effects: Publishes beambot/current_gripper without changing _current_gripper.

Referenced in source (2)

MTCOrchestratorServer._set_current_gripper()

Assign the active gripper and publish the new label immediately.

Internal helper Β· Source

_set_current_gripper(self, gripper: str)

Parameter

Meaning

gripper

New gripper label.

Returns: None.

Errors: Publication errors propagate after the local assignment.

Side effects: Mutates _current_gripper and publishes it; does not independently verify attachment.

Referenced in source (2)

MTCOrchestratorServer._update_feedback()

Populate action label, current gripper, status text and current_step/total_steps percentage, then publish the same feedback object.

Internal helper Β· Source

_update_feedback(
    self,
    feedback: MTCExecution.Feedback,
    goal_handle: ServerGoalHandle,
    current_step: int,
    total_steps: int,
    task_type: str,
)

Parameter

Meaning

feedback

Mutable MTCExecution.Feedback message.

goal_handle

Goal handle receiving feedback.

current_step

Reported step number; callers may use the active step rather than the completed count.

total_steps

Expanded task count; nonpositive totals yield 0% progress.

task_type

Action description; empty means Task completed.

Returns: None.

Errors: Publication/type errors propagate; step range is not clamped.

Side effects: Mutates feedback fields and publishes feedback.

Referenced in source (1)