Skip to content

Commit add5ccb

Browse files
committed
feat(step-generation): create delay compound commands and delayLocationHelper util
1 parent e5bfd63 commit add5ccb

File tree

10 files changed

+297
-135
lines changed

10 files changed

+297
-135
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { describe, it, expect } from 'vitest'
2+
import {
3+
makeContext,
4+
getSuccessResult,
5+
getInitialRobotStateStandard,
6+
} from '../fixtures'
7+
import { delayInTrash } from '../commandCreators/compound'
8+
import type { RobotState, InvariantContext } from '../types'
9+
10+
const mockTrashBinId = 'trashBinId'
11+
const invariantContext: InvariantContext = {
12+
...makeContext(),
13+
additionalEquipmentEntities: {
14+
[mockTrashBinId]: {
15+
id: mockTrashBinId,
16+
name: 'trashBin',
17+
pythonName: 'mock_trash_bin_1',
18+
location: 'cutoutA3',
19+
},
20+
},
21+
}
22+
const prevRobotState: RobotState = getInitialRobotStateStandard(
23+
invariantContext
24+
)
25+
26+
describe('delayInTrash', () => {
27+
it('moves to waste chute and delays', () => {
28+
const args = {
29+
pipetteId: 'p10SingleId',
30+
destinationId: mockTrashBinId,
31+
seconds: 30,
32+
}
33+
34+
const result = delayInTrash(args, invariantContext, prevRobotState)
35+
const res = getSuccessResult(result)
36+
expect(res.commands).toEqual([
37+
{
38+
commandType: 'moveToAddressableArea',
39+
key: expect.any(String),
40+
params: {
41+
pipetteId: 'p10SingleId',
42+
offset: { x: 0, y: 0, z: 0 },
43+
addressableAreaName: 'movableTrashA3',
44+
},
45+
},
46+
{
47+
commandType: 'waitForDuration',
48+
key: expect.any(String),
49+
params: {
50+
seconds: 30,
51+
},
52+
},
53+
])
54+
})
55+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { describe, it, expect } from 'vitest'
2+
import { WASTE_CHUTE_CUTOUT } from '@opentrons/shared-data'
3+
import {
4+
makeContext,
5+
getSuccessResult,
6+
getInitialRobotStateStandard,
7+
} from '../fixtures'
8+
import { delayInWasteChute } from '../commandCreators/compound'
9+
import type { RobotState, InvariantContext } from '../types'
10+
11+
const wasteChuteId = 'wasteChuteId'
12+
const invariantContext: InvariantContext = {
13+
...makeContext(),
14+
additionalEquipmentEntities: {
15+
[wasteChuteId]: {
16+
id: wasteChuteId,
17+
name: 'wasteChute',
18+
pythonName: 'mock_waste_chute_1',
19+
location: WASTE_CHUTE_CUTOUT,
20+
},
21+
},
22+
}
23+
const prevRobotState: RobotState = getInitialRobotStateStandard(
24+
invariantContext
25+
)
26+
27+
describe('delayInWasteChute', () => {
28+
it('moves to waste chute and delays', () => {
29+
const args = {
30+
pipetteId: 'p10SingleId',
31+
seconds: 30,
32+
}
33+
34+
const result = delayInWasteChute(args, invariantContext, prevRobotState)
35+
const res = getSuccessResult(result)
36+
expect(res.commands).toEqual([
37+
{
38+
commandType: 'moveToAddressableArea',
39+
key: expect.any(String),
40+
params: {
41+
pipetteId: 'p10SingleId',
42+
offset: { x: 0, y: 0, z: 0 },
43+
addressableAreaName: '1ChannelWasteChute',
44+
},
45+
},
46+
{
47+
commandType: 'waitForDuration',
48+
key: expect.any(String),
49+
params: {
50+
seconds: 30,
51+
},
52+
},
53+
])
54+
})
55+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import { beforeEach, describe, it, expect } from 'vitest'
2+
import {
3+
makeContext,
4+
getRobotStateWithTipStandard,
5+
getSuccessResult,
6+
SOURCE_LABWARE,
7+
} from '../fixtures'
8+
import { delayInWell } from '../commandCreators/compound'
9+
import type { RobotState, InvariantContext } from '../types'
10+
11+
describe('delayInWell', () => {
12+
let invariantContext: InvariantContext
13+
let robotStateWithTip: RobotState
14+
15+
beforeEach(() => {
16+
invariantContext = makeContext()
17+
robotStateWithTip = getRobotStateWithTipStandard(invariantContext)
18+
})
19+
it('moves to well and delays', () => {
20+
const args = {
21+
pipetteId: 'p10SingleId',
22+
zOffset: 10,
23+
destinationId: SOURCE_LABWARE,
24+
well: 'B1',
25+
seconds: 30,
26+
}
27+
28+
const result = delayInWell(args, invariantContext, robotStateWithTip)
29+
const res = getSuccessResult(result)
30+
expect(res.commands).toEqual([
31+
{
32+
commandType: 'moveToWell',
33+
key: expect.any(String),
34+
params: {
35+
labwareId: 'sourcePlateId',
36+
pipetteId: 'p10SingleId',
37+
wellLocation: {
38+
offset: {
39+
x: 0,
40+
y: 0,
41+
z: 10,
42+
},
43+
origin: 'bottom',
44+
},
45+
wellName: 'B1',
46+
},
47+
},
48+
{
49+
commandType: 'waitForDuration',
50+
key: expect.any(String),
51+
params: {
52+
seconds: 30,
53+
},
54+
},
55+
])
56+
})
57+
})

step-generation/src/commandCreators/compound/consolidate.ts

+10-22
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,20 @@ import * as errorCreators from '../../errorCreators'
99
import { getPipetteWithTipMaxVol } from '../../robotStateSelectors'
1010
import { dropTipInTrash } from './dropTipInTrash'
1111
import {
12+
airGapLocationHelper,
1213
blowoutLocationHelper,
1314
curryCommandCreator,
14-
reduceCommandCreators,
15-
airGapLocationHelper,
1615
dispenseLocationHelper,
17-
moveHelper,
18-
getIsSafePipetteMovement,
1916
getHasWasteChute,
17+
getIsSafePipetteMovement,
18+
moveAndDelayLocationHelper,
19+
reduceCommandCreators,
2020
} from '../../utils'
2121
import {
2222
aspirate,
2323
configureForVolume,
2424
delay,
2525
dropTip,
26-
moveToWell,
2726
touchTip,
2827
} from '../atomic'
2928
import { mixUtil } from './mix'
@@ -200,20 +199,11 @@ export const consolidate: CommandCreator<ConsolidateArgs> = (
200199
const delayAfterAspirateCommands =
201200
aspirateDelay != null
202201
? [
203-
curryCommandCreator(moveToWell, {
202+
curryCommandCreator(moveAndDelayLocationHelper, {
204203
pipetteId: args.pipette,
205-
labwareId: args.sourceLabware,
206-
wellName: sourceWell,
207-
wellLocation: {
208-
origin: 'bottom',
209-
offset: {
210-
x: 0,
211-
y: 0,
212-
z: aspirateDelay.mmFromBottom,
213-
},
214-
},
215-
}),
216-
curryCommandCreator(delay, {
204+
destinationId: args.sourceLabware,
205+
well: sourceWell,
206+
zOffset: aspirateDelay.mmFromBottom,
217207
seconds: aspirateDelay.seconds,
218208
}),
219209
]
@@ -371,13 +361,11 @@ export const consolidate: CommandCreator<ConsolidateArgs> = (
371361
const delayAfterDispenseCommands =
372362
dispenseDelay != null
373363
? [
374-
curryCommandCreator(moveHelper, {
364+
curryCommandCreator(moveAndDelayLocationHelper, {
375365
pipetteId: args.pipette,
376366
destinationId: args.destLabware,
377-
well: destinationWell ?? undefined,
367+
well: destinationWell,
378368
zOffset: dispenseDelay.mmFromBottom,
379-
}),
380-
curryCommandCreator(delay, {
381369
seconds: dispenseDelay.seconds,
382370
}),
383371
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import {
2+
curryCommandCreator,
3+
getTrashBinAddressableAreaName,
4+
reduceCommandCreators,
5+
} from '../../utils'
6+
import { ZERO_OFFSET } from '../../constants'
7+
import { delay, moveToAddressableArea } from '../atomic'
8+
import type { CommandCreator, CurriedCommandCreator } from '../../types'
9+
import type { CutoutId } from '@opentrons/shared-data'
10+
11+
interface DelayInTrashArgs {
12+
destinationId: string
13+
pipetteId: string
14+
seconds: number
15+
}
16+
17+
export const delayInTrash: CommandCreator<DelayInTrashArgs> = (
18+
args,
19+
invariantContext,
20+
prevRobotState
21+
) => {
22+
const { seconds, pipetteId, destinationId } = args
23+
const addressableAreaName = getTrashBinAddressableAreaName(
24+
invariantContext.additionalEquipmentEntities[destinationId]
25+
.location as CutoutId
26+
)
27+
28+
const commandCreators: CurriedCommandCreator[] = [
29+
curryCommandCreator(moveToAddressableArea, {
30+
pipetteId,
31+
addressableAreaName,
32+
offset: ZERO_OFFSET,
33+
}),
34+
curryCommandCreator(delay, {
35+
seconds: seconds,
36+
}),
37+
]
38+
39+
return reduceCommandCreators(
40+
commandCreators,
41+
invariantContext,
42+
prevRobotState
43+
)
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import {
2+
curryCommandCreator,
3+
getWasteChuteAddressableAreaNamePip,
4+
reduceCommandCreators,
5+
} from '../../utils'
6+
import { ZERO_OFFSET } from '../../constants'
7+
import { delay, moveToAddressableArea } from '../atomic'
8+
import type { CommandCreator, CurriedCommandCreator } from '../../types'
9+
10+
interface delayInWasteChuteArgs {
11+
pipetteId: string
12+
seconds: number
13+
}
14+
15+
export const delayInWasteChute: CommandCreator<delayInWasteChuteArgs> = (
16+
args,
17+
invariantContext,
18+
prevRobotState
19+
) => {
20+
const { seconds, pipetteId } = args
21+
const pipetteChannels =
22+
invariantContext.pipetteEntities[pipetteId].spec.channels
23+
24+
const commandCreators: CurriedCommandCreator[] = [
25+
curryCommandCreator(moveToAddressableArea, {
26+
pipetteId,
27+
addressableAreaName: getWasteChuteAddressableAreaNamePip(pipetteChannels),
28+
offset: ZERO_OFFSET,
29+
}),
30+
curryCommandCreator(delay, {
31+
seconds: seconds,
32+
}),
33+
]
34+
35+
return reduceCommandCreators(
36+
commandCreators,
37+
invariantContext,
38+
prevRobotState
39+
)
40+
}

step-generation/src/commandCreators/compound/distribute.ts

+9-27
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ import {
1818
getIsSafePipetteMovement,
1919
getHasWasteChute,
2020
airGapLocationHelper,
21+
moveAndDelayLocationHelper,
2122
} from '../../utils'
2223
import {
2324
aspirate,
2425
configureForVolume,
2526
delay,
2627
dispense,
2728
dropTip,
28-
moveToWell,
2929
touchTip,
3030
} from '../atomic'
3131
import { mixUtil } from './mix'
@@ -241,20 +241,11 @@ export const distribute: CommandCreator<DistributeArgs> = (
241241
const delayAfterDispenseCommands =
242242
dispenseDelay != null
243243
? [
244-
curryCommandCreator(moveToWell, {
244+
curryCommandCreator(moveAndDelayLocationHelper, {
245245
pipetteId: args.pipette,
246-
labwareId: args.destLabware,
247-
wellName: destWell,
248-
wellLocation: {
249-
origin: 'bottom',
250-
offset: {
251-
x: 0,
252-
y: 0,
253-
z: dispenseDelay.mmFromBottom,
254-
},
255-
},
256-
}),
257-
curryCommandCreator(delay, {
246+
destinationId: args.destLabware,
247+
well: destWell,
248+
zOffset: dispenseDelay.mmFromBottom,
258249
seconds: dispenseDelay.seconds,
259250
}),
260251
]
@@ -385,20 +376,11 @@ export const distribute: CommandCreator<DistributeArgs> = (
385376
const delayAfterAspirateCommands =
386377
aspirateDelay != null
387378
? [
388-
curryCommandCreator(moveToWell, {
379+
curryCommandCreator(moveAndDelayLocationHelper, {
389380
pipetteId: args.pipette,
390-
labwareId: args.sourceLabware,
391-
wellName: args.sourceWell,
392-
wellLocation: {
393-
origin: 'bottom',
394-
offset: {
395-
x: 0,
396-
y: 0,
397-
z: aspirateDelay.mmFromBottom,
398-
},
399-
},
400-
}),
401-
curryCommandCreator(delay, {
381+
destinationId: args.sourceLabware,
382+
well: args.sourceWell,
383+
zOffset: aspirateDelay.mmFromBottom,
402384
seconds: aspirateDelay.seconds,
403385
}),
404386
]

step-generation/src/commandCreators/compound/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ export { airGapInWell } from './airGapInWell'
66
export { blowOutInTrash } from './blowOutInTrash'
77
export { blowOutInWasteChute } from './blowOutInWasteChute'
88
export { consolidate } from './consolidate'
9+
export { delayInTrash } from './delayInTrash'
10+
export { delayInWasteChute } from './delayInWasteChute'
911
export { delayInWell } from './delayInWell'
1012
export { dispenseInTrash } from './dispenseInTrash'
1113
export { dispenseInWasteChute } from './dispenseInWasteChute'

0 commit comments

Comments
 (0)