Skip to content

Commit

Permalink
feat(api): decrease plunger acceleration and add drop tip speed to co…
Browse files Browse the repository at this point in the history
…nfig (#2904)

- decrease plunger acceleration to reduce strain on internal seal
- add drop tip speed to pipette configs and respect it during drop tip
  • Loading branch information
andySigler authored and sfoster1 committed Jan 23, 2019
1 parent bc3c3ac commit dc64b0d
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 6 deletions.
2 changes: 2 additions & 0 deletions api/src/opentrons/config/pipette_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
'model_offset',
'plunger_current',
'drop_tip_current',
'drop_tip_speed',
'min_volume',
'max_volume',
'ul_per_mm',
Expand Down Expand Up @@ -99,6 +100,7 @@ def load(pipette_model: str) -> pipette_config:
model_offset=cfg.get('modelOffset'),
plunger_current=cfg.get('plungerCurrent'),
drop_tip_current=cfg.get('dropTipCurrent'),
drop_tip_speed=cfg.get('dropTipSpeed'),
min_volume=cfg.get('minVolume'),
max_volume=cfg.get('maxVolume'),
ul_per_mm=cfg.get('ulPerMm'),
Expand Down
17 changes: 16 additions & 1 deletion api/src/opentrons/config/robot_configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,22 @@
[0.00, 0.00, 1.00, 0.00],
[0.00, 0.00, 0.00, 1.00]]

DEFAULT_ACCELERATION = 'M204 S10000 X3000 Y2000 Z1500 A1500 B2000 C2000'
X_ACCELERATION = 3000
Y_ACCELERATION = 2000
Z_ACCELERATION = 1500
A_ACCELERATION = 1500
B_ACCELERATION = 200
C_ACCELERATION = 200

DEFAULT_ACCELERATION = {
'X': X_ACCELERATION,
'Y': Y_ACCELERATION,
'Z': Z_ACCELERATION,
'A': A_ACCELERATION,
'B': B_ACCELERATION,
'C': C_ACCELERATION
}

DEFAULT_STEPS_PER_MM = 'M92 X80.00 Y80.00 Z400 A400 B768 C768'
# This probe height is ~73 from deck to the top surface of the switch body
# per CAD; 74.3mm is the nominal for engagement from the switch drawing.
Expand Down
32 changes: 30 additions & 2 deletions api/src/opentrons/drivers/smoothie_drivers/driver_3_0.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@
'SET_MAX_SPEED': 'M203.1',
'SET_CURRENT': 'M907',
'DISENGAGE_MOTOR': 'M18',
'HOMING_STATUS': 'G28.6'}
'HOMING_STATUS': 'G28.6',
'ACCELERATION': 'M204 S10000'}

# Number of digits after the decimal point for coordinates being sent
# to Smoothie
Expand Down Expand Up @@ -301,6 +302,9 @@ def __init__(self, config):
self._combined_speed = float(DEFAULT_AXES_SPEED)
self._saved_axes_speed = float(self._combined_speed)

self._acceleration = config.acceleration.copy()
self._saved_acceleration = config.acceleration.copy()

# position after homing
self._homed_position = HOMED_POSITION.copy()
self.homed_flags = {}
Expand Down Expand Up @@ -599,6 +603,30 @@ def push_axis_max_speed(self):
def pop_axis_max_speed(self):
self.set_axis_max_speed(self._saved_max_speed_settings)

def set_acceleration(self, settings):
'''
Sets the acceleration (mm/sec^2) that a given axis will move
settings
Dict with axes as valies (e.g.: 'X', 'Y', 'Z', 'A', 'B', or 'C')
and floating point number for mm-per-second-squared (mm/sec^2)
'''
self._acceleration.update(settings)
values = ['{}{}'.format(axis.upper(), value)
for axis, value in sorted(settings.items())]
command = '{} {}'.format(
GCODES['ACCELERATION'],
' '.join(values)
)
log.debug("set_acceleration: {}".format(command))
self._send_command(command)

def push_acceleration(self):
self._saved_acceleration = self._acceleration.copy()

def pop_acceleration(self):
self.set_acceleration(self._saved_acceleration)

def set_active_current(self, settings):
'''
Sets the amperage of each motor for when it is activated by driver.
Expand Down Expand Up @@ -956,13 +984,13 @@ def _setup(self):
# use gpio to reset into a known state
self._smoothie_reset()
self._reset_from_error()
self._send_command(self._config.acceleration)
self._send_command(self._config.steps_per_mm)
self._send_command(GCODES['ABSOLUTE_COORDS'])
self._save_current(self.current, axes_active=False)
self.update_position(default=self.homed_position)
self.pop_axis_max_speed()
self.pop_speed()
self.pop_acceleration()

def _read_from_pipette(self, gcode, mount) -> Optional[str]:
'''
Expand Down
3 changes: 2 additions & 1 deletion api/src/opentrons/hardware_control/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,8 @@ async def drop_tip(self, mount, home_after=True):
await self._move_plunger(mount, bottom)
self._backend.set_active_current(plunger_ax,
instr.config.drop_tip_current)
await self._move_plunger(mount, droptip)
await self._move_plunger(
mount, droptip, speed=instr.config.drop_tip_speed)
await self._shake_off_tips(mount)
instr.set_current_volume(0)
instr.remove_tip()
Expand Down
1 change: 1 addition & 0 deletions api/src/opentrons/legacy_api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ def _create_pipette_from_config(
max_volume=config.max_volume,
plunger_current=config.plunger_current,
drop_tip_current=config.drop_tip_current,
drop_tip_speed=config.drop_tip_speed,
plunger_positions=config.plunger_positions.copy(),
ul_per_mm=config.ul_per_mm,
pick_up_current=config.pick_up_current,
Expand Down
8 changes: 6 additions & 2 deletions api/src/opentrons/legacy_api/instruments/pipette.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
}

