diff --git a/protocol-designer/src/steplist/formLevel/stepFormToArgs/moveLabwareFormToArgs.ts b/protocol-designer/src/steplist/formLevel/stepFormToArgs/moveLabwareFormToArgs.ts index 92ab07b935c..5484d050188 100644 --- a/protocol-designer/src/steplist/formLevel/stepFormToArgs/moveLabwareFormToArgs.ts +++ b/protocol-designer/src/steplist/formLevel/stepFormToArgs/moveLabwareFormToArgs.ts @@ -1,3 +1,4 @@ +import type { LabwareMovementStrategy } from '@opentrons/shared-data' import type { HydratedMoveLabwareFormData } from '../../../form-types' import type { MoveLabwareArgs } from '@opentrons/step-generation' @@ -16,8 +17,10 @@ export const moveLabwareFormToArgs = ( commandCreatorFnName: 'moveLabware', name: stepName, description: stepDetails, - labware: labware.id, - useGripper, + labwareId: labware.id, newLocation, + strategy: useGripper + ? 'usingGripper' + : ('manualMoveWithPause' as LabwareMovementStrategy), } } diff --git a/protocol-designer/src/steplist/formLevel/stepFormToArgs/pauseFormToArgs.ts b/protocol-designer/src/steplist/formLevel/stepFormToArgs/pauseFormToArgs.ts index 4c99996cbdd..d5369fe3ddf 100644 --- a/protocol-designer/src/steplist/formLevel/stepFormToArgs/pauseFormToArgs.ts +++ b/protocol-designer/src/steplist/formLevel/stepFormToArgs/pauseFormToArgs.ts @@ -34,7 +34,7 @@ export const pauseFormToArgs = ( commandCreatorFnName: 'delay', name: formData.stepName, description: formData.stepDetails ?? '', - wait: totalSeconds, + seconds: totalSeconds, message, meta: { hours, @@ -48,7 +48,6 @@ export const pauseFormToArgs = ( commandCreatorFnName: 'delay', name: formData.stepName, description: formData.stepDetails ?? '', - wait: true, message, meta: { hours, diff --git a/protocol-designer/src/steplist/formLevel/stepFormToArgs/test/pauseFormToArgs.test.ts b/protocol-designer/src/steplist/formLevel/stepFormToArgs/test/pauseFormToArgs.test.ts index e5bd236d17b..aa043cc1e9f 100644 --- a/protocol-designer/src/steplist/formLevel/stepFormToArgs/test/pauseFormToArgs.test.ts +++ b/protocol-designer/src/steplist/formLevel/stepFormToArgs/test/pauseFormToArgs.test.ts @@ -41,7 +41,6 @@ describe('pauseFormToArgs', () => { const expected = { commandCreatorFnName: 'delay', name: 'pause step', - wait: true, message: 'some message', description: 'some details', meta: { @@ -66,7 +65,7 @@ describe('pauseFormToArgs', () => { const expected = { commandCreatorFnName: 'delay', name: 'pause step', - wait: 3600 + 20 * 60 + 5, + seconds: 3600 + 20 * 60 + 5, message: 'some message', description: 'some details', meta: { diff --git a/protocol-designer/src/timelineMiddleware/generateRobotStateTimeline.ts b/protocol-designer/src/timelineMiddleware/generateRobotStateTimeline.ts index 27d123d9e69..9294547d1d9 100644 --- a/protocol-designer/src/timelineMiddleware/generateRobotStateTimeline.ts +++ b/protocol-designer/src/timelineMiddleware/generateRobotStateTimeline.ts @@ -8,6 +8,7 @@ import { reduceCommandCreators, commandCreatorsTimeline, getPipetteIdFromCCArgs, + ZERO_OFFSET, } from '@opentrons/step-generation' import { commandCreatorFromStepArgs } from '../file-data/helpers' import type { StepArgsAndErrorsById } from '../steplist/types' @@ -95,6 +96,7 @@ export const generateRobotStateTimeline = ( curryCommandCreator(moveToAddressableArea, { pipetteId, addressableAreaName, + offset: ZERO_OFFSET, }), curryCommandCreator(dropTipInPlace, { pipetteId, diff --git a/protocol-designer/src/ui/steps/selectors.ts b/protocol-designer/src/ui/steps/selectors.ts index 20c651e0fce..49563aeab56 100644 --- a/protocol-designer/src/ui/steps/selectors.ts +++ b/protocol-designer/src/ui/steps/selectors.ts @@ -154,7 +154,7 @@ export const getHoveredStepLabware = createSelector( } if (stepArgs.commandCreatorFnName === 'moveLabware') { - const src = stepArgs.labware + const src = stepArgs.labwareId return [src] } diff --git a/protocol-designer/src/ui/steps/test/selectors.test.ts b/protocol-designer/src/ui/steps/test/selectors.test.ts index daa6643eab9..e91dc7a82ac 100644 --- a/protocol-designer/src/ui/steps/test/selectors.test.ts +++ b/protocol-designer/src/ui/steps/test/selectors.test.ts @@ -25,6 +25,7 @@ import { getMockMoveLiquidStep, getMockMixStep } from '../__fixtures__' import * as utils from '../../modules/utils' +import type { MoveLabwareArgs } from '@opentrons/step-generation' import type { FormData } from '../../../form-types' import type { StepArgsAndErrorsById } from '../../../steplist/types' import type { AllTemporalPropertiesForTimelineFrame } from '../../../step-forms' @@ -46,7 +47,6 @@ function createArgsForStepId( const hoveredStepId = 'hoveredStepId' const labware = 'well plate' const mixCommand = 'mix' -const moveLabwareCommand = 'moveLabware' describe('getHoveredStepLabware', () => { let initialDeckState: AllTemporalPropertiesForTimelineFrame beforeEach(() => { @@ -135,9 +135,13 @@ describe('getHoveredStepLabware', () => { }) it('correct labware is returned when command is moveLabware', () => { - const stepArgs = { - commandCreatorFnName: moveLabwareCommand, - labware, + const stepArgs: MoveLabwareArgs = { + labwareId: labware, + strategy: 'usingGripper', + newLocation: { slotName: 'A1' }, + commandCreatorFnName: 'moveLabware', + name: 'some name', + description: 'some description', } const argsByStepId = createArgsForStepId(hoveredStepId, stepArgs) const result = getHoveredStepLabware.resultFunc( @@ -146,7 +150,7 @@ describe('getHoveredStepLabware', () => { initialDeckState ) - expect(result).toEqual([labware]) + expect(result).toEqual([stepArgs.labwareId]) }) describe('modules', () => { diff --git a/shared-data/command/types/annotation.ts b/shared-data/command/types/annotation.ts index 5d9ed3aa4d6..4312b2bf195 100644 --- a/shared-data/command/types/annotation.ts +++ b/shared-data/command/types/annotation.ts @@ -17,7 +17,7 @@ export interface CommentRunTimeCommand result?: any } -interface CommentParams { +export interface CommentParams { message: string } diff --git a/shared-data/command/types/gantry.ts b/shared-data/command/types/gantry.ts index 2e55b2b1fe2..8d5c911a20e 100644 --- a/shared-data/command/types/gantry.ts +++ b/shared-data/command/types/gantry.ts @@ -163,7 +163,7 @@ interface RetractAxisParams { axis: MotorAxis } -interface AddressableOffsetVector { +export interface AddressableOffsetVector { x: number y: number z: number diff --git a/shared-data/command/types/setup.ts b/shared-data/command/types/setup.ts index 2a29c6d7b71..554c7706977 100644 --- a/shared-data/command/types/setup.ts +++ b/shared-data/command/types/setup.ts @@ -199,7 +199,7 @@ interface NozzleConfigurationParams { style: NozzleConfigurationStyle } -interface ConfigureNozzleLayoutParams { +export interface ConfigureNozzleLayoutParams { pipetteId: string configurationParams: NozzleConfigurationParams } diff --git a/shared-data/command/types/timing.ts b/shared-data/command/types/timing.ts index 7902f613167..550c2e53d04 100644 --- a/shared-data/command/types/timing.ts +++ b/shared-data/command/types/timing.ts @@ -22,7 +22,7 @@ export interface WaitForResumeRunTimeCommand result?: any } -interface WaitForResumeParams { +export interface WaitForResumeParams { message?: string } @@ -37,7 +37,7 @@ export interface WaitForDurationRunTimeCommand result?: any } -interface WaitForDurationParams { +export interface WaitForDurationParams { seconds: number message?: string } diff --git a/step-generation/src/__tests__/aspirate.test.ts b/step-generation/src/__tests__/aspirate.test.ts index 085df38dc85..f5f53621250 100644 --- a/step-generation/src/__tests__/aspirate.test.ts +++ b/step-generation/src/__tests__/aspirate.test.ts @@ -11,7 +11,6 @@ import { } from '@opentrons/shared-data' import { - absorbanceReaderCollision, pipetteIntoHeaterShakerLatchOpen, thermocyclerPipetteCollision, pipetteIntoHeaterShakerWhileShaking, @@ -30,8 +29,10 @@ import { SOURCE_LABWARE, getInitialRobotStateWithOffDeckLabwareStandard, } from '../fixtures' -import type { LabwareDefinition2 } from '@opentrons/shared-data' -import type { AspDispAirgapParams } from '@opentrons/shared-data/protocol/types/schemaV3' +import type { + LabwareDefinition2, + AspDispAirgapParams, +} from '@opentrons/shared-data' import type { InvariantContext, RobotState } from '../' const fixtureTiprack10ul = tip10 as LabwareDefinition2 @@ -54,7 +55,10 @@ describe('aspirate', () => { robotStateWithTip = getRobotStateWithTipStandard(invariantContext) flowRateAndOffsets = { flowRate: 6, - offsetFromBottomMm: 5, + wellLocation: { + origin: 'bottom', + offset: { z: 5, y: 0, x: 0 }, + }, } }) afterEach(() => { @@ -64,14 +68,12 @@ describe('aspirate', () => { const params = { ...({ ...flowRateAndOffsets, - pipette: DEFAULT_PIPETTE, + pipetteId: DEFAULT_PIPETTE, volume: 50, - labware: SOURCE_LABWARE, - well: 'A1', + labwareId: SOURCE_LABWARE, + wellName: 'A1', } as AspDispAirgapParams), tipRack: 'tiprack1Id', - xOffset: 0, - yOffset: 0, nozzles: null, } const result = aspirate(params, invariantContext, robotStateWithTip) @@ -108,14 +110,12 @@ describe('aspirate', () => { { ...({ ...flowRateAndOffsets, - pipette: DEFAULT_PIPETTE, + pipetteId: DEFAULT_PIPETTE, volume: 201, - labware: SOURCE_LABWARE, - well: 'A1', + labwareId: SOURCE_LABWARE, + wellName: 'A1', } as AspDispAirgapParams), tipRack: 'tiprack1Id', - xOffset: 0, - yOffset: 0, nozzles: null, }, invariantContext, @@ -138,14 +138,12 @@ describe('aspirate', () => { { ...({ ...flowRateAndOffsets, - pipette: DEFAULT_PIPETTE, + pipetteId: DEFAULT_PIPETTE, volume: 301, - labware: SOURCE_LABWARE, - well: 'A1', + labwareId: SOURCE_LABWARE, + wellName: 'A1', } as AspDispAirgapParams), tipRack: 'tipRack', - xOffset: 0, - yOffset: 0, nozzles: null, }, invariantContext, @@ -161,14 +159,12 @@ describe('aspirate', () => { { ...({ ...flowRateAndOffsets, - pipette: 'badPipette', + pipetteId: 'badPipette', volume: 50, - labware: SOURCE_LABWARE, - well: 'A1', + labwareId: SOURCE_LABWARE, + wellName: 'A1', } as AspDispAirgapParams), tipRack: 'tipRack', - xOffset: 0, - yOffset: 0, nozzles: null, }, invariantContext, @@ -181,14 +177,12 @@ describe('aspirate', () => { { ...({ ...flowRateAndOffsets, - pipette: DEFAULT_PIPETTE, + pipetteId: DEFAULT_PIPETTE, volume: 50, - labware: SOURCE_LABWARE, - well: 'A1', + labwareId: SOURCE_LABWARE, + wellName: 'A1', } as AspDispAirgapParams), tipRack: 'tipRack', - xOffset: 0, - yOffset: 0, nozzles: null, }, invariantContext, @@ -204,14 +198,12 @@ describe('aspirate', () => { { ...({ ...flowRateAndOffsets, - pipette: DEFAULT_PIPETTE, + pipetteId: DEFAULT_PIPETTE, volume: 50, - labware: 'problemaaticLabwareId', - well: 'A1', + labwareId: 'problemaaticLabwareId', + wellName: 'A1', } as AspDispAirgapParams), tipRack: 'tipRack', - xOffset: 0, - yOffset: 0, nozzles: null, }, invariantContext, @@ -231,14 +223,12 @@ describe('aspirate', () => { { ...({ ...flowRateAndOffsets, - pipette: DEFAULT_PIPETTE, + pipetteId: DEFAULT_PIPETTE, volume: 50, - labware: SOURCE_LABWARE, - well: 'A1', + labwareId: SOURCE_LABWARE, + wellName: 'A1', } as AspDispAirgapParams), tipRack: 'tipRack', - xOffset: 0, - yOffset: 0, nozzles: null, }, invariantContext, @@ -266,14 +256,12 @@ describe('aspirate', () => { { ...({ ...flowRateAndOffsets, - pipette: DEFAULT_PIPETTE, + pipetteId: DEFAULT_PIPETTE, volume: 50, - labware: SOURCE_LABWARE, - well: 'A1', + labwareId: SOURCE_LABWARE, + wellName: 'A1', } as AspDispAirgapParams), tipRack: 'tipRack', - xOffset: 0, - yOffset: 0, nozzles: null, }, invariantContext, @@ -284,41 +272,6 @@ describe('aspirate', () => { type: 'THERMOCYCLER_LID_CLOSED', }) }) - it('should return an error when aspirating from absorbance with pipette collision', () => { - vi.mocked(absorbanceReaderCollision).mockImplementationOnce( - ( - modules: RobotState['modules'], - labware: RobotState['labware'], - labwareId: string - ) => { - expect(modules).toBe(robotStateWithTip.modules) - expect(labware).toBe(robotStateWithTip.labware) - expect(labwareId).toBe(SOURCE_LABWARE) - return true - } - ) - const result = aspirate( - { - ...({ - ...flowRateAndOffsets, - pipette: DEFAULT_PIPETTE, - volume: 50, - labware: SOURCE_LABWARE, - well: 'A1', - } as AspDispAirgapParams), - tipRack: 'tipRack', - xOffset: 0, - yOffset: 0, - nozzles: null, - }, - invariantContext, - robotStateWithTip - ) - expect(getErrorResult(result).errors).toHaveLength(1) - expect(getErrorResult(result).errors[0]).toMatchObject({ - type: 'ABSORBANCE_READER_LID_CLOSED', - }) - }) it('should return an error when aspirating from heaterShaker with latch opened', () => { vi.mocked(pipetteIntoHeaterShakerLatchOpen).mockImplementationOnce( ( @@ -336,14 +289,12 @@ describe('aspirate', () => { { ...({ ...flowRateAndOffsets, - pipette: DEFAULT_PIPETTE, + pipetteId: DEFAULT_PIPETTE, volume: 50, - labware: SOURCE_LABWARE, - well: 'A1', + labwareId: SOURCE_LABWARE, + wellName: 'A1', } as AspDispAirgapParams), tipRack: 'tipRack', - xOffset: 0, - yOffset: 0, nozzles: null, }, invariantContext, @@ -377,14 +328,12 @@ describe('aspirate', () => { { ...({ ...flowRateAndOffsets, - pipette: DEFAULT_PIPETTE, + pipetteId: DEFAULT_PIPETTE, volume: 50, - labware: SOURCE_LABWARE, - well: 'A1', + labwareId: SOURCE_LABWARE, + wellName: 'A1', } as AspDispAirgapParams), tipRack: 'tipRack', - xOffset: 0, - yOffset: 0, nozzles: null, }, invariantContext, @@ -412,14 +361,12 @@ describe('aspirate', () => { { ...({ ...flowRateAndOffsets, - pipette: DEFAULT_PIPETTE, + pipetteId: DEFAULT_PIPETTE, volume: 50, - labware: SOURCE_LABWARE, - well: 'A1', + labwareId: SOURCE_LABWARE, + wellName: 'A1', } as AspDispAirgapParams), tipRack: 'tipRack', - xOffset: 0, - yOffset: 0, nozzles: null, }, invariantContext, @@ -453,14 +400,12 @@ describe('aspirate', () => { { ...({ ...flowRateAndOffsets, - pipette: DEFAULT_PIPETTE, + pipetteId: DEFAULT_PIPETTE, volume: 50, - labware: SOURCE_LABWARE, - well: 'A1', + labwareId: SOURCE_LABWARE, + wellName: 'A1', } as AspDispAirgapParams), tipRack: 'tipRack', - xOffset: 0, - yOffset: 0, nozzles: null, }, invariantContext, @@ -484,14 +429,12 @@ describe('aspirate', () => { { ...({ ...flowRateAndOffsets, - pipette: DEFAULT_PIPETTE, + pipetteId: DEFAULT_PIPETTE, volume: 50, - labware: SOURCE_LABWARE, - well: 'A1', + labwareId: SOURCE_LABWARE, + wellName: 'A1', } as AspDispAirgapParams), tipRack: 'tipRack', - xOffset: 0, - yOffset: 0, nozzles: null, }, invariantContext, @@ -514,14 +457,12 @@ describe('aspirate', () => { { ...({ ...flowRateAndOffsets, - pipette: DEFAULT_PIPETTE, + pipetteId: DEFAULT_PIPETTE, volume: 50, - labware: SOURCE_LABWARE, - well: 'A1', + labwareId: SOURCE_LABWARE, + wellName: 'A1', } as AspDispAirgapParams), tipRack: 'tipRack', - xOffset: 0, - yOffset: 0, nozzles: null, }, invariantContext, @@ -545,14 +486,12 @@ describe('aspirate', () => { { ...({ ...flowRateAndOffsets, - pipette: DEFAULT_PIPETTE, + pipetteId: DEFAULT_PIPETTE, volume: 50, - labware: SOURCE_LABWARE, - well: 'A1', + labwareId: SOURCE_LABWARE, + wellName: 'A1', } as AspDispAirgapParams), tipRack: 'tipRack', - xOffset: 0, - yOffset: 0, nozzles: null, }, invariantContext, @@ -577,14 +516,12 @@ describe('aspirate', () => { { ...({ ...flowRateAndOffsets, - pipette: DEFAULT_PIPETTE, + pipetteId: DEFAULT_PIPETTE, volume: 50, - labware: SOURCE_LABWARE, - well: 'A1', + labwareId: SOURCE_LABWARE, + wellName: 'A1', } as AspDispAirgapParams), tipRack: 'tipRack', - xOffset: 0, - yOffset: 0, nozzles: null, }, invariantContext, diff --git a/step-generation/src/__tests__/blowout.test.ts b/step-generation/src/__tests__/blowout.test.ts index edafc19d808..4e0dfdc65ef 100644 --- a/step-generation/src/__tests__/blowout.test.ts +++ b/step-generation/src/__tests__/blowout.test.ts @@ -31,6 +31,7 @@ describe('blowout', () => { wellName: 'A1', flowRate: 21.1, wellLocation: { + origin: 'top', offset: { z: -1.3, }, diff --git a/step-generation/src/__tests__/blowoutUtil.test.ts b/step-generation/src/__tests__/blowoutUtil.test.ts index 7337e517769..7fe75bdabf3 100644 --- a/step-generation/src/__tests__/blowoutUtil.test.ts +++ b/step-generation/src/__tests__/blowoutUtil.test.ts @@ -22,15 +22,15 @@ import { getInitialRobotStateStandard, } from '../fixtures' import type { RobotState, InvariantContext } from '../types' -import type { BlowoutParams } from '@opentrons/shared-data/protocol/types/schemaV3' +import type { BlowoutParams } from '@opentrons/shared-data' vi.mock('../utils/curryCommandCreator') let blowoutArgs: { - pipette: BlowoutParams['pipette'] + pipette: BlowoutParams['pipetteId'] sourceLabwareId: string - sourceWell: BlowoutParams['well'] + sourceWell: BlowoutParams['wellName'] destLabwareId: string - destWell: BlowoutParams['well'] + destWell: BlowoutParams['wellName'] blowoutLocation: string | null | undefined flowRate: number offsetFromTopMm: number @@ -68,6 +68,7 @@ describe('blowoutUtil', () => { wellName: blowoutArgs.sourceWell, flowRate: blowoutArgs.flowRate, wellLocation: { + origin: 'top', offset: { z: expect.any(Number), }, @@ -96,6 +97,7 @@ describe('blowoutUtil', () => { expect(curryCommandCreator).toHaveBeenCalledWith(moveToAddressableArea, { addressableAreaName: ONE_CHANNEL_WASTE_CHUTE_ADDRESSABLE_AREA, pipetteId: blowoutArgs.pipette, + offset: { x: 0, y: 0, z: 0 }, }) expect(curryCommandCreator).toHaveBeenCalledWith(blowOutInPlace, { flowRate: 2.3, @@ -113,6 +115,7 @@ describe('blowoutUtil', () => { wellName: blowoutArgs.destWell, flowRate: blowoutArgs.flowRate, wellLocation: { + origin: 'top', offset: { z: expect.any(Number), }, @@ -130,6 +133,7 @@ describe('blowoutUtil', () => { wellName: 'A1', flowRate: blowoutArgs.flowRate, wellLocation: { + origin: 'top', offset: { z: expect.any(Number), }, diff --git a/step-generation/src/__tests__/configureNozzleLayout.test.ts b/step-generation/src/__tests__/configureNozzleLayout.test.ts index 8474b5d2d07..c346575124c 100644 --- a/step-generation/src/__tests__/configureNozzleLayout.test.ts +++ b/step-generation/src/__tests__/configureNozzleLayout.test.ts @@ -14,7 +14,13 @@ const mockPipette = 'mockPipette' describe('configureNozzleLayout', () => { it('should call configureNozzleLayout with correct params for full tip', () => { const result = configureNozzleLayout( - { nozzles: ALL, pipetteId: mockPipette }, + { + configurationParams: { + primaryNozzle: undefined, + style: ALL, + }, + pipetteId: mockPipette, + }, invariantContext, robotInitialState ) @@ -32,7 +38,13 @@ describe('configureNozzleLayout', () => { }) it('should call configureNozzleLayout with correct params for column tip', () => { const result = configureNozzleLayout( - { nozzles: COLUMN, pipetteId: mockPipette }, + { + configurationParams: { + primaryNozzle: 'A12', + style: COLUMN, + }, + pipetteId: mockPipette, + }, invariantContext, robotInitialState ) diff --git a/step-generation/src/__tests__/delay.test.ts b/step-generation/src/__tests__/delay.test.ts index 6a843ab11f5..7383eba249d 100644 --- a/step-generation/src/__tests__/delay.test.ts +++ b/step-generation/src/__tests__/delay.test.ts @@ -1,4 +1,4 @@ -import { beforeEach, describe, it, expect } from 'vitest' +import { describe, it, expect } from 'vitest' import { delay } from '../commandCreators/atomic/delay' import { getSuccessResult } from '../fixtures' import type { PauseArgs } from '../types' @@ -11,21 +11,12 @@ const getRobotInitialState = (): any => { // neither should InvariantContext const invariantContext: any = {} let mixInArgs: PauseArgs -beforeEach(() => { - mixInArgs = { - commandCreatorFnName: 'delay', - meta: null, - name: 'Delay Test', - description: 'test blah blah', - wait: true, - } -}) describe('delay', () => { it('should delay until the user clicks resume', () => { const robotInitialState = getRobotInitialState() const message = 'delay indefinitely message' const result = delay( - { ...mixInArgs, message, wait: true }, + { ...mixInArgs, message }, invariantContext, robotInitialState ) @@ -45,7 +36,7 @@ describe('delay', () => { const robotInitialState = getRobotInitialState() const message = 'delay 95.5 secs message' const result = delay( - { ...mixInArgs, message, wait: 95.5 }, + { ...mixInArgs, message, seconds: 95.5 }, invariantContext, robotInitialState ) diff --git a/step-generation/src/__tests__/dispense.test.ts b/step-generation/src/__tests__/dispense.test.ts index a8f36841090..35afadcdc4e 100644 --- a/step-generation/src/__tests__/dispense.test.ts +++ b/step-generation/src/__tests__/dispense.test.ts @@ -22,7 +22,7 @@ import { SOURCE_LABWARE, } from '../fixtures' import { dispense } from '../commandCreators/atomic/dispense' -import type { ExtendedDispenseParams } from '../commandCreators/atomic/dispense' +import type { DispenseAtomicCommandParams } from '../commandCreators/atomic/dispense' import type { InvariantContext, RobotState } from '../types' vi.mock('../utils/absorbanceReaderCollision') @@ -45,17 +45,18 @@ describe('dispense', () => { vi.resetAllMocks() }) describe('tip tracking & commands:', () => { - let params: ExtendedDispenseParams + let params: DispenseAtomicCommandParams beforeEach(() => { params = { - pipette: DEFAULT_PIPETTE, + pipetteId: DEFAULT_PIPETTE, volume: 50, - labware: SOURCE_LABWARE, - well: 'A1', - offsetFromBottomMm: 5, + labwareId: SOURCE_LABWARE, + wellName: 'A1', + wellLocation: { + origin: 'bottom', + offset: { z: 5, x: 0, y: 0 }, + }, flowRate: 6, - xOffset: 0, - yOffset: 0, tipRack: 'tiprack1Id', nozzles: null, } @@ -99,13 +100,14 @@ describe('dispense', () => { const result = dispense( { flowRate: 10, - offsetFromBottomMm: 5, - pipette: DEFAULT_PIPETTE, + wellLocation: { + origin: 'bottom', + offset: { z: 5, x: 0, y: 0 }, + }, + pipetteId: DEFAULT_PIPETTE, volume: 50, - labware: SOURCE_LABWARE, - well: 'A1', - xOffset: 0, - yOffset: 0, + labwareId: SOURCE_LABWARE, + wellName: 'A1', tipRack: 'tiprack1Id', nozzles: null, }, @@ -119,7 +121,7 @@ describe('dispense', () => { }) it('dispense to nonexistent labware should throw error', () => { const result = dispense( - { ...params, labware: 'someBadLabwareId' }, + { ...params, labwareId: 'someBadLabwareId' }, invariantContext, robotStateWithTip ) diff --git a/step-generation/src/__tests__/movableTrashCommandsUtil.test.ts b/step-generation/src/__tests__/movableTrashCommandsUtil.test.ts index 184ccd65984..3c555b19b31 100644 --- a/step-generation/src/__tests__/movableTrashCommandsUtil.test.ts +++ b/step-generation/src/__tests__/movableTrashCommandsUtil.test.ts @@ -28,6 +28,7 @@ const mockCutout = 'cutoutA3' const mockMoveToAddressableAreaParams = { pipetteId: mockId, addressableAreaName: 'movableTrashA3', + offset: { x: 0, y: 0, z: 0 }, } const invariantContext = makeContext() @@ -88,7 +89,10 @@ describe('movableTrashCommandsUtil', () => { }) expect(curryCommandCreator).toHaveBeenCalledWith( moveToAddressableAreaForDropTip, - mockMoveToAddressableAreaParams + { + pipetteId: mockId, + addressableAreaName: 'movableTrashA3', + } ) expect(curryCommandCreator).toHaveBeenCalledWith(dropTipInPlace, { pipetteId: mockId, diff --git a/step-generation/src/__tests__/moveLabware.test.ts b/step-generation/src/__tests__/moveLabware.test.ts index 1f1a973a520..c48f6b38f87 100644 --- a/step-generation/src/__tests__/moveLabware.test.ts +++ b/step-generation/src/__tests__/moveLabware.test.ts @@ -15,9 +15,11 @@ import { } from '../fixtures' import { moveLabware } from '..' -import type { LabwareDefinition2 } from '@opentrons/shared-data' +import type { + LabwareDefinition2, + MoveLabwareParams, +} from '@opentrons/shared-data' import type { InvariantContext, RobotState } from '../types' -import type { MoveLabwareArgs } from '..' const mockWasteChuteId = 'mockWasteChuteId' const mockGripperId = 'mockGripperId' @@ -44,11 +46,10 @@ describe('moveLabware', () => { }) it('should return a moveLabware command for manualMoveWithPause given only the required params', () => { const params = { - commandCreatorFnName: 'moveLabware', - labware: SOURCE_LABWARE, - useGripper: false, + labwareId: SOURCE_LABWARE, + strategy: 'manualMoveWithPause', newLocation: { slotName: 'A1' }, - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware(params, invariantContext, robotState) expect(getSuccessResult(result).commands).toEqual([ @@ -65,11 +66,10 @@ describe('moveLabware', () => { }) it('should return a moveLabware command for moving with a gripper given only the required params', () => { const params = { - commandCreatorFnName: 'moveLabware', - labware: SOURCE_LABWARE, - useGripper: true, + labwareId: SOURCE_LABWARE, + strategy: 'usingGripper', newLocation: { slotName: 'A1' }, - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware(params, invariantContext, robotState) expect(getSuccessResult(result).commands).toEqual([ @@ -86,11 +86,10 @@ describe('moveLabware', () => { }) it('should return an error for labware does not exist with bad labwareid', () => { const params = { - commandCreatorFnName: 'moveLabware', - labware: 'badLabware', - useGripper: true, + labwareId: 'badLabware', + strategy: 'usingGripper', newLocation: { slotName: 'A1' }, - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware(params, invariantContext, robotState) expect(getErrorResult(result).errors).toHaveLength(1) @@ -103,11 +102,10 @@ describe('moveLabware', () => { invariantContext ) const params = { - commandCreatorFnName: 'moveLabware', - labware: SOURCE_LABWARE, - useGripper: true, + labwareId: SOURCE_LABWARE, + strategy: 'usingGripper', newLocation: { slotName: 'A1' }, - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware(params, invariantContext, robotState) expect(getErrorResult(result).errors).toHaveLength(1) @@ -117,11 +115,10 @@ describe('moveLabware', () => { }) it('should return an error for trying to move the labware to an occupied slot', () => { const params = { - commandCreatorFnName: 'moveLabware', - labware: SOURCE_LABWARE, - useGripper: true, + labwareId: SOURCE_LABWARE, + strategy: 'usingGripper', newLocation: { slotName: '1' }, - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware(params, invariantContext, robotState) expect(getErrorResult(result).errors).toHaveLength(1) @@ -146,11 +143,10 @@ describe('moveLabware', () => { [SOURCE_LABWARE]: { slot: 'gripperWasteChute' }, } const params = { - commandCreatorFnName: 'moveLabware', - labware: SOURCE_LABWARE, - useGripper: true, + labwareId: SOURCE_LABWARE, + strategy: 'usingGripper', newLocation: { slotName: 'A1' }, - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware(params, wasteChuteInvariantContext, robotState) expect(getErrorResult(result).errors).toHaveLength(1) @@ -160,11 +156,10 @@ describe('moveLabware', () => { }) it('should return an error for trying to move the labware off deck with a gripper', () => { const params = { - commandCreatorFnName: 'moveLabware', - labware: SOURCE_LABWARE, - useGripper: true, + labwareId: SOURCE_LABWARE, + strategy: 'usingGripper', newLocation: 'offDeck', - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware(params, invariantContext, robotState) expect(getErrorResult(result).errors).toHaveLength(1) @@ -195,11 +190,10 @@ describe('moveLabware', () => { } const params = { - commandCreatorFnName: 'moveLabware', - labware: SOURCE_LABWARE, - useGripper: true, + labwareId: SOURCE_LABWARE, + strategy: 'usingGripper', newLocation: { slotName: 'A1' }, - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware(params, invariantContext, robotState) expect(getErrorResult(result).errors).toHaveLength(1) @@ -219,11 +213,10 @@ describe('moveLabware', () => { const tcRobotState = stateAndContext.robotState const params = { - commandCreatorFnName: 'moveLabware', - labware: SOURCE_LABWARE, - useGripper: false, + labwareId: SOURCE_LABWARE, + strategy: 'manualMoveWithPause', newLocation: { moduleId: thermocyclerId }, - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware(params, tcInvariantContext, tcRobotState) expect(getErrorResult(result).errors).toHaveLength(1) @@ -251,11 +244,10 @@ describe('moveLabware', () => { }, } const params = { - commandCreatorFnName: 'moveLabware', - labware: SOURCE_LABWARE, - useGripper: true, + labwareId: SOURCE_LABWARE, + strategy: 'usingGripper', newLocation: { moduleId: HEATER_SHAKER_ID }, - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware(params, invariantContext, robotState) expect(getErrorResult(result).errors).toHaveLength(1) @@ -290,11 +282,10 @@ describe('moveLabware', () => { }, } const params = { - commandCreatorFnName: 'moveLabware', - labware: SOURCE_LABWARE, - useGripper: true, + labwareId: SOURCE_LABWARE, + strategy: 'usingGripper', newLocation: { labwareId: ADAPTER_ID }, - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware(params, invariantContext, robotState) expect(getErrorResult(result).errors).toHaveLength(1) @@ -322,11 +313,10 @@ describe('moveLabware', () => { }, } const params = { - commandCreatorFnName: 'moveLabware', - labware: SOURCE_LABWARE, - useGripper: true, + labwareId: SOURCE_LABWARE, + strategy: 'usingGripper', newLocation: { moduleId: HEATER_SHAKER_ID }, - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware(params, invariantContext, robotState) expect(getErrorResult(result).errors).toHaveLength(1) @@ -359,11 +349,10 @@ describe('moveLabware', () => { }, } as any) as RobotState const params = { - commandCreatorFnName: 'moveLabware', - labware: TIPRACK_1, - useGripper: true, + labwareId: TIPRACK_1, + strategy: 'usingGripper', newLocation: { addressableAreaName: 'gripperWasteChute' }, - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware( params, @@ -398,11 +387,10 @@ describe('moveLabware', () => { }, } as any) as RobotState const params = { - commandCreatorFnName: 'moveLabware', - labware: SOURCE_LABWARE, - useGripper: true, + labwareId: SOURCE_LABWARE, + strategy: 'usingGripper', newLocation: { addressableAreaName: 'gripperWasteChute' }, - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware( params, @@ -423,11 +411,10 @@ describe('moveLabware', () => { } as InvariantContext const params = { - commandCreatorFnName: 'moveLabware', - labware: SOURCE_LABWARE, - useGripper: true, + labwareId: SOURCE_LABWARE, + strategy: 'usingGripper', newLocation: { slotName: 'A1' }, - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware(params, invariantContext, robotState) expect(getErrorResult(result).errors).toHaveLength(1) @@ -449,11 +436,10 @@ describe('moveLabware', () => { } as InvariantContext const params = { - commandCreatorFnName: 'moveLabware', - labware: SOURCE_LABWARE, - useGripper: false, + labwareId: SOURCE_LABWARE, + strategy: 'manualMoveWithPause', newLocation: { addressableAreaName: 'gripperWasteChute' }, - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware(params, invariantContext, robotState) expect(getErrorResult(result).errors).toHaveLength(1) @@ -475,11 +461,10 @@ describe('moveLabware', () => { } as any) as RobotState const params = { - commandCreatorFnName: 'moveLabware', - labware: SOURCE_LABWARE, - useGripper: true, + labwareId: SOURCE_LABWARE, + strategy: 'usingGripper', newLocation: { addressableAreaName: 'gripperWasteChute' }, - } as MoveLabwareArgs + } as MoveLabwareParams const result = moveLabware(params, invariantContext, robotStateWithTipOnPip) expect(getErrorResult(result).errors).toHaveLength(1) diff --git a/step-generation/src/__tests__/moveToAddressableArea.test.ts b/step-generation/src/__tests__/moveToAddressableArea.test.ts index 80ba935c0b8..54ae062804d 100644 --- a/step-generation/src/__tests__/moveToAddressableArea.test.ts +++ b/step-generation/src/__tests__/moveToAddressableArea.test.ts @@ -20,7 +20,11 @@ describe('moveToAddressableArea', () => { const robotInitialState = getRobotInitialState() const mockName = '1ChannelWasteChute' const result = moveToAddressableArea( - { pipetteId: mockId, addressableAreaName: mockName }, + { + pipetteId: mockId, + addressableAreaName: mockName, + offset: { x: 0, y: 0, z: 0 }, + }, invariantContext, robotInitialState ) diff --git a/step-generation/src/__tests__/moveToWell.test.ts b/step-generation/src/__tests__/moveToWell.test.ts index bb4ad86f54e..0beac7f5c18 100644 --- a/step-generation/src/__tests__/moveToWell.test.ts +++ b/step-generation/src/__tests__/moveToWell.test.ts @@ -43,9 +43,9 @@ describe('moveToWell', () => { }) it('should return a moveToWell command given only the required params', () => { const params = { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', } const result = moveToWell(params, invariantContext, robotStateWithTip) expect(getSuccessResult(result).commands).toEqual([ @@ -62,13 +62,16 @@ describe('moveToWell', () => { }) it('should apply the optional params to the command', () => { const params = { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', - offset: { - x: 1, - y: 2, - z: 3, + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', + wellLocation: { + origin: 'bottom' as any, + offset: { + x: 1, + y: 2, + z: 3, + }, }, minimumZHeight: 5, forceDirect: true, @@ -99,9 +102,9 @@ describe('moveToWell', () => { it('should return an error if pipette does not exist', () => { const result = moveToWell( { - pipette: 'badPipette', - labware: SOURCE_LABWARE, - well: 'A1', + pipetteId: 'badPipette', + labwareId: SOURCE_LABWARE, + wellName: 'A1', }, invariantContext, robotStateWithTip @@ -111,9 +114,9 @@ describe('moveToWell', () => { it('should return error if labware does not exist', () => { const result = moveToWell( { - pipette: DEFAULT_PIPETTE, - labware: 'problematicLabwareId', - well: 'A1', + pipetteId: DEFAULT_PIPETTE, + labwareId: 'problematicLabwareId', + wellName: 'A1', }, invariantContext, robotStateWithTip @@ -129,9 +132,9 @@ describe('moveToWell', () => { ) const result = moveToWell( { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', }, invariantContext, initialRobotState @@ -150,9 +153,9 @@ describe('moveToWell', () => { } const result = moveToWell( { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', }, invariantContext, robotStateWithTip @@ -177,9 +180,9 @@ describe('moveToWell', () => { ) const result = moveToWell( { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', }, invariantContext, robotStateWithTip @@ -204,9 +207,9 @@ describe('moveToWell', () => { ) const result = moveToWell( { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', }, invariantContext, robotStateWithTip @@ -232,9 +235,9 @@ describe('moveToWell', () => { ) const result = moveToWell( { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', }, invariantContext, robotStateWithTip @@ -266,9 +269,9 @@ describe('moveToWell', () => { ) const result = moveToWell( { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', }, invariantContext, robotStateWithTip @@ -307,9 +310,9 @@ describe('moveToWell', () => { const result = moveToWell( { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', }, invariantContext, robotStateWithTip @@ -348,9 +351,9 @@ describe('moveToWell', () => { const result = moveToWell( { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', }, invariantContext, robotStateWithTip @@ -395,9 +398,9 @@ describe('moveToWell', () => { const result = moveToWell( { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', }, invariantContext, robotStateWithTip @@ -437,9 +440,9 @@ describe('moveToWell', () => { const result = moveToWell( { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', }, invariantContext, robotStateWithTip @@ -462,9 +465,9 @@ describe('moveToWell', () => { const result = moveToWell( { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', }, invariantContext, robotStateWithTip @@ -485,9 +488,9 @@ describe('moveToWell', () => { const result = moveToWell( { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', }, invariantContext, robotStateWithTip @@ -508,9 +511,9 @@ describe('moveToWell', () => { const result = moveToWell( { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', }, invariantContext, robotStateWithTip @@ -532,9 +535,9 @@ describe('moveToWell', () => { const result = moveToWell( { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', }, invariantContext, robotStateWithTip diff --git a/step-generation/src/__tests__/replaceTip.test.ts b/step-generation/src/__tests__/replaceTip.test.ts index f814ca8a04b..fd901ec29d5 100644 --- a/step-generation/src/__tests__/replaceTip.test.ts +++ b/step-generation/src/__tests__/replaceTip.test.ts @@ -19,7 +19,7 @@ import { DEFAULT_PIPETTE, PIPETTE_96, } from '../fixtures' -import { replaceTip } from '../commandCreators/atomic/replaceTip' +import { replaceTip } from '../commandCreators/compound/replaceTip' import { FIXED_TRASH_ID } from '../constants' import type { LabwareDefinition2 } from '@opentrons/shared-data' import type { InvariantContext, RobotState } from '../types' diff --git a/step-generation/src/__tests__/touchTip.test.ts b/step-generation/src/__tests__/touchTip.test.ts index 498624fda41..1c6e23cbcb4 100644 --- a/step-generation/src/__tests__/touchTip.test.ts +++ b/step-generation/src/__tests__/touchTip.test.ts @@ -12,6 +12,11 @@ import { } from '../fixtures' import type { InvariantContext, RobotState } from '../types' +const wellLocation: any = { + origin: 'bottom', + offset: { z: 10 }, +} + describe('touchTip', () => { let invariantContext: InvariantContext let initialRobotState: RobotState @@ -26,10 +31,10 @@ describe('touchTip', () => { it('touchTip with tip, specifying offsetFromBottomMm', () => { const result = touchTip( { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', - offsetFromBottomMm: 10, + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', + wellLocation, }, invariantContext, robotStateWithTip @@ -58,10 +63,10 @@ describe('touchTip', () => { it('touchTip with invalid pipette ID should throw error', () => { const result = touchTip( { - pipette: 'badPipette', - labware: SOURCE_LABWARE, - well: 'A1', - offsetFromBottomMm: 10, + pipetteId: 'badPipette', + labwareId: SOURCE_LABWARE, + wellName: 'A1', + wellLocation, }, invariantContext, robotStateWithTip @@ -74,10 +79,10 @@ describe('touchTip', () => { it('touchTip with no tip should throw error', () => { const result = touchTip( { - pipette: DEFAULT_PIPETTE, - labware: SOURCE_LABWARE, - well: 'A1', - offsetFromBottomMm: 10, + pipetteId: DEFAULT_PIPETTE, + labwareId: SOURCE_LABWARE, + wellName: 'A1', + wellLocation, }, invariantContext, initialRobotState diff --git a/step-generation/src/__tests__/wasteChuteCommandsUtil.test.ts b/step-generation/src/__tests__/wasteChuteCommandsUtil.test.ts index 879cb395c5a..79d275248b5 100644 --- a/step-generation/src/__tests__/wasteChuteCommandsUtil.test.ts +++ b/step-generation/src/__tests__/wasteChuteCommandsUtil.test.ts @@ -30,6 +30,7 @@ const args = { const mockMoveToAddressableAreaParams = { pipetteId: mockId, addressableAreaName: mockAddressableAreaName, + offset: { x: 0, y: 0, z: 0 }, } const mockPipEntities: PipetteEntities = { diff --git a/step-generation/src/commandCreators/atomic/aspirate.ts b/step-generation/src/commandCreators/atomic/aspirate.ts index 01d33e00605..07b95f3459d 100644 --- a/step-generation/src/commandCreators/atomic/aspirate.ts +++ b/step-generation/src/commandCreators/atomic/aspirate.ts @@ -19,15 +19,14 @@ import { COLUMN_4_SLOTS } from '../../constants' import type { CreateCommand, NozzleConfigurationStyle, + AspDispAirgapParams, } from '@opentrons/shared-data' -import type { AspirateParams } from '@opentrons/shared-data/protocol/types/schemaV3' import type { CommandCreator, CommandCreatorError } from '../../types' - -export interface ExtendedAspirateParams extends AspirateParams { - xOffset: number - yOffset: number +import type { Point } from '../../utils' +export interface ExtendedAspirateParams extends AspDispAirgapParams { tipRack: string nozzles: NozzleConfigurationStyle | null + isAirGap?: boolean } /** Aspirate with given args. Requires tip. */ export const aspirate: CommandCreator = ( @@ -36,28 +35,26 @@ export const aspirate: CommandCreator = ( prevRobotState ) => { const { - pipette, + pipetteId, volume, - labware, - well, - offsetFromBottomMm, + labwareId, + wellName, flowRate, isAirGap, tipRack, - xOffset, - yOffset, + wellLocation, nozzles, } = args const actionName = 'aspirate' const labwareState = prevRobotState.labware const errors: CommandCreatorError[] = [] - const pipetteSpec = invariantContext.pipetteEntities[pipette]?.spec + const pipetteSpec = invariantContext.pipetteEntities[pipetteId]?.spec const isFlexPipette = (pipetteSpec?.displayCategory === 'FLEX' || pipetteSpec?.channels === 96) ?? false const slotName = getLabwareSlot( - labware, + labwareId, prevRobotState.labware, prevRobotState.modules ) @@ -65,19 +62,19 @@ export const aspirate: CommandCreator = ( if (!pipetteSpec) { errors.push( errorCreators.pipetteDoesNotExist({ - pipette, + pipette: pipetteId, }) ) } - if (!labware || !prevRobotState.labware[labware]) { + if (!labwareId || !prevRobotState.labware[labwareId]) { errors.push( errorCreators.labwareDoesNotExist({ actionName, - labware, + labware: labwareId, }) ) - } else if (prevRobotState.labware[labware].slot === 'offDeck') { + } else if (prevRobotState.labware[labwareId].slot === 'offDeck') { errors.push(errorCreators.labwareOffDeck()) } @@ -94,8 +91,8 @@ export const aspirate: CommandCreator = ( if ( modulePipetteCollision({ - pipette, - labware, + pipette: pipetteId, + labware: labwareId, invariantContext, prevRobotState, }) @@ -103,19 +100,19 @@ export const aspirate: CommandCreator = ( errors.push(errorCreators.modulePipetteCollisionDanger()) } - if (!prevRobotState.tipState.pipettes[pipette]) { + if (!prevRobotState.tipState.pipettes[pipetteId]) { errors.push( errorCreators.noTipOnPipette({ actionName, - pipette, - labware, - well, + pipette: pipetteId, + labware: labwareId, + well: wellName, }) ) } const is96Channel = - invariantContext.pipetteEntities[args.pipette]?.spec.channels === 96 + invariantContext.pipetteEntities[pipetteId]?.spec.channels === 96 if ( is96Channel && @@ -123,11 +120,11 @@ export const aspirate: CommandCreator = ( !getIsSafePipetteMovement( prevRobotState, invariantContext, - args.pipette, - args.labware, - args.tipRack, - { x: xOffset, y: yOffset, z: offsetFromBottomMm }, - args.well + pipetteId, + labwareId, + tipRack, + (wellLocation?.offset as Point) ?? { x: 0, y: 0, z: 0 }, + wellName ) ) { errors.push(errorCreators.possiblePipetteCollision()) @@ -137,7 +134,7 @@ export const aspirate: CommandCreator = ( thermocyclerPipetteCollision( prevRobotState.modules, prevRobotState.labware, - labware + labwareId ) ) { errors.push(errorCreators.thermocyclerLidClosed()) @@ -147,7 +144,7 @@ export const aspirate: CommandCreator = ( absorbanceReaderCollision( prevRobotState.modules, prevRobotState.labware, - labware + labwareId ) ) { errors.push(errorCreators.absorbanceReaderLidClosed()) @@ -157,7 +154,7 @@ export const aspirate: CommandCreator = ( pipetteIntoHeaterShakerLatchOpen( prevRobotState.modules, prevRobotState.labware, - labware + labwareId ) ) { errors.push(errorCreators.heaterShakerLatchOpen()) @@ -167,7 +164,7 @@ export const aspirate: CommandCreator = ( pipetteIntoHeaterShakerWhileShaking( prevRobotState.modules, prevRobotState.labware, - labware + labwareId ) ) { errors.push(errorCreators.heaterShakerIsShaking()) @@ -203,7 +200,7 @@ export const aspirate: CommandCreator = ( prevRobotState.modules, slotName, pipetteSpec, - invariantContext.labwareEntities[labware] + invariantContext.labwareEntities[labwareId] ) ) { errors.push( @@ -227,7 +224,7 @@ export const aspirate: CommandCreator = ( if (errors.length === 0 && pipetteSpec) { const tipMaxVolume = getPipetteWithTipMaxVol( - pipette, + pipetteId, invariantContext, tipRack ) @@ -253,18 +250,11 @@ export const aspirate: CommandCreator = ( commandType: 'aspirate', key: uuid(), params: { - pipetteId: pipette, + pipetteId, volume, - labwareId: labware, - wellName: well, - wellLocation: { - origin: 'bottom', - offset: { - z: offsetFromBottomMm, - x: xOffset, - y: yOffset, - }, - }, + labwareId, + wellName, + wellLocation, flowRate, }, ...(isAirGap && { meta: { isAirGap } }), diff --git a/step-generation/src/commandCreators/atomic/blowout.ts b/step-generation/src/commandCreators/atomic/blowout.ts index 46bf398e19f..78f7306166c 100644 --- a/step-generation/src/commandCreators/atomic/blowout.ts +++ b/step-generation/src/commandCreators/atomic/blowout.ts @@ -193,12 +193,7 @@ export const blowout: CommandCreator = ( labwareId, wellName, flowRate, - wellLocation: { - origin: 'top', - offset: { - z: wellLocation?.offset?.z, - }, - }, + wellLocation, }, }, ] diff --git a/step-generation/src/commandCreators/atomic/comment.ts b/step-generation/src/commandCreators/atomic/comment.ts index f01a1fadec0..7f1884c3604 100644 --- a/step-generation/src/commandCreators/atomic/comment.ts +++ b/step-generation/src/commandCreators/atomic/comment.ts @@ -1,8 +1,8 @@ import { uuid } from '../../utils' -import type { CommentCreateCommand } from '@opentrons/shared-data' +import type { CommentParams } from '@opentrons/shared-data' import type { CommandCreator } from '../../types' -export const comment: CommandCreator = ( +export const comment: CommandCreator = ( args, invariantContext, prevRobotState diff --git a/step-generation/src/commandCreators/atomic/configureForVolume.ts b/step-generation/src/commandCreators/atomic/configureForVolume.ts index ee977c8a47b..2c42d06c222 100644 --- a/step-generation/src/commandCreators/atomic/configureForVolume.ts +++ b/step-generation/src/commandCreators/atomic/configureForVolume.ts @@ -1,11 +1,8 @@ import { uuid } from '../../utils' +import type { ConfigureForVolumeParams } from '@opentrons/shared-data' import type { CommandCreator } from '../../types' -interface configureForVolumeArgs { - pipetteId: string - volume: number -} -export const configureForVolume: CommandCreator = ( +export const configureForVolume: CommandCreator = ( args, invariantContext, prevRobotState diff --git a/step-generation/src/commandCreators/atomic/configureNozzleLayout.ts b/step-generation/src/commandCreators/atomic/configureNozzleLayout.ts index bff6a097eda..736f4d24189 100644 --- a/step-generation/src/commandCreators/atomic/configureNozzleLayout.ts +++ b/step-generation/src/commandCreators/atomic/configureNozzleLayout.ts @@ -1,19 +1,13 @@ -import { COLUMN } from '@opentrons/shared-data' import { uuid } from '../../utils' +import type { ConfigureNozzleLayoutParams } from '@opentrons/shared-data' import type { CommandCreator } from '../../types' -import type { NozzleConfigurationStyle } from '@opentrons/shared-data' -interface configureNozzleLayoutArgs { - pipetteId: string - nozzles: NozzleConfigurationStyle -} - -export const configureNozzleLayout: CommandCreator = ( +export const configureNozzleLayout: CommandCreator = ( args, invariantContext, prevRobotState ) => { - const { pipetteId, nozzles } = args + const { pipetteId, configurationParams } = args const commands = [ { @@ -21,10 +15,7 @@ export const configureNozzleLayout: CommandCreator = key: uuid(), params: { pipetteId, - configurationParams: { - primaryNozzle: nozzles === COLUMN ? 'A12' : undefined, - style: nozzles, - }, + configurationParams, }, }, ] diff --git a/step-generation/src/commandCreators/atomic/delay.ts b/step-generation/src/commandCreators/atomic/delay.ts index b81bc132631..9f023a1acc7 100644 --- a/step-generation/src/commandCreators/atomic/delay.ts +++ b/step-generation/src/commandCreators/atomic/delay.ts @@ -1,27 +1,29 @@ import { uuid } from '../../utils' -import type { PauseArgs, CommandCreator } from '../../types' import type { WaitForDurationCreateCommand, + WaitForDurationParams, WaitForResumeCreateCommand, + WaitForResumeParams, } from '@opentrons/shared-data' -export const delay: CommandCreator = ( - args, - invariantContext, - prevRobotState -) => { +import type { CommandCreator } from '../../types' + +export const delay: CommandCreator< + WaitForResumeParams | WaitForDurationParams +> = (args, invariantContext, prevRobotState) => { + const { message } = args // delay is deprecated and now is either waitForResume or waitForDuration let command: WaitForResumeCreateCommand | WaitForDurationCreateCommand - if (args.wait === true) { + if ('seconds' in args) { command = { - commandType: 'waitForResume', + commandType: 'waitForDuration', key: uuid(), - params: { message: args.message }, + params: { seconds: args.seconds, message }, } } else { command = { - commandType: 'waitForDuration', + commandType: 'waitForResume', key: uuid(), - params: { seconds: args.wait, message: args.message }, + params: { message }, } } return { diff --git a/step-generation/src/commandCreators/atomic/dispense.ts b/step-generation/src/commandCreators/atomic/dispense.ts index 09630daeb21..554ebbce840 100644 --- a/step-generation/src/commandCreators/atomic/dispense.ts +++ b/step-generation/src/commandCreators/atomic/dispense.ts @@ -17,44 +17,43 @@ import { import { COLUMN_4_SLOTS } from '../../constants' import type { CreateCommand, + DispenseParams, NozzleConfigurationStyle, } from '@opentrons/shared-data' -import type { DispenseParams } from '@opentrons/shared-data/protocol/types/schemaV3' +import type { Point } from '../../utils' import type { CommandCreator, CommandCreatorError } from '../../types' -export interface ExtendedDispenseParams extends DispenseParams { - xOffset: number - yOffset: number - tipRack: string +export interface DispenseAtomicCommandParams extends DispenseParams { nozzles: NozzleConfigurationStyle | null + tipRack: string + isAirGap?: boolean } /** Dispense with given args. Requires tip. */ -export const dispense: CommandCreator = ( +export const dispense: CommandCreator = ( args, invariantContext, prevRobotState ) => { const { - pipette, + pipetteId, volume, - labware, - well, - offsetFromBottomMm, + labwareId, + wellName, flowRate, isAirGap, - xOffset, - yOffset, + wellLocation, nozzles, + tipRack, } = args const actionName = 'dispense' const labwareState = prevRobotState.labware const errors: CommandCreatorError[] = [] - const pipetteSpec = invariantContext.pipetteEntities[pipette]?.spec + const pipetteSpec = invariantContext.pipetteEntities[pipetteId]?.spec const isFlexPipette = (pipetteSpec?.displayCategory === 'FLEX' || pipetteSpec?.channels === 96) ?? false const slotName = getLabwareSlot( - labware, + labwareId, prevRobotState.labware, prevRobotState.modules ) @@ -62,15 +61,15 @@ export const dispense: CommandCreator = ( if (!pipetteSpec) { errors.push( errorCreators.pipetteDoesNotExist({ - pipette, + pipette: pipetteId, }) ) } if ( modulePipetteCollision({ - pipette, - labware, + pipette: pipetteId, + labware: labwareId, invariantContext, prevRobotState, }) @@ -78,25 +77,25 @@ export const dispense: CommandCreator = ( errors.push(errorCreators.modulePipetteCollisionDanger()) } - if (!prevRobotState.tipState.pipettes[pipette]) { + if (!prevRobotState.tipState.pipettes[pipetteId]) { errors.push( errorCreators.noTipOnPipette({ actionName, - pipette, - labware, - well, + pipette: pipetteId, + labware: labwareId, + well: wellName, }) ) } - if (!labware || !prevRobotState.labware[labware]) { + if (!labwareId || !prevRobotState.labware[labwareId]) { errors.push( errorCreators.labwareDoesNotExist({ actionName, - labware, + labware: labwareId, }) ) - } else if (prevRobotState.labware[labware]?.slot === 'offDeck') { + } else if (prevRobotState.labware[labwareId]?.slot === 'offDeck') { errors.push(errorCreators.labwareOffDeck()) } @@ -112,7 +111,7 @@ export const dispense: CommandCreator = ( } const is96Channel = - invariantContext.pipetteEntities[args.pipette]?.spec.channels === 96 + invariantContext.pipetteEntities[pipetteId]?.spec.channels === 96 if ( is96Channel && @@ -120,11 +119,11 @@ export const dispense: CommandCreator = ( !getIsSafePipetteMovement( prevRobotState, invariantContext, - args.pipette, - args.labware, - args.tipRack, - { x: xOffset, y: yOffset, z: offsetFromBottomMm }, - args.well + pipetteId, + labwareId, + tipRack, + (wellLocation?.offset as Point) ?? { x: 0, y: 0, z: 0 }, + wellName ) ) { errors.push(errorCreators.possiblePipetteCollision()) @@ -134,7 +133,7 @@ export const dispense: CommandCreator = ( thermocyclerPipetteCollision( prevRobotState.modules, prevRobotState.labware, - labware + labwareId ) ) { errors.push(errorCreators.thermocyclerLidClosed()) @@ -144,7 +143,7 @@ export const dispense: CommandCreator = ( absorbanceReaderCollision( prevRobotState.modules, prevRobotState.labware, - labware + labwareId ) ) { errors.push(errorCreators.absorbanceReaderLidClosed()) @@ -154,7 +153,7 @@ export const dispense: CommandCreator = ( pipetteIntoHeaterShakerLatchOpen( prevRobotState.modules, prevRobotState.labware, - labware + labwareId ) ) { errors.push(errorCreators.heaterShakerLatchOpen()) @@ -164,7 +163,7 @@ export const dispense: CommandCreator = ( pipetteIntoHeaterShakerWhileShaking( prevRobotState.modules, prevRobotState.labware, - labware + labwareId ) ) { errors.push(errorCreators.heaterShakerIsShaking()) @@ -199,7 +198,7 @@ export const dispense: CommandCreator = ( prevRobotState.modules, slotName, pipetteSpec, - invariantContext.labwareEntities[labware] + invariantContext.labwareEntities[labwareId] ) ) { errors.push( @@ -218,18 +217,11 @@ export const dispense: CommandCreator = ( commandType: 'dispense', key: uuid(), params: { - pipetteId: pipette, + pipetteId, volume, - labwareId: labware, - wellName: well, - wellLocation: { - origin: 'bottom', - offset: { - z: offsetFromBottomMm, - x: xOffset, - y: yOffset, - }, - }, + labwareId, + wellName, + wellLocation, flowRate, // pushOut will always be undefined in step-generation for now // since there is no easy way to allow users to for it in PD diff --git a/step-generation/src/commandCreators/atomic/index.ts b/step-generation/src/commandCreators/atomic/index.ts index 34399f7a2f3..5390c77d017 100644 --- a/step-generation/src/commandCreators/atomic/index.ts +++ b/step-generation/src/commandCreators/atomic/index.ts @@ -21,10 +21,11 @@ import { moveLabware } from './moveLabware' import { moveToAddressableArea } from './moveToAddressableArea' import { moveToAddressableAreaForDropTip } from './moveToAddressableAreaForDropTip' import { moveToWell } from './moveToWell' -import { replaceTip } from './replaceTip' import { setTemperature } from './setTemperature' import { touchTip } from './touchTip' import { waitForTemperature } from './waitForTemperature' +import { pickUpTip } from './pickUpTip' + export { absorbanceReaderCloseLid, absorbanceReaderInitialize, @@ -34,9 +35,9 @@ export { aspirateInPlace, blowout, blowOutInPlace, + comment, configureForVolume, configureNozzleLayout, - comment, deactivateTemperature, delay, disengageMagnet, @@ -49,7 +50,7 @@ export { moveToAddressableArea, moveToAddressableAreaForDropTip, moveToWell, - replaceTip, + pickUpTip, setTemperature, touchTip, waitForTemperature, diff --git a/step-generation/src/commandCreators/atomic/moveLabware.ts b/step-generation/src/commandCreators/atomic/moveLabware.ts index 4976b6d7827..253679e5bad 100644 --- a/step-generation/src/commandCreators/atomic/moveLabware.ts +++ b/step-generation/src/commandCreators/atomic/moveLabware.ts @@ -11,33 +11,30 @@ import { getLabwareHasLiquid, uuid, } from '../../utils' -import type { - CreateCommand, - LabwareMovementStrategy, -} from '@opentrons/shared-data' +import type { CreateCommand, MoveLabwareParams } from '@opentrons/shared-data' import type { CommandCreator, CommandCreatorError, - MoveLabwareArgs, CommandCreatorWarning, } from '../../types' /** Move labware from one location to another, manually or via a gripper. */ -export const moveLabware: CommandCreator = ( +export const moveLabware: CommandCreator = ( args, invariantContext, prevRobotState ) => { - const { labware, useGripper, newLocation } = args + const { labwareId, strategy, newLocation } = args + const useGripper = strategy === 'usingGripper' const { additionalEquipmentEntities, labwareEntities } = invariantContext const hasWasteChute = getHasWasteChute(additionalEquipmentEntities) const tiprackHasTip = prevRobotState.tipState != null - ? getTiprackHasTips(prevRobotState.tipState, labware) + ? getTiprackHasTips(prevRobotState.tipState, labwareId) : false const labwareHasLiquid = prevRobotState.liquidState != null - ? getLabwareHasLiquid(prevRobotState.liquidState, labware) + ? getLabwareHasLiquid(prevRobotState.liquidState, labwareId) : false const hasTipOnPipettes = Object.values( prevRobotState.tipState.pipettes @@ -72,14 +69,17 @@ export const moveLabware: CommandCreator = ( prevRobotState.modules ).find(module => module.slot === newLocationSlot) - if (!labware || !prevRobotState.labware[labware]) { + if (!labwareId || !prevRobotState.labware[labwareId]) { errors.push( errorCreators.labwareDoesNotExist({ actionName, - labware, + labware: labwareId, }) ) - } else if (prevRobotState.labware[labware].slot === 'offDeck' && useGripper) { + } else if ( + prevRobotState.labware[labwareId].slot === 'offDeck' && + useGripper + ) { errors.push(errorCreators.labwareOffDeck()) } else if ( multipleObjectsInSameSlotLabware || @@ -89,7 +89,7 @@ export const moveLabware: CommandCreator = ( } const isAluminumBlock = - labwareEntities[labware]?.def.metadata.displayCategory === 'aluminumBlock' + labwareEntities[labwareId]?.def.metadata.displayCategory === 'aluminumBlock' if (useGripper && isAluminumBlock) { errors.push(errorCreators.cannotMoveWithGripper()) @@ -106,7 +106,7 @@ export const moveLabware: CommandCreator = ( errors.push(errorCreators.pipetteHasTip()) } - const initialLabwareSlot = prevRobotState.labware[labware]?.slot + const initialLabwareSlot = prevRobotState.labware[labwareId]?.slot if (hasWasteChute && initialLabwareSlot === 'gripperWasteChute') { errors.push(errorCreators.labwareDiscarded()) @@ -198,10 +198,8 @@ export const moveLabware: CommandCreator = ( } const params = { - labwareId: labware, - strategy: useGripper - ? 'usingGripper' - : ('manualMoveWithPause' as LabwareMovementStrategy), + labwareId, + strategy, newLocation, } diff --git a/step-generation/src/commandCreators/atomic/moveToAddressableArea.ts b/step-generation/src/commandCreators/atomic/moveToAddressableArea.ts index be5314fba36..aee092a28bc 100644 --- a/step-generation/src/commandCreators/atomic/moveToAddressableArea.ts +++ b/step-generation/src/commandCreators/atomic/moveToAddressableArea.ts @@ -1,18 +1,13 @@ -import type { AddressableAreaName } from '@opentrons/shared-data' - import { uuid } from '../../utils' +import type { MoveToAddressableAreaParams } from '@opentrons/shared-data' import type { CommandCreator } from '../../types' -export interface MoveToAddressableAreaArgs { - pipetteId: string - addressableAreaName: AddressableAreaName -} -export const moveToAddressableArea: CommandCreator = ( +export const moveToAddressableArea: CommandCreator = ( args, invariantContext, prevRobotState ) => { - const { pipetteId, addressableAreaName } = args + const { pipetteId, addressableAreaName, offset } = args const commands = [ { @@ -21,7 +16,7 @@ export const moveToAddressableArea: CommandCreator = params: { pipetteId, addressableAreaName, - offset: { x: 0, y: 0, z: 0 }, + offset, }, }, ] diff --git a/step-generation/src/commandCreators/atomic/moveToAddressableAreaForDropTip.ts b/step-generation/src/commandCreators/atomic/moveToAddressableAreaForDropTip.ts index 103f3db43db..d422f6b000d 100644 --- a/step-generation/src/commandCreators/atomic/moveToAddressableAreaForDropTip.ts +++ b/step-generation/src/commandCreators/atomic/moveToAddressableAreaForDropTip.ts @@ -1,13 +1,8 @@ -import type { AddressableAreaName } from '@opentrons/shared-data' - import { uuid } from '../../utils' +import type { MoveToAddressableAreaForDropTipParams } from '@opentrons/shared-data' import type { CommandCreator } from '../../types' -export interface MoveToAddressableAreaForDropTipArgs { - pipetteId: string - addressableAreaName: AddressableAreaName -} -export const moveToAddressableAreaForDropTip: CommandCreator = ( +export const moveToAddressableAreaForDropTip: CommandCreator = ( args, invariantContext, prevRobotState diff --git a/step-generation/src/commandCreators/atomic/moveToWell.ts b/step-generation/src/commandCreators/atomic/moveToWell.ts index 1ecb91b2c80..d7d124e6baa 100644 --- a/step-generation/src/commandCreators/atomic/moveToWell.ts +++ b/step-generation/src/commandCreators/atomic/moveToWell.ts @@ -14,30 +14,35 @@ import { uuid, } from '../../utils' import { COLUMN_4_SLOTS } from '../../constants' -import type { CreateCommand } from '@opentrons/shared-data' -import type { MoveToWellParams as v5MoveToWellParams } from '@opentrons/shared-data/protocol/types/schemaV5' -import type { MoveToWellParams as v6MoveToWellParams } from '@opentrons/shared-data/protocol/types/schemaV6/command/gantry' +import type { CreateCommand, MoveToWellParams } from '@opentrons/shared-data' import type { CommandCreator, CommandCreatorError } from '../../types' /** Move to specified well of labware, with optional offset and pathing options. */ -export const moveToWell: CommandCreator = ( +export const moveToWell: CommandCreator = ( args, invariantContext, prevRobotState ) => { - const { pipette, labware, well, offset, minimumZHeight, forceDirect } = args + const { + pipetteId, + labwareId, + wellName, + wellLocation, + minimumZHeight, + forceDirect, + } = args const actionName = 'moveToWell' const errors: CommandCreatorError[] = [] const labwareState = prevRobotState.labware // TODO(2020-07-30, IL): the below is duplicated or at least similar // across aspirate/dispense/blowout, we can probably DRY it up - const pipetteSpec = invariantContext.pipetteEntities[pipette]?.spec + const pipetteSpec = invariantContext.pipetteEntities[pipetteId]?.spec const isFlexPipette = (pipetteSpec?.displayCategory === 'FLEX' || pipetteSpec?.channels === 96) ?? false const slotName = getLabwareSlot( - labware, + labwareId, prevRobotState.labware, prevRobotState.modules ) @@ -45,19 +50,19 @@ export const moveToWell: CommandCreator = ( if (!pipetteSpec) { errors.push( errorCreators.pipetteDoesNotExist({ - pipette, + pipette: pipetteId, }) ) } - if (!labware || !prevRobotState.labware[labware]) { + if (!labwareId || !prevRobotState.labware[labwareId]) { errors.push( errorCreators.labwareDoesNotExist({ actionName, - labware, + labware: labwareId, }) ) - } else if (prevRobotState.labware[labware].slot === 'offDeck') { + } else if (prevRobotState.labware[labwareId].slot === 'offDeck') { errors.push(errorCreators.labwareOffDeck()) } @@ -76,8 +81,8 @@ export const moveToWell: CommandCreator = ( if ( modulePipetteCollision({ - pipette, - labware, + pipette: pipetteId, + labware: labwareId, invariantContext, prevRobotState, }) @@ -89,7 +94,7 @@ export const moveToWell: CommandCreator = ( thermocyclerPipetteCollision( prevRobotState.modules, prevRobotState.labware, - labware + labwareId ) ) { errors.push(errorCreators.thermocyclerLidClosed()) @@ -99,7 +104,7 @@ export const moveToWell: CommandCreator = ( pipetteIntoHeaterShakerLatchOpen( prevRobotState.modules, prevRobotState.labware, - labware + labwareId ) ) { errors.push(errorCreators.heaterShakerLatchOpen()) @@ -109,7 +114,7 @@ export const moveToWell: CommandCreator = ( absorbanceReaderCollision( prevRobotState.modules, prevRobotState.labware, - labware + labwareId ) ) { errors.push(errorCreators.absorbanceReaderLidClosed()) @@ -119,7 +124,7 @@ export const moveToWell: CommandCreator = ( pipetteIntoHeaterShakerWhileShaking( prevRobotState.modules, prevRobotState.labware, - labware + labwareId ) ) { errors.push(errorCreators.heaterShakerIsShaking()) @@ -155,7 +160,7 @@ export const moveToWell: CommandCreator = ( prevRobotState.modules, slotName, pipetteSpec, - invariantContext.labwareEntities[labware] + invariantContext.labwareEntities[labwareId] ) ) { errors.push( @@ -169,38 +174,18 @@ export const moveToWell: CommandCreator = ( } } - const requiredParams: v6MoveToWellParams = { - pipetteId: pipette, - labwareId: labware, - wellName: well, - } - - const wellLocationParams: Pick = { - wellLocation: { - origin: 'bottom', - offset, - }, - } - - const params = { - ...requiredParams, - ...(offset != null && wellLocationParams), - } - - // add optional fields only if specified - if (forceDirect != null) { - params.forceDirect = forceDirect - } - - if (minimumZHeight != null) { - params.minimumZHeight = minimumZHeight - } - const commands: CreateCommand[] = [ { commandType: 'moveToWell', key: uuid(), - params, + params: { + pipetteId, + labwareId, + wellName, + wellLocation, + forceDirect, + minimumZHeight, + }, }, ] return { diff --git a/step-generation/src/commandCreators/atomic/pickUpTip.ts b/step-generation/src/commandCreators/atomic/pickUpTip.ts new file mode 100644 index 00000000000..7c6fd8e9e3e --- /dev/null +++ b/step-generation/src/commandCreators/atomic/pickUpTip.ts @@ -0,0 +1,72 @@ +import { COLUMN } from '@opentrons/shared-data' +import { + pipettingIntoColumn4, + possiblePipetteCollision, +} from '../../errorCreators' +import { COLUMN_4_SLOTS } from '../../constants' +import { uuid, getIsSafePipetteMovement } from '../../utils' +import type { + NozzleConfigurationStyle, + PickUpTipParams, +} from '@opentrons/shared-data' +import type { CommandCreator, CommandCreatorError } from '../../types' + +interface PickUpTipAtomicParams extends PickUpTipParams { + nozzles?: NozzleConfigurationStyle +} + +export const pickUpTip: CommandCreator = ( + args, + invariantContext, + prevRobotState +) => { + const { pipetteId, labwareId, wellName, nozzles } = args + const errors: CommandCreatorError[] = [] + + const is96Channel = + invariantContext.pipetteEntities[pipetteId]?.spec.channels === 96 + + if ( + is96Channel && + nozzles === COLUMN && + !getIsSafePipetteMovement( + prevRobotState, + invariantContext, + pipetteId, + labwareId, + labwareId, + // we don't adjust the offset when moving to the tiprack + { x: 0, y: 0 }, + wellName + ) + ) { + errors.push(possiblePipetteCollision()) + } + + const tiprackSlot = prevRobotState.labware[labwareId].slot + if (COLUMN_4_SLOTS.includes(tiprackSlot)) { + errors.push(pipettingIntoColumn4({ typeOfStep: 'pick up tip' })) + } else if (prevRobotState.labware[tiprackSlot] != null) { + const adapterSlot = prevRobotState.labware[tiprackSlot].slot + if (COLUMN_4_SLOTS.includes(adapterSlot)) { + errors.push(pipettingIntoColumn4({ typeOfStep: 'pick up tip' })) + } + } + + if (errors.length > 0) { + return { errors } + } + return { + commands: [ + { + commandType: 'pickUpTip', + key: uuid(), + params: { + pipetteId, + labwareId, + wellName, + }, + }, + ], + } +} diff --git a/step-generation/src/commandCreators/atomic/touchTip.ts b/step-generation/src/commandCreators/atomic/touchTip.ts index 75047c0b610..28796a42eb6 100644 --- a/step-generation/src/commandCreators/atomic/touchTip.ts +++ b/step-generation/src/commandCreators/atomic/touchTip.ts @@ -1,8 +1,7 @@ import { uuid } from '../../utils' import { noTipOnPipette, pipetteDoesNotExist } from '../../errorCreators' +import type { CreateCommand, TouchTipParams } from '@opentrons/shared-data' import type { CommandCreator, CommandCreatorError } from '../../types' -import type { CreateCommand } from '@opentrons/shared-data' -import type { TouchTipParams } from '@opentrons/shared-data/protocol/types/schemaV3' export const touchTip: CommandCreator = ( args, @@ -11,25 +10,25 @@ export const touchTip: CommandCreator = ( ) => { /** touchTip with given args. Requires tip. */ const actionName = 'touchTip' - const { pipette, labware, well, offsetFromBottomMm } = args - const pipetteData = prevRobotState.pipettes[pipette] + const { pipetteId, labwareId, wellName, wellLocation } = args + const pipetteData = prevRobotState.pipettes[pipetteId] const errors: CommandCreatorError[] = [] if (!pipetteData) { errors.push( pipetteDoesNotExist({ - pipette, + pipette: pipetteId, }) ) } - if (!prevRobotState.tipState.pipettes[pipette]) { + if (!prevRobotState.tipState.pipettes[pipetteId]) { errors.push( noTipOnPipette({ actionName, - pipette, - labware, - well, + pipette: pipetteId, + labware: labwareId, + well: wellName, }) ) } @@ -45,15 +44,10 @@ export const touchTip: CommandCreator = ( commandType: 'touchTip', key: uuid(), params: { - pipetteId: pipette, - labwareId: labware, - wellName: well, - wellLocation: { - origin: 'bottom', - offset: { - z: offsetFromBottomMm, - }, - }, + pipetteId, + labwareId, + wellName, + wellLocation, }, }, ] diff --git a/step-generation/src/commandCreators/compound/consolidate.ts b/step-generation/src/commandCreators/compound/consolidate.ts index 94d20e255f0..f9cb803f9e2 100644 --- a/step-generation/src/commandCreators/compound/consolidate.ts +++ b/step-generation/src/commandCreators/compound/consolidate.ts @@ -29,10 +29,10 @@ import { delay, dropTip, moveToWell, - replaceTip, touchTip, } from '../atomic' import { mixUtil } from './mix' +import { replaceTip } from './replaceTip' import type { ConsolidateArgs, @@ -222,26 +222,27 @@ export const consolidate: CommandCreator = ( const airGapAfterAspirateCommands = aspirateAirGapVolume ? [ curryCommandCreator(aspirate, { - pipette: args.pipette, + pipetteId: args.pipette, volume: aspirateAirGapVolume, - labware: args.sourceLabware, - well: sourceWell, + labwareId: args.sourceLabware, + wellName: sourceWell, flowRate: aspirateFlowRateUlSec, - offsetFromBottomMm: airGapOffsetSourceWell, + wellLocation: { + origin: 'bottom', + offset: { + z: airGapOffsetSourceWell, + x: 0, + y: 0, + }, + }, isAirGap: true, tipRack: args.tipRack, - xOffset: 0, - yOffset: 0, nozzles, }), ...(aspirateDelay != null ? [ curryCommandCreator(delay, { - commandCreatorFnName: 'delay', - description: null, - name: null, - meta: null, - wait: aspirateDelay.seconds, + seconds: aspirateDelay.seconds, }), ] : []), @@ -251,47 +252,55 @@ export const consolidate: CommandCreator = ( aspirateDelay != null ? [ curryCommandCreator(moveToWell, { - pipette: args.pipette, - labware: args.sourceLabware, - well: sourceWell, - offset: { - x: 0, - y: 0, - z: aspirateDelay.mmFromBottom, + pipetteId: args.pipette, + labwareId: args.sourceLabware, + wellName: sourceWell, + wellLocation: { + origin: 'bottom', + offset: { + x: 0, + y: 0, + z: aspirateDelay.mmFromBottom, + }, }, }), curryCommandCreator(delay, { - commandCreatorFnName: 'delay', - description: null, - name: null, - meta: null, - wait: aspirateDelay.seconds, + seconds: aspirateDelay.seconds, }), ] : [] const touchTipAfterAspirateCommand = args.touchTipAfterAspirate ? [ curryCommandCreator(touchTip, { - pipette: args.pipette, - labware: args.sourceLabware, - well: sourceWell, - offsetFromBottomMm: - args.touchTipAfterAspirateOffsetMmFromBottom, + pipetteId: args.pipette, + labwareId: args.sourceLabware, + wellName: sourceWell, + wellLocation: { + origin: 'bottom', + offset: { + z: args.touchTipAfterAspirateOffsetMmFromBottom, + }, + }, }), ] : [] return [ curryCommandCreator(aspirate, { - pipette: args.pipette, + pipetteId: args.pipette, volume: args.volume, - labware: args.sourceLabware, - well: sourceWell, + labwareId: args.sourceLabware, + wellName: sourceWell, flowRate: aspirateFlowRateUlSec, - offsetFromBottomMm: aspirateOffsetFromBottomMm, + wellLocation: { + origin: 'bottom', + offset: { + z: aspirateOffsetFromBottomMm, + x: aspirateXOffset, + y: aspirateYOffset, + }, + }, tipRack: args.tipRack, - xOffset: aspirateXOffset, - yOffset: aspirateYOffset, nozzles, }), ...delayAfterAspirateCommands, @@ -320,11 +329,15 @@ export const consolidate: CommandCreator = ( args.touchTipAfterDispense && destinationWell != null ? [ curryCommandCreator(touchTip, { - pipette: args.pipette, - labware: args.destLabware, - well: destinationWell, - offsetFromBottomMm: - args.touchTipAfterDispenseOffsetMmFromBottom, + pipetteId: args.pipette, + labwareId: args.destLabware, + wellName: destinationWell, + wellLocation: { + origin: 'bottom', + offset: { + z: args.touchTipAfterDispenseOffsetMmFromBottom, + }, + }, }), ] : [] @@ -434,11 +447,7 @@ export const consolidate: CommandCreator = ( zOffset: dispenseDelay.mmFromBottom, }), curryCommandCreator(delay, { - commandCreatorFnName: 'delay', - description: null, - name: null, - meta: null, - wait: dispenseDelay.seconds, + seconds: dispenseDelay.seconds, }), ] : [] @@ -473,11 +482,7 @@ export const consolidate: CommandCreator = ( ...(aspirateDelay != null ? [ curryCommandCreator(delay, { - commandCreatorFnName: 'delay', - description: null, - name: null, - meta: null, - wait: aspirateDelay.seconds, + seconds: aspirateDelay.seconds, }), ] : []), diff --git a/step-generation/src/commandCreators/compound/distribute.ts b/step-generation/src/commandCreators/compound/distribute.ts index ceba8f3e89b..3f7f7b7e629 100644 --- a/step-generation/src/commandCreators/compound/distribute.ts +++ b/step-generation/src/commandCreators/compound/distribute.ts @@ -28,10 +28,11 @@ import { dispense, dropTip, moveToWell, - replaceTip, touchTip, } from '../atomic' import { mixUtil } from './mix' +import { replaceTip } from './replaceTip' + import type { DistributeArgs, CommandCreator, @@ -215,50 +216,52 @@ export const distribute: CommandCreator = ( const airGapAfterAspirateCommands = aspirateAirGapVolume ? [ curryCommandCreator(aspirate, { - pipette: args.pipette, + pipetteId: args.pipette, volume: aspirateAirGapVolume, - labware: args.sourceLabware, - well: args.sourceWell, + labwareId: args.sourceLabware, + wellName: args.sourceWell, flowRate: aspirateFlowRateUlSec, - offsetFromBottomMm: airGapOffsetSourceWell, + wellLocation: { + origin: 'bottom', + offset: { + z: airGapOffsetSourceWell, + x: 0, + y: 0, + }, + }, isAirGap: true, - xOffset: 0, - yOffset: 0, tipRack: args.tipRack, nozzles, }), ...(aspirateDelay != null ? [ curryCommandCreator(delay, { - commandCreatorFnName: 'delay', - description: null, - name: null, - meta: null, - wait: aspirateDelay.seconds, + seconds: aspirateDelay.seconds, }), ] : []), curryCommandCreator(dispense, { - pipette: args.pipette, + pipetteId: args.pipette, volume: aspirateAirGapVolume, - labware: args.destLabware, - well: firstDestWell, + labwareId: args.destLabware, + wellName: firstDestWell, flowRate: dispenseFlowRateUlSec, - offsetFromBottomMm: airGapOffsetDestWell, + wellLocation: { + origin: 'bottom', + offset: { + z: airGapOffsetDestWell, + x: 0, + y: 0, + }, + }, isAirGap: true, - xOffset: 0, - yOffset: 0, nozzles, tipRack: args.tipRack, }), ...(dispenseDelay != null ? [ curryCommandCreator(delay, { - commandCreatorFnName: 'delay', - description: null, - name: null, - meta: null, - wait: dispenseDelay.seconds, + seconds: dispenseDelay.seconds, }), ] : []), @@ -271,45 +274,53 @@ export const distribute: CommandCreator = ( dispenseDelay != null ? [ curryCommandCreator(moveToWell, { - pipette: args.pipette, - labware: args.destLabware, - well: destWell, - offset: { - x: 0, - y: 0, - z: dispenseDelay.mmFromBottom, + pipetteId: args.pipette, + labwareId: args.destLabware, + wellName: destWell, + wellLocation: { + origin: 'bottom', + offset: { + x: 0, + y: 0, + z: dispenseDelay.mmFromBottom, + }, }, }), curryCommandCreator(delay, { - commandCreatorFnName: 'delay', - description: null, - name: null, - meta: null, - wait: dispenseDelay.seconds, + seconds: dispenseDelay.seconds, }), ] : [] const touchTipAfterDispenseCommand = args.touchTipAfterDispense ? [ curryCommandCreator(touchTip, { - pipette, - labware: args.destLabware, - well: destWell, - offsetFromBottomMm: - args.touchTipAfterDispenseOffsetMmFromBottom, + pipetteId: pipette, + labwareId: args.destLabware, + wellName: destWell, + wellLocation: { + origin: 'bottom', + offset: { + z: args.touchTipAfterDispenseOffsetMmFromBottom, + }, + }, }), ] : [] return [ curryCommandCreator(dispense, { - pipette, + pipetteId: pipette, volume: args.volume, - labware: args.destLabware, - well: destWell, + labwareId: args.destLabware, + wellName: destWell, flowRate: dispenseFlowRateUlSec, - offsetFromBottomMm: dispenseOffsetFromBottomMm, - xOffset: dispenseXOffset, - yOffset: dispenseYOffset, + wellLocation: { + origin: 'bottom', + offset: { + z: dispenseOffsetFromBottomMm, + x: dispenseXOffset, + y: dispenseYOffset, + }, + }, nozzles, tipRack: args.tipRack, }), @@ -352,26 +363,28 @@ export const distribute: CommandCreator = ( dispenseAirGapVolume && !willReuseTip ? [ curryCommandCreator(aspirate, { - pipette: args.pipette, + pipetteId: args.pipette, volume: dispenseAirGapVolume, - labware: dispenseAirGapLabware, - well: dispenseAirGapWell, + labwareId: dispenseAirGapLabware, + wellName: dispenseAirGapWell, flowRate: aspirateFlowRateUlSec, - offsetFromBottomMm: airGapOffsetDestWell, + wellLocation: { + origin: 'bottom', + offset: { + z: airGapOffsetDestWell, + x: 0, + y: 0, + }, + }, isAirGap: true, tipRack: args.tipRack, - xOffset: 0, - yOffset: 0, + nozzles, }), ...(aspirateDelay != null ? [ curryCommandCreator(delay, { - commandCreatorFnName: 'delay', - description: null, - name: null, - meta: null, - wait: aspirateDelay.seconds, + seconds: aspirateDelay.seconds, }), ] : []), @@ -422,31 +435,35 @@ export const distribute: CommandCreator = ( aspirateDelay != null ? [ curryCommandCreator(moveToWell, { - pipette: args.pipette, - labware: args.sourceLabware, - well: args.sourceWell, - offset: { - x: 0, - y: 0, - z: aspirateDelay.mmFromBottom, + pipetteId: args.pipette, + labwareId: args.sourceLabware, + wellName: args.sourceWell, + wellLocation: { + origin: 'bottom', + offset: { + x: 0, + y: 0, + z: aspirateDelay.mmFromBottom, + }, }, }), curryCommandCreator(delay, { - commandCreatorFnName: 'delay', - description: null, - name: null, - meta: null, - wait: aspirateDelay.seconds, + seconds: aspirateDelay.seconds, }), ] : [] const touchTipAfterAspirateCommand = args.touchTipAfterAspirate ? [ curryCommandCreator(touchTip, { - pipette: args.pipette, - labware: args.sourceLabware, - well: args.sourceWell, - offsetFromBottomMm: args.touchTipAfterAspirateOffsetMmFromBottom, + pipetteId: args.pipette, + labwareId: args.sourceLabware, + wellName: args.sourceWell, + wellLocation: { + origin: 'bottom', + offset: { + z: args.touchTipAfterAspirateOffsetMmFromBottom, + }, + }, }), ] : [] @@ -489,7 +506,7 @@ export const distribute: CommandCreator = ( ...configureForVolumeCommand, ...mixBeforeAspirateCommands, curryCommandCreator(aspirate, { - pipette, + pipetteId: pipette, volume: args.volume * destWellChunk.length + // only add disposal volume if its the 1st chunk and changing tip once @@ -497,13 +514,18 @@ export const distribute: CommandCreator = ( (args.changeTip === 'once' && blowoutLocation == null ? aspirateDisposalVolumeOnce : disposalVolume), - labware: args.sourceLabware, - well: args.sourceWell, + labwareId: args.sourceLabware, + wellName: args.sourceWell, flowRate: aspirateFlowRateUlSec, - offsetFromBottomMm: aspirateOffsetFromBottomMm, + wellLocation: { + origin: 'bottom', + offset: { + z: aspirateOffsetFromBottomMm, + x: aspirateXOffset, + y: aspirateYOffset, + }, + }, tipRack: args.tipRack, - xOffset: aspirateXOffset, - yOffset: aspirateYOffset, nozzles, }), ...delayAfterAspirateCommands, diff --git a/step-generation/src/commandCreators/compound/heaterShaker.ts b/step-generation/src/commandCreators/compound/heaterShaker.ts index 45e89ef6759..294b7796feb 100644 --- a/step-generation/src/commandCreators/compound/heaterShaker.ts +++ b/step-generation/src/commandCreators/compound/heaterShaker.ts @@ -87,11 +87,7 @@ export const heaterShaker: CommandCreator = ( (args.timerSeconds ?? 0) + (args.timerMinutes ?? 0) * 60 commandCreators.push( curryCommandCreator(delay, { - commandCreatorFnName: 'delay', - description: null, - name: null, - meta: null, - wait: totalSeconds, + seconds: totalSeconds, }) ) commandCreators.push( diff --git a/step-generation/src/commandCreators/compound/index.ts b/step-generation/src/commandCreators/compound/index.ts index 021909496bb..086b9e0c8af 100644 --- a/step-generation/src/commandCreators/compound/index.ts +++ b/step-generation/src/commandCreators/compound/index.ts @@ -2,8 +2,9 @@ export { absorbanceReaderCloseInitialize } from './absorbanceReaderCloseInitiali export { absorbanceReaderCloseRead } from './absorbanceReaderCloseRead' export { consolidate } from './consolidate' export { distribute } from './distribute' +export { heaterShaker } from './heaterShaker' export { mix } from './mix' +export { replaceTip } from './replaceTip' export { thermocyclerProfileStep } from './thermocyclerProfileStep' export { thermocyclerStateStep } from './thermocyclerStateStep' export { transfer } from './transfer' -export { heaterShaker } from './heaterShaker' diff --git a/step-generation/src/commandCreators/compound/mix.ts b/step-generation/src/commandCreators/compound/mix.ts index 15ceb73221c..992d08c41f7 100644 --- a/step-generation/src/commandCreators/compound/mix.ts +++ b/step-generation/src/commandCreators/compound/mix.ts @@ -18,9 +18,9 @@ import { configureForVolume, delay, dispense, - replaceTip, touchTip, } from '../atomic' +import { replaceTip } from './replaceTip' import type { NozzleConfigurationStyle } from '@opentrons/shared-data' import type { @@ -72,11 +72,7 @@ export function mixUtil(args: { seconds ? [ curryCommandCreator(delay, { - commandCreatorFnName: 'delay', - description: null, - name: null, - meta: null, - wait: seconds, + seconds, }), ] : [] @@ -84,27 +80,37 @@ export function mixUtil(args: { return repeatArray( [ curryCommandCreator(aspirate, { - pipette, + pipetteId: pipette, volume, - labware, - well, - offsetFromBottomMm: aspirateOffsetFromBottomMm, + labwareId: labware, + wellName: well, flowRate: aspirateFlowRateUlSec, tipRack, - xOffset: aspirateXOffset, - yOffset: aspirateYOffset, + wellLocation: { + origin: 'bottom', + offset: { + z: aspirateOffsetFromBottomMm, + x: aspirateXOffset, + y: aspirateYOffset, + }, + }, nozzles: null, }), ...getDelayCommand(aspirateDelaySeconds), curryCommandCreator(dispense, { - pipette, + pipetteId: pipette, volume, - labware, - well, - offsetFromBottomMm: dispenseOffsetFromBottomMm, + labwareId: labware, + wellName: well, + wellLocation: { + origin: 'bottom', + offset: { + z: dispenseOffsetFromBottomMm, + x: dispenseXOffset, + y: dispenseYOffset, + }, + }, flowRate: dispenseFlowRateUlSec, - xOffset: dispenseXOffset, - yOffset: dispenseYOffset, tipRack, nozzles: nozzles, }), @@ -254,10 +260,15 @@ export const mix: CommandCreator = ( const touchTipCommands = data.touchTip ? [ curryCommandCreator(touchTip, { - pipette, - labware, - well, - offsetFromBottomMm: data.touchTipMmFromBottom, + pipetteId: pipette, + labwareId: labware, + wellName: well, + wellLocation: { + origin: 'bottom', + offset: { + z: data.touchTipMmFromBottom, + }, + }, }), ] : [] diff --git a/step-generation/src/commandCreators/atomic/replaceTip.ts b/step-generation/src/commandCreators/compound/replaceTip.ts similarity index 72% rename from step-generation/src/commandCreators/atomic/replaceTip.ts rename to step-generation/src/commandCreators/compound/replaceTip.ts index c516a1a4012..21d6a7e6c73 100644 --- a/step-generation/src/commandCreators/atomic/replaceTip.ts +++ b/step-generation/src/commandCreators/compound/replaceTip.ts @@ -6,96 +6,25 @@ import { } from '@opentrons/shared-data' import { getNextTiprack } from '../../robotStateSelectors' import * as errorCreators from '../../errorCreators' -import { COLUMN_4_SLOTS } from '../../constants' import { movableTrashCommandsUtil } from '../../utils/movableTrashCommandsUtil' import { curryCommandCreator, getIsHeaterShakerEastWestMultiChannelPipette, getIsHeaterShakerEastWestWithLatchOpen, - getIsSafePipetteMovement, getLabwareSlot, modulePipetteCollision, pipetteAdjacentHeaterShakerWhileShaking, reduceCommandCreators, - uuid, wasteChuteCommandsUtil, getWasteChuteAddressableAreaNamePip, + PRIMARY_NOZZLE, } from '../../utils' -import { dropTip } from './dropTip' -import { configureNozzleLayout } from './configureNozzleLayout' +import { dropTip } from '../atomic/dropTip' +import { pickUpTip } from '../atomic/pickUpTip' +import { configureNozzleLayout } from '../atomic/configureNozzleLayout' import type { NozzleConfigurationStyle } from '@opentrons/shared-data' -import type { - CommandCreator, - CommandCreatorError, - CurriedCommandCreator, -} from '../../types' - -interface PickUpTipArgs { - pipette: string - tiprack: string - well: string - nozzles?: NozzleConfigurationStyle -} - -const _pickUpTip: CommandCreator = ( - args, - invariantContext, - prevRobotState -) => { - const errors: CommandCreatorError[] = [] - - const is96Channel = - invariantContext.pipetteEntities[args.pipette]?.spec.channels === 96 - - if ( - is96Channel && - args.nozzles === COLUMN && - !getIsSafePipetteMovement( - prevRobotState, - invariantContext, - args.pipette, - args.tiprack, - args.tiprack, - // we don't adjust the offset when moving to the tiprack - { x: 0, y: 0 }, - args.well - ) - ) { - errors.push(errorCreators.possiblePipetteCollision()) - } - - const tiprackSlot = prevRobotState.labware[args.tiprack].slot - if (COLUMN_4_SLOTS.includes(tiprackSlot)) { - errors.push( - errorCreators.pipettingIntoColumn4({ typeOfStep: 'pick up tip' }) - ) - } else if (prevRobotState.labware[tiprackSlot] != null) { - const adapterSlot = prevRobotState.labware[tiprackSlot].slot - if (COLUMN_4_SLOTS.includes(adapterSlot)) { - errors.push( - errorCreators.pipettingIntoColumn4({ typeOfStep: 'pick up tip' }) - ) - } - } - - if (errors.length > 0) { - return { errors } - } - return { - commands: [ - { - commandType: 'pickUpTip', - key: uuid(), - params: { - pipetteId: args.pipette, - labwareId: args.tiprack, - wellName: args.well, - }, - }, - ], - } -} +import type { CommandCreator, CurriedCommandCreator } from '../../types' interface ReplaceTipArgs { pipette: string @@ -254,7 +183,11 @@ export const replaceTip: CommandCreator = ( channels === 96 && args.nozzles != null && args.nozzles !== stateNozzles ? [ curryCommandCreator(configureNozzleLayout, { - nozzles: args.nozzles, + configurationParams: { + primaryNozzle: + args.nozzles === COLUMN ? PRIMARY_NOZZLE : undefined, + style: args.nozzles, + }, pipetteId: args.pipette, }), ] @@ -266,10 +199,10 @@ export const replaceTip: CommandCreator = ( dropTipLocation, }), ...configureNozzleLayoutCommand, - curryCommandCreator(_pickUpTip, { - pipette, - tiprack: nextTiprack.tiprackId, - well: nextTiprack.well, + curryCommandCreator(pickUpTip, { + pipetteId: pipette, + labwareId: nextTiprack.tiprackId, + wellName: nextTiprack.well, nozzles: args.nozzles, }), ] @@ -282,10 +215,10 @@ export const replaceTip: CommandCreator = ( prevRobotState, }), ...configureNozzleLayoutCommand, - curryCommandCreator(_pickUpTip, { - pipette, - tiprack: nextTiprack.tiprackId, - well: nextTiprack.well, + curryCommandCreator(pickUpTip, { + pipetteId: pipette, + labwareId: nextTiprack.tiprackId, + wellName: nextTiprack.well, nozzles: args.nozzles, }), ] @@ -299,10 +232,10 @@ export const replaceTip: CommandCreator = ( invariantContext, }), ...configureNozzleLayoutCommand, - curryCommandCreator(_pickUpTip, { - pipette, - tiprack: nextTiprack.tiprackId, - well: nextTiprack.well, + curryCommandCreator(pickUpTip, { + pipetteId: pipette, + labwareId: nextTiprack.tiprackId, + wellName: nextTiprack.well, nozzles: args.nozzles, }), ] diff --git a/step-generation/src/commandCreators/compound/transfer.ts b/step-generation/src/commandCreators/compound/transfer.ts index 18f99b7e036..e2fb4385f6f 100644 --- a/step-generation/src/commandCreators/compound/transfer.ts +++ b/step-generation/src/commandCreators/compound/transfer.ts @@ -28,10 +28,10 @@ import { dispense, dropTip, moveToWell, - replaceTip, touchTip, } from '../atomic' import { mixUtil } from './mix' +import { replaceTip } from './replaceTip' import type { TransferArgs, @@ -39,6 +39,7 @@ import type { CommandCreator, CommandCreatorError, } from '../../types' + export const transfer: CommandCreator = ( args, invariantContext, @@ -326,32 +327,35 @@ export const transfer: CommandCreator = ( aspirateDelay != null ? [ curryCommandCreator(moveToWell, { - pipette: args.pipette, - labware: args.sourceLabware, - well: sourceWell, - offset: { - x: 0, - y: 0, - z: aspirateDelay.mmFromBottom, + pipetteId: args.pipette, + labwareId: args.sourceLabware, + wellName: sourceWell, + wellLocation: { + origin: 'bottom', + offset: { + x: 0, + y: 0, + z: aspirateDelay.mmFromBottom, + }, }, }), curryCommandCreator(delay, { - commandCreatorFnName: 'delay', - description: null, - name: null, - meta: null, - wait: aspirateDelay.seconds, + seconds: aspirateDelay.seconds, }), ] : [] const touchTipAfterAspirateCommands = args.touchTipAfterAspirate ? [ curryCommandCreator(touchTip, { - pipette: args.pipette, - labware: args.sourceLabware, - well: sourceWell, - offsetFromBottomMm: - args.touchTipAfterAspirateOffsetMmFromBottom, + pipetteId: args.pipette, + labwareId: args.sourceLabware, + wellName: sourceWell, + wellLocation: { + origin: 'bottom', + offset: { + z: args.touchTipAfterAspirateOffsetMmFromBottom, + }, + }, }), ] : [] @@ -360,11 +364,15 @@ export const transfer: CommandCreator = ( args.touchTipAfterDispense && destinationWell != null ? [ curryCommandCreator(touchTip, { - pipette: args.pipette, - labware: args.destLabware, - well: destinationWell, - offsetFromBottomMm: - args.touchTipAfterDispenseOffsetMmFromBottom, + pipetteId: args.pipette, + labwareId: args.destLabware, + wellName: destinationWell, + wellLocation: { + origin: 'bottom', + offset: { + z: args.touchTipAfterDispenseOffsetMmFromBottom, + }, + }, }), ] : [] @@ -396,50 +404,52 @@ export const transfer: CommandCreator = ( aspirateAirGapVolume && destinationWell != null ? [ curryCommandCreator(aspirate, { - pipette: args.pipette, + pipetteId: args.pipette, volume: aspirateAirGapVolume, - labware: args.sourceLabware, - well: sourceWell, + labwareId: args.sourceLabware, + wellName: sourceWell, flowRate: aspirateFlowRateUlSec, - offsetFromBottomMm: airGapOffsetSourceWell, + wellLocation: { + origin: 'bottom', + offset: { + z: airGapOffsetSourceWell, + x: 0, + y: 0, + }, + }, isAirGap: true, tipRack, - xOffset: 0, - yOffset: 0, nozzles: args.nozzles, }), ...(aspirateDelay != null ? [ curryCommandCreator(delay, { - commandCreatorFnName: 'delay', - description: null, - name: null, - meta: null, - wait: aspirateDelay.seconds, + seconds: aspirateDelay.seconds, }), ] : []), curryCommandCreator(dispense, { - pipette: args.pipette, + pipetteId: args.pipette, volume: aspirateAirGapVolume, - labware: args.destLabware, - well: destinationWell, + labwareId: args.destLabware, + wellName: destinationWell, flowRate: dispenseFlowRateUlSec, - offsetFromBottomMm: airGapOffsetDestWell, + wellLocation: { + origin: 'bottom', + offset: { + z: airGapOffsetDestWell, + x: 0, + y: 0, + }, + }, isAirGap: true, - xOffset: 0, - yOffset: 0, tipRack: args.tipRack, nozzles: args.nozzles, }), ...(dispenseDelay != null ? [ curryCommandCreator(delay, { - commandCreatorFnName: 'delay', - description: null, - name: null, - meta: null, - wait: dispenseDelay.seconds, + seconds: dispenseDelay.seconds, }), ] : []), @@ -465,15 +475,20 @@ export const transfer: CommandCreator = ( const aspirateCommand = [ curryCommandCreator(aspirate, { - pipette: args.pipette, + pipetteId: args.pipette, volume: subTransferVol, - labware: args.sourceLabware, - well: sourceWell, + labwareId: args.sourceLabware, + wellName: sourceWell, flowRate: aspirateFlowRateUlSec, - offsetFromBottomMm: aspirateOffsetFromBottomMm, + wellLocation: { + origin: 'bottom', + offset: { + z: aspirateOffsetFromBottomMm, + x: aspirateXOffset, + y: aspirateYOffset, + }, + }, tipRack, - xOffset: aspirateXOffset, - yOffset: aspirateYOffset, nozzles: args.nozzles, }), ] @@ -502,11 +517,7 @@ export const transfer: CommandCreator = ( zOffset: dispenseDelay.mmFromBottom, }), curryCommandCreator(delay, { - commandCreatorFnName: 'delay', - description: null, - name: null, - meta: null, - wait: dispenseDelay.seconds, + seconds: dispenseDelay.seconds, }), ] : [] @@ -543,11 +554,7 @@ export const transfer: CommandCreator = ( ...(aspirateDelay != null ? [ curryCommandCreator(delay, { - commandCreatorFnName: 'delay', - description: null, - name: null, - meta: null, - wait: aspirateDelay.seconds, + seconds: aspirateDelay.seconds, }), ] : []), diff --git a/step-generation/src/commandCreators/index.ts b/step-generation/src/commandCreators/index.ts index 2eced9e279d..2b64769a9f1 100644 --- a/step-generation/src/commandCreators/index.ts +++ b/step-generation/src/commandCreators/index.ts @@ -1,13 +1,14 @@ export { - transfer, - mix, + absorbanceReaderCloseInitialize, + absorbanceReaderCloseRead, consolidate, distribute, + heaterShaker, + mix, + replaceTip, thermocyclerProfileStep, thermocyclerStateStep, - heaterShaker, - absorbanceReaderCloseInitialize, - absorbanceReaderCloseRead, + transfer, } from './compound' export { @@ -16,8 +17,8 @@ export { absorbanceReaderOpenLid, absorbanceReaderRead, aspirate, - waitForTemperature, blowout, + comment, deactivateTemperature, delay, disengageMagnet, @@ -25,10 +26,9 @@ export { dropTip, dropTipInPlace, engageMagnet, - replaceTip, - setTemperature, - touchTip, moveLabware, moveToAddressableArea, - comment, + setTemperature, + touchTip, + waitForTemperature, } from './atomic' diff --git a/step-generation/src/constants.ts b/step-generation/src/constants.ts index ba3196c274f..1ac33327bbd 100644 --- a/step-generation/src/constants.ts +++ b/step-generation/src/constants.ts @@ -9,7 +9,11 @@ import { MAGNETIC_BLOCK_TYPE, } from '@opentrons/shared-data' -import type { ModuleType, ModuleModel } from '@opentrons/shared-data' +import type { + ModuleType, + ModuleModel, + AddressableOffsetVector, +} from '@opentrons/shared-data' import type { MagneticModuleState, TemperatureModuleState, @@ -73,10 +77,10 @@ export const MODULE_INITIAL_STATE_BY_TYPE: { [TEMPERATURE_MODULE_TYPE]: TEMPERATURE_MODULE_INITIAL_STATE, [THERMOCYCLER_MODULE_TYPE]: THERMOCYCLER_MODULE_INITIAL_STATE, [HEATERSHAKER_MODULE_TYPE]: HEATERSHAKER_MODULE_INITIAL_STATE, - // TODO(jr, 6/24/24): add the initial state for absorabance reader [ABSORBANCE_READER_TYPE]: ABSORBANCE_READER_INITIAL_STATE, [MAGNETIC_BLOCK_TYPE]: MAGNETIC_BLOCK_INITIAL_STATE, } export const OT_2_TRASH_DEF_URI = 'opentrons/opentrons_1_trash_1100ml_fixed/1' export const FLEX_TRASH_DEF_URI = 'opentrons/opentrons_1_trash_3200ml_fixed/1' export const COLUMN_4_SLOTS = ['A4', 'B4', 'C4', 'D4'] +export const ZERO_OFFSET: AddressableOffsetVector = { x: 0, y: 0, z: 0 } diff --git a/step-generation/src/types.ts b/step-generation/src/types.ts index 881fda45e42..ae700c111a7 100644 --- a/step-generation/src/types.ts +++ b/step-generation/src/types.ts @@ -15,17 +15,15 @@ import type { PipetteMount as Mount, PipetteV2Specs, ShakeSpeedParams, + LabwareMovementStrategy, } from '@opentrons/shared-data' import type { AtomicProfileStep } from '@opentrons/shared-data/protocol/types/schemaV4' -import type { Command } from '@opentrons/shared-data/protocol/types/schemaV5Addendum' import type { TEMPERATURE_DEACTIVATED, TEMPERATURE_AT_TARGET, TEMPERATURE_APPROACHING_TARGET, } from './constants' -export type { Command } - // Copied from PD export type DeckSlot = string type THERMOCYCLER_STATE = 'thermocyclerState' @@ -327,7 +325,7 @@ export type MixArgs = CommonArgs & { export type PauseArgs = CommonArgs & { commandCreatorFnName: 'delay' message?: string - wait: number | true + seconds?: number pauseTemperature?: number | null meta: | { @@ -464,9 +462,9 @@ export type AbsorbanceReaderArgs = export interface MoveLabwareArgs extends CommonArgs { commandCreatorFnName: 'moveLabware' - labware: string - useGripper: boolean + labwareId: string newLocation: LabwareLocation + strategy: LabwareMovementStrategy } export interface CommentArgs extends CommonArgs { diff --git a/step-generation/src/utils/misc.ts b/step-generation/src/utils/misc.ts index e9170833ebf..2a8678ceab7 100644 --- a/step-generation/src/utils/misc.ts +++ b/step-generation/src/utils/misc.ts @@ -301,6 +301,7 @@ export const blowoutUtil = (args: { wellName: well, flowRate, wellLocation: { + origin: 'top', offset: { z: offsetFromTopMm, }, @@ -518,14 +519,19 @@ export const dispenseLocationHelper: CommandCreator ) { commands = [ curryCommandCreator(dispense, { - pipette: pipetteId, + pipetteId, volume, - labware: destinationId, - well, + labwareId: destinationId, + wellName: well, flowRate, - offsetFromBottomMm, - xOffset, - yOffset, + wellLocation: { + origin: 'bottom', + offset: { + z: offsetFromBottomMm, + x: xOffset, + y: yOffset, + }, + }, tipRack, nozzles, }), @@ -580,11 +586,13 @@ export const moveHelper: CommandCreator = ( if (trashOrLabware === 'labware' && well != null) { commands = [ curryCommandCreator(moveToWell, { - pipette: pipetteId, - labware: destinationId, - - well, - offset: { x: 0, y: 0, z: zOffset }, + pipetteId: pipetteId, + labwareId: destinationId, + wellName: well, + wellLocation: { + origin: 'bottom', + offset: { x: 0, y: 0, z: zOffset }, + }, }), ] } else if (trashOrLabware === 'wasteChute') { @@ -596,6 +604,7 @@ export const moveHelper: CommandCreator = ( addressableAreaName: getWasteChuteAddressableAreaNamePip( pipetteChannels ), + offset: { x: 0, y: 0, z: 0 }, }), ] } else { @@ -666,16 +675,21 @@ export const airGapHelper: CommandCreator = ( commands = [ curryCommandCreator(aspirate, { - pipette: pipetteId, + pipetteId: pipetteId, volume, - labware: dispenseAirGapLabware, - well: dispenseAirGapWell, + labwareId: dispenseAirGapLabware, + wellName: dispenseAirGapWell, flowRate, - offsetFromBottomMm, + wellLocation: { + origin: 'bottom', + offset: { + z: offsetFromBottomMm, + x: 0, + y: 0, + }, + }, isAirGap: true, tipRack, - xOffset: 0, - yOffset: 0, nozzles, }), ] @@ -683,17 +697,21 @@ export const airGapHelper: CommandCreator = ( } else { commands = [ curryCommandCreator(aspirate, { - pipette: pipetteId, + pipetteId: pipetteId, volume, - labware: destinationId, - well: destWell, + labwareId: destinationId, + wellName: destWell, flowRate, - offsetFromBottomMm, + wellLocation: { + origin: 'bottom', + offset: { + z: offsetFromBottomMm, + x: 0, + y: 0, + }, + }, isAirGap: true, tipRack, - // NOTE: airgap aspirates happen at default x/y offset - xOffset: 0, - yOffset: 0, nozzles, }), ] diff --git a/step-generation/src/utils/movableTrashCommandsUtil.ts b/step-generation/src/utils/movableTrashCommandsUtil.ts index 280eda3445b..157693f2bfa 100644 --- a/step-generation/src/utils/movableTrashCommandsUtil.ts +++ b/step-generation/src/utils/movableTrashCommandsUtil.ts @@ -11,6 +11,7 @@ import { moveToAddressableArea, moveToAddressableAreaForDropTip, } from '../commandCreators/atomic' +import { ZERO_OFFSET } from '../constants' import { curryCommandCreator } from './curryCommandCreator' import type { AddressableAreaName, CutoutId } from '@opentrons/shared-data' import type { @@ -46,6 +47,7 @@ export const movableTrashCommandsUtil = ( volume, flowRate, } = args + const offset = ZERO_OFFSET const trash = Object.values( invariantContext.additionalEquipmentEntities ).find(aE => aE.name === 'trashBin') @@ -89,6 +91,7 @@ export const movableTrashCommandsUtil = ( curryCommandCreator(moveToAddressableArea, { pipetteId, addressableAreaName, + offset, }), curryCommandCreator(aspirateInPlace, { pipetteId, @@ -123,6 +126,7 @@ export const movableTrashCommandsUtil = ( curryCommandCreator(moveToAddressableArea, { pipetteId, addressableAreaName, + offset, }), curryCommandCreator(dispenseInPlace, { pipetteId, @@ -140,6 +144,7 @@ export const movableTrashCommandsUtil = ( curryCommandCreator(moveToAddressableArea, { pipetteId, addressableAreaName, + offset, }), curryCommandCreator(blowOutInPlace, { pipetteId, @@ -154,6 +159,7 @@ export const movableTrashCommandsUtil = ( curryCommandCreator(moveToAddressableArea, { pipetteId, addressableAreaName, + offset, }), ] } diff --git a/step-generation/src/utils/safePipetteMovements.ts b/step-generation/src/utils/safePipetteMovements.ts index 3b306db3687..b8fc4a814dd 100644 --- a/step-generation/src/utils/safePipetteMovements.ts +++ b/step-generation/src/utils/safePipetteMovements.ts @@ -22,7 +22,7 @@ import type { const A12_column_front_left_bound = { x: -11.03, y: 2 } const A12_column_back_right_bound = { x: 526.77, y: 506.2 } -const PRIMARY_NOZZLE = 'A12' +export const PRIMARY_NOZZLE = 'A12' const NOZZLE_CONFIGURATION = 'COLUMN' const FLEX_TC_LID_COLLISION_ZONE = { back_left: { x: -43.25, y: 454.9, z: 211.91 }, @@ -44,7 +44,7 @@ interface SlotInfo { addressableArea: AddressableArea | null position: CoordinateTuple | null } -interface Point { +export interface Point { x: number y: number z?: number diff --git a/step-generation/src/utils/wasteChuteCommandsUtil.ts b/step-generation/src/utils/wasteChuteCommandsUtil.ts index 2ceeb2b19b5..788a4b5f34d 100644 --- a/step-generation/src/utils/wasteChuteCommandsUtil.ts +++ b/step-generation/src/utils/wasteChuteCommandsUtil.ts @@ -5,6 +5,7 @@ import { dropTipInPlace, moveToAddressableArea, } from '../commandCreators/atomic' +import { ZERO_OFFSET } from '../constants' import { curryCommandCreator } from './curryCommandCreator' import type { AddressableAreaName } from '@opentrons/shared-data' import type { RobotState, CurriedCommandCreator } from '../types' @@ -35,7 +36,7 @@ export const wasteChuteCommandsUtil = ( volume, flowRate, } = args - + const offset = ZERO_OFFSET let commands: CurriedCommandCreator[] = [] switch (type) { case 'dropTip': { @@ -45,6 +46,7 @@ export const wasteChuteCommandsUtil = ( curryCommandCreator(moveToAddressableArea, { pipetteId, addressableAreaName, + offset, }), curryCommandCreator(dropTipInPlace, { pipetteId, @@ -60,6 +62,7 @@ export const wasteChuteCommandsUtil = ( curryCommandCreator(moveToAddressableArea, { pipetteId, addressableAreaName, + offset, }), curryCommandCreator(dispenseInPlace, { pipetteId, @@ -77,6 +80,7 @@ export const wasteChuteCommandsUtil = ( curryCommandCreator(moveToAddressableArea, { pipetteId, addressableAreaName, + offset, }), curryCommandCreator(blowOutInPlace, { pipetteId, @@ -93,6 +97,7 @@ export const wasteChuteCommandsUtil = ( curryCommandCreator(moveToAddressableArea, { pipetteId, addressableAreaName, + offset, }), curryCommandCreator(aspirateInPlace, { pipetteId,