Skip to content

Commit

Permalink
Supervisor actions (#628)
Browse files Browse the repository at this point in the history
* Add device_emulator reconnect on lost connection

* HWP Supervisor Action system

* docs, misc changes

* Separate "gripper" and "driver" ibootbars

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Makes tcp reconnection optional

* Docs updates

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Addresses Brian's feedback

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
jlashner and pre-commit-ci[bot] authored Feb 20, 2024
1 parent 4a1c6a7 commit af4b872
Show file tree
Hide file tree
Showing 5 changed files with 463 additions and 170 deletions.
110 changes: 103 additions & 7 deletions docs/agents/hwp_supervisor_agent.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,113 @@ This agent has two main purposes:
- Serve as a host for high-level HWP operations that require coordinated control
of various HWP subsystems, such as "Begin rotating at 2 Hz"

Right now only the first point is implemented, but operations can be added here
as we need them.

HWP subsystems should implement a ``monitor_shutdown`` process that uses the
``get_op_data`` function to get the hwp-supervisor's session data, and check
the ``action`` field to determine if shutdown should be initiated.

For the first point, the supervisor agent implements the ``monitor`` process,
which monitors HWP-related processes to compile full state info for the HWP, and uses
that to make a determination if the HWP should be shutdown.

For high-level control, the HWP supervisor implements a state machine that
is used to perform complex operations with HWP agents that depend on the global
state of the HWP and related hardware.

Control States and Actions
`````````````````````````````
In the context of the HWP supervisor state machine, a *Control State* is a python
dataclass that contains data to dictate what the supervisor will do on each
update call. For example, while in the ``WaitForTargetFreq`` state, the
supervisor will do nothing until the HWP frequency is within tolerance of a
specified freq for a specified period of time, at which point it will transition
into the Done state.

A *Control Action* is a user-requested operation, in which a starting control
state is requested, that then transitions through any number of subsequent
states before completing. The action object contains its current state, state
history, completion status, and whether it considers itself successful. The
action is considered "complete" when it transitions into a "completion state",
which can be ``Done``, ``Error``, ``Abort``, or ``Idle``, at which point no more
state transitions will occur. In between update calls, a control action may be
aborted by the state-machine, where the action will transition into the
completed "Abort" state, and no further action will be taken.

OCS agent operations are generally one-to-one with control actions, where each
operation begins a new action, and sleeps until that action is complete.
If an operation is started while there is already an action is in progress, the
current action will be aborted at the next opportunity and replaced with the new
requested action. The ``abort_action`` task can be used to abort the current
action without beginning a new one.

Examples
```````````
Below is an example client script that runs the PID to freq operation, and waits
until the target freq has been reached.

.. code-block:: python
supervisor = OCSClient("hwp-supervisor")
result = supervisor.pid_to_freq(target_freq=2.0)
print(result.session['data']['action'])
>> {'action_id': 6,
'completed': True,
'cur_state': {'class': 'Done', 'msg': None, 'success': True},
'state_history': [{'class': 'PIDToFreq',
'direction': '0',
'freq_tol': 0.05,
'freq_tol_duration': 10.0,
'target_freq': 2.0},
{'class': 'WaitForTargetFreq',
'freq_tol': 0.05,
'freq_tol_duration': 10.0,
'freq_within_tol_start': 1706829677.7613404,
'target_freq': 2.0},
{'class': 'Done', 'msg': None, 'success': True}],
'success': True}
Below is an example of a client script that starts to PID the HWP to 2 Hz, then
aborts the PID action, and shuts off the PMX power supply. Note that the
``abort_action`` here is technically redundant, since starting the new action
would abort the active action in the same manner.

.. code-block:: python
supervisor = OCSClient("hwp-supervisor")
supervisor.pid_to_freq.start(target_freq=2.0)
supervisor.abort_action()
res1 = supervisor.pid_to_freq.wait()
res2 = supervisor.pmx_off()
print("Result 1:")
print(res1.session['data']['action'])
print("Result 2: ")
print(res2.session['data']['action'])
>>
Result 1:
{'action_id': 1,
'completed': True,
'cur_state': {'class': 'Abort'},
'state_history': [{'class': 'PIDToFreq',
'direction': '0',
'freq_tol': 0.05,
'freq_tol_duration': 10.0,
'target_freq': 2.0},
{'class': 'Abort'}],
'success': False}
Result 2:
{'action_id': 3,
'completed': True,
'cur_state': {'class': 'Done', 'msg': None, 'success': True},
'state_history': [{'class': 'PmxOff', 'success': True},
{'class': 'Done', 'msg': None, 'success': True}],
'success': True}
Agent API
-----------

.. autoclass:: socs.agents.hwp_supervisor.agent.ControlAction
:members:

.. autoclass:: socs.agents.hwp_supervisor.agent.HWPSupervisor
:members:

Expand Down
Loading

0 comments on commit af4b872

Please sign in to comment.