Skip to content

Commit aa02e10

Browse files
authored
fix(app): update robot state in Quick transfer (#18995)
closes AUTH-2133
1 parent 1ceeb66 commit aa02e10

File tree

3 files changed

+120
-85
lines changed

3 files changed

+120
-85
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import * as StepGeneration from '@opentrons/step-generation'
2+
3+
import type { MoveLiquidStepArgs } from './generateQuickTransferArgs'
4+
5+
export const createCommandCreatorFromStepArgs = (
6+
args: MoveLiquidStepArgs
7+
): StepGeneration.CurriedCommandCreator | null => {
8+
if (args == null) {
9+
return null
10+
}
11+
12+
switch (args.commandCreatorFnName) {
13+
case 'transfer': {
14+
return StepGeneration.curryCommandCreator(StepGeneration.transfer, args)
15+
}
16+
case 'consolidate': {
17+
return StepGeneration.curryCommandCreator(
18+
StepGeneration.consolidate,
19+
args
20+
)
21+
}
22+
case 'distribute': {
23+
return StepGeneration.curryCommandCreator(StepGeneration.distribute, args)
24+
}
25+
}
26+
}

app/src/organisms/ODD/QuickTransferFlow/utils/createQuickTransferFile.ts

Lines changed: 12 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,28 @@
1+
import flatMap from 'lodash/flatMap'
12
import uuidv1 from 'uuid/v4'
23

34
import {
45
FLEX_ROBOT_TYPE,
56
FLEX_STANDARD_DECKID,
67
getAllLiquidClassDefs,
7-
getDeckDefFromRobotType,
88
getFlexNameConversion,
9-
TRASH_BIN_ADAPTER_FIXTURE,
10-
WASTE_CHUTE_FIXTURES,
119
} from '@opentrons/shared-data'
1210
import {
13-
consolidate,
14-
distribute,
1511
getLiquidClassName,
1612
getSlotInLocationStack,
17-
getWasteChuteAddressableAreaNamePip,
1813
pythonImports,
1914
pythonMetadata,
2015
pythonRequirements,
21-
transfer,
2216
} from '@opentrons/step-generation'
2317

24-
import { generateQuickTransferArgs } from './'
18+
import { generateQuickTransferArgs } from './generateQuickTransferArgs'
19+
import { generateQuickTransferRobotStateTimeline } from './generateQuickTransferRobotStateTimeline'
2520
import { pythonDef } from './pythonDef'
2621

2722
import type {
28-
AddressableAreaName,
2923
CommandAnnotationV1Mixin,
3024
CommandV14Mixin,
3125
CreateCommand,
32-
CutoutId,
3326
DeckConfiguration,
3427
LabwareDefinition2,
3528
LabwareV2Mixin,
@@ -39,7 +32,6 @@ import type {
3932
LoadPipetteCreateCommand,
4033
OT3RobotMixin,
4134
} from '@opentrons/shared-data'
42-
import type { CommandCreatorResult } from '@opentrons/step-generation'
4335
import type { QuickTransferSummaryState } from '../types'
4436

4537
const uuid: () => string = uuidv1
@@ -151,87 +143,22 @@ export function createQuickTransferFile(
151143
}
152144
: null
153145

154-
let nonLoadCommandCreator: CommandCreatorResult | null = null
155-
if (stepArgs?.commandCreatorFnName === 'transfer') {
156-
nonLoadCommandCreator = transfer(
157-
stepArgs,
158-
invariantContext,
159-
initialRobotState
160-
)
161-
} else if (stepArgs?.commandCreatorFnName === 'consolidate') {
162-
nonLoadCommandCreator = consolidate(
163-
stepArgs,
164-
invariantContext,
165-
initialRobotState
166-
)
167-
} else if (stepArgs?.commandCreatorFnName === 'distribute') {
168-
nonLoadCommandCreator = distribute(
169-
stepArgs,
170-
invariantContext,
171-
initialRobotState
172-
)
173-
}
174-
175-
const nonLoadCommands =
176-
nonLoadCommandCreator != null && 'commands' in nonLoadCommandCreator
177-
? nonLoadCommandCreator.commands
178-
: []
146+
const robotStateTimeline = generateQuickTransferRobotStateTimeline({
147+
stepArgs,
148+
initialRobotState,
149+
invariantContext,
150+
})
151+
const nonLoadCommands: CreateCommand[] = flatMap(
152+
robotStateTimeline.timeline,
153+
timelineFrame => timelineFrame.commands
154+
)
179155

180-
let finalDropTipCommands: CreateCommand[] = []
181-
let addressableAreaName: AddressableAreaName | null = null
182-
if (
183-
quickTransferState.dropTipLocation.cutoutFixtureId ===
184-
TRASH_BIN_ADAPTER_FIXTURE
185-
) {
186-
const trashLocation = quickTransferState.dropTipLocation.cutoutId
187-
const deckDef = getDeckDefFromRobotType(FLEX_ROBOT_TYPE)
188-
const cutouts: Record<CutoutId, AddressableAreaName[]> | null =
189-
deckDef.cutoutFixtures.find(
190-
cutoutFixture => cutoutFixture.id === 'trashBinAdapter'
191-
)?.providesAddressableAreas ?? null
192-
addressableAreaName =
193-
trashLocation != null && cutouts != null
194-
? cutouts[trashLocation]?.[0] ?? null
195-
: null
196-
} else if (
197-
WASTE_CHUTE_FIXTURES.includes(
198-
quickTransferState.dropTipLocation.cutoutFixtureId
199-
)
200-
) {
201-
addressableAreaName = getWasteChuteAddressableAreaNamePip(
202-
pipetteEntity.spec.channels
203-
)
204-
}
205-
if (addressableAreaName == null) {
206-
console.error(
207-
`expected to find addressableAreaName with trashBin or wasteChute location but could not`
208-
)
209-
} else {
210-
finalDropTipCommands = [
211-
{
212-
key: uuid(),
213-
commandType: 'moveToAddressableAreaForDropTip',
214-
params: {
215-
pipetteId: pipetteEntity.id,
216-
addressableAreaName,
217-
},
218-
},
219-
{
220-
key: uuid(),
221-
commandType: 'dropTipInPlace',
222-
params: {
223-
pipetteId: pipetteEntity.id,
224-
},
225-
},
226-
]
227-
}
228156
const commands: CreateCommand[] = [
229157
loadPipetteCommand,
230158
...loadAdapterCommands,
231159
...loadLabwareCommands,
232160
...(loadLiquidCommand != null ? [loadLiquidCommand] : []),
233161
...nonLoadCommands,
234-
...finalDropTipCommands,
235162
]
236163
const sourceLabwareName = quickTransferState.source.metadata.displayName
237164
let destinationLabwareName = sourceLabwareName
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import {
2+
commandCreatorsTimeline,
3+
curryCommandCreator,
4+
dropTip,
5+
dropTipInTrash,
6+
dropTipInWasteChute,
7+
reduceCommandCreators,
8+
} from '@opentrons/step-generation'
9+
10+
import { createCommandCreatorFromStepArgs } from './createCommandCreatorFromStepArgs'
11+
12+
import type { CutoutId } from '@opentrons/shared-data'
13+
import type * as StepGeneration from '@opentrons/step-generation'
14+
import type { MoveLiquidStepArgs } from './generateQuickTransferArgs'
15+
16+
export interface GenerateQuickTransferRobotStateTimelineArgs {
17+
stepArgs: MoveLiquidStepArgs
18+
initialRobotState: StepGeneration.RobotState
19+
invariantContext: StepGeneration.InvariantContext
20+
}
21+
export const generateQuickTransferRobotStateTimeline = (
22+
args: GenerateQuickTransferRobotStateTimelineArgs
23+
): StepGeneration.Timeline => {
24+
const { stepArgs, initialRobotState, invariantContext } = args
25+
26+
const curriedCommandCreator = createCommandCreatorFromStepArgs(stepArgs)
27+
28+
if (curriedCommandCreator == null || stepArgs == null) {
29+
return { timeline: [] }
30+
}
31+
32+
const pipetteId = stepArgs.pipette
33+
const dropTipLocation = stepArgs.dropTipLocation
34+
35+
const curriedCommandCreators: StepGeneration.CurriedCommandCreator[] = []
36+
37+
// Always add the transfer/consolidate/distribute commands first
38+
curriedCommandCreators.push(curriedCommandCreator)
39+
40+
const isWasteChute =
41+
invariantContext.wasteChuteEntities[dropTipLocation] != null
42+
const isTrashBin = invariantContext.trashBinEntities[dropTipLocation] != null
43+
44+
let dropTipCommand: StepGeneration.CurriedCommandCreator
45+
46+
if (isWasteChute) {
47+
dropTipCommand = curryCommandCreator(dropTipInWasteChute, {
48+
pipetteId,
49+
wasteChuteId: invariantContext.wasteChuteEntities[dropTipLocation].id,
50+
})
51+
} else if (isTrashBin) {
52+
const trashLocation =
53+
invariantContext.trashBinEntities[dropTipLocation].location
54+
dropTipCommand = curryCommandCreator(dropTipInTrash, {
55+
pipetteId,
56+
trashLocation: trashLocation as CutoutId,
57+
})
58+
} else {
59+
dropTipCommand = curryCommandCreator(dropTip, {
60+
pipette: pipetteId,
61+
dropTipLocation,
62+
})
63+
}
64+
65+
// Wrap drop tip commands and rest of commands in a grouped reducer
66+
curriedCommandCreators[curriedCommandCreators.length - 1] = (
67+
_invariantContext,
68+
_prevRobotState
69+
) =>
70+
reduceCommandCreators(
71+
[curriedCommandCreator, dropTipCommand],
72+
_invariantContext,
73+
_prevRobotState
74+
)
75+
76+
const timeline = commandCreatorsTimeline(
77+
curriedCommandCreators,
78+
invariantContext,
79+
initialRobotState
80+
)
81+
return timeline
82+
}

0 commit comments

Comments
 (0)