Fix jog queue blocking waiting to put new commands.
This commit is contained in:
parent
f1d974c922
commit
728880e49d
2 changed files with 36 additions and 2 deletions
|
|
@ -70,6 +70,25 @@ class JogStopCommand(JogCommand):
|
|||
"""A command to stop a jog move."""
|
||||
|
||||
|
||||
class JogQueue(queue.Queue[JogCommand]):
|
||||
"""A class queue for JogCommands. This always returns the most recent command."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Set up a queue with a max size of 1."""
|
||||
super().__init__(maxsize=1)
|
||||
|
||||
def put(
|
||||
self, item: JogCommand, block: bool = False, timeout: Optional[float] = None
|
||||
) -> None:
|
||||
"""Put the next command into the queue, bumping anything already there."""
|
||||
try:
|
||||
# First remove existing item if present
|
||||
self.get_nowait()
|
||||
except queue.Empty:
|
||||
pass
|
||||
super().put(item, block=block, timeout=timeout)
|
||||
|
||||
|
||||
class BaseStage(lt.Thing):
|
||||
"""A base stage class for OpenFlexure translation stages.
|
||||
|
||||
|
|
@ -97,7 +116,7 @@ class BaseStage(lt.Thing):
|
|||
super().__init__(thing_server_interface)
|
||||
self._hardware_lock = threading.RLock()
|
||||
self._jog_lock = threading.Lock()
|
||||
self._jog_queue: queue.Queue[JogCommand] = queue.Queue[JogCommand](maxsize=1)
|
||||
self._jog_queue = JogQueue()
|
||||
self._jog_thread: Optional[threading.Thread] = None
|
||||
self._hardware_position = dict.fromkeys(self._axis_names, 0)
|
||||
|
||||
|
|
@ -310,7 +329,7 @@ class BaseStage(lt.Thing):
|
|||
# Check the background thread is running, and restart it if not.
|
||||
if self._jog_thread is None or not self._jog_thread.is_alive():
|
||||
self.logger.info("Starting background thread for jog commands")
|
||||
self._jog_queue = queue.Queue[JogCommand](maxsize=1)
|
||||
self._jog_queue = JogQueue()
|
||||
self._jog_thread = threading.Thread(
|
||||
target=self._jog_loop, args=(command,)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ from labthings_fastapi.testing import create_thing_without_server
|
|||
from openflexure_microscope_server.things.camera.simulation import SimulatedCamera
|
||||
from openflexure_microscope_server.things.stage import (
|
||||
BaseStage,
|
||||
JogMoveCommand,
|
||||
RedefinedBaseMovementError,
|
||||
)
|
||||
from openflexure_microscope_server.things.stage.dummy import DummyStage
|
||||
|
|
@ -300,3 +301,17 @@ def test_thing_description_equivalence(dummy_stage, mocker):
|
|||
|
||||
assert sanga_actions == dummy_actions == base_actions
|
||||
assert sanga_properties == dummy_properties == base_properties
|
||||
|
||||
|
||||
def test_get_jog_from_queue_most_recent(dummy_stage):
|
||||
"""Test that the jog queue gives the most recent Jog Command."""
|
||||
# Try to stack 4 moves in the queue, only 1 should be queued.
|
||||
for i in range(4):
|
||||
dummy_stage._jog_queue.put(JogMoveCommand([i, i, i]))
|
||||
|
||||
command = dummy_stage._get_from_jog_queue(0.001)
|
||||
assert isinstance(command, JogMoveCommand)
|
||||
# Should be the last one queued
|
||||
assert command.displacement == [3, 3, 3]
|
||||
# Nothing else is queued
|
||||
assert dummy_stage._get_from_jog_queue(0.001) is None
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue