Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(hardware): give options for sensor data output during probe #14673

Merged
merged 14 commits into from
Mar 25, 2024
Merged
6 changes: 4 additions & 2 deletions api/src/opentrons/config/defaults_ot3.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
LiquidProbeSettings,
ZSenseSettings,
EdgeSenseSettings,
OutputOptions,
)


DEFAULT_PIPETTE_OFFSET = [0.0, 0.0, 0.0]
DEFAULT_MODULE_OFFSET = [0.0, 0.0, 0.0]

Expand All @@ -28,7 +30,7 @@
plunger_speed=5,
sensor_threshold_pascals=40,
expected_liquid_height=110,
log_pressure=True,
output_option=OutputOptions.stream_to_csv,
aspirate_while_sensing=False,
auto_zero_sensor=True,
num_baseline_reads=10,
Expand Down Expand Up @@ -290,7 +292,7 @@ def _build_default_liquid_probe(
expected_liquid_height=from_conf.get(
"expected_liquid_height", default.expected_liquid_height
),
log_pressure=from_conf.get("log_pressure", default.log_pressure),
output_option=from_conf.get("output_option", default.output_option),
aspirate_while_sensing=from_conf.get(
"aspirate_while_sensing", default.aspirate_while_sensing
),
Expand Down
16 changes: 13 additions & 3 deletions api/src/opentrons/config/types.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from enum import Enum
from dataclasses import dataclass, asdict, fields
from typing import Dict, Tuple, TypeVar, Generic, List, cast
from typing import Dict, Tuple, TypeVar, Generic, List, cast, Optional
from typing_extensions import TypedDict, Literal
from opentrons.hardware_control.types import OT3AxisKind

Expand Down Expand Up @@ -116,6 +116,16 @@ class ZSenseSettings:
pass_settings: CapacitivePassSettings


# str enum so it can be json serializable
class OutputOptions(int, Enum):
"""Specifies where we should report sensor data to during a sensor pass."""

stream_to_csv = 0x1
sync_buffer_to_csv = 0x2
can_bus_only = 0x4
sync_only = 0x8


@dataclass
class LiquidProbeSettings:
starting_mount_height: float
Expand All @@ -125,11 +135,11 @@ class LiquidProbeSettings:
plunger_speed: float
sensor_threshold_pascals: float
expected_liquid_height: float
log_pressure: bool
output_option: OutputOptions
aspirate_while_sensing: bool
auto_zero_sensor: bool
num_baseline_reads: int
data_file: str
data_file: Optional[str]


@dataclass(frozen=True)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from opentrons_shared_data.pipette.dev_types import (
PipetteName,
)
from opentrons.config.types import GantryLoad
from opentrons.config.types import GantryLoad, OutputOptions
from opentrons.hardware_control.types import (
BoardRevision,
Axis,
Expand Down Expand Up @@ -146,7 +146,8 @@ async def liquid_probe(
mount_speed: float,
plunger_speed: float,
threshold_pascals: float,
log_pressure: bool = True,
output_format: OutputOptions = OutputOptions.can_bus_only,
data_file: Optional[str] = None,
auto_zero_sensor: bool = True,
num_baseline_reads: int = 10,
probe: InstrumentProbeType = InstrumentProbeType.PRIMARY,
Expand Down
44 changes: 31 additions & 13 deletions api/src/opentrons/hardware_control/backends/ot3controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
Union,
Mapping,
)
from opentrons.config.types import OT3Config, GantryLoad
from opentrons.config.types import OT3Config, GantryLoad, OutputOptions
from opentrons.config import gripper_config
from .ot3utils import (
axis_convert,
Expand Down Expand Up @@ -1350,25 +1350,43 @@ async def liquid_probe(
mount_speed: float,
plunger_speed: float,
threshold_pascals: float,
log_pressure: bool = True,
output_option: OutputOptions = OutputOptions.can_bus_only,
data_file: Optional[str] = None,
auto_zero_sensor: bool = True,
num_baseline_reads: int = 10,
probe: InstrumentProbeType = InstrumentProbeType.PRIMARY,
) -> float:
if output_option == OutputOptions.sync_buffer_to_csv:
assert (
self._subsystem_manager.device_info[
SubSystem.of_mount(mount)
].revision.tertiary
== "1"
)
head_node = axis_to_node(Axis.by_mount(mount))
tool = sensor_node_for_pipette(OT3Mount(mount.value))
csv_output = bool(output_option.value & OutputOptions.stream_to_csv.value)
sync_buffer_output = bool(
output_option.value & OutputOptions.sync_buffer_to_csv.value
)
can_bus_only_output = bool(
output_option.value & OutputOptions.can_bus_only.value
)
positions = await liquid_probe(
self._messenger,
tool,
head_node,
max_z_distance,
plunger_speed,
mount_speed,
threshold_pascals,
log_pressure,
auto_zero_sensor,
num_baseline_reads,
sensor_id_for_instrument(probe),
messenger=self._messenger,
tool=tool,
head_node=head_node,
max_z_distance=max_z_distance,
plunger_speed=plunger_speed,
mount_speed=mount_speed,
threshold_pascals=threshold_pascals,
csv_output=csv_output,
sync_buffer_output=sync_buffer_output,
can_bus_only_output=can_bus_only_output,
data_file=data_file,
auto_zero_sensor=auto_zero_sensor,
num_baseline_reads=num_baseline_reads,
sensor_id=sensor_id_for_instrument(probe),
)
for node, point in positions.items():
self._position.update({node: point.motor_position})
Expand Down
6 changes: 4 additions & 2 deletions api/src/opentrons/hardware_control/backends/ot3simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
Mapping,
)

from opentrons.config.types import OT3Config, GantryLoad
from opentrons.config.types import OT3Config, GantryLoad, OutputOptions
from opentrons.config import gripper_config

from opentrons.hardware_control.module_control import AttachedModulesControl
Expand Down Expand Up @@ -64,6 +64,7 @@
from .types import HWStopCondition
from .flex_protocol import FlexBackend


log = logging.getLogger(__name__)

AXIS_TO_SUBSYSTEM = {
Expand Down Expand Up @@ -344,7 +345,8 @@ async def liquid_probe(
mount_speed: float,
plunger_speed: float,
threshold_pascals: float,
log_pressure: bool = True,
output_format: OutputOptions = OutputOptions.can_bus_only,
data_file: Optional[str] = None,
auto_zero_sensor: bool = True,
num_baseline_reads: int = 10,
probe: InstrumentProbeType = InstrumentProbeType.PRIMARY,
Expand Down
3 changes: 2 additions & 1 deletion api/src/opentrons/hardware_control/ot3api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2572,7 +2572,8 @@ async def liquid_probe(
probe_settings.mount_speed,
(probe_settings.plunger_speed * plunger_direction),
probe_settings.sensor_threshold_pascals,
probe_settings.log_pressure,
probe_settings.output_option,
probe_settings.data_file,
probe_settings.auto_zero_sensor,
probe_settings.num_baseline_reads,
probe=probe if probe else InstrumentProbeType.PRIMARY,
Expand Down
4 changes: 3 additions & 1 deletion api/tests/opentrons/config/ot3_settings.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from opentrons.config.types import OutputOptions

ot3_dummy_settings = {
"name": "Marie Curie",
"model": "OT-3 Standard",
Expand Down Expand Up @@ -123,7 +125,7 @@
"plunger_speed": 10,
"sensor_threshold_pascals": 17,
"expected_liquid_height": 90,
"log_pressure": True,
"output_option": OutputOptions.stream_to_csv,
"aspirate_while_sensing": False,
"auto_zero_sensor": True,
"num_baseline_reads": 10,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@
MessageListenerCallbackFilter,
CanMessenger,
)
from opentrons.config.types import OT3Config, GantryLoad, LiquidProbeSettings
from opentrons.config.types import (
OT3Config,
GantryLoad,
LiquidProbeSettings,
OutputOptions,
)
from opentrons.config.robot_configs import build_config_ot3
from opentrons_hardware.firmware_bindings.arbitration_id import ArbitrationId
from opentrons_hardware.firmware_bindings.constants import (
Expand Down Expand Up @@ -176,7 +181,7 @@ def fake_liquid_settings() -> LiquidProbeSettings:
plunger_speed=10,
sensor_threshold_pascals=15,
expected_liquid_height=109,
log_pressure=False,
output_option=OutputOptions.can_bus_only,
aspirate_while_sensing=False,
auto_zero_sensor=False,
num_baseline_reads=8,
Expand Down Expand Up @@ -715,7 +720,7 @@ async def test_liquid_probe(
mount_speed=fake_liquid_settings.mount_speed,
plunger_speed=fake_liquid_settings.plunger_speed,
threshold_pascals=fake_liquid_settings.sensor_threshold_pascals,
log_pressure=fake_liquid_settings.log_pressure,
output_option=fake_liquid_settings.output_option,
)
move_groups = (mock_move_group_run.call_args_list[0][0][0]._move_groups)[0][0]
head_node = axis_to_node(Axis.by_mount(mount))
Expand Down
8 changes: 5 additions & 3 deletions api/tests/opentrons/hardware_control/test_ot3_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
GantryLoad,
CapacitivePassSettings,
LiquidProbeSettings,
OutputOptions,
)
from opentrons.hardware_control.dev_types import (
AttachedGripper,
Expand Down Expand Up @@ -119,7 +120,7 @@ def fake_liquid_settings() -> LiquidProbeSettings:
plunger_speed=10,
sensor_threshold_pascals=15,
expected_liquid_height=109,
log_pressure=False,
output_option=OutputOptions.can_bus_only,
aspirate_while_sensing=False,
auto_zero_sensor=False,
num_baseline_reads=10,
Expand Down Expand Up @@ -804,7 +805,7 @@ async def test_liquid_probe(
plunger_speed=10,
sensor_threshold_pascals=15,
expected_liquid_height=109,
log_pressure=False,
output_option=OutputOptions.can_bus_only,
aspirate_while_sensing=True,
auto_zero_sensor=False,
num_baseline_reads=10,
Expand All @@ -818,7 +819,8 @@ async def test_liquid_probe(
fake_settings_aspirate.mount_speed,
(fake_settings_aspirate.plunger_speed * -1),
fake_settings_aspirate.sensor_threshold_pascals,
fake_settings_aspirate.log_pressure,
fake_settings_aspirate.output_option,
fake_settings_aspirate.data_file,
fake_settings_aspirate.auto_zero_sensor,
fake_settings_aspirate.num_baseline_reads,
probe=InstrumentProbeType.PRIMARY,
Expand Down
4 changes: 2 additions & 2 deletions hardware-testing/hardware_testing/gravimetric/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import List, Dict, Tuple
from typing_extensions import Final
from enum import Enum
from opentrons.config.types import LiquidProbeSettings
from opentrons.config.types import LiquidProbeSettings, OutputOptions
from opentrons.protocol_api.labware import Well


Expand Down Expand Up @@ -194,7 +194,7 @@ def _get_liquid_probe_settings(
plunger_speed=lqid_cfg["plunger_speed"],
sensor_threshold_pascals=lqid_cfg["sensor_threshold_pascals"],
expected_liquid_height=110,
log_pressure=True,
output_option=OutputOptions.stream_to_csv,
aspirate_while_sensing=False,
auto_zero_sensor=True,
num_baseline_reads=10,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from opentrons_hardware.firmware_bindings.messages.messages import MessageDefinition
from opentrons_hardware.firmware_bindings.constants import SensorType, SensorId

from opentrons.config.types import LiquidProbeSettings
from opentrons.config.types import LiquidProbeSettings, OutputOptions
from opentrons.hardware_control.types import (
TipStateType,
FailedTipStateCheck,
Expand Down Expand Up @@ -1382,7 +1382,7 @@ async def _test_liquid_probe(
plunger_speed=probe_cfg.plunger_speed,
sensor_threshold_pascals=probe_cfg.sensor_threshold_pascals,
expected_liquid_height=0, # FIXME: remove
log_pressure=False, # FIXME: remove
output_option=OutputOptions.can_bus_only, # FIXME: remove
aspirate_while_sensing=False, # FIXME: I heard this doesn't work
auto_zero_sensor=True, # TODO: when would we want to adjust this?
num_baseline_reads=10, # TODO: when would we want to adjust this?
Expand Down
3 changes: 3 additions & 0 deletions hardware/opentrons_hardware/firmware_bindings/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ class MessageId(int, Enum):
execute_move_group_request = 0x18
clear_all_move_groups_request = 0x19
home_request = 0x20
add_sensor_move_request = 0x23
move_completed = 0x13

motor_position_request = 0x12
Expand Down Expand Up @@ -250,6 +251,7 @@ class MessageId(int, Enum):
peripheral_status_request = 0x8C
peripheral_status_response = 0x8D
baseline_sensor_response = 0x8E
send_accumulated_pressure_data = 0x8F

set_hepa_fan_state_request = 0x90
get_hepa_fan_state_request = 0x91
Expand Down Expand Up @@ -405,6 +407,7 @@ class MoveStopCondition(int, Enum):
stall = 0x10
ignore_stalls = 0x20
limit_switch_backoff = 0x40
sensor_report = 0x80


@unique
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,19 @@ class AddLinearMoveRequest(BaseMessage): # noqa: D101
message_id: Literal[MessageId.add_move_request] = MessageId.add_move_request


@dataclass
class AddSensorLinearMoveRequest(BaseMessage):
"""Sensor Linear Move Request."""

payload: payloads.AddSensorLinearMoveBasePayload
payload_type: Type[
payloads.AddSensorLinearMoveBasePayload
] = payloads.AddSensorLinearMoveBasePayload
message_id: Literal[
MessageId.add_sensor_move_request
] = MessageId.add_sensor_move_request


@dataclass
class GetMoveGroupRequest(BaseMessage): # noqa: D101
payload: payloads.MoveGroupRequestPayload
Expand Down Expand Up @@ -988,3 +1001,16 @@ class GetHepaUVStateResponse(BaseMessage):
message_id: Literal[
MessageId.get_hepa_uv_state_response
] = MessageId.get_hepa_uv_state_response


@dataclass
class SendAccumulatedPressureDataRequest(BaseMessage):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what response message does this use?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this prompts all of the ReadFromSensorResponse messages to be dumped from the array the firmware accumulates during liquid probe

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sends the same ReadFromSensorResponse as we did before

"""Send all the saved sensor data."""

payload: payloads.SendAccumulatedPressureDataPayload
payload_type: Type[
payloads.SendAccumulatedPressureDataPayload
] = payloads.SendAccumulatedPressureDataPayload
message_id: Literal[
MessageId.send_accumulated_pressure_data
] = MessageId.send_accumulated_pressure_data
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@
defs.SetHepaUVStateRequest,
defs.GetHepaUVStateRequest,
defs.GetHepaUVStateResponse,
defs.SendAccumulatedPressureDataRequest,
defs.AddSensorLinearMoveRequest,
]


Expand Down
Loading
Loading