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

feat(hardware): add csv file logging capability to capacitive_probe method #14785

Merged
merged 23 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,6 @@ opentrons-robot-app.tar.gz
# asdf versions file
.tool-versions
mock_dir
hardware/.npm-cache/_update-notifier-last-checked
pmoegenburg marked this conversation as resolved.
Show resolved Hide resolved
hardware/.npm-cache/_cacache/content-v2/sha512/e0/f2/0b78b807658be0f5790f7dfcb48708e26a9ed3a9632250264215afa1e5a04fee513f603e12351fcbd1e18e9c6d553cac9858275e1b00cb6d3a049ab6a435
pmoegenburg marked this conversation as resolved.
Show resolved Hide resolved
hardware/.npm-cache/_cacache/index-v5/af/03/5c781820370e585dc2323edbbc80669bf714da5b47d56510c7d0bd7521ee
6 changes: 6 additions & 0 deletions api/src/opentrons/config/defaults_ot3.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
max_overrun_distance_mm=5.0,
speed_mm_per_s=1.0,
sensor_threshold_pf=3.0,
output_option=OutputOptions.stream_to_csv,
pmoegenburg marked this conversation as resolved.
Show resolved Hide resolved
data_file="/var/capacitive_sensor_data.csv",
),
),
edge_sense=EdgeSenseSettings(
Expand All @@ -54,6 +56,8 @@
max_overrun_distance_mm=0.5,
speed_mm_per_s=1,
sensor_threshold_pf=3.0,
output_option=OutputOptions.stream_to_csv,
data_file="/var/capacitive_sensor_data.csv",
pmoegenburg marked this conversation as resolved.
Show resolved Hide resolved
),
search_initial_tolerance_mm=12.0,
search_iteration_limit=8,
Expand Down Expand Up @@ -272,6 +276,8 @@ 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),
data_file=from_conf.get("data_file", default.data_file),
)


Expand Down
22 changes: 12 additions & 10 deletions api/src/opentrons/config/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,29 +103,31 @@ def by_gantry_load(
)


# str enum so it can be json serializable
pmoegenburg marked this conversation as resolved.
Show resolved Hide resolved
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
pmoegenburg marked this conversation as resolved.
Show resolved Hide resolved


@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_file: Optional[str]


@dataclass(frozen=True)
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 Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,8 @@ async def capacitive_probe(
speed_mm_per_s: float,
sensor_threshold_pf: float,
probe: InstrumentProbeType,
output_format: OutputOptions = OutputOptions.can_bus_only,
data_file: Optional[str] = None,
) -> bool:
...

