Commit ff534e6a authored by Joel Collins's avatar Joel Collins
Browse files

Initial support for SBv3 and MockStage

parent 068ce9e7
Loading
Loading
Loading
Loading
+8 −6
Original line number Diff line number Diff line
@@ -13,7 +13,8 @@ from openflexure_microscope.api.utilities import list_routes

from openflexure_microscope import Microscope
from openflexure_microscope.camera.pi import StreamingCamera
from openflexure_microscope.stage.openflexure import Stage
from openflexure_microscope.stage.sanga import SangaStage
from openflexure_microscope.stage.mock import MockStage

import atexit
import logging
@@ -71,11 +72,12 @@ def attach_microscope():
    
    logging.debug("Creating stage object...")
    try:
        api_stage = Stage("/dev/ttyUSB0")
    except SerialException as e:
        api_camera.close()
        raise e
    else:
        api_stage = SangaStage()
    except (SerialException, OSError) as e:
        logging.error(e)
        logging.warning("No valid stage hardware found. Falling back to mock stage!")
        api_stage = MockStage()
    finally:
        logging.debug("Attaching devices to microscope...")
        api_microscope.attach(
            api_camera,
+2 −2
Original line number Diff line number Diff line
from flask import jsonify
from flask import jsonify, escape
from werkzeug.exceptions import default_exceptions
from werkzeug.exceptions import HTTPException

@@ -21,7 +21,7 @@ class JSONExceptionHandler(object):

        response = {
            'status_code': status_code,
            'message': message
            'message': escape(message)
        }
        return jsonify(response), status_code

+7 −20
Original line number Diff line number Diff line
@@ -163,26 +163,10 @@ class Microscope(object):
            dict: Dictionary containing position data, and :py:attr:`openflexure_microscope.camera.base.BaseCamera.state`
        """
        state = {
            'camera': {},
            'stage': {},
            'plugin': {}
            'camera': self.camera.state,
            'stage': self.stage.state,
            'plugin': self.plugin.state
        }

        # Add stage position
        if self.stage:  # If stage exists, populate with real values
            position = self.stage.position
        else:  # Else, zero
            position = [0, 0, 0]

        state['stage']['position'] = {
            'x': position[0],
            'y': position[1],
            'z': position[2],
        }

        # Add camera state
        state['camera'] = self.camera.state

        return state

    def write_config(self, config: dict):
@@ -216,7 +200,10 @@ class Microscope(object):

        # If attached to a stage
        if self.stage:
            if hasattr(self.stage.backlash, 'tolist'):
                backlash = self.stage.backlash.tolist() 
            else:
                backlash = self.stage.backlash
        else:
            backlash = [0, 0, 0]

+6 −1
Original line number Diff line number Diff line
@@ -131,11 +131,16 @@ class PluginMount(object):
        self.plugins = []
        print("Creating plugin mount")

    @property
    def state(self):
        return [m[0] for m in self.members]

    @property
    def members(self):
        ignores = ['state', 'members', 'attach']
        plugin_array = []
        for obj_name in dir(self):
            if not obj_name == "plugins" and not obj_name[:2] == '__':
            if not obj_name in ignores and not obj_name[:2] == '__':
                obj = getattr(self, obj_name)
                if isinstance(obj, MicroscopePlugin):
                    plugin_members = [member for member in inspect.getmembers(obj) if not member[0][:2] == '__']
+58 −0
Original line number Diff line number Diff line
from abc import ABCMeta, abstractmethod
from openflexure_microscope.lock import StrictLock

class BaseStage(metaclass=ABCMeta):
    def __init__(self):
        self.lock = StrictLock(timeout=5)  #: :py:class:`openflexure_microscope.lock.StrictLock`: Strict lock controlling thread access to camera hardware

    @property
    @abstractmethod
    def state(self):
        """The general state dictionary of the board.
        Should at least contain 'position', and 'board' keys.
        Note: A None/Null value for 'board' will disable stage 
        movement in the OpenFlexure eV client software,
        """
        pass

    @property
    @abstractmethod
    def n_axes(self):
        """The number of axes this stage has."""
        pass

    @property
    @abstractmethod
    def position(self):
        """The current position, as a list"""
        pass

    @property
    @abstractmethod
    def backlash(self):
        """Get the distance used for backlash compensation."""
        pass

    @backlash.setter
    @abstractmethod
    def backlash(self):
        """Set the distance used for backlash compensation."""
        pass

    @abstractmethod
    def move_rel(self, displacement, backlash=True):
        """Make a relative move, optionally correcting for backlash.
        displacement: integer or array/list of 3 integers
        backlash: (default: True) whether to correct for backlash.
        """
        pass

    @abstractmethod
    def move_abs(self, final, **kwargs):
        """Make an absolute move to a position"""
        pass

    @abstractmethod
    def close(self):
        """Cleanly close communication with the stage"""
        pass
Loading