DROP_TIP_RELEASE_DISTANCE = 20
DEFAULT_DROP_TIP_SPEED = 5

DEFAULT_ASPIRATE_SPEED = 5
DEFAULT_DISPENSE_SPEED = 10
Expand Down Expand Up @@ -122,6 +123,7 @@ def __init__(
dispense_flow_rate=None,
plunger_current=0.5,
drop_tip_current=0.5,
drop_tip_speed=DEFAULT_DROP_TIP_SPEED,
plunger_positions=PLUNGER_POSITIONS,
pick_up_current=DEFAULT_PLUNGE_CURRENT,
pick_up_distance=DEFAULT_TIP_PRESS_MM,
Expand Down Expand Up @@ -197,13 +199,12 @@ def __init__(
self._pick_up_distance = pick_up_distance
self._pick_up_current = pick_up_current

# TODO (andy) these values maybe should persist between sessions,
# by saving within `robot_config`
self._plunger_current = plunger_current
self._drop_tip_current = drop_tip_current

self.speeds = {}
self.set_speed(aspirate=aspirate_speed, dispense=dispense_speed)
self._drop_tip_speed = drop_tip_speed

self.set_flow_rate(
aspirate=aspirate_flow_rate, dispense=dispense_flow_rate)
Expand Down Expand Up @@ -1046,10 +1047,13 @@ def _drop_tip(location, instrument=self):
x=pos_bottom
)
self.instrument_actuator.set_active_current(self._drop_tip_current)
self.instrument_actuator.push_speed()
self.instrument_actuator.set_speed(self._drop_tip_speed)
self.robot.poses = self.instrument_actuator.move(
self.robot.poses,
x=pos_drop_tip
)
self.instrument_actuator.pop_speed()
self._shake_off_tips(location)
if home_after:
self._home_after_drop_tip()
Expand Down
12 changes: 12 additions & 0 deletions api/src/opentrons/legacy_api/robot/mover.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ def push_active_current(self):
def pop_active_current(self):
self._driver.pop_active_current()

def set_acceleration(self, acceleration):
self._driver.set_acceleration({
axis.upper(): acceleration
for axis in self._axis_mapping.values()
})

def push_acceleration(self):
self._driver.push_acceleration()

def pop_acceleration(self):
self._driver.pop_acceleration()

def probe(self, pose_tree, axis, movement):
assert axis in self._axis_mapping, "mapping is not set for " + axis

Expand Down
39 changes: 39 additions & 0 deletions api/tests/opentrons/drivers/test_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,45 @@ def _parse_position_response(arg):
fuzzy_assert(result=command_log, expected=expected)


def test_set_acceleration(smoothie, monkeypatch):
from opentrons.drivers import serial_communication
from opentrons.drivers.smoothie_drivers import driver_3_0
command_log = []
smoothie._setup()
smoothie.home()
smoothie.simulating = False

def write_with_log(command, ack, connection, timeout):
command_log.append(command.strip())
return driver_3_0.SMOOTHIE_ACK

def _parse_position_response(arg):
return smoothie.position

monkeypatch.setattr(serial_communication, 'write_and_return',
write_with_log)
monkeypatch.setattr(
driver_3_0, '_parse_position_response', _parse_position_response)

smoothie.set_acceleration(
{'X': 1, 'Y': 2, 'Z': 3, 'A': 4, 'B': 5, 'C': 6})
smoothie.push_acceleration()
smoothie.pop_acceleration()
smoothie.set_acceleration(
{'X': 10, 'Y': 20, 'Z': 30, 'A': 40, 'B': 50, 'C': 60})
smoothie.pop_acceleration()

expected = [
['M204 S10000 A4 B5 C6 X1 Y2 Z3 M400'],
['M204 S10000 A4 B5 C6 X1 Y2 Z3 M400'],
['M204 S10000 A40 B50 C60 X10 Y20 Z30 M400'],
['M204 S10000 A4 B5 C6 X1 Y2 Z3 M400']
]
# from pprint import pprint
# pprint(command_log)
fuzzy_assert(result=command_log, expected=expected)


def test_active_dwelling_current_push_pop(smoothie):
assert smoothie._active_current_settings != \
smoothie._dwelling_current_settings
Expand Down
Loading

0 comments on commit dc64b0d

Please sign in to comment.