Expand Down
32 changes: 26 additions & 6 deletions api/src/opentrons/hardware_control/backends/ot3controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -1401,14 +1401,34 @@ async def capacitive_probe(
speed_mm_per_s: float,
sensor_threshold_pf: float,
probe: InstrumentProbeType,
output_option: OutputOptions = OutputOptions.can_bus_only,
data_file: Optional[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
pmoegenburg marked this conversation as resolved.
Show resolved Hide resolved
)
can_bus_only_output = bool(
output_option.value & OutputOptions.can_bus_only.value
)
status = await capacitive_probe(
self._messenger,
sensor_node_for_mount(mount),
axis_to_node(moving),
distance_mm,
speed_mm_per_s,
sensor_id_for_instrument(probe),
messenger=self._messenger,
tool=sensor_node_for_mount(mount),
mover=axis_to_node(moving),
distance=distance_mm,
speed=speed_mm_per_s,
csv_output=csv_output,
sync_buffer_output=sync_buffer_output,
can_bus_only_output=can_bus_only_output,
data_file=data_file,
sensor_id=sensor_id_for_instrument(probe),
relative_threshold_pf=sensor_threshold_pf,
)

Expand Down
2 changes: 2 additions & 0 deletions api/src/opentrons/hardware_control/backends/ot3simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,8 @@ async def capacitive_probe(
speed_mm_per_s: float,
sensor_threshold_pf: float,
probe: InstrumentProbeType,
output_format: OutputOptions = OutputOptions.can_bus_only,
data_file: Optional[str] = None,
) -> bool:
self._position[moving] += distance_mm
return True
Expand Down
6 changes: 4 additions & 2 deletions api/src/opentrons/hardware_control/ot3api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2587,7 +2587,7 @@ async def liquid_probe(
await self.move_to(mount, probe_start_pos)
return end_pos.z

async def capacitive_probe(
async def capacitive_probe( # careful with changes, this is what calibration uses
pmoegenburg marked this conversation as resolved.
Show resolved Hide resolved
self,
mount: OT3Mount,
moving_axis: Axis,
Expand Down Expand Up @@ -2639,7 +2639,9 @@ async def capacitive_probe(
machine_pass_distance,
pass_settings.speed_mm_per_s,
pass_settings.sensor_threshold_pf,
probe=probe,
probe,
pass_settings.output_option,
pass_settings.data_file,
)
end_pos = await self.gantry_position(mount, refresh=True)
if retract_after:
Expand Down
4 changes: 4 additions & 0 deletions api/tests/opentrons/config/ot3_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@
"max_overrun_distance_mm": 2,
"speed_mm_per_s": 3,
"sensor_threshold_pf": 4,
"output_option": OutputOptions.stream_to_csv,
"data_file": "/var/capacitive_sensor_data.csv",
},
},
"edge_sense": {
Expand All @@ -148,6 +150,8 @@
"max_overrun_distance_mm": 5,
"speed_mm_per_s": 6,
"sensor_threshold_pf": 7,
"output_option": OutputOptions.stream_to_csv,
"data_file": "/var/capacitive_sensor_data.csv",
},
"search_initial_tolerance_mm": 18,
"search_iteration_limit": 3,
Expand Down
13 changes: 12 additions & 1 deletion api/tests/opentrons/hardware_control/test_ot3_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ def fake_settings() -> CapacitivePassSettings:
max_overrun_distance_mm=2,
speed_mm_per_s=4,
sensor_threshold_pf=1.0,
output_option=OutputOptions.can_bus_only,
data_file="fake_file_name",
)


Expand Down Expand Up @@ -486,6 +488,8 @@ def _update_position(
speed_mm_per_s: float,
threshold_pf: float,
probe: InstrumentProbeType,
output_option: OutputOptions = OutputOptions.can_bus_only,
data_file: Optional[str] = None,
) -> None:
hardware_backend._position[moving] += distance_mm / 2

Expand Down Expand Up @@ -865,7 +869,14 @@ async def test_capacitive_probe(
# This is a negative probe because the current position is the home position
# which is very large.
mock_backend_capacitive_probe.assert_called_once_with(
mount, moving, 3, 4, 1.0, InstrumentProbeType.PRIMARY
mount,
moving,
3,
4,
1.0,
InstrumentProbeType.PRIMARY,
fake_settings.output_option,
fake_settings.data_file,
)

original = moving.set_in_point(here, 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import argparse
import asyncio

from opentrons.config.types import CapacitivePassSettings
from opentrons.config.types import CapacitivePassSettings, OutputOptions
from opentrons.hardware_control.ot3api import OT3API

from hardware_testing.opentrons_api import types
Expand Down Expand Up @@ -44,12 +44,16 @@
max_overrun_distance_mm=3,
speed_mm_per_s=1,
sensor_threshold_pf=STABLE_CAP_PF,
output_option=OutputOptions.can_bus_only,
data_file="fake_file_name",
)
PROBE_SETTINGS_XY_AXIS = CapacitivePassSettings(
prep_distance_mm=CUTOUT_SIZE / 2,
max_overrun_distance_mm=3,
speed_mm_per_s=1,
sensor_threshold_pf=STABLE_CAP_PF,
output_option=OutputOptions.can_bus_only,
data_file="fake_file_name",
)


Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Test Instruments."""
from typing import List, Tuple, Optional, Union

from opentrons.config.types import CapacitivePassSettings
from opentrons.config.types import CapacitivePassSettings, OutputOptions
from opentrons.hardware_control.ot3api import OT3API

from hardware_testing.data.csv_report import (
Expand Down Expand Up @@ -30,6 +30,8 @@
max_overrun_distance_mm=0,
speed_mm_per_s=Z_PROBE_DISTANCE_MM / Z_PROBE_TIME_SECONDS,
sensor_threshold_pf=1.0,
output_option=OutputOptions.can_bus_only,
data_file="fake_file_name",
)

RELATIVE_MOVE_FROM_HOME_DELTA = Point(x=-500, y=-300)
Expand Down
4 changes: 3 additions & 1 deletion hardware-testing/hardware_testing/scripts/gripper_ot3.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from dataclasses import dataclass
from typing import Optional, List, Any, Dict

from opentrons.config.defaults_ot3 import CapacitivePassSettings
from opentrons.config.defaults_ot3 import CapacitivePassSettings, OutputOptions
from opentrons.hardware_control.ot3api import OT3API

from hardware_testing.opentrons_api import types
Expand Down Expand Up @@ -73,6 +73,8 @@
max_overrun_distance_mm=1,
speed_mm_per_s=1,
sensor_threshold_pf=0.5,
output_option=OutputOptions.can_bus_only,
data_file="fake_file_name",
)
LABWARE_PROBE_CORNER_TOP_LEFT_XY = {
"plate": Point(x=5, y=-5),
Expand Down
5 changes: 3 additions & 2 deletions hardware/opentrons_hardware/firmware_bindings/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ class MessageId(int, Enum):
peripheral_status_request = 0x8C
peripheral_status_response = 0x8D
baseline_sensor_response = 0x8E
send_accumulated_pressure_data = 0x8F
send_accumulated_sensor_data = 0x8F

set_hepa_fan_state_request = 0x90
get_hepa_fan_state_request = 0x91
Expand Down Expand Up @@ -420,7 +420,8 @@ class MoveStopCondition(int, Enum):
stall = 0x10
ignore_stalls = 0x20
limit_switch_backoff = 0x40
sensor_report = 0x80
pressure_sensor_report = 0x80
capacitive_sensor_report = 0x81 # make sure this format works with firmware!!!


@unique
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1024,13 +1024,13 @@ class GetHepaUVStateResponse(BaseMessage):


@dataclass
class SendAccumulatedPressureDataRequest(BaseMessage):
class SendAccumulatedSensorDataRequest(BaseMessage):
"""Send all the saved sensor data."""

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


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ class AddSensorLinearMoveBasePayload(AddLinearMoveRequestPayload):
"""A request to add a linear move that also requires sensor reading for its duration."""

sensor_id: SensorIdField
sensor_type: SensorTypeField


@dataclass(eq=False)
Expand Down Expand Up @@ -687,7 +688,8 @@ class GetHepaUVStatePayloadResponse(EmptyPayload):


@dataclass(eq=False)
class SendAccumulatedPressureDataPayload(EmptyPayload):
class SendAccumulatedSensorDataPayload(EmptyPayload):
"""Send queued readings from a sensor."""

sensor_id: SensorIdField
sensor_type: SensorTypeField
6 changes: 4 additions & 2 deletions hardware/opentrons_hardware/hardware_control/motion.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class MoveType(int, Enum):
home = 0x1
calibration = 0x2
grip = 0x3
sensor = 0x4
pressure_sensor = 0x4
capacitive_sensor = 0x5

@classmethod
def get_move_type(cls, condition: MoveStopCondition) -> "MoveType":
Expand All @@ -37,7 +38,8 @@ def get_move_type(cls, condition: MoveStopCondition) -> "MoveType":
MoveStopCondition.gripper_force: cls.grip,
MoveStopCondition.stall: cls.linear,
MoveStopCondition.limit_switch_backoff: cls.linear,
MoveStopCondition.sensor_report: cls.sensor,
MoveStopCondition.pressure_sensor_report: cls.pressure_sensor,
MoveStopCondition.capacitive_sensor_report: cls.capacitive_sensor,
}
return mapping[condition]

Expand Down
Loading
Loading