Skip to content

Commit

Permalink
[fix] simulated stage could take very long doing an absolute move to 0
Browse files Browse the repository at this point in the history
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
  • Loading branch information
pieleric committed Jan 9, 2025
1 parent 380da13 commit 1f9ebdc
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
12 changes: 8 additions & 4 deletions src/odemis/driver/simulated.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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()

Expand Down
18 changes: 18 additions & 0 deletions src/odemis/driver/test/simulated_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {}
Expand Down

0 comments on commit 1f9ebdc

Please sign in to comment.