|
75 | 75 | CommandPreconditionViolated,
|
76 | 76 | CommandParameterLimitViolated,
|
77 | 77 | PipetteLiquidNotFoundError,
|
| 78 | + UnexpectedTipRemovalError, |
78 | 79 | )
|
79 | 80 | from opentrons_shared_data.gripper.gripper_definition import GripperModel
|
80 | 81 | from opentrons_shared_data.pipette.types import (
|
@@ -1788,6 +1789,106 @@ async def test_plunger_ready_to_aspirate_after_dispense(
|
1788 | 1789 | )
|
1789 | 1790 |
|
1790 | 1791 |
|
| 1792 | +@pytest.mark.parametrize("is_ready", [True, False]) |
| 1793 | +@pytest.mark.parametrize("tip_present", [True, False]) |
| 1794 | +async def test_aspirate_while_tracking( |
| 1795 | + ot3_hardware: ThreadManager[OT3API], |
| 1796 | + mock_move: AsyncMock, |
| 1797 | + is_ready: bool, |
| 1798 | + tip_present: bool, |
| 1799 | +) -> None: |
| 1800 | + mount = OT3Mount.LEFT |
| 1801 | + |
| 1802 | + instr_data = AttachedPipette( |
| 1803 | + config=load_pipette_data.load_definition( |
| 1804 | + PipetteModelType("p1000"), |
| 1805 | + PipetteChannelType(1), |
| 1806 | + PipetteVersionType(3, 4), |
| 1807 | + PipetteOEMType.OT, |
| 1808 | + ), |
| 1809 | + id="fakepip", |
| 1810 | + ) |
| 1811 | + await ot3_hardware.cache_pipette(OT3Mount.LEFT, instr_data, None) |
| 1812 | + pipette = ot3_hardware.hardware_pipettes[OT3Mount.LEFT.to_mount()] |
| 1813 | + assert pipette |
| 1814 | + |
| 1815 | + if tip_present: |
| 1816 | + ot3_hardware.add_tip(mount, 100) |
| 1817 | + if is_ready: |
| 1818 | + await ot3_hardware.prepare_for_aspirate(OT3Mount.LEFT) |
| 1819 | + |
| 1820 | + if not tip_present: |
| 1821 | + with pytest.raises(UnexpectedTipRemovalError): |
| 1822 | + await ot3_hardware.aspirate_while_tracking(mount, 8.0, 80.0) |
| 1823 | + elif not is_ready: |
| 1824 | + with pytest.raises(RuntimeError): |
| 1825 | + await ot3_hardware.aspirate_while_tracking(mount, 8.0, 80.0) |
| 1826 | + else: |
| 1827 | + await ot3_hardware.aspirate_while_tracking(mount, 8.0, 80.0) |
| 1828 | + # make sure the move planning math stays the same |
| 1829 | + expected_target_pos = { |
| 1830 | + Axis.X: 477.2, |
| 1831 | + Axis.Y: 493.8, |
| 1832 | + Axis.Z_L: 261.475, |
| 1833 | + Axis.P_L: 65.983786, |
| 1834 | + } |
| 1835 | + expected_speed = 46.504982 |
| 1836 | + called_target_pos = mock_move.call_args_list[-1][0][0] |
| 1837 | + called_speed = mock_move.call_args_list[-1][1]["speed"] |
| 1838 | + assert expected_target_pos == called_target_pos |
| 1839 | + assert expected_speed == called_speed |
| 1840 | + |
| 1841 | + |
| 1842 | +@pytest.mark.parametrize("tip_present", [True, False]) |
| 1843 | +@pytest.mark.parametrize("is_ready", [True, False]) |
| 1844 | +async def test_dispense_while_tracking( |
| 1845 | + ot3_hardware: ThreadManager[OT3API], |
| 1846 | + mock_move: AsyncMock, |
| 1847 | + tip_present: bool, |
| 1848 | + is_ready: bool, |
| 1849 | +) -> None: |
| 1850 | + mount = OT3Mount.LEFT |
| 1851 | + |
| 1852 | + instr_data = AttachedPipette( |
| 1853 | + config=load_pipette_data.load_definition( |
| 1854 | + PipetteModelType("p1000"), |
| 1855 | + PipetteChannelType(1), |
| 1856 | + PipetteVersionType(3, 4), |
| 1857 | + PipetteOEMType.OT, |
| 1858 | + ), |
| 1859 | + id="fakepip", |
| 1860 | + ) |
| 1861 | + await ot3_hardware.cache_pipette(OT3Mount.LEFT, instr_data, None) |
| 1862 | + pipette = ot3_hardware.hardware_pipettes[OT3Mount.LEFT.to_mount()] |
| 1863 | + assert pipette |
| 1864 | + |
| 1865 | + if tip_present: |
| 1866 | + ot3_hardware.add_tip(mount, 100) |
| 1867 | + if is_ready: |
| 1868 | + pipette.set_current_volume(80.0) |
| 1869 | + |
| 1870 | + if not tip_present: |
| 1871 | + with pytest.raises(UnexpectedTipRemovalError): |
| 1872 | + await ot3_hardware.dispense_while_tracking(mount, 8.0, 80.0, push_out=None) |
| 1873 | + else: |
| 1874 | + await ot3_hardware.dispense_while_tracking(mount, 8.0, 80.0, push_out=None) |
| 1875 | + if is_ready: |
| 1876 | + # make sure the move planning math stays the same |
| 1877 | + expected_target_pos = { |
| 1878 | + Axis.X: 477.2, |
| 1879 | + Axis.Y: 493.8, |
| 1880 | + Axis.Z_L: 261.475, |
| 1881 | + Axis.P_L: 72.75754527162978, |
| 1882 | + } |
| 1883 | + expected_speed = 46.504982 |
| 1884 | + called_target_pos = mock_move.call_args_list[-1][0][0] |
| 1885 | + called_speed = mock_move.call_args_list[-1][1]["speed"] |
| 1886 | + assert expected_target_pos == called_target_pos |
| 1887 | + assert expected_speed == called_speed |
| 1888 | + else: |
| 1889 | + assert len(mock_move.call_args_list) == 0 |
| 1890 | + |
| 1891 | + |
1791 | 1892 | async def test_move_to_plunger_bottom(
|
1792 | 1893 | ot3_hardware: ThreadManager[OT3API],
|
1793 | 1894 | mock_move: AsyncMock,
|
|
0 commit comments