def move(self, position): """Move to the requested position. If the motor is already moving, then update the target position. Return an object that may be used to check whether the move is complete (see move_status). """ id = self._last_move_id if self.program_running(): self._interrupt_move() self.mcm.set_global('gp0', position) start = ptime.time() else: self.mcm.set_global('gp0', position) self.mcm.start_program() start = ptime.time() self._target_position = position id += 1 self._last_move_id = id self._move_status[id] = {'start': start, 'status': 'moving', 'target': position} return id
def run(self): lastUpdate = ptime.time() while True: with self.lock: if self._quit: break target = self.target speed = self.speed velocity = self.velocity currentMove = self.currentMove pos = self.pos now = ptime.time() dt = now - lastUpdate lastUpdate = now if target is not None: dif = target - pos dist = np.linalg.norm(dif) stepDist = speed * dt if stepDist >= dist: self._setPosition(target) self.currentMove._finished = True self.stop() else: unit = dif / dist step = unit * stepDist self._setPosition(pos + step) elif self.velocity is not None and not np.all(velocity == 0): self._setPosition(pos + velocity * dt) time.sleep(self.interval)
def measureSpeedTable(dev, drive, dist=3e-3): """Measure table of speeds supported by the stage. Warning: this function moves the stage to (0, 0, 0); do not run this function unless you know it is safe for your setup! """ from acq4.pyqtgraph import ptime v = [] for i in range(16): pos = (dist, 0, 0) dev.moveTo(drive, [0,0,0], 'fast') start = ptime.time() dev.moveTo(drive, pos, i, timeout=100) stop = ptime.time() dt = stop - start v.append(dist / dt) print('%d: %0.4g, # %0.2g m / %0.2g s' % (i, v[-1], dist, dt)) dist *= 1.1 return v
def percentDone(self): """Return an estimate of the percent of move completed based on the device's speed table. """ if self.isDone(): return 100 dt = ptime.time() - self._getStatus()[0] if self._expectedDuration == 0: return 99 return max(min(100 * dt / self._expectedDuration, 99), 0)
def run(self): minInterval = 100e-3 interval = minInterval while True: try: with self.lock: if self.stopped: break maxInterval = self.interval moveRequest = self.moveRequest self.moveRequest = None if moveRequest is None: # just check for position update if self.dev._checkPositionChange() is not False: interval = minInterval else: interval = min(maxInterval, interval * 2) else: # move the drive mid, drive, pos, speed = moveRequest try: with self.dev.dev.lock: # record the move starting time only after locking the device start = ptime.time() with self.lock: self._moveStatus[mid] = (start, False) pos = self.dev.dev.moveTo(drive, pos, speed) self.dev._checkPositionChange(drive, pos) except Exception as err: debug.printExc('Move error:') try: if hasattr(err, 'lastPosition'): self.dev._checkPositionChange( drive, err.lastPosition) finally: with self.lock: self._moveStatus[mid] = (start, err) else: with self.lock: self._moveStatus[mid] = (start, True) time.sleep(interval) except: debug.printExc('Error in MPC200 monitor thread:') time.sleep(maxInterval)
def sleep(self, until): # Wait until some event occurs # check for pause / stop while waiting while True: with self.lock: if self._stop: raise Exception("stopped") paused = self._paused frame = self._frame if paused: wait = 0.1 else: if until == 'frame': if frame is not None: return wait = 0.1 else: now = ptime.time() wait = until - now if wait <= 0: return time.sleep(min(0.1, wait))
def start(self): self._quit = False self.lastUpdate = ptime.time() Thread.start(self)