Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API work to enable calibration experience #352

Merged
merged 8 commits into from
Sep 28, 2017
45 changes: 35 additions & 10 deletions api/opentrons/commands/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,16 @@ def home(axis):
)


def aspirate(volume, location, rate):
def aspirate(volume, location, rate, self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rename this self parameter to instrument (as it is used everywhere)? Also, does it make more sense to have instrument be the first parameter?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^Agreed, using self outside of the context of a class is confusing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Talked to @mcous IRL. The signature is this because of the decorator. Possibly we could have implemented actual commands as functions with 'instrument' as an argument, but since they are not, and since the decorator is magic we'll keep magic inside of it and map 'self' to instrument. That will change command builder's signature from 'self' to 'instrument'.

instrument = self
location = drop_coodrinates(location)
text = 'Aspirating {volume} uL from {location} at {rate} speed'.format(
volume=volume, location=location, rate=rate
)
return make_command(
name=types.ASPIRATE,
payload={
'instrument': instrument,
'volume': volume,
'location': location,
'rate': rate,
Expand All @@ -41,7 +43,8 @@ def aspirate(volume, location, rate):
)


def dispense(volume, location, rate):
def dispense(volume, location, rate, self):
instrument = self
location = drop_coodrinates(location)
text = 'Dispensing {volume} uL into {location}'.format(
volume=volume, location=location, rate=rate
Expand All @@ -50,6 +53,7 @@ def dispense(volume, location, rate):
return make_command(
name=types.DISPENSE,
payload={
'instrument': instrument,
'volume': volume,
'location': location,
'rate': rate,
Expand All @@ -58,7 +62,8 @@ def dispense(volume, location, rate):
)


def consolidate(volume, source, dest):
def consolidate(volume, source, dest, self):
instrument = self
text = 'Consolidating {volume} from {source} to {dest}'.format(
volume=volume,
source=source,
Expand All @@ -67,6 +72,8 @@ def consolidate(volume, source, dest):
return make_command(
name=types.CONSOLIDATE,
payload={
'instrument': instrument,
'locations': [source, dest],
'volume': volume,
'source': source,
'dest': dest,
Expand All @@ -75,7 +82,8 @@ def consolidate(volume, source, dest):
)


def distribute(volume, source, dest):
def distribute(volume, source, dest, self):
instrument = self
text = 'Distributing {volume} from {source} to {dest}'.format(
volume=volume,
source=source,
Expand All @@ -84,6 +92,8 @@ def distribute(volume, source, dest):
return make_command(
name=types.DISTRIBUTE,
payload={
'instrument': instrument,
'locations': [source, dest],
'volume': volume,
'source': source,
'dest': dest,
Expand All @@ -92,7 +102,8 @@ def distribute(volume, source, dest):
)


def transfer(volume, source, dest):
def transfer(volume, source, dest, self):
instrument = self
text = 'Transferring {volume} from {source} to {dest}'.format(
volume=volume,
source=source,
Expand All @@ -101,6 +112,8 @@ def transfer(volume, source, dest):
return make_command(
name=types.TRANSFER,
payload={
'instrument': instrument,
'locations': [source, dest],
'volume': volume,
'source': source,
'dest': dest,
Expand All @@ -119,21 +132,25 @@ def comment(msg):
)


def mix(repetitions, volume):
def mix(repetitions, volume, location, self):
instrument = self
text = 'Mixing {repetitions} times with a volume of {volume}ul'.format(
repetitions=repetitions, volume=volume
)
return make_command(
name=types.MIX,
payload={
'instrument': instrument,
'location': location,
'volume': volume,
'repetitions': repetitions,
'text': text
}
)


def blow_out(location):
def blow_out(location, self):
instrument = self
location = drop_coodrinates(location)
text = 'Blowing out'

Expand All @@ -143,17 +160,20 @@ def blow_out(location):
return make_command(
name=types.BLOW_OUT,
payload={
'instrument': instrument,
'location': location,
'text': text
}
)


def touch_tip():
def touch_tip(self):
instrument = self
text = 'Touching tip'
return make_command(
name=types.TOUCH_TIP,
payload={
'instrument': instrument,
'text': text
}
)
Expand All @@ -179,23 +199,28 @@ def return_tip():
)


def pick_up_tip(location):
def pick_up_tip(location, self):
instrument = self
location = drop_coodrinates(location)
text = 'Picking up tip {location}'.format(location=location)
return make_command(
name=types.PICK_UP_TIP,
payload={
'instrument': instrument,
'location': location,
'text': text
}
)


def drop_tip(location):
def drop_tip(location, self):
instrument = self
location = drop_coodrinates(location)
text = 'Dropping tip {location}'.format(location=location)
return make_command(
name=types.DROP_TIP,
payload={
'instrument': instrument,
'location': location,
'text': text
}
Expand Down
6 changes: 4 additions & 2 deletions api/opentrons/containers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
Container,
Well,
WellSeries,
unpack_location
unpack_location,
get_container
)
from opentrons.containers.calibrator import apply_calibration
from opentrons.util import environment
Expand All @@ -21,7 +22,8 @@
Well,
WellSeries,
unpack_location,
apply_calibration]
apply_calibration,
get_container]


def load(robot, container_name, slot, label=None, share=False):
Expand Down
8 changes: 8 additions & 0 deletions api/opentrons/containers/placeable.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ def unpack_location(location):
return (placeable, Vector(coordinates))


def get_container(location):
obj, _ = unpack_location(location)
if isinstance(obj, Container):
return obj
if isinstance(obj.parent, Container):
return obj.parent


def humanize_location(location):
well, _ = unpack_location(location)
return repr(well)
Expand Down
4 changes: 2 additions & 2 deletions api/opentrons/instruments/pipette.py
Original file line number Diff line number Diff line change
Expand Up @@ -748,7 +748,7 @@ def pick_up_tip(self, location=None, presses=3):
presses = (1 if not helpers.is_number(presses) else presses)

@commands.publish.both(command=commands.pick_up_tip)
def _pick_up_tip(location):
def _pick_up_tip(location, self=self):
self.motor.move(self._get_plunger_position('bottom'))
self.current_volume = 0

Expand Down Expand Up @@ -813,7 +813,7 @@ def drop_tip(self, location=None, home_after=True):
location = location.bottom(self._drop_tip_offset)

@commands.publish.both(command=commands.drop_tip)
def _drop_tip(location):
def _drop_tip(location, self=self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this not match the signature for _pick_up_tip above?

@commands.publish.both(command=commands.pick_up_tip)
def _pick_up_tip(location, instrument=self):

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

if location:
self.move_to(location, strategy='arc')

Expand Down
5 changes: 3 additions & 2 deletions api/opentrons/server/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
import sys
import logging
from opentrons.server.rpc import Server
from opentrons.session import SessionManager
from opentrons.session import Shell
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't love the name Shell... maybe MainRouter?

Also, re: outgrowing the scope of Session, I like the opentrons.api proposal the most. Alternatively, opentrons.app-api

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make it 'opentrons.api'

from logging.config import dictConfig


log = logging.getLogger(__name__)


Expand Down Expand Up @@ -77,7 +78,7 @@ def log_init():
# TODO(artyom, 20170828): consider moving class name definition into
# command line arguments, so one could us as a shell starting various
# RPC servers with different root objects from a command line
server = Server(SessionManager())
server = Server(Shell())
print(
'Started Opentrons API Server listening at ws://{host}:{port}/'
.format(host=host, port=port))
Expand Down
6 changes: 5 additions & 1 deletion api/opentrons/session/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from .session import Session, SessionManager
from .shell import Shell
from .calibration import CalibrationManager

__all__ = [
Session,
SessionManager
SessionManager,
Shell,
CalibrationManager
]
25 changes: 25 additions & 0 deletions api/opentrons/session/calibration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
PIPETTE_CHANGE_POSITION = (50, 50, 50)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this for?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will clean up.



class CalibrationManager:
def __init__(self, robot, loop=None):
self._loop = loop
self._robot = robot

def tip_probe(self, instrument):
raise NotImplemented()

def move_to_front(self, instrument):
# instrument.move_to(PIPETTE_CHANGE_POSITION)
raise NotImplemented()

def move_to(self, instrument, obj):
# instrument.move_to(obj[0])
raise NotImplemented()

def jog(self, instrument, coordinates):
# instrument.jog(coordinates)
raise NotImplemented()

def update_container_offset(self):
raise NotImplemented()
Loading