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

Background Bluesky action device

Submit orchestrator tasks from Bluesky and process completion in a background ROS thread.

bluesky_ros.mtc_ophyd_device_async · Source

Clients and integrations · Guide · Symbol index

How it is used

Use MTCExecutionDeviceAsync.set() when the Bluesky plan should receive a status while ROS callbacks continue in a background thread. Initialize ROS first. The call can still wait up to ten seconds for server discovery before returning; it supports one current goal, not independent overlapping submissions.

The normal result callback completes the status and stops the thread. stop(success=False) requests cancellation while keeping result processing active. As in the blocking wrapper, canceled and aborted status labels are currently reversed, although both report failure.

Start here

Callable

Purpose

MTCExecutionDeviceAsync.set

Submit a task and start a background thread to process its result. Server discovery can block for ten seconds before the status is returned; prior background spinning is stopped first.

MTCExecutionDeviceAsync.stop

Request cancellation when success=False; leave the task running when success=True. Keep processing callbacks until the normal action result arrives.

MTCExecutionDeviceAsync.cancel_goal

Send an asynchronous cancel request for the retained handle and install a logging-only completion callback.

MTCExecutionDeviceAsync

A ROS node implementing the Bluesky movable interface with one background callback thread and one active execution status.

Inherits from: Node, Movable.

MTCExecutionDeviceAsync.set()

Submit a task and start a background thread to process its result. Server discovery can block for ten seconds before the status is returned; prior background spinning is stopped first.

Method · Source

set(self, json_path_or_string)

Parameter

Meaning

json_path_or_string

Task-file path ending in .json or JSON text accepted by the goal builder.

Returns: ActionStatus immediately after send/thread startup, or an already-failed status for server unavailability. It can block during prior-thread join, file read and discovery.

Errors: File/build/send errors propagate; server timeout becomes status exception. Does not explicitly cancel the previous goal or reset _goal_handle before replacing current status, so concurrent/repeated use is unsafe.

Side effects: May read a file, submit robot tasks, stop/start callback threads and log progress.

MTCExecutionDeviceAsync.stop()

Request cancellation when success=False; leave the task running when success=True. Keep processing callbacks until the normal action result arrives.

Method · Source

stop(self, *, success=False)

Parameter

Meaning

success

Keyword-only Boolean: False requests cancellation; True represents normal plan completion and leaves background execution active.

Returns: None; cancellation return value is ignored.

Errors: cancel_goal errors propagate.

Side effects: Logs and may send cancel request; does not shut down the node or thread directly.

MTCExecutionDeviceAsync.cancel_goal()

Send an asynchronous cancel request for the retained handle and install a logging-only completion callback.

Method · Source

cancel_goal(self)

Returns: False if no handle exists, otherwise True once the request is scheduled; does not mean cancellation was accepted.

Errors: Request creation errors propagate; completion errors are handled by cancel_done. A completed/stale retained handle is still eligible.

Side effects: Requests ROS action cancellation; relies on ongoing ROS spinning and does not itself update the status.

Referenced in source (1)

MTCExecutionDeviceAsync.__init__()

Initialize a ROS node with Bluesky name/parent attributes, resolve the MTCExecution action type and create a beambot_execution client plus background-spin state and lock.

Lifecycle · Source

__init__(self, name='mtc_executor', **kwargs)

Parameter

Meaning

name

ROS node name and Bluesky device name.

kwargs

Additional Node constructor keyword arguments, not Ophyd device arguments.

Returns: None; active goal/status/futures start None.

Errors: ROS/type-resolution/client setup errors propagate; does not call rclpy.init().

Side effects: Creates ROS node/client and an in-memory thread lock.

MTCExecutionDeviceAsync.construct_goal_message()

Populate full_json from a file only when the input is a string ending exactly in .json; otherwise assign the input directly as JSON text.

Method · Source

construct_goal_message(self, json_path_or_string)

Parameter

Meaning

json_path_or_string

String file path with .json suffix or raw JSON string. Path objects are not recognized as paths; no JSON syntax/schema check occurs.

Returns: MTCExecution.Goal with full_json populated.

Errors: File errors and ROS message type-assignment errors propagate.

Side effects: May read a task file; does not submit it.

Referenced in source (1)

MTCExecutionDeviceAsync.__del__()

Invoke the spin-stop helper when the object is finalized.

