Skip to content

Commit 2aee023

Browse files
committed
Merge branch 'edge' into testing-1000ul-height-estimation
2 parents 6fc2fc0 + c7bcbad commit 2aee023

File tree

360 files changed

+9190
-4325
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

360 files changed

+9190
-4325
lines changed

api-client/src/maintenance_runs/types.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type {
77
import type {
88
RunCommandSummary,
99
LegacyLabwareOffsetCreateData,
10+
LabwareOffsetCreateData,
1011
RunStatus,
1112
RunAction,
1213
} from '../runs'
@@ -42,7 +43,7 @@ export interface MaintenanceRunError {
4243
}
4344

4445
export interface CreateMaintenanceRunData {
45-
labwareOffsets?: LegacyLabwareOffsetCreateData[]
46+
labwareOffsets?: LegacyLabwareOffsetCreateData[] | LabwareOffsetCreateData[]
4647
}
4748

4849
export interface LabwareDefinitionSummary {

api-client/src/runs/types.ts

+6
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,12 @@ export interface LegacyLabwareOffsetCreateData {
172172
vector: VectorOffset
173173
}
174174

175+
export interface LabwareOffsetCreateData {
176+
definitionUri: string
177+
locationSequence: LabwareOffsetLocationSequence
178+
vector: VectorOffset
179+
}
180+
175181
type RunTimeParameterValuesType = string | number | boolean | { id: string }
176182
export type RunTimeParameterValuesCreateData = Record<
177183
string,

api-client/src/types.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { AxiosRequestConfig } from 'axios'
22
import type { ResponsePromise } from './request'
3-
import type { ModuleModel } from '@opentrons/shared-data'
3+
import type { AddressableAreaName, ModuleModel } from '@opentrons/shared-data'
44

55
export interface HostConfig {
66
hostname: string
@@ -60,7 +60,7 @@ export interface OnModuleOffsetLocationSequenceComponent
6060
export interface OnAddressableAreaOffsetLocationSequenceComponent
6161
extends BaseOffsetLocationSequenceComponent {
6262
kind: 'onAddressableArea'
63-
addressableAreaName: string
63+
addressableAreaName: AddressableAreaName
6464
}
6565

6666
export type LabwareOffsetLocationSequenceComponent =

api/src/opentrons/drivers/flex_stacker/driver.py

+55-53
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
StackerInfo,
2121
HardwareRevision,
2222
MoveParams,
23+
AxisParams,
2324
LimitSwitchStatus,
2425
LEDColor,
2526
StallGuardParams,
@@ -57,56 +58,67 @@
5758
STALLGUARD_CONFIG = {
5859
StackerAxis.X: StallGuardParams(StackerAxis.X, True, 2),
5960
StackerAxis.Z: StallGuardParams(StackerAxis.Z, True, 2),
60-
StackerAxis.L: StallGuardParams(StackerAxis.L, True, 2),
6161
}
6262

6363
STACKER_MOTION_CONFIG = {
6464
StackerAxis.X: {
65-
"home": MoveParams(
66-
StackerAxis.X,
67-
max_speed=10.0, # mm/s
68-
acceleration=100.0, # mm/s^2
69-
max_speed_discont=40, # mm/s
70-
current=1.5, # mAmps
65+
"home": AxisParams(
66+
run_current=1.5, # mAmps
67+
hold_current=0.75,
68+
move_params=MoveParams(
69+
max_speed=10.0, # mm/s
70+
acceleration=100.0, # mm/s^2
71+
max_speed_discont=40.0, # mm/s
72+
),
7173
),
72-
"move": MoveParams(
73-
StackerAxis.X,
74-
max_speed=200.0,
75-
acceleration=1500.0,
76-
max_speed_discont=40,
77-
current=1.0,
74+
"move": AxisParams(
75+
run_current=1.0,
76+
hold_current=0.75,
77+
move_params=MoveParams(
78+
max_speed=200.0,
79+
acceleration=1500.0,
80+
max_speed_discont=40.0,
81+
),
7882
),
7983
},
8084
StackerAxis.Z: {
81-
"home": MoveParams(
82-
StackerAxis.Z,
83-
max_speed=10.0,
84-
acceleration=100.0,
85-
max_speed_discont=40,
86-
current=1.5,
85+
"home": AxisParams(
86+
run_current=1.5,
87+
hold_current=1.8,
88+
move_params=MoveParams(
89+
max_speed=10.0,
90+
acceleration=100.0,
91+
max_speed_discont=25.0,
92+
),
8793
),
88-
"move": MoveParams(
89-
StackerAxis.Z,
90-
max_speed=200.0,
91-
acceleration=500.0,
92-
max_speed_discont=40,
93-
current=1.5,
94+
"move": AxisParams(
95+
run_current=1.5,
96+
hold_current=0.5,
97+
move_params=MoveParams(
98+
max_speed=150.0,
99+
acceleration=500.0,
100+
max_speed_discont=25.0,
101+
),
94102
),
95103
},
96104
StackerAxis.L: {
97-
"home": MoveParams(
98-
StackerAxis.L,
99-
max_speed=100.0,
100-
acceleration=800.0,
101-
max_speed_discont=40,
102-
current=0.8,
105+
"home": AxisParams(
106+
run_current=0.8,
107+
hold_current=0.15,
108+
move_params=MoveParams(
109+
max_speed=100.0,
110+
acceleration=800.0,
111+
max_speed_discont=40.0,
112+
),
103113
),
104-
"move": MoveParams(
105-
StackerAxis.L,
106-
max_speed=100.0,
107-
acceleration=800.0,
108-
max_speed_discont=40,
109-
current=0.6,
114+
"move": AxisParams(
115+
run_current=0.6,
116+
hold_current=0.15,
117+
move_params=MoveParams(
118+
max_speed=100.0,
119+
acceleration=800.0,
120+
max_speed_discont=40.0,
121+
),
110122
),
111123
},
112124
}
@@ -183,18 +195,12 @@ def parse_installation_detected(cls, response: str) -> bool:
183195
def parse_move_params(cls, response: str) -> MoveParams:
184196
"""Parse move params."""
185197
field_names = MoveParams.get_fields()
186-
pattern = r"\s".join(
187-
[
188-
rf"{f}:(?P<{f}>(\d*\.)?\d+)" if f != "M" else rf"{f}:(?P<{f}>[XZL])"
189-
for f in field_names
190-
]
191-
)
192-
_RE = re.compile(f"^{GCODE.GET_MOVE_PARAMS} {pattern}$")
198+
pattern = r"\s".join(rf"{f}:(?P<{f}>(\d*\.)?\d+)" for f in field_names)
199+
_RE = re.compile(rf"^{GCODE.GET_MOVE_PARAMS} M:([XZL]) {pattern}$")
193200
m = _RE.match(response)
194201
if not m:
195202
raise ValueError(f"Incorrect Response for move params: {response}")
196203
return MoveParams(
197-
axis=StackerAxis(m.group("M")),
198204
max_speed=float(m.group("V")),
199205
acceleration=float(m.group("A")),
200206
max_speed_discont=float(m.group("D")),
@@ -294,14 +300,9 @@ def append_move_params(
294300
) -> CommandBuilder:
295301
"""Append move params."""
296302
if params is not None:
297-
if params.max_speed is not None:
298-
command.add_float("V", params.max_speed, GCODE_ROUNDING_PRECISION)
299-
if params.acceleration is not None:
300-
command.add_float("A", params.acceleration, GCODE_ROUNDING_PRECISION)
301-
if params.max_speed_discont is not None:
302-
command.add_float(
303-
"D", params.max_speed_discont, GCODE_ROUNDING_PRECISION
304-
)
303+
command.add_float("V", params.max_speed, GCODE_ROUNDING_PRECISION)
304+
command.add_float("A", params.acceleration, GCODE_ROUNDING_PRECISION)
305+
command.add_float("D", params.max_speed_discont, GCODE_ROUNDING_PRECISION)
305306
return command
306307

307308
@classmethod
@@ -410,6 +411,7 @@ async def set_stallguard_threshold(
410411
self, axis: StackerAxis, enable: bool, threshold: int
411412
) -> bool:
412413
"""Enables and sets the stallguard threshold for the given axis motor."""
414+
assert axis != StackerAxis.L, "Stallguard not supported for L axis"
413415
if not -64 < threshold < 63:
414416
raise ValueError(
415417
f"Threshold value ({threshold}) should be between -64 and 63."

api/src/opentrons/drivers/flex_stacker/errors.py

+8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@
77
)
88

99

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+
1017
class MotorStallDetected(ErrorResponse):
1118
"""Raised when a motor stall is detected."""
1219

@@ -47,6 +54,7 @@ class StackerErrorCodes(BaseErrorCode):
4754
"""Stacker-specific error codes."""
4855

4956
UNHANDLED_GCODE = ("ERR003", UnhandledGcode)
57+
ESTOP_TRIGGERED = ("ERR006", EStopTriggered)
5058
MOTOR_STALL_DETECTED = ("ERR403", MotorStallDetected)
5159
MOTOR_QUEUE_FULL = ("ERR404", MotorQueueFull)
5260
UNEXPECTED_LIMIT_SWITCH = ("ERR405", UnexpectedLimitSwitch)

api/src/opentrons/drivers/flex_stacker/simulator.py

+9-7
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ def __init__(self, serial_number: Optional[str] = None) -> None:
4545
self._tof_registers: Dict[TOFSensor, Dict[int, int]] = {
4646
a: {} for a in TOFSensor
4747
}
48+
self._tof_sensor_status: Dict[TOFSensor, TOFSensorStatus] = {
49+
s: TOFSensorStatus(s, TOFSensorState.IDLE, TOFSensorMode.MEASURE, True)
50+
for s in TOFSensor
51+
}
4852

4953
def set_limit_switch(self, status: LimitSwitchStatus) -> bool:
5054
self._limit_switch_status = status
@@ -116,6 +120,9 @@ async def set_stallguard_threshold(
116120
@ensure_yield
117121
async def enable_tof_sensor(self, sensor: TOFSensor, enable: bool) -> bool:
118122
"""Enable or disable the TOF sensor."""
123+
state = TOFSensorState.IDLE if enable else TOFSensorState.DISABLED
124+
self._tof_sensor_status[sensor].state = state
125+
self._tof_sensor_status[sensor].ok = enable
119126
return True
120127

121128
@ensure_yield
@@ -174,17 +181,12 @@ async def get_tof_driver_register(self, sensor: TOFSensor, reg: int) -> int:
174181
@ensure_yield
175182
async def get_tof_sensor_status(self, sensor: TOFSensor) -> TOFSensorStatus:
176183
"""Get the status of the tof sensor."""
177-
return TOFSensorStatus(
178-
sensor=sensor,
179-
mode=TOFSensorMode.MEASURE,
180-
state=TOFSensorState.IDLE,
181-
ok=True,
182-
)
184+
return self._tof_sensor_status[sensor]
183185

184186
@ensure_yield
185187
async def get_motion_params(self, axis: StackerAxis) -> MoveParams:
186188
"""Get the motion parameters used by the given axis motor."""
187-
return MoveParams(axis, 1, 1, 1)
189+
return MoveParams(1, 1, 1)
188190

189191
@ensure_yield
190192
async def get_stallguard_threshold(self, axis: StackerAxis) -> StallGuardParams:

api/src/opentrons/drivers/flex_stacker/types.py

+30-6
Original file line numberDiff line numberDiff line change
@@ -207,16 +207,40 @@ class TOFSensorStatus:
207207
class MoveParams:
208208
"""Move Parameters."""
209209

210-
axis: Optional[StackerAxis] = None
211-
max_speed: Optional[float] = None
212-
acceleration: Optional[float] = None
213-
max_speed_discont: Optional[float] = None
214-
current: Optional[float] = 0
210+
max_speed: float
211+
acceleration: float
212+
max_speed_discont: float
215213

216214
@classmethod
217215
def get_fields(cls) -> List[str]:
218216
"""Get parsing fields."""
219-
return ["M", "V", "A", "D"]
217+
return ["V", "A", "D"]
218+
219+
def update(
220+
self,
221+
max_speed: Optional[float] = None,
222+
acceleration: Optional[float] = None,
223+
max_speed_discont: Optional[float] = None,
224+
) -> "MoveParams":
225+
"""Update the move parameters and return a new object."""
226+
return MoveParams(
227+
max_speed=max_speed if max_speed is not None else self.max_speed,
228+
acceleration=acceleration
229+
if acceleration is not None
230+
else self.acceleration,
231+
max_speed_discont=max_speed_discont
232+
if max_speed_discont is not None
233+
else self.max_speed_discont,
234+
)
235+
236+
237+
@dataclass
238+
class AxisParams:
239+
"""Axis Parameters."""
240+
241+
run_current: float
242+
hold_current: float
243+
move_params: MoveParams
220244

221245

222246
@dataclass

api/src/opentrons/drivers/flex_stacker/utils.py

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
NUMBER_OF_ZONES = 10
2+
NUMBER_OF_BINS = 128
3+
4+
15
def validate_histogram_frame(data: bytes, next_frame_id: int) -> bool:
26
"""Validate Histogram frame, Raise error if invalid."""
37
start_delimn = data[0]

0 commit comments

Comments
 (0)