Skip to content

Commit

Permalink
Merge branch 'edge' into opentrons-ai-client-landing-page
Browse files Browse the repository at this point in the history
  • Loading branch information
fbelginetw committed Oct 21, 2024
2 parents fde8b2c + 0fc0db9 commit ddb7ebc
Show file tree
Hide file tree
Showing 44 changed files with 1,044 additions and 685 deletions.
9 changes: 9 additions & 0 deletions api/src/opentrons/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,15 @@ class ConfigElement(NamedTuple):
" absolute path, it will be used directly. If it is a "
"relative path it will be relative to log_dir",
),
ConfigElement(
"sensor_log_file",
"Sensor Log File",
Path("logs") / "sensor.log",
ConfigElementType.FILE,
"The location of the file to save sensor logs to. If this is an"
" absolute path, it will be used directly. If it is a "
"relative path it will be relative to log_dir",
),
ConfigElement(
"serial_log_file",
"Serial Log File",
Expand Down
36 changes: 0 additions & 36 deletions api/src/opentrons/config/defaults_ot3.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
LiquidProbeSettings,
ZSenseSettings,
EdgeSenseSettings,
OutputOptions,
)


Expand All @@ -27,13 +26,11 @@
plunger_speed=15,
plunger_impulse_time=0.2,
sensor_threshold_pascals=15,
output_option=OutputOptions.sync_buffer_to_csv,
aspirate_while_sensing=False,
z_overlap_between_passes_mm=0.1,
plunger_reset_offset=2.0,
samples_for_baselining=20,
sample_time_sec=0.004,
data_files={InstrumentProbeType.PRIMARY: "/data/pressure_sensor_data.csv"},
)

DEFAULT_CALIBRATION_SETTINGS: Final[OT3CalibrationSettings] = OT3CalibrationSettings(
Expand All @@ -43,7 +40,6 @@
max_overrun_distance_mm=5.0,
speed_mm_per_s=1.0,
sensor_threshold_pf=3.0,
output_option=OutputOptions.sync_only,
),
),
edge_sense=EdgeSenseSettings(
Expand All @@ -54,7 +50,6 @@
max_overrun_distance_mm=0.5,
speed_mm_per_s=1,
sensor_threshold_pf=3.0,
output_option=OutputOptions.sync_only,
),
search_initial_tolerance_mm=12.0,
search_iteration_limit=8,
Expand Down Expand Up @@ -195,23 +190,6 @@
)


def _build_output_option_with_default(
from_conf: Any, default: OutputOptions
) -> OutputOptions:
if from_conf is None:
return default
else:
if isinstance(from_conf, OutputOptions):
return from_conf
else:
try:
enumval = OutputOptions[from_conf]
except KeyError: # not an enum entry
return default
else:
return enumval