Lifecycle · Source

__del__(self)

Returns: None.

Errors: No guard for partially initialized attributes or interpreter teardown; finalizer exceptions may be reported by Python.

Side effects: May stop/join callback thread; does not explicitly cancel goals, destroy node or shut down ROS.

Internal callbacks and helpers

MTCExecutionDeviceAsync._spin_in_background()

Process ROS callbacks while _spinning is true, stopping once the current status is done or spin_once raises, then clear spin-thread bookkeeping under the lock.

Internal helper · Source

_spin_in_background(self)

Returns: None after the loop exits.

Errors: spin_once Exceptions log and end the thread but do not explicitly fail the status, potentially leaving a pending status.

Side effects: Runs ROS callbacks in a daemon thread and resets _spinning/_spin_thread.

Referenced in source (1)

MTCExecutionDeviceAsync._stop_spinning()

Set the stop flag, wait up to one second for another live spin thread, then clear its reference; avoid joining from that same thread.

Internal helper · Source

_stop_spinning(self)

Returns: None.

Errors: No exception catch. Join holds _spin_lock, which the worker also needs for final cleanup; timeout can expire before the thread exits.

Side effects: Changes thread bookkeeping and may block one second; does not cancel a goal or destroy ROS resources.

Referenced in source (4)

MTCExecutionDeviceAsync._feedback_callback()

Log the current step/action, one-decimal progress percentage and status message from MTC feedback.

Callback · Source

_feedback_callback(self, feedback_msg)

Parameter

Meaning

feedback_msg

MTCExecution feedback wrapper with feedback.current_step/current_action/progress_percentage/status_message.

Returns: None.

Errors: Malformed feedback/logging errors propagate.

Side effects: Writes an INFO ROS log.

Referenced in source (1)

MTCExecutionDeviceAsync._goal_response_callback()

Handle send-future exceptions/rejection by failing status and stopping spinning; otherwise retain the goal and attach the result callback.

Callback · Source

_goal_response_callback(self, future)

Parameter

Meaning

future

Completed asynchronous send-goal future.

Returns: None.

Errors: Catches future.result Exceptions; malformed/None handles and failures after result retrieval can still propagate.

Side effects: Mutates goal/status/future state, logs and may stop the callback thread or invoke failure cancellation.

Referenced in source (1)

MTCExecutionDeviceAsync._result_callback()

Translate raw status 4 into success, 5 into a Task aborted exception with server detail, 6 into Task canceled, and other statuses into an Unknown status exception; then stop spinning.

Callback · Source

_result_callback(self, future)

Parameter

Meaning

future

Completed action result future with status and result payload.

Returns: None; updates the current Ophyd status if one exists.

Errors: Catches future.result Exceptions and fails status; subsequent malformed payload/status errors may propagate. Numeric 5/6 labels are reversed relative to ROS 2 standard statuses.

Side effects: Logs outcome, changes Ophyd status and stops spinning; failure hooks can request cancellation, while the goal handle remains retained.

Referenced in source (1)

MTCExecutionDeviceAsync.cancel_goal.cancel_done()

Log whether the cancel response contains any goals_canceling entries.

Callback · Source

cancel_done(future)

Parameter

Meaning

future

Completed cancellation future.

Returns: None.

Errors: Catches any response/access Exception and logs it.

Side effects: Writes logs only; does not change device status or restart spinning.

Referenced in source (1)

ActionStatus

Track an execution result for Ophyd and request cancellation through the device when the status fails.

Inherits from: DeviceStatus.

ActionStatus.__init__()

Initialize an Ophyd DeviceStatus tied to the ROS action device.

Lifecycle · Source

__init__(self, device, **kwargs)

Parameter

Meaning

device

Device whose cancel_goal() is called by the failure hook.

kwargs

Keyword arguments forwarded to DeviceStatus, such as timeout/settle-time options supported by installed Ophyd.

Errors: Base DeviceStatus validation/construction errors propagate.

Side effects: Creates status bookkeeping; no ROS goal is sent.

Referenced in source (1)

ActionStatus._handle_failure()

Log a debug message and request cancellation through the attached device when Ophyd marks the status failed.

Extension hook · Source

_handle_failure(self)

Returns: None; cancel_goal return value is discarded.

Errors: Cancellation errors propagate; no local catch.

Side effects: May send ROS action cancellation asynchronously.