opentrons 8.3.2__py2.py3-none-any.whl → 8.4.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of opentrons might be problematic. Click here for more details.
- opentrons/calibration_storage/ot2/mark_bad_calibration.py +2 -0
- opentrons/calibration_storage/ot2/tip_length.py +6 -6
- opentrons/config/advanced_settings.py +9 -11
- opentrons/config/feature_flags.py +0 -4
- opentrons/config/reset.py +7 -2
- opentrons/drivers/asyncio/communication/__init__.py +2 -0
- opentrons/drivers/asyncio/communication/async_serial.py +4 -0
- opentrons/drivers/asyncio/communication/errors.py +41 -8
- opentrons/drivers/asyncio/communication/serial_connection.py +36 -10
- opentrons/drivers/flex_stacker/__init__.py +9 -3
- opentrons/drivers/flex_stacker/abstract.py +140 -15
- opentrons/drivers/flex_stacker/driver.py +593 -47
- opentrons/drivers/flex_stacker/errors.py +64 -0
- opentrons/drivers/flex_stacker/simulator.py +222 -24
- opentrons/drivers/flex_stacker/types.py +211 -15
- opentrons/drivers/flex_stacker/utils.py +19 -0
- opentrons/execute.py +4 -2
- opentrons/hardware_control/api.py +5 -0
- opentrons/hardware_control/backends/flex_protocol.py +4 -0
- opentrons/hardware_control/backends/ot3controller.py +12 -1
- opentrons/hardware_control/backends/ot3simulator.py +3 -0
- opentrons/hardware_control/backends/subsystem_manager.py +8 -4
- opentrons/hardware_control/instruments/ot2/instrument_calibration.py +10 -6
- opentrons/hardware_control/instruments/ot3/pipette_handler.py +59 -6
- opentrons/hardware_control/modules/__init__.py +12 -1
- opentrons/hardware_control/modules/absorbance_reader.py +11 -9
- opentrons/hardware_control/modules/flex_stacker.py +498 -0
- opentrons/hardware_control/modules/heater_shaker.py +12 -10
- opentrons/hardware_control/modules/magdeck.py +5 -1
- opentrons/hardware_control/modules/tempdeck.py +5 -1
- opentrons/hardware_control/modules/thermocycler.py +15 -14
- opentrons/hardware_control/modules/types.py +191 -1
- opentrons/hardware_control/modules/utils.py +3 -0
- opentrons/hardware_control/motion_utilities.py +20 -0
- opentrons/hardware_control/ot3api.py +145 -15
- opentrons/hardware_control/protocols/liquid_handler.py +47 -1
- opentrons/hardware_control/types.py +6 -0
- opentrons/legacy_commands/commands.py +102 -5
- opentrons/legacy_commands/helpers.py +74 -1
- opentrons/legacy_commands/types.py +33 -2
- opentrons/protocol_api/__init__.py +2 -0
- opentrons/protocol_api/_liquid.py +39 -8
- opentrons/protocol_api/_liquid_properties.py +20 -19
- opentrons/protocol_api/_transfer_liquid_validation.py +91 -0
- opentrons/protocol_api/core/common.py +3 -1
- opentrons/protocol_api/core/engine/deck_conflict.py +11 -1
- opentrons/protocol_api/core/engine/instrument.py +1356 -107
- opentrons/protocol_api/core/engine/labware.py +8 -4
- opentrons/protocol_api/core/engine/load_labware_params.py +68 -10
- opentrons/protocol_api/core/engine/module_core.py +118 -2
- opentrons/protocol_api/core/engine/pipette_movement_conflict.py +6 -14
- opentrons/protocol_api/core/engine/protocol.py +253 -11
- opentrons/protocol_api/core/engine/stringify.py +19 -8
- opentrons/protocol_api/core/engine/transfer_components_executor.py +858 -0
- opentrons/protocol_api/core/engine/well.py +73 -5
- opentrons/protocol_api/core/instrument.py +71 -21
- opentrons/protocol_api/core/labware.py +6 -2
- opentrons/protocol_api/core/legacy/labware_offset_provider.py +7 -3
- opentrons/protocol_api/core/legacy/legacy_instrument_core.py +76 -49
- opentrons/protocol_api/core/legacy/legacy_labware_core.py +8 -4
- opentrons/protocol_api/core/legacy/legacy_protocol_core.py +36 -0
- opentrons/protocol_api/core/legacy/legacy_well_core.py +27 -2
- opentrons/protocol_api/core/legacy/load_info.py +4 -12
- opentrons/protocol_api/core/legacy/module_geometry.py +6 -1
- opentrons/protocol_api/core/legacy/well_geometry.py +3 -3
- opentrons/protocol_api/core/legacy_simulator/legacy_instrument_core.py +73 -23
- opentrons/protocol_api/core/module.py +43 -0
- opentrons/protocol_api/core/protocol.py +33 -0
- opentrons/protocol_api/core/well.py +23 -2
- opentrons/protocol_api/instrument_context.py +454 -150
- opentrons/protocol_api/labware.py +98 -50
- opentrons/protocol_api/module_contexts.py +140 -0
- opentrons/protocol_api/protocol_context.py +163 -19
- opentrons/protocol_api/validation.py +51 -41
- opentrons/protocol_engine/__init__.py +21 -2
- opentrons/protocol_engine/actions/actions.py +5 -5
- opentrons/protocol_engine/clients/sync_client.py +6 -0
- opentrons/protocol_engine/commands/__init__.py +66 -36
- opentrons/protocol_engine/commands/absorbance_reader/__init__.py +0 -1
- opentrons/protocol_engine/commands/air_gap_in_place.py +3 -2
- opentrons/protocol_engine/commands/aspirate.py +6 -2
- opentrons/protocol_engine/commands/aspirate_in_place.py +3 -1
- opentrons/protocol_engine/commands/aspirate_while_tracking.py +210 -0
- opentrons/protocol_engine/commands/blow_out.py +2 -0
- opentrons/protocol_engine/commands/blow_out_in_place.py +4 -1
- opentrons/protocol_engine/commands/command_unions.py +102 -33
- opentrons/protocol_engine/commands/configure_for_volume.py +3 -0
- opentrons/protocol_engine/commands/dispense.py +3 -1
- opentrons/protocol_engine/commands/dispense_in_place.py +3 -0
- opentrons/protocol_engine/commands/dispense_while_tracking.py +204 -0
- opentrons/protocol_engine/commands/drop_tip.py +23 -1
- opentrons/protocol_engine/commands/flex_stacker/__init__.py +106 -0
- opentrons/protocol_engine/commands/flex_stacker/close_latch.py +72 -0
- opentrons/protocol_engine/commands/flex_stacker/common.py +15 -0
- opentrons/protocol_engine/commands/flex_stacker/empty.py +161 -0
- opentrons/protocol_engine/commands/flex_stacker/fill.py +164 -0
- opentrons/protocol_engine/commands/flex_stacker/open_latch.py +70 -0
- opentrons/protocol_engine/commands/flex_stacker/prepare_shuttle.py +112 -0
- opentrons/protocol_engine/commands/flex_stacker/retrieve.py +394 -0
- opentrons/protocol_engine/commands/flex_stacker/set_stored_labware.py +190 -0
- opentrons/protocol_engine/commands/flex_stacker/store.py +291 -0
- opentrons/protocol_engine/commands/generate_command_schema.py +31 -2
- opentrons/protocol_engine/commands/labware_handling_common.py +29 -0
- opentrons/protocol_engine/commands/liquid_probe.py +27 -13
- opentrons/protocol_engine/commands/load_labware.py +42 -39
- opentrons/protocol_engine/commands/load_lid.py +21 -13
- opentrons/protocol_engine/commands/load_lid_stack.py +130 -47
- opentrons/protocol_engine/commands/load_module.py +18 -17
- opentrons/protocol_engine/commands/load_pipette.py +3 -0
- opentrons/protocol_engine/commands/move_labware.py +139 -20
- opentrons/protocol_engine/commands/move_to_well.py +5 -11
- opentrons/protocol_engine/commands/pick_up_tip.py +5 -2
- opentrons/protocol_engine/commands/pipetting_common.py +159 -8
- opentrons/protocol_engine/commands/prepare_to_aspirate.py +15 -5
- opentrons/protocol_engine/commands/{evotip_dispense.py → pressure_dispense.py} +33 -34
- opentrons/protocol_engine/commands/reload_labware.py +6 -19
- opentrons/protocol_engine/commands/{evotip_seal_pipette.py → seal_pipette_to_tip.py} +97 -76
- opentrons/protocol_engine/commands/unsafe/unsafe_blow_out_in_place.py +3 -1
- opentrons/protocol_engine/commands/unsafe/unsafe_drop_tip_in_place.py +6 -1
- opentrons/protocol_engine/commands/{evotip_unseal_pipette.py → unseal_pipette_from_tip.py} +31 -40
- opentrons/protocol_engine/errors/__init__.py +10 -0
- opentrons/protocol_engine/errors/exceptions.py +62 -0
- opentrons/protocol_engine/execution/equipment.py +123 -106
- opentrons/protocol_engine/execution/labware_movement.py +8 -6
- opentrons/protocol_engine/execution/pipetting.py +235 -25
- opentrons/protocol_engine/execution/tip_handler.py +82 -32
- opentrons/protocol_engine/labware_offset_standardization.py +194 -0
- opentrons/protocol_engine/protocol_engine.py +22 -13
- opentrons/protocol_engine/resources/deck_configuration_provider.py +98 -2
- opentrons/protocol_engine/resources/deck_data_provider.py +1 -1
- opentrons/protocol_engine/resources/labware_data_provider.py +32 -12
- opentrons/protocol_engine/resources/labware_validation.py +7 -5
- opentrons/protocol_engine/slot_standardization.py +11 -23
- opentrons/protocol_engine/state/addressable_areas.py +84 -46
- opentrons/protocol_engine/state/frustum_helpers.py +36 -14
- opentrons/protocol_engine/state/geometry.py +892 -227
- opentrons/protocol_engine/state/labware.py +252 -55
- opentrons/protocol_engine/state/module_substates/__init__.py +4 -0
- opentrons/protocol_engine/state/module_substates/flex_stacker_substate.py +68 -0
- opentrons/protocol_engine/state/module_substates/heater_shaker_module_substate.py +22 -0
- opentrons/protocol_engine/state/module_substates/temperature_module_substate.py +13 -0
- opentrons/protocol_engine/state/module_substates/thermocycler_module_substate.py +20 -0
- opentrons/protocol_engine/state/modules.py +210 -67
- opentrons/protocol_engine/state/pipettes.py +54 -0
- opentrons/protocol_engine/state/state.py +1 -1
- opentrons/protocol_engine/state/tips.py +14 -0
- opentrons/protocol_engine/state/update_types.py +180 -25
- opentrons/protocol_engine/state/wells.py +55 -9
- opentrons/protocol_engine/types/__init__.py +300 -0
- opentrons/protocol_engine/types/automatic_tip_selection.py +39 -0
- opentrons/protocol_engine/types/command_annotations.py +53 -0
- opentrons/protocol_engine/types/deck_configuration.py +72 -0
- opentrons/protocol_engine/types/execution.py +96 -0
- opentrons/protocol_engine/types/hardware_passthrough.py +25 -0
- opentrons/protocol_engine/types/instrument.py +47 -0
- opentrons/protocol_engine/types/instrument_sensors.py +47 -0
- opentrons/protocol_engine/types/labware.py +111 -0
- opentrons/protocol_engine/types/labware_movement.py +22 -0
- opentrons/protocol_engine/types/labware_offset_location.py +111 -0
- opentrons/protocol_engine/types/labware_offset_vector.py +33 -0
- opentrons/protocol_engine/types/liquid.py +40 -0
- opentrons/protocol_engine/types/liquid_class.py +59 -0
- opentrons/protocol_engine/types/liquid_handling.py +13 -0
- opentrons/protocol_engine/types/liquid_level_detection.py +131 -0
- opentrons/protocol_engine/types/location.py +194 -0
- opentrons/protocol_engine/types/module.py +301 -0
- opentrons/protocol_engine/types/partial_tip_configuration.py +76 -0
- opentrons/protocol_engine/types/run_time_parameters.py +133 -0
- opentrons/protocol_engine/types/tip.py +18 -0
- opentrons/protocol_engine/types/util.py +21 -0
- opentrons/protocol_engine/types/well_position.py +124 -0
- opentrons/protocol_reader/extract_labware_definitions.py +7 -3
- opentrons/protocol_reader/file_format_validator.py +5 -3
- opentrons/protocol_runner/json_translator.py +4 -2
- opentrons/protocol_runner/legacy_command_mapper.py +6 -2
- opentrons/protocol_runner/run_orchestrator.py +4 -1
- opentrons/protocols/advanced_control/transfers/common.py +48 -1
- opentrons/protocols/advanced_control/transfers/transfer_liquid_utils.py +204 -0
- opentrons/protocols/api_support/definitions.py +1 -1
- opentrons/protocols/api_support/instrument.py +16 -3
- opentrons/protocols/labware.py +27 -23
- opentrons/protocols/models/__init__.py +0 -21
- opentrons/simulate.py +4 -2
- opentrons/types.py +20 -7
- opentrons/util/logging_config.py +94 -25
- opentrons/util/logging_queue_handler.py +61 -0
- {opentrons-8.3.2.dist-info → opentrons-8.4.0.dist-info}/METADATA +4 -4
- {opentrons-8.3.2.dist-info → opentrons-8.4.0.dist-info}/RECORD +192 -151
- opentrons/calibration_storage/ot2/models/defaults.py +0 -0
- opentrons/calibration_storage/ot3/models/defaults.py +0 -0
- opentrons/protocol_api/core/legacy/legacy_robot_core.py +0 -0
- opentrons/protocol_engine/types.py +0 -1311
- {opentrons-8.3.2.dist-info → opentrons-8.4.0.dist-info}/LICENSE +0 -0
- {opentrons-8.3.2.dist-info → opentrons-8.4.0.dist-info}/WHEEL +0 -0
- {opentrons-8.3.2.dist-info → opentrons-8.4.0.dist-info}/entry_points.txt +0 -0
- {opentrons-8.3.2.dist-info → opentrons-8.4.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""Stacker-specific error codes and exceptions."""
|
|
2
|
+
|
|
3
|
+
from opentrons.drivers.asyncio.communication.errors import (
|
|
4
|
+
BaseErrorCode,
|
|
5
|
+
ErrorResponse,
|
|
6
|
+
UnhandledGcode,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class EStopTriggered(ErrorResponse):
|
|
11
|
+
"""Raised when the estop is triggered during a move."""
|
|
12
|
+
|
|
13
|
+
def __init__(self, port: str, response: str, command: str) -> None:
|
|
14
|
+
super().__init__(port, response, command)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class MotorStallDetected(ErrorResponse):
|
|
18
|
+
"""Raised when a motor stall is detected."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, port: str, response: str, command: str) -> None:
|
|
21
|
+
super().__init__(port, response, command)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class MotorQueueFull(ErrorResponse):
|
|
25
|
+
"""Raised when the motor command queue is full."""
|
|
26
|
+
|
|
27
|
+
def __init__(self, port: str, response: str, command: str) -> None:
|
|
28
|
+
super().__init__(port, response, command)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class UnexpectedLimitSwitch(ErrorResponse):
|
|
32
|
+
"""Raised when an unexpected limit switch is triggered."""
|
|
33
|
+
|
|
34
|
+
def __init__(self, port: str, response: str, command: str) -> None:
|
|
35
|
+
super().__init__(port, response, command)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class MotorBusy(ErrorResponse):
|
|
39
|
+
"""Raised when a motor is busy."""
|
|
40
|
+
|
|
41
|
+
# TODO: differentiate between motors
|
|
42
|
+
def __init__(self, port: str, response: str, command: str) -> None:
|
|
43
|
+
super().__init__(port, response, command)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class StopRequested(ErrorResponse):
|
|
47
|
+
"""Raised when a stop is requested during a movement."""
|
|
48
|
+
|
|
49
|
+
def __init__(self, port: str, response: str, command: str) -> None:
|
|
50
|
+
super().__init__(port, response, command)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class StackerErrorCodes(BaseErrorCode):
|
|
54
|
+
"""Stacker-specific error codes."""
|
|
55
|
+
|
|
56
|
+
UNHANDLED_GCODE = ("ERR003", UnhandledGcode)
|
|
57
|
+
ESTOP_TRIGGERED = ("ERR006", EStopTriggered)
|
|
58
|
+
MOTOR_STALL_DETECTED = ("ERR403", MotorStallDetected)
|
|
59
|
+
MOTOR_QUEUE_FULL = ("ERR404", MotorQueueFull)
|
|
60
|
+
UNEXPECTED_LIMIT_SWITCH = ("ERR405", UnexpectedLimitSwitch)
|
|
61
|
+
X_MOTOR_BUSY = ("ERR501", MotorBusy)
|
|
62
|
+
Z_MOTOR_BUSY = ("ERR502", MotorBusy)
|
|
63
|
+
L_MOTOR_BUSY = ("ERR503", MotorBusy)
|
|
64
|
+
STOP_REQUESTED = ("ERR504", StopRequested)
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
from typing import Optional
|
|
1
|
+
from typing import List, Optional, Dict
|
|
2
2
|
|
|
3
|
+
from opentrons.drivers.flex_stacker.driver import NUMBER_OF_BINS
|
|
3
4
|
from opentrons.util.async_helpers import ensure_yield
|
|
4
5
|
|
|
5
|
-
from .abstract import
|
|
6
|
+
from .abstract import AbstractFlexStackerDriver
|
|
6
7
|
from .types import (
|
|
8
|
+
ActiveRange,
|
|
9
|
+
LEDColor,
|
|
10
|
+
LEDPattern,
|
|
11
|
+
MeasurementKind,
|
|
12
|
+
MoveResult,
|
|
13
|
+
SpadMapID,
|
|
7
14
|
StackerAxis,
|
|
8
15
|
PlatformStatus,
|
|
9
16
|
Direction,
|
|
@@ -11,10 +18,18 @@ from .types import (
|
|
|
11
18
|
HardwareRevision,
|
|
12
19
|
MoveParams,
|
|
13
20
|
LimitSwitchStatus,
|
|
21
|
+
StallGuardParams,
|
|
22
|
+
TOFConfiguration,
|
|
23
|
+
TOFMeasurement,
|
|
24
|
+
TOFMeasurementResult,
|
|
25
|
+
TOFSensor,
|
|
26
|
+
TOFSensorMode,
|
|
27
|
+
TOFSensorState,
|
|
28
|
+
TOFSensorStatus,
|
|
14
29
|
)
|
|
15
30
|
|
|
16
31
|
|
|
17
|
-
class SimulatingDriver(
|
|
32
|
+
class SimulatingDriver(AbstractFlexStackerDriver):
|
|
18
33
|
"""FLEX Stacker driver simulator."""
|
|
19
34
|
|
|
20
35
|
def __init__(self, serial_number: Optional[str] = None) -> None:
|
|
@@ -22,33 +37,51 @@ class SimulatingDriver(AbstractStackerDriver):
|
|
|
22
37
|
self._limit_switch_status = LimitSwitchStatus(False, False, False, False, False)
|
|
23
38
|
self._platform_sensor_status = PlatformStatus(False, False)
|
|
24
39
|
self._door_closed = True
|
|
40
|
+
self._install_detected = True
|
|
41
|
+
self._connected = True
|
|
42
|
+
self._stallgard_threshold = {
|
|
43
|
+
a: StallGuardParams(a, False, 0) for a in StackerAxis
|
|
44
|
+
}
|
|
45
|
+
self._motor_registers: Dict[StackerAxis, Dict[int, int]] = {
|
|
46
|
+
a: {} for a in StackerAxis
|
|
47
|
+
}
|
|
48
|
+
self._tof_registers: Dict[TOFSensor, Dict[int, int]] = {
|
|
49
|
+
a: {} for a in TOFSensor
|
|
50
|
+
}
|
|
51
|
+
self._tof_sensor_status: Dict[TOFSensor, TOFSensorStatus] = {
|
|
52
|
+
s: TOFSensorStatus(s, TOFSensorState.IDLE, TOFSensorMode.MEASURE, True)
|
|
53
|
+
for s in TOFSensor
|
|
54
|
+
}
|
|
55
|
+
self._tof_sensor_configuration: Dict[TOFSensor, TOFConfiguration] = {
|
|
56
|
+
s: TOFConfiguration(
|
|
57
|
+
s, SpadMapID.SPAD_MAP_ID_14, ActiveRange.SHORT_RANGE, 4000, 500, True
|
|
58
|
+
)
|
|
59
|
+
for s in TOFSensor
|
|
60
|
+
}
|
|
25
61
|
|
|
26
|
-
def set_limit_switch(self, status: LimitSwitchStatus) ->
|
|
62
|
+
def set_limit_switch(self, status: LimitSwitchStatus) -> None:
|
|
27
63
|
self._limit_switch_status = status
|
|
28
|
-
return True
|
|
29
64
|
|
|
30
|
-
def set_platform_sensor(self, status: PlatformStatus) ->
|
|
65
|
+
def set_platform_sensor(self, status: PlatformStatus) -> None:
|
|
31
66
|
self._platform_sensor_status = status
|
|
32
|
-
return True
|
|
33
67
|
|
|
34
|
-
def set_door_closed(self, door_closed: bool) ->
|
|
68
|
+
def set_door_closed(self, door_closed: bool) -> None:
|
|
35
69
|
self._door_closed = door_closed
|
|
36
|
-
return True
|
|
37
70
|
|
|
38
71
|
@ensure_yield
|
|
39
72
|
async def connect(self) -> None:
|
|
40
73
|
"""Connect to stacker."""
|
|
41
|
-
|
|
74
|
+
self._connected = True
|
|
42
75
|
|
|
43
76
|
@ensure_yield
|
|
44
77
|
async def disconnect(self) -> None:
|
|
45
78
|
"""Disconnect from stacker."""
|
|
46
|
-
|
|
79
|
+
self._connected = False
|
|
47
80
|
|
|
48
81
|
@ensure_yield
|
|
49
82
|
async def is_connected(self) -> bool:
|
|
50
83
|
"""Check connection to stacker."""
|
|
51
|
-
return
|
|
84
|
+
return self._connected
|
|
52
85
|
|
|
53
86
|
@ensure_yield
|
|
54
87
|
async def get_device_info(self) -> StackerInfo:
|
|
@@ -56,14 +89,139 @@ class SimulatingDriver(AbstractStackerDriver):
|
|
|
56
89
|
return StackerInfo(fw="stacker-fw", hw=HardwareRevision.EVT, sn=self._sn)
|
|
57
90
|
|
|
58
91
|
@ensure_yield
|
|
59
|
-
async def set_serial_number(self, sn: str) ->
|
|
92
|
+
async def set_serial_number(self, sn: str) -> None:
|
|
60
93
|
"""Set Serial Number."""
|
|
61
|
-
|
|
94
|
+
self._sn = sn
|
|
95
|
+
|
|
96
|
+
@ensure_yield
|
|
97
|
+
async def enable_motors(self, axis: List[StackerAxis]) -> None:
|
|
98
|
+
"""Enables the axis motor if present, disables it otherwise."""
|
|
99
|
+
pass
|
|
100
|
+
|
|
101
|
+
@ensure_yield
|
|
102
|
+
async def stop_motors(self) -> None:
|
|
103
|
+
"""Stop all motor movement."""
|
|
104
|
+
pass
|
|
105
|
+
|
|
106
|
+
@ensure_yield
|
|
107
|
+
async def set_run_current(self, axis: StackerAxis, current: float) -> None:
|
|
108
|
+
"""Set axis peak run current in amps."""
|
|
109
|
+
pass
|
|
110
|
+
|
|
111
|
+
@ensure_yield
|
|
112
|
+
async def set_ihold_current(self, axis: StackerAxis, current: float) -> None:
|
|
113
|
+
"""Set axis hold current in amps."""
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
@ensure_yield
|
|
117
|
+
async def set_stallguard_threshold(
|
|
118
|
+
self, axis: StackerAxis, enable: bool, threshold: int
|
|
119
|
+
) -> None:
|
|
120
|
+
"""Enables and sets the stallguard threshold for the given axis motor."""
|
|
121
|
+
self._stallgard_threshold[axis] = StallGuardParams(axis, enable, threshold)
|
|
122
|
+
|
|
123
|
+
@ensure_yield
|
|
124
|
+
async def enable_tof_sensor(self, sensor: TOFSensor, enable: bool) -> None:
|
|
125
|
+
"""Enable or disable the TOF sensor."""
|
|
126
|
+
state = TOFSensorState.IDLE if enable else TOFSensorState.DISABLED
|
|
127
|
+
self._tof_sensor_status[sensor].state = state
|
|
128
|
+
self._tof_sensor_status[sensor].ok = enable
|
|
129
|
+
|
|
130
|
+
@ensure_yield
|
|
131
|
+
async def manage_tof_measurement(
|
|
132
|
+
self,
|
|
133
|
+
sensor: TOFSensor,
|
|
134
|
+
kind: MeasurementKind = MeasurementKind.HISTOGRAM,
|
|
135
|
+
start: bool = True,
|
|
136
|
+
) -> TOFMeasurement:
|
|
137
|
+
"""Start or stop Measurements from the TOF sensor."""
|
|
138
|
+
return TOFMeasurement(
|
|
139
|
+
sensor=sensor,
|
|
140
|
+
kind=kind,
|
|
141
|
+
cancelled=not start,
|
|
142
|
+
# Each histogram frame is 135 bytes and there are 30 frames.
|
|
143
|
+
# (3b header + 4b sub-header + 128 data) * 30 frames = 3840b.
|
|
144
|
+
# The firmware sends 0 when the measurement is cancelled.
|
|
145
|
+
total_bytes=3840 if start else 0,
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
@ensure_yield
|
|
149
|
+
async def get_tof_histogram(self, sensor: TOFSensor) -> TOFMeasurementResult:
|
|
150
|
+
"""Get the full histogram measurement from the TOF sensor."""
|
|
151
|
+
return TOFMeasurementResult(
|
|
152
|
+
sensor=sensor,
|
|
153
|
+
kind=MeasurementKind.HISTOGRAM,
|
|
154
|
+
bins={c: [b for b in range(NUMBER_OF_BINS)] for c in range(10)},
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
async def set_tof_configuration(
|
|
158
|
+
self,
|
|
159
|
+
sensor: TOFSensor,
|
|
160
|
+
spad_map_id: SpadMapID,
|
|
161
|
+
active_range: Optional[ActiveRange] = None,
|
|
162
|
+
kilo_iterations: Optional[int] = None,
|
|
163
|
+
report_period_ms: Optional[int] = None,
|
|
164
|
+
histogram_dump: Optional[bool] = None,
|
|
165
|
+
) -> None:
|
|
166
|
+
"""Set the configuration of the TOF sensor.
|
|
167
|
+
|
|
168
|
+
:param sensor: The TOF sensor to configure.
|
|
169
|
+
:param spad_map_id: The pre-defined SPAD map which sets the fov and focus area (14 default).
|
|
170
|
+
:active_range: The operating mode Short-range high-accuracy (default) or long range.
|
|
171
|
+
:kilo_iterations: The Measurement iterations times 1024 (4000 default).
|
|
172
|
+
:report_period_ms: The reporting period before each measurement (500 default).
|
|
173
|
+
:histogram_dump: Enables/Disables histogram measurements (True default).
|
|
174
|
+
:return: None
|
|
175
|
+
"""
|
|
176
|
+
config = self._tof_sensor_configuration[sensor]
|
|
177
|
+
config.spad_map_id = spad_map_id
|
|
178
|
+
config.active_range = active_range or config.active_range
|
|
179
|
+
config.kilo_iterations = kilo_iterations or config.kilo_iterations
|
|
180
|
+
config.report_period_ms = report_period_ms or config.report_period_ms
|
|
181
|
+
config.histogram_dump = histogram_dump or config.histogram_dump
|
|
182
|
+
|
|
183
|
+
async def get_tof_configuration(self, sensor: TOFSensor) -> TOFConfiguration:
|
|
184
|
+
"""Get the configuration of the TOF sensor."""
|
|
185
|
+
return self._tof_sensor_configuration[sensor]
|
|
186
|
+
|
|
187
|
+
@ensure_yield
|
|
188
|
+
async def set_motor_driver_register(
|
|
189
|
+
self, axis: StackerAxis, reg: int, value: int
|
|
190
|
+
) -> None:
|
|
191
|
+
"""Set the register of the given motor axis driver to the given value."""
|
|
192
|
+
self._motor_registers[axis].update({reg: value})
|
|
193
|
+
|
|
194
|
+
@ensure_yield
|
|
195
|
+
async def get_motor_driver_register(self, axis: StackerAxis, reg: int) -> int:
|
|
196
|
+
"""Gets the register value of the given motor axis driver."""
|
|
197
|
+
return self._motor_registers[axis].get(reg, 0)
|
|
198
|
+
|
|
199
|
+
@ensure_yield
|
|
200
|
+
async def set_tof_driver_register(
|
|
201
|
+
self, sensor: TOFSensor, reg: int, value: int
|
|
202
|
+
) -> None:
|
|
203
|
+
"""Set the register of the given tof sensor driver to the given value."""
|
|
204
|
+
self._tof_registers[sensor].update({reg: value})
|
|
205
|
+
|
|
206
|
+
@ensure_yield
|
|
207
|
+
async def get_tof_driver_register(self, sensor: TOFSensor, reg: int) -> int:
|
|
208
|
+
"""Gets the register value of the given tof sensor driver."""
|
|
209
|
+
return self._tof_registers[sensor].get(reg, 0)
|
|
62
210
|
|
|
63
211
|
@ensure_yield
|
|
64
|
-
async def
|
|
65
|
-
"""
|
|
66
|
-
return
|
|
212
|
+
async def get_tof_sensor_status(self, sensor: TOFSensor) -> TOFSensorStatus:
|
|
213
|
+
"""Get the status of the tof sensor."""
|
|
214
|
+
return self._tof_sensor_status[sensor]
|
|
215
|
+
|
|
216
|
+
@ensure_yield
|
|
217
|
+
async def get_motion_params(self, axis: StackerAxis) -> MoveParams:
|
|
218
|
+
"""Get the motion parameters used by the given axis motor."""
|
|
219
|
+
return MoveParams(1, 1, 1)
|
|
220
|
+
|
|
221
|
+
@ensure_yield
|
|
222
|
+
async def get_stallguard_threshold(self, axis: StackerAxis) -> StallGuardParams:
|
|
223
|
+
"""Get the stallguard parameters by the given axis motor."""
|
|
224
|
+
return self._stallgard_threshold[axis]
|
|
67
225
|
|
|
68
226
|
@ensure_yield
|
|
69
227
|
async def get_limit_switch(self, axis: StackerAxis, direction: Direction) -> bool:
|
|
@@ -79,11 +237,16 @@ class SimulatingDriver(AbstractStackerDriver):
|
|
|
79
237
|
return self._limit_switch_status
|
|
80
238
|
|
|
81
239
|
@ensure_yield
|
|
82
|
-
async def
|
|
240
|
+
async def get_platform_sensor(self, direction: Direction) -> bool:
|
|
83
241
|
"""Get platform sensor status.
|
|
84
242
|
|
|
85
|
-
:return: True if platform is
|
|
243
|
+
:return: True if platform is present, False otherwise
|
|
86
244
|
"""
|
|
245
|
+
return self._platform_sensor_status.get(direction)
|
|
246
|
+
|
|
247
|
+
@ensure_yield
|
|
248
|
+
async def get_platform_status(self) -> PlatformStatus:
|
|
249
|
+
"""Get platform status."""
|
|
87
250
|
return self._platform_sensor_status
|
|
88
251
|
|
|
89
252
|
@ensure_yield
|
|
@@ -94,16 +257,51 @@ class SimulatingDriver(AbstractStackerDriver):
|
|
|
94
257
|
"""
|
|
95
258
|
return self._door_closed
|
|
96
259
|
|
|
260
|
+
@ensure_yield
|
|
261
|
+
async def get_installation_detected(self) -> bool:
|
|
262
|
+
"""Get whether or not installation is detected.
|
|
263
|
+
|
|
264
|
+
:return: True if installation is detected, False otherwise
|
|
265
|
+
"""
|
|
266
|
+
return self._install_detected
|
|
267
|
+
|
|
97
268
|
@ensure_yield
|
|
98
269
|
async def move_in_mm(
|
|
99
270
|
self, axis: StackerAxis, distance: float, params: MoveParams | None = None
|
|
100
|
-
) ->
|
|
101
|
-
"""Move axis."""
|
|
102
|
-
return
|
|
271
|
+
) -> MoveResult:
|
|
272
|
+
"""Move axis by the given distance in mm."""
|
|
273
|
+
return MoveResult.NO_ERROR
|
|
103
274
|
|
|
104
275
|
@ensure_yield
|
|
105
276
|
async def move_to_limit_switch(
|
|
106
277
|
self, axis: StackerAxis, direction: Direction, params: MoveParams | None = None
|
|
107
|
-
) ->
|
|
278
|
+
) -> MoveResult:
|
|
108
279
|
"""Move until limit switch is triggered."""
|
|
109
|
-
return
|
|
280
|
+
return MoveResult.NO_ERROR
|
|
281
|
+
|
|
282
|
+
@ensure_yield
|
|
283
|
+
async def home_axis(self, axis: StackerAxis, direction: Direction) -> MoveResult:
|
|
284
|
+
"""Home axis."""
|
|
285
|
+
return MoveResult.NO_ERROR
|
|
286
|
+
|
|
287
|
+
@ensure_yield
|
|
288
|
+
async def set_led(
|
|
289
|
+
self,
|
|
290
|
+
power: float,
|
|
291
|
+
color: Optional[LEDColor] = None,
|
|
292
|
+
external: Optional[bool] = None,
|
|
293
|
+
pattern: Optional[LEDPattern] = None,
|
|
294
|
+
duration: Optional[int] = None,
|
|
295
|
+
reps: Optional[int] = None,
|
|
296
|
+
) -> None:
|
|
297
|
+
"""Set LED Status bar color and pattern."""
|
|
298
|
+
pass
|
|
299
|
+
|
|
300
|
+
@ensure_yield
|
|
301
|
+
async def enter_programming_mode(self) -> None:
|
|
302
|
+
"""Reboot into programming mode"""
|
|
303
|
+
pass
|
|
304
|
+
|
|
305
|
+
def reset_serial_buffers(self) -> None:
|
|
306
|
+
"""Reset the input and output serial buffers."""
|
|
307
|
+
pass
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
2
|
from dataclasses import dataclass, fields
|
|
3
|
-
from typing import List
|
|
3
|
+
from typing import List, Dict, Optional
|
|
4
4
|
|
|
5
5
|
from opentrons.drivers.command_builder import CommandBuilder
|
|
6
6
|
|
|
@@ -11,13 +11,30 @@ class GCODE(str, Enum):
|
|
|
11
11
|
MOVE_TO_SWITCH = "G5"
|
|
12
12
|
HOME_AXIS = "G28"
|
|
13
13
|
STOP_MOTORS = "M0"
|
|
14
|
+
ENABLE_MOTORS = "M17"
|
|
14
15
|
GET_RESET_REASON = "M114"
|
|
15
16
|
DEVICE_INFO = "M115"
|
|
16
17
|
GET_LIMIT_SWITCH = "M119"
|
|
17
|
-
|
|
18
|
+
GET_MOVE_PARAMS = "M120"
|
|
18
19
|
GET_PLATFORM_SENSOR = "M121"
|
|
19
20
|
GET_DOOR_SWITCH = "M122"
|
|
21
|
+
GET_INSTALL_DETECTED = "M123"
|
|
22
|
+
GET_STALLGUARD_THRESHOLD = "M911"
|
|
23
|
+
GET_MOTOR_DRIVER_REGISTER = "M920"
|
|
24
|
+
GET_TOF_SENSOR_STATUS = "M215"
|
|
25
|
+
GET_TOF_DRIVER_REGISTER = "M222"
|
|
26
|
+
GET_TOF_MEASUREMENT = "M226"
|
|
27
|
+
ENABLE_TOF_SENSOR = "M224"
|
|
28
|
+
MANAGE_TOF_MEASUREMENT = "M225"
|
|
29
|
+
SET_TOF_CONFIGURATION = "M227"
|
|
30
|
+
GET_TOF_CONFIGURATION = "M228"
|
|
31
|
+
SET_LED = "M200"
|
|
20
32
|
SET_SERIAL_NUMBER = "M996"
|
|
33
|
+
SET_RUN_CURRENT = "M906"
|
|
34
|
+
SET_IHOLD_CURRENT = "M907"
|
|
35
|
+
SET_STALLGUARD = "M910"
|
|
36
|
+
SET_MOTOR_DRIVER_REGISTER = "M921"
|
|
37
|
+
SET_TOF_DRIVER_REGISTER = "M223"
|
|
21
38
|
ENTER_BOOTLOADER = "dfu"
|
|
22
39
|
|
|
23
40
|
def build_command(self) -> CommandBuilder:
|
|
@@ -35,6 +52,7 @@ class HardwareRevision(Enum):
|
|
|
35
52
|
|
|
36
53
|
NFF = "nff"
|
|
37
54
|
EVT = "a1"
|
|
55
|
+
DVT = "b1"
|
|
38
56
|
|
|
39
57
|
|
|
40
58
|
@dataclass
|
|
@@ -44,18 +62,31 @@ class StackerInfo:
|
|
|
44
62
|
fw: str
|
|
45
63
|
hw: HardwareRevision
|
|
46
64
|
sn: str
|
|
65
|
+
rr: int = 0
|
|
66
|
+
|
|
67
|
+
def to_dict(self) -> Dict[str, str]:
|
|
68
|
+
"""Build command."""
|
|
69
|
+
return {
|
|
70
|
+
"serial": self.sn,
|
|
71
|
+
"version": self.fw,
|
|
72
|
+
"model": self.hw.value,
|
|
73
|
+
"reset_reason": str(self.rr),
|
|
74
|
+
}
|
|
47
75
|
|
|
48
76
|
|
|
49
|
-
class StackerAxis(Enum):
|
|
77
|
+
class StackerAxis(str, Enum):
|
|
50
78
|
"""Stacker Axis."""
|
|
51
79
|
|
|
52
80
|
X = "X"
|
|
53
81
|
Z = "Z"
|
|
54
82
|
L = "L"
|
|
55
83
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
84
|
+
|
|
85
|
+
class TOFSensor(str, Enum):
|
|
86
|
+
"""Stacker TOF sensor."""
|
|
87
|
+
|
|
88
|
+
X = "X"
|
|
89
|
+
Z = "Z"
|
|
59
90
|
|
|
60
91
|
|
|
61
92
|
class LEDColor(Enum):
|
|
@@ -65,13 +96,23 @@ class LEDColor(Enum):
|
|
|
65
96
|
RED = 1
|
|
66
97
|
GREEN = 2
|
|
67
98
|
BLUE = 3
|
|
99
|
+
YELLOW = 4
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class LEDPattern(Enum):
|
|
103
|
+
"""Stacker LED Pattern."""
|
|
104
|
+
|
|
105
|
+
STATIC = 0
|
|
106
|
+
FLASH = 1
|
|
107
|
+
PULSE = 2
|
|
108
|
+
CONFIRM = 3
|
|
68
109
|
|
|
69
110
|
|
|
70
111
|
class Direction(Enum):
|
|
71
112
|
"""Direction."""
|
|
72
113
|
|
|
73
114
|
RETRACT = 0 # negative
|
|
74
|
-
|
|
115
|
+
EXTEND = 1 # positive
|
|
75
116
|
|
|
76
117
|
def __str__(self) -> str:
|
|
77
118
|
"""Convert to tag for clear logging."""
|
|
@@ -79,13 +120,31 @@ class Direction(Enum):
|
|
|
79
120
|
|
|
80
121
|
def opposite(self) -> "Direction":
|
|
81
122
|
"""Get opposite direction."""
|
|
82
|
-
return Direction.
|
|
123
|
+
return Direction.EXTEND if self == Direction.RETRACT else Direction.RETRACT
|
|
83
124
|
|
|
84
125
|
def distance(self, distance: float) -> float:
|
|
85
126
|
"""Get signed distance, where retract direction is negative."""
|
|
86
127
|
return distance * -1 if self == Direction.RETRACT else distance
|
|
87
128
|
|
|
88
129
|
|
|
130
|
+
class TOFSensorState(Enum):
|
|
131
|
+
"""TOF Sensor state."""
|
|
132
|
+
|
|
133
|
+
DISABLED = 0
|
|
134
|
+
INITIALIZING = 1
|
|
135
|
+
IDLE = 2
|
|
136
|
+
MEASURING = 3
|
|
137
|
+
ERROR = 4
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class TOFSensorMode(Enum):
|
|
141
|
+
"""The mode the sensor is in."""
|
|
142
|
+
|
|
143
|
+
UNKNOWN = 0
|
|
144
|
+
MEASURE = 0x03
|
|
145
|
+
BOOTLOADER = 0x80
|
|
146
|
+
|
|
147
|
+
|
|
89
148
|
@dataclass
|
|
90
149
|
class LimitSwitchStatus:
|
|
91
150
|
"""Stacker Limit Switch Statuses."""
|
|
@@ -104,10 +163,10 @@ class LimitSwitchStatus:
|
|
|
104
163
|
def get(self, axis: StackerAxis, direction: Direction) -> bool:
|
|
105
164
|
"""Get limit switch status."""
|
|
106
165
|
if axis == StackerAxis.X:
|
|
107
|
-
return self.XE if direction == Direction.
|
|
166
|
+
return self.XE if direction == Direction.EXTEND else self.XR
|
|
108
167
|
if axis == StackerAxis.Z:
|
|
109
|
-
return self.ZE if direction == Direction.
|
|
110
|
-
if direction == Direction.
|
|
168
|
+
return self.ZE if direction == Direction.EXTEND else self.ZR
|
|
169
|
+
if direction == Direction.EXTEND:
|
|
111
170
|
raise ValueError("Latch does not have extent limit switch")
|
|
112
171
|
return self.LR
|
|
113
172
|
|
|
@@ -126,13 +185,150 @@ class PlatformStatus:
|
|
|
126
185
|
|
|
127
186
|
def get(self, direction: Direction) -> bool:
|
|
128
187
|
"""Get platform status."""
|
|
129
|
-
return self.E if direction == Direction.
|
|
188
|
+
return self.E if direction == Direction.EXTEND else self.R
|
|
189
|
+
|
|
190
|
+
def to_dict(self) -> Dict[str, bool]:
|
|
191
|
+
"""Dict of the data."""
|
|
192
|
+
return {
|
|
193
|
+
"extent": self.E,
|
|
194
|
+
"retract": self.R,
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
@dataclass
|
|
199
|
+
class TOFSensorStatus:
|
|
200
|
+
"""Stacker TOF sensor status."""
|
|
201
|
+
|
|
202
|
+
sensor: TOFSensor
|
|
203
|
+
state: TOFSensorState
|
|
204
|
+
mode: TOFSensorMode
|
|
205
|
+
ok: bool
|
|
130
206
|
|
|
131
207
|
|
|
132
208
|
@dataclass
|
|
133
209
|
class MoveParams:
|
|
134
210
|
"""Move Parameters."""
|
|
135
211
|
|
|
136
|
-
max_speed: float
|
|
137
|
-
acceleration: float
|
|
138
|
-
max_speed_discont: float
|
|
212
|
+
max_speed: float
|
|
213
|
+
acceleration: float
|
|
214
|
+
max_speed_discont: float
|
|
215
|
+
|
|
216
|
+
@classmethod
|
|
217
|
+
def get_fields(cls) -> List[str]:
|
|
218
|
+
"""Get parsing fields."""
|
|
219
|
+
return ["V", "A", "D"]
|
|
220
|
+
|
|
221
|
+
def update(
|
|
222
|
+
self,
|
|
223
|
+
max_speed: Optional[float] = None,
|
|
224
|
+
acceleration: Optional[float] = None,
|
|
225
|
+
max_speed_discont: Optional[float] = None,
|
|
226
|
+
) -> "MoveParams":
|
|
227
|
+
"""Update the move parameters and return a new object."""
|
|
228
|
+
return MoveParams(
|
|
229
|
+
max_speed=max_speed if max_speed is not None else self.max_speed,
|
|
230
|
+
acceleration=acceleration
|
|
231
|
+
if acceleration is not None
|
|
232
|
+
else self.acceleration,
|
|
233
|
+
max_speed_discont=max_speed_discont
|
|
234
|
+
if max_speed_discont is not None
|
|
235
|
+
else self.max_speed_discont,
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
@dataclass
|
|
240
|
+
class AxisParams:
|
|
241
|
+
"""Axis Parameters."""
|
|
242
|
+
|
|
243
|
+
run_current: float
|
|
244
|
+
hold_current: float
|
|
245
|
+
move_params: MoveParams
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
@dataclass
|
|
249
|
+
class StallGuardParams:
|
|
250
|
+
"""StallGuard Parameters."""
|
|
251
|
+
|
|
252
|
+
axis: StackerAxis
|
|
253
|
+
enabled: bool
|
|
254
|
+
threshold: int
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
class MoveResult(str, Enum):
|
|
258
|
+
"""The result of a move command."""
|
|
259
|
+
|
|
260
|
+
NO_ERROR = "ok"
|
|
261
|
+
STALL_ERROR = "stall"
|
|
262
|
+
UNKNOWN_ERROR = "unknown"
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
class MeasurementKind(Enum):
|
|
266
|
+
"""The kind of measurement to request."""
|
|
267
|
+
|
|
268
|
+
HISTOGRAM = 0
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
class SpadMapID(Enum):
|
|
272
|
+
"""The spad map id for the TOF sensor."""
|
|
273
|
+
|
|
274
|
+
SPAD_MAP_ID_1 = 1
|
|
275
|
+
# 3x3 macro 1 mode 33°x47° FoV off center
|
|
276
|
+
SPAD_MAP_ID_2 = 2
|
|
277
|
+
# 3x3 macro 2 mode 33°x47° FoV
|
|
278
|
+
SPAD_MAP_ID_3 = 3
|
|
279
|
+
# 3x3 wide mode 41°x52° FoV
|
|
280
|
+
SPAD_MAP_ID_6 = 6
|
|
281
|
+
# 3x3 mode 33°x32° FoV, checkerboard
|
|
282
|
+
SPAD_MAP_ID_11 = 11
|
|
283
|
+
# 3x3 mode 33°x32° FoV, inverted checkerboard
|
|
284
|
+
SPAD_MAP_ID_12 = 12
|
|
285
|
+
# User defined mode, single measurement mode
|
|
286
|
+
SPAD_MAP_ID_14 = 14
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
class ActiveRange(Enum):
|
|
290
|
+
"""The active range for the TOF sensor."""
|
|
291
|
+
|
|
292
|
+
NOT_SUPPORTED = 0
|
|
293
|
+
SHORT_RANGE = 0x6E
|
|
294
|
+
LONG_RANGE = 0x6F
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
@dataclass
|
|
298
|
+
class TOFMeasurement:
|
|
299
|
+
"""The start measurement data."""
|
|
300
|
+
|
|
301
|
+
sensor: TOFSensor
|
|
302
|
+
kind: MeasurementKind
|
|
303
|
+
cancelled: bool
|
|
304
|
+
total_bytes: int
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
@dataclass
|
|
308
|
+
class TOFMeasurementFrame:
|
|
309
|
+
"""Stacker TOF measurement frame."""
|
|
310
|
+
|
|
311
|
+
sensor: TOFSensor
|
|
312
|
+
frame_id: int
|
|
313
|
+
data: bytes
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
@dataclass
|
|
317
|
+
class TOFMeasurementResult:
|
|
318
|
+
"""Stacker TOF measurement result."""
|
|
319
|
+
|
|
320
|
+
sensor: TOFSensor
|
|
321
|
+
kind: MeasurementKind
|
|
322
|
+
bins: Dict[int, List[int]]
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
@dataclass
|
|
326
|
+
class TOFConfiguration:
|
|
327
|
+
"""Stacker TOF configuration."""
|
|
328
|
+
|
|
329
|
+
sensor: TOFSensor
|
|
330
|
+
spad_map_id: SpadMapID
|
|
331
|
+
active_range: Optional[ActiveRange]
|
|
332
|
+
kilo_iterations: Optional[int]
|
|
333
|
+
report_period_ms: Optional[int]
|
|
334
|
+
histogram_dump: Optional[bool]
|