From ead4491c7d8f4bcb528cfdca4552b52ad2fa6f68 Mon Sep 17 00:00:00 2001 From: Alise Au <20424172+ahiuchingau@users.noreply.github.com> Date: Thu, 21 Nov 2024 12:20:16 -0500 Subject: [PATCH] feat(hardware-testing): stacker estop and door switch qc scripts (#16924) --- .../modules/flex_stacker_evt_qc/config.py | 20 ++++ .../modules/flex_stacker_evt_qc/driver.py | 14 +++ .../flex_stacker_evt_qc/test_door_switch.py | 36 ++++++++ .../modules/flex_stacker_evt_qc/test_estop.py | 91 +++++++++++++++++++ 4 files changed, 161 insertions(+) create mode 100644 hardware-testing/hardware_testing/modules/flex_stacker_evt_qc/test_door_switch.py create mode 100644 hardware-testing/hardware_testing/modules/flex_stacker_evt_qc/test_estop.py diff --git a/hardware-testing/hardware_testing/modules/flex_stacker_evt_qc/config.py b/hardware-testing/hardware_testing/modules/flex_stacker_evt_qc/config.py index a8fc32ca142..5b94e014f0f 100644 --- a/hardware-testing/hardware_testing/modules/flex_stacker_evt_qc/config.py +++ b/hardware-testing/hardware_testing/modules/flex_stacker_evt_qc/config.py @@ -10,6 +10,8 @@ test_z_axis, test_x_axis, test_l_axis, + test_door_switch, + test_estop, ) @@ -20,6 +22,8 @@ class TestSection(enum.Enum): Z_AXIS = "Z_AXIS" L_AXIS = "L_AXIS" X_AXIS = "X_AXIS" + DOOR_SWITCH = "DOOR_SWITCH" + ESTOP = "ESTOP" @dataclass @@ -47,6 +51,14 @@ class TestConfig: TestSection.X_AXIS, test_x_axis.run, ), + ( + TestSection.DOOR_SWITCH, + test_door_switch.run, + ), + ( + TestSection.ESTOP, + test_estop.run, + ), ] @@ -71,5 +83,13 @@ def build_report(test_name: str) -> CSVReport: title=TestSection.X_AXIS.value, lines=test_x_axis.build_csv_lines(), ), + CSVSection( + title=TestSection.DOOR_SWITCH.value, + lines=test_door_switch.build_csv_lines(), + ), + CSVSection( + title=TestSection.ESTOP.value, + lines=test_estop.build_csv_lines(), + ), ], ) diff --git a/hardware-testing/hardware_testing/modules/flex_stacker_evt_qc/driver.py b/hardware-testing/hardware_testing/modules/flex_stacker_evt_qc/driver.py index 3005405e61b..e219b68dae3 100644 --- a/hardware-testing/hardware_testing/modules/flex_stacker_evt_qc/driver.py +++ b/hardware-testing/hardware_testing/modules/flex_stacker_evt_qc/driver.py @@ -176,6 +176,20 @@ def get_hopper_door_closed(self) -> bool: assert match, f"Incorrect Response for hopper door switch: {res}" return bool(int(match.group(1))) + def get_estop(self) -> bool: + """Get E-Stop status. + + :return: True if E-Stop is triggered, False otherwise + """ + if self._simulating: + return True + + _LS_RE = re.compile(r"^M112 (\d) OK\n") + res = self._send_and_recv("M112\n", "M112 ") + match = _LS_RE.match(res) + assert match, f"Incorrect Response for E-Stop switch: {res}" + return bool(int(match.group(1))) + def move_in_mm( self, axis: StackerAxis, distance: float, params: MoveParams | None = None ) -> None: diff --git a/hardware-testing/hardware_testing/modules/flex_stacker_evt_qc/test_door_switch.py b/hardware-testing/hardware_testing/modules/flex_stacker_evt_qc/test_door_switch.py new file mode 100644 index 00000000000..ab104a10d01 --- /dev/null +++ b/hardware-testing/hardware_testing/modules/flex_stacker_evt_qc/test_door_switch.py @@ -0,0 +1,36 @@ +"""Test Door Switch.""" + + +from typing import List, Union +from hardware_testing.data import ui +from hardware_testing.data.csv_report import ( + CSVReport, + CSVLine, + CSVLineRepeating, + CSVResult, +) + +from .driver import FlexStacker + + +def build_csv_lines() -> List[Union[CSVLine, CSVLineRepeating]]: + """Build CSV Lines.""" + return [ + CSVLine("close-door", [CSVResult]), + CSVLine("open-door", [CSVResult]), + ] + + +def run(driver: FlexStacker, report: CSVReport, section: str) -> None: + """Run.""" + ui.print_header("Close Door") + if not driver._simulating: + ui.get_user_ready("Close the hopper door") + closed = driver.get_hopper_door_closed() + report(section, "close-door", [CSVResult.from_bool(closed)]) + + ui.print_header("Open Door") + if not driver._simulating: + ui.get_user_ready("Open the hopper door") + closed = driver.get_hopper_door_closed() + report(section, "open-door", [CSVResult.from_bool(not closed)]) diff --git a/hardware-testing/hardware_testing/modules/flex_stacker_evt_qc/test_estop.py b/hardware-testing/hardware_testing/modules/flex_stacker_evt_qc/test_estop.py new file mode 100644 index 00000000000..c0ee8b4150b --- /dev/null +++ b/hardware-testing/hardware_testing/modules/flex_stacker_evt_qc/test_estop.py @@ -0,0 +1,91 @@ +"""Test E-Stop.""" + + +from typing import List, Union +from hardware_testing.data import ui +from hardware_testing.data.csv_report import ( + CSVReport, + CSVLine, + CSVLineRepeating, + CSVResult, +) + +from .driver import FlexStacker, Direction, StackerAxis + + +def build_csv_lines() -> List[Union[CSVLine, CSVLineRepeating]]: + """Build CSV Lines.""" + return [ + CSVLine("trigger-estop", [CSVResult]), + CSVLine("x-move-disabled", [CSVResult]), + CSVLine("z-move-disabled", [CSVResult]), + CSVLine("l-move-disabled", [CSVResult]), + CSVLine("untrigger-estop", [CSVResult]), + ] + + +def axis_at_limit(driver: FlexStacker, axis: StackerAxis) -> Direction: + """Check which direction an axis is at the limit switch.""" + if axis is StackerAxis.L: + # L axis only has one limit switch + if driver.get_limit_switch(axis, Direction.RETRACT): + print(axis, "is at ", Direction.RETRACT, "limit switch") + return Direction.RETRACT + else: + for dir in Direction: + if driver.get_limit_switch(axis, dir): + print(axis, "is at ", dir, "limit switch") + return dir + raise RuntimeError(f"{axis} is not at any limit switch") + + +def run(driver: FlexStacker, report: CSVReport, section: str) -> None: + """Run.""" + if not driver._simulating and driver.get_estop(): + raise RuntimeError("E-Stop is either triggered/not attached.") + + x_limit = axis_at_limit(driver, StackerAxis.X) + z_limit = axis_at_limit(driver, StackerAxis.Z) + l_limit = axis_at_limit(driver, StackerAxis.L) + + ui.print_header("Trigger E-Stop") + if not driver._simulating: + ui.get_user_ready("Trigger the E-Stop") + + if not driver.get_estop(): + print("E-Stop is not triggered") + report(section, "trigger-estop", [CSVResult.FAIL]) + return + + report(section, "trigger-estop", [CSVResult.PASS]) + + print("try to move X axis...") + driver.move_in_mm(StackerAxis.X, x_limit.opposite().distance(10)) + print("X should not move") + report( + section, + "x-move-disabled", + [CSVResult.from_bool(driver.get_limit_switch(StackerAxis.X, x_limit))], + ) + + print("try to move Z axis...") + driver.move_in_mm(StackerAxis.Z, z_limit.opposite().distance(10)) + print("Z should not move") + report( + section, + "z-move-disabled", + [CSVResult.from_bool(driver.get_limit_switch(StackerAxis.Z, z_limit))], + ) + + print("try to move L axis...") + driver.move_in_mm(StackerAxis.L, l_limit.opposite().distance(10)) + print("L should not move") + report( + section, + "l-move-disabled", + [CSVResult.from_bool(driver.get_limit_switch(StackerAxis.L, l_limit))], + ) + + if not driver._simulating: + ui.get_user_ready("Untrigger the E-Stop") + report(section, "untrigger-estop", [CSVResult.from_bool(not driver.get_estop())])