From 90f5a755b1599b854a921153f85a5d54e86bccca Mon Sep 17 00:00:00 2001 From: Richard Bowman Date: Tue, 27 Apr 2021 10:55:51 +0100 Subject: [PATCH] Handle absolute moves correctly I've changed the default values in MoveStageAPI so that it correctly handles absolute moves with missing axes. I've also simplified it so it isn't using axes_to_array as that resulted in a confusing code path. --- .../api/v2/views/actions/stage.py | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/openflexure_microscope/api/v2/views/actions/stage.py b/openflexure_microscope/api/v2/views/actions/stage.py index a87e100c..d9231bf6 100644 --- a/openflexure_microscope/api/v2/views/actions/stage.py +++ b/openflexure_microscope/api/v2/views/actions/stage.py @@ -12,39 +12,39 @@ class MoveStageAPI(ActionView): "absolute": fields.Boolean( missing=False, example=False, description="Move to an absolute position" ), - "x": fields.Int(missing=0, example=100), - "y": fields.Int(missing=0, example=100), - "z": fields.Int(missing=0, example=20), + "x": fields.Int(missing=None, example=100), + "y": fields.Int(missing=None, example=100), + "z": fields.Int(missing=None, example=20), } def post(self, args): """ Move the microscope stage in x, y, z + + Any axes that are not specifed will not move. """ microscope = find_component("org.openflexure.microscope") - # Handle absolute positioning (calculate a relative move from current position and target) - if (args.get("absolute")) and (microscope.stage): # Only if stage exists - target_position: List[int] = axes_to_array(args, ["x", "y", "z"]) - logging.debug("TARGET: %s", (target_position)) - position: Tuple[int, int, int] = ( - target_position[i] - microscope.stage.position[i] for i in range(3) - ) - logging.debug("DELTA: %s", (position)) - - else: - # Get coordinates from payload - position = axes_to_array(args, ["x", "y", "z"], [0, 0, 0]) - - logging.debug(position) - - # Move if stage exists - if microscope.stage: - # Explicitally acquire lock with 1s timeout - with microscope.stage.lock(timeout=1): - microscope.stage.move_rel(position) - else: + if not microscope.stage: logging.warning("Unable to move. No stage found.") + return microscope.state["stage"]["position"] + + absolute_move = args.get("absolute") + move = [0, 0, 0] # Default to no motion + for i, axis in enumerate(["x", "y", "z"]): + if axis in args and args[axis] is not None: + if absolute_move: + # We emulate absolute moves by calculating a relative move that + # will take us to the right position. + move[i] = args[axis] - microscope.stage.position[i] + else: + move[i] = args[axis] + + logging.debug(f"Moving stage by {move}, request was {args}") + + # Explicitly acquire lock with 1s timeout + with microscope.stage.lock(timeout=1): + microscope.stage.move_rel(move) return microscope.state["stage"]["position"]