-
Notifications
You must be signed in to change notification settings - Fork 179
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(api): Add hardware_control submodule
The hardware_control submodule is the controller of the robot's hardware. Its API can move the robot at a level of abstraction that portrays the robot as a whole, not including the labware. In this PR, the module is a stub, and not used by default. Further PRs will introduce more functionality. Closes #2232
- Loading branch information
Showing
1 changed file
with
177 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,178 @@ | ||
""" hardware_control: the single controller for the OT2's hardware | ||
This module presents a medium level api for controlling the OT2. It allows | ||
callers to specify movements in deck-absolute coordinates and manage hardware | ||
actions like firmware updates or scanning for attached modules. It encapsulates | ||
deck calibration and jogging. It has no concept of the higher level commands | ||
such as liquid distribution or even arc movements; it simply allows direct | ||
control of the robot. | ||
""" | ||
hardware_control: The sole authority for controlling the hardware of an OT2. | ||
The hardware_control module presents a unified api for the lowest level of | ||
hardware command that takes into account the robot as a whole. For instance, | ||
it presents an API for moving a specific pipette mount (not a specific motor | ||
or axis) to a deck-absolute point (not a Smoothie-coordinate point). | ||
This module is not for use outside the opentrons api module. Higher-level | ||
functions are available elsewhere. | ||
""" | ||
|
||
import asyncio | ||
import logging | ||
|
||
mod_log = logging.getLogger(__name__) | ||
|
||
|
||
def _log_call(func): | ||
def _log_call_inner(*args, **kwargs): | ||
args[0]._log.debug(func.__name__) | ||
return func(*args, **kwargs) | ||
return _log_call_inner | ||
|
||
|
||
class API: | ||
""" This API is the primary interface to the hardware controller. | ||
Because the hardware manager controls access to the system's hardware | ||
as a whole, it is designed as a class of which only one should be | ||
instantiated at a time. This class's methods should be the only method | ||
of external access to the hardware. Each method may be minimal - it may | ||
only delegate the call to another submodule of the hardware manager - | ||
but its purpose is to be gathered here to provide a single interface. | ||
""" | ||
|
||
CLS_LOG = mod_log.getChild('API') | ||
|
||
def __init__(self, config=None, loop=None): | ||
""" Initialize an API instance. | ||
""" | ||
self._log = self.CLS_LOG.getChild(str(id(self))) | ||
if None is loop: | ||
self._loop = asyncio.get_event_loop() | ||
else: | ||
self._loop = loop | ||
|
||
# Query API | ||
@_log_call | ||
def get_connected_hardware(self): | ||
""" Get the cached hardware connected to the robot. | ||
""" | ||
pass | ||
|
||
# Incidentals (i.e. not motion) API | ||
@_log_call | ||
def turn_on_button_light(self): | ||
pass | ||
|
||
@_log_call | ||
def turn_off_button_light(self): | ||
pass | ||
|
||
@_log_call | ||
def turn_on_rail_lights(self): | ||
pass | ||
|
||
@_log_call | ||
def turn_off_rail_lights(self): | ||
pass | ||
|
||
@_log_call | ||
def identify(self, seconds): | ||
pass | ||
|
||
@_log_call | ||
def cache_instrument_models(self): | ||
pass | ||
|
||
@_log_call | ||
def update_smoothie_firmware(self, firmware_file): | ||
pass | ||
|
||
# Global actions API | ||
@_log_call | ||
def pause(self): | ||
pass | ||
|
||
@_log_call | ||
def resume(self): | ||
pass | ||
|
||
@_log_call | ||
def halt(self): | ||
pass | ||
|
||
# Gantry/frame (i.e. not pipette) action API | ||
@_log_call | ||
def home(self, *args, **kwargs): | ||
pass | ||
|
||
@_log_call | ||
def home_z(self): | ||
pass | ||
|
||
@_log_call | ||
def move_to(self, mount, position=None, position_rel=None): | ||
pass | ||
|
||
# Gantry/frame (i.e. not pipette) config API | ||
@_log_call | ||
def head_speed(self, combined_speed=None, | ||
x=None, y=None, z=None, a=None, b=None, c=None): | ||
pass | ||
|
||
# Pipette action API | ||
@_log_call | ||
def aspirate(self, mount, volume=None, rate=None): | ||
pass | ||
|
||
@_log_call | ||
def dispense(self, mount, volume=None, rate=None): | ||
pass | ||
|
||
@_log_call | ||
def blow_out(self, mount): | ||
pass | ||
|
||
@_log_call | ||
def air_gap(self, mount, volume=None): | ||
pass | ||
|
||
@_log_call | ||
def pick_up_tip(self, mount, tip_length): | ||
pass | ||
|
||
@_log_call | ||
def drop_tip(self, mount): | ||
pass | ||
|
||
# Pipette config api | ||
@_log_call | ||
def calibrate_plunger( | ||
self, mount, top=None, bottom=None, blow_out=None, drop_tip=None): | ||
pass | ||
|
||
@_log_call | ||
def set_flow_rate(self, mount, aspirate=None, dispense=None): | ||
pass | ||
|
||
@_log_call | ||
def set_pick_up_current(self, mount, amperes): | ||
pass | ||
|
||
# Modules api | ||
@_log_call | ||
def update_module_firmware(self, module, firmware_file): | ||
pass | ||
|
||
@_log_call | ||
def deactivate_module(self, module): | ||
pass | ||
|
||
@_log_call | ||
def get_module_status(self, module): | ||
pass | ||
|
||
@_log_call | ||
def tempdeck_set_temperature(self, temp_deck, celsius): | ||
pass | ||
|
||
@_log_call | ||
def magdeck_calibrate(self, mag_deck): | ||
pass | ||
|
||
@_log_call | ||
def magdeck_engage(self, mag_deck, **kwargs): | ||
pass |