Skip to content

Commit

Permalink
Implement dome parking / DM-45609
Browse files Browse the repository at this point in the history
- Add the `park_dome` method in `MTCS` to park the dome. This includes:
  - Ensuring the dome is enabled before initiating the park sequence.
  - Commanding the dome to park and waiting for the dome's azimuth
    motion state to reach `PARKED`.
  - Added a polling mechanism to periodically check the dome's
    `azMotion` event until it reaches the `PARKED` state or a timeout
    occurs.
  - Raised an error if the dome fails to park within the timeout
    window.

- Updated the `MTCSAsyncMock` class to simulate dome parking behavior:
  - Mocked the `evt_azMotion` event to simulate the dome reaching the
    `PARKED` state with `inPosition=True`.
  - Added mocking for the `cmd_park` command to simulate a dome park
    action.

- Added a new unit test `test_park_dome`
  - Asserted that the `evt_azMotion` event is awaited and reaches
    the `PARKED` state with `inPosition=True`.
  • Loading branch information
iglesu committed Sep 5, 2024
1 parent a43ac20 commit 2f8d0dd
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 3 deletions.
53 changes: 50 additions & 3 deletions python/lsst/ts/observatory/control/maintel/mtcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@
import numpy as np
from astropy.coordinates import Angle
from lsst.ts import salobj, utils
from lsst.ts.idl.enums import MTM1M3, MTM2, MTPtg, MTRotator
from lsst.ts.utils import angle_diff
from lsst.ts.xml.enums import MTM1M3, MTM2, MTPtg, MTRotator
from lsst.ts.xml.enums.MTDome import MotionState

try:
from lsst.ts.xml.tables.m1m3 import FATable
Expand Down Expand Up @@ -508,9 +509,9 @@ async def wait_for_dome_inposition(
Parameters
----------
timeout: `float`
How to to wait for mount to be in position (in seconds).
How to wait for mount to be in position (in seconds).
wait_settle: `bool`
After receiving the in position command add an addional settle
After receiving the in position command, add an additional settle
wait? (default: True)
Returns
Expand Down Expand Up @@ -579,6 +580,52 @@ async def dome_el_in_position(self) -> str:
await self._dome_el_in_position.wait()
return "Dome elevation in position."

async def wait_for_dome_ready(self) -> None:
"""Wait for the dome to be in a state where it can be moved."""
dome_state = await self.rem.mtdome.evt_summaryState.aget(
timeout=self.fast_timeout
)
if dome_state.summaryState != salobj.State.ENABLED:
raise RuntimeError("Dome is not enabled. Cannot move.")

self.log.info("Dome is ready for movement.")

async def park_dome(self) -> None:
"""Park the dome by moving it to the park azimuth."""
self.log.info(f"Parking dome at azimuth {self.dome_park_az}.")

# Ensure the dome is ready for a move
await self.wait_for_dome_ready()

# Move the dome to the park position
await self.rem.mtdome.cmd_park.set_start(timeout=self.long_timeout)

# Wait for the dome to emit the evt_azMotion event in the PARKED state
self.log.info("Waiting for dome to reach the PARKED status.")

# Define the polling interval (in seconds)
polling_interval = 1.0

# Loop to check the dome's motion state periodically until timeout
timeout_time = self.long_long_timeout
start_time = asyncio.get_event_loop().time()

while asyncio.get_event_loop().time() - start_time < timeout_time:
az_motion = await self.rem.mtdome.evt_azMotion.aget(
timeout=polling_interval
)

# Check if the dome is in the PARKED state and in position
if az_motion.state == MotionState.PARKED and az_motion.inPosition:
self.log.info("Dome parked successfully.")
return
await asyncio.sleep(polling_interval)

# If we exit the loop without success, raise an error
raise RuntimeError(
"Dome did not reach the park azimuth within the timeout period."
)

def set_azel_slew_checks(self, wait_dome: bool) -> typing.Any:
"""Handle azEl slew to wait or not for the dome.
Expand Down
26 changes: 26 additions & 0 deletions python/lsst/ts/observatory/control/mock/mtcs_async_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from lsst.ts.idl.enums import MTM1M3
from lsst.ts.observatory.control.maintel.mtcs import MTCS, MTCSUsages
from lsst.ts.observatory.control.mock import RemoteGroupAsyncMock
from lsst.ts.xml.enums import MTDome


class MTCSAsyncMock(RemoteGroupAsyncMock):
Expand Down Expand Up @@ -119,6 +120,11 @@ async def setup_types(self) -> None:
positionCommanded=0.0,
)

# MTDome Motion PARKED state
self._mtdome_evt_azMotion_state = types.SimpleNamespace(
state=MTDome.MotionState.ENABLED, inPosition=False
)

# MTM1M3 data
self._mtm1m3_evt_detailed_state = types.SimpleNamespace(
detailedState=idl.enums.MTM1M3.DetailedState.PARKED
Expand Down Expand Up @@ -229,6 +235,8 @@ async def setup_mtdome(self) -> None:
mtdome_mocks = {
"tel_azimuth.next.side_effect": self.mtdome_tel_azimuth_next,
"tel_lightWindScreen.next.side_effect": self.mtdome_tel_light_wind_screen_next,
"cmd_park.set_start.side_effect": self.mtdome_cmd_park,
"evt_azMotion.aget.side_effect": self.mtdome_evt_az_motion_state_next,
}

self.mtcs.rem.mtdome.configure_mock(**mtdome_mocks)
Expand Down Expand Up @@ -461,6 +469,24 @@ async def mtdome_tel_light_wind_screen_next(
) -> types.SimpleNamespace:
return self._mtdome_tel_light_wind_screen

async def mtdome_cmd_park(self, *args: typing.Any, **kwargs: typing.Any) -> None:
asyncio.create_task(self._mtdome_park())

async def _mtdome_park(self, *args: typing.Any, **kwargs: typing.Any) -> None:
# Mock implementation of cmd_park
await asyncio.sleep(self.heartbeat_time)
self.log.info("Dome park command executed")
self._mtdome_evt_azMotion_state = types.SimpleNamespace(
state=MTDome.MotionState.PARKED, inPosition=True
)

async def mtdome_evt_az_motion_state_next(
self, *args: typing.Any, **kwargs: typing.Any
) -> types.SimpleNamespace:
"""Mock evt_azMotion to simulate dome reaching PARKED state."""
await asyncio.sleep(self.heartbeat_time)
return self._mtdome_evt_azMotion_state

async def mtm1m3_evt_detailed_state(
self, *args: typing.Any, **kwargs: typing.Any
) -> types.SimpleNamespace:
Expand Down
16 changes: 16 additions & 0 deletions tests/maintel/test_mtcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from lsst.ts.idl.enums import MTM1M3, MTM2
from lsst.ts.observatory.control.mock.mtcs_async_mock import MTCSAsyncMock
from lsst.ts.observatory.control.utils import RotType
from lsst.ts.xml.enums import MTDome


class TestMTCS(MTCSAsyncMock):
Expand Down Expand Up @@ -764,6 +765,21 @@ async def test_offset_xy_absorb(self) -> None:
num=0,
)

async def test_park_dome(self) -> None:
await self.mtcs.enable()
await self.mtcs.assert_all_enabled()

# Call the park_dome method
await self.mtcs.park_dome()

az_motion = await self.mtcs.rem.mtdome.evt_azMotion.aget()

# Check the state of the azMotion event
assert (
az_motion.state == MTDome.MotionState.PARKED
), "Dome did not reach the PARKED state."
assert az_motion.inPosition, "Dome is not in position."

async def test_slew_dome_to(self) -> None:
az = 90.0

Expand Down

0 comments on commit 2f8d0dd

Please sign in to comment.