def _build_log_files_with_default(
from_conf: Any,
default: Optional[Dict[InstrumentProbeType, str]],
Expand Down Expand Up @@ -316,24 +294,12 @@ def _build_default_cap_pass(
sensor_threshold_pf=from_conf.get(
"sensor_threshold_pf", default.sensor_threshold_pf
),
output_option=from_conf.get("output_option", default.output_option),
)


def _build_default_liquid_probe(
from_conf: Any, default: LiquidProbeSettings
) -> LiquidProbeSettings:
output_option = _build_output_option_with_default(
from_conf.get("output_option", None), default.output_option
)
data_files: Optional[Dict[InstrumentProbeType, str]] = None
if (
output_option is OutputOptions.sync_buffer_to_csv
or output_option is OutputOptions.stream_to_csv
):
data_files = _build_log_files_with_default(
from_conf.get("data_files", None), default.data_files
)
return LiquidProbeSettings(
mount_speed=from_conf.get("mount_speed", default.mount_speed),
plunger_speed=from_conf.get("plunger_speed", default.plunger_speed),
Expand All @@ -343,7 +309,6 @@ def _build_default_liquid_probe(
sensor_threshold_pascals=from_conf.get(
"sensor_threshold_pascals", default.sensor_threshold_pascals
),
output_option=from_conf.get("output_option", default.output_option),
aspirate_while_sensing=from_conf.get(
"aspirate_while_sensing", default.aspirate_while_sensing
),
Expand All @@ -357,7 +322,6 @@ def _build_default_liquid_probe(
"samples_for_baselining", default.samples_for_baselining
),
sample_time_sec=from_conf.get("sample_time_sec", default.sample_time_sec),
data_files=data_files,
)


Expand Down
19 changes: 2 additions & 17 deletions api/src/opentrons/config/types.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from enum import Enum
from dataclasses import dataclass, asdict, fields
from typing import Dict, Tuple, TypeVar, Generic, List, cast, Optional
from typing import Dict, Tuple, TypeVar, Generic, List, cast
from typing_extensions import TypedDict, Literal
from opentrons.hardware_control.types import OT3AxisKind, InstrumentProbeType
from opentrons.hardware_control.types import OT3AxisKind


class AxisDict(TypedDict):
Expand Down Expand Up @@ -103,25 +103,12 @@ def by_gantry_load(
)


class OutputOptions(int, Enum):
"""Specifies where we should report sensor data to during a sensor pass."""

stream_to_csv = 0x1 # compile sensor data stream into a csv file, in addition to can_bus_only behavior
sync_buffer_to_csv = 0x2 # collect sensor data on pipette mcu, then stream to robot server and compile into a csv file, in addition to can_bus_only behavior
can_bus_only = (
0x4 # stream sensor data over CAN bus, in addition to sync_only behavior
)
sync_only = 0x8 # trigger pipette sync line upon sensor's detection of something


@dataclass(frozen=True)
class CapacitivePassSettings:
prep_distance_mm: float
max_overrun_distance_mm: float
speed_mm_per_s: float
sensor_threshold_pf: float
output_option: OutputOptions
data_files: Optional[Dict[InstrumentProbeType, str]] = None


@dataclass(frozen=True)
Expand All @@ -135,13 +122,11 @@ class LiquidProbeSettings:
plunger_speed: float
plunger_impulse_time: float
sensor_threshold_pascals: float
output_option: OutputOptions
aspirate_while_sensing: bool
z_overlap_between_passes_mm: float
plunger_reset_offset: float
samples_for_baselining: int
sample_time_sec: float
data_files: Optional[Dict[InstrumentProbeType, str]]


@dataclass(frozen=True)
Expand Down
11 changes: 6 additions & 5 deletions api/src/opentrons/hardware_control/backends/flex_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from opentrons_shared_data.pipette.types import (
PipetteName,
)
from opentrons.config.types import GantryLoad, OutputOptions
from opentrons.config.types import GantryLoad
from opentrons.hardware_control.types import (
BoardRevision,
Axis,
Expand All @@ -38,6 +38,8 @@
StatusBarState,
)
from opentrons.hardware_control.module_control import AttachedModulesControl
from opentrons_hardware.firmware_bindings.constants import SensorId
from opentrons_hardware.sensors.types import SensorDataType
from ..dev_types import OT3AttachedInstruments
from .types import HWStopCondition

Expand Down Expand Up @@ -152,10 +154,11 @@ async def liquid_probe(
threshold_pascals: float,
plunger_impulse_time: float,
num_baseline_reads: int,
output_format: OutputOptions = OutputOptions.can_bus_only,
data_files: Optional[Dict[InstrumentProbeType, str]] = None,
probe: InstrumentProbeType = InstrumentProbeType.PRIMARY,
force_both_sensors: bool = False,
response_queue: Optional[
asyncio.Queue[Dict[SensorId, List[SensorDataType]]]
] = None,
) -> float:
...

Expand Down Expand Up @@ -371,8 +374,6 @@ async def capacitive_probe(
speed_mm_per_s: float,
sensor_threshold_pf: float,
probe: InstrumentProbeType = InstrumentProbeType.PRIMARY,
output_format: OutputOptions = OutputOptions.sync_only,
data_files: Optional[Dict[InstrumentProbeType, str]] = None,
) -> bool:
...

Expand Down
57 changes: 7 additions & 50 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, OutputOptions
from opentrons.config.types import OT3Config, GantryLoad
from opentrons.config import gripper_config
from .ot3utils import (
axis_convert,
Expand Down Expand Up @@ -102,7 +102,9 @@
NodeId,
PipetteName as FirmwarePipetteName,
ErrorCode,
SensorId,
)
from opentrons_hardware.sensors.types import SensorDataType
from opentrons_hardware.firmware_bindings.messages.message_definitions import (
StopRequest,
)
Expand Down Expand Up @@ -1368,28 +1370,14 @@ async def liquid_probe(
threshold_pascals: float,
plunger_impulse_time: float,
num_baseline_reads: int,
output_option: OutputOptions = OutputOptions.can_bus_only,
data_files: Optional[Dict[InstrumentProbeType, str]] = None,
probe: InstrumentProbeType = InstrumentProbeType.PRIMARY,
force_both_sensors: bool = False,
response_queue: Optional[
asyncio.Queue[Dict[SensorId, List[SensorDataType]]]
] = None,
) -> float:
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
)
data_files_transposed = (
None
if data_files is None
else {
sensor_id_for_instrument(probe): data_files[probe]
for probe in data_files.keys()
}
)
positions = await liquid_probe(
messenger=self._messenger,
tool=tool,
Expand All @@ -1400,12 +1388,9 @@ async def liquid_probe(
threshold_pascals=threshold_pascals,
plunger_impulse_time=plunger_impulse_time,
num_baseline_reads=num_baseline_reads,
csv_output=csv_output,
sync_buffer_output=sync_buffer_output,
can_bus_only_output=can_bus_only_output,
data_files=data_files_transposed,
sensor_id=sensor_id_for_instrument(probe),
force_both_sensors=force_both_sensors,
response_queue=response_queue,
)
for node, point in positions.items():
self._position.update({node: point.motor_position})
Expand All @@ -1432,41 +1417,13 @@ async def capacitive_probe(
speed_mm_per_s: float,
sensor_threshold_pf: float,
probe: InstrumentProbeType = InstrumentProbeType.PRIMARY,
output_option: OutputOptions = OutputOptions.sync_only,
data_files: Optional[Dict[InstrumentProbeType, str]] = None,
) -> bool:
if output_option == OutputOptions.sync_buffer_to_csv:
assert (
self._subsystem_manager.device_info[
SubSystem.of_mount(mount)
].revision.tertiary
== "1"
)
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
)
data_files_transposed = (
None
if data_files is None
else {
sensor_id_for_instrument(probe): data_files[probe]
for probe in data_files.keys()
}
)
status = await capacitive_probe(
messenger=self._messenger,
tool=sensor_node_for_mount(mount),
mover=axis_to_node(moving),
distance=distance_mm,
mount_speed=speed_mm_per_s,
csv_output=csv_output,
sync_buffer_output=sync_buffer_output,
can_bus_only_output=can_bus_only_output,
data_files=data_files_transposed,
sensor_id=sensor_id_for_instrument(probe),
relative_threshold_pf=sensor_threshold_pf,
)
Expand Down
12 changes: 6 additions & 6 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, OutputOptions
from opentrons.config.types import OT3Config, GantryLoad
from opentrons.config import gripper_config

from opentrons.hardware_control.module_control import AttachedModulesControl
Expand Down Expand Up @@ -63,7 +63,8 @@
from opentrons.util.async_helpers import ensure_yield
from .types import HWStopCondition
from .flex_protocol import FlexBackend

from opentrons_hardware.firmware_bindings.constants import SensorId
from opentrons_hardware.sensors.types import SensorDataType

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -347,10 +348,11 @@ async def liquid_probe(
threshold_pascals: float,
plunger_impulse_time: float,
num_baseline_reads: int,
output_format: OutputOptions = OutputOptions.can_bus_only,
data_files: Optional[Dict[InstrumentProbeType, str]] = None,
probe: InstrumentProbeType = InstrumentProbeType.PRIMARY,
force_both_sensors: bool = False,
response_queue: Optional[
asyncio.Queue[Dict[SensorId, List[SensorDataType]]]
] = None,
) -> float:
z_axis = Axis.by_mount(mount)
pos = self._position
Expand Down Expand Up @@ -750,8 +752,6 @@ async def capacitive_probe(
speed_mm_per_s: float,
sensor_threshold_pf: float,
probe: InstrumentProbeType = InstrumentProbeType.PRIMARY,
output_format: OutputOptions = OutputOptions.sync_only,
data_files: Optional[Dict[InstrumentProbeType, str]] = None,
) -> bool:
self._position[moving] += distance_mm
return True
Expand Down
Loading

0 comments on commit ddb7ebc

Please sign in to comment.