From 1f9ebdc6b63b7f5461123e484eb129c4f6deed08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Piel?= Date: Thu, 9 Jan 2025 17:11:55 +0100 Subject: [PATCH] [fix] simulated stage could take very long doing an absolute move to 0 When asking a moveAbs() to position 0, which is usually the center of the axis, the code would detect it's not a float, and concider it as a "arbitrary move". If the speed was set to something "reasonable" like 1 mm/s, that would cause a 100 s move. => detect it's a arbitrary move by the presence of .choices --- src/odemis/driver/simulated.py | 12 ++++++++---- src/odemis/driver/test/simulated_test.py | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/odemis/driver/simulated.py b/src/odemis/driver/simulated.py index 1a18099c2c..b6f17f3039 100644 --- a/src/odemis/driver/simulated.py +++ b/src/odemis/driver/simulated.py @@ -382,8 +382,8 @@ def _doMoveRel(self, shift): (axis, self._position[axis] + change, rng)) self._position[axis] += change - logging.info("moving axis %s to %f", axis, self._position[axis]) maxtime = max(maxtime, abs(change) / self.speed.value[axis] + 0.001) + logging.info("moving axis %s to %f", axis, self._position[axis]) logging.debug("Sleeping %g s", maxtime) time.sleep(maxtime) @@ -392,14 +392,18 @@ def _doMoveRel(self, shift): def _doMoveAbs(self, pos): maxtime = 0 for axis, new_pos in pos.items(): - if isinstance(new_pos, float): + if hasattr(self.axes[axis], "choices"): + # It's not a linear axis => just make it last an arbitrary time, corresponding to moving by 1m. + # Default speed is 1 m/s, so 1s. + maxtime = max(maxtime, 1 / self.speed.value[axis]) + else: # linear axis change = self._position[axis] - new_pos maxtime = max(maxtime, abs(change) / self.speed.value[axis]) - else: # for axes which are not of type float - maxtime = max(maxtime, 1 / self.speed.value[axis]) + self._position[axis] = new_pos logging.info("moving axis %s to %s", axis, self._position[axis]) + logging.debug("Sleeping %g s", maxtime) time.sleep(maxtime) self._updatePosition() diff --git a/src/odemis/driver/test/simulated_test.py b/src/odemis/driver/test/simulated_test.py index c304cf2254..3dab21bb23 100644 --- a/src/odemis/driver/test/simulated_test.py +++ b/src/odemis/driver/test/simulated_test.py @@ -105,6 +105,24 @@ def test_moveAbs(self): f.result() # wait testing.assert_pos_almost_equal(move, self.dev.position.value, atol=1e-7) + # Move to 0 (int), which used to cause a bug in the speed computation + speed = {} + for axis in self.dev.axes: + rng = self.dev.axes[axis].range + move[axis] = rng[0] + print(rng) + speed[axis] = (rng[1] - rng[0]) / 1 # 1 s to go to whole range + self.dev.moveAbsSync(move) + logging.info("Updating speed to %s", speed) + self.dev.speed.value = speed + + # Should take ~1s (used to take 5s) + move = {a: 0 for a in self.dev.axes} + t_start = time.time() + self.dev.moveAbsSync(move) + t_end = time.time() + self.assertLess(t_end - t_start, 2) + def test_moveRel(self): prev_pos = self.dev.position.value move = {}