diff --git a/secop_psi/attocube.py b/secop_psi/attocube.py index ee6a9a5..d85d8c4 100644 --- a/secop_psi/attocube.py +++ b/secop_psi/attocube.py @@ -19,7 +19,7 @@ import sys import time -from secop.core import Drivable, Parameter, Command, Property, ERROR, BUSY, IDLE, Done, nopoll +from secop.core import Drivable, Parameter, Command, Property, ERROR, WARN, BUSY, IDLE, Done, nopoll from secop.features import HasTargetLimits, HasSimpleOffset from secop.datatypes import IntRange, FloatRange, StringType, BoolType from secop.errors import ConfigError, BadValueError @@ -61,7 +61,7 @@ class FreezeStatus: self.status = code, text -class Axis(HasTargetLimits, HasSimpleOffset, FreezeStatus, Drivable): +class Axis(HasTargetLimits, FreezeStatus, Drivable): axis = Property('axis number', IntRange(0, 2), 0) value = Parameter('axis position', FloatRange(unit='deg')) frequency = Parameter('frequency', FloatRange(1, unit='Hz'), readonly=False) @@ -89,7 +89,6 @@ class Axis(HasTargetLimits, HasSimpleOffset, FreezeStatus, Drivable): try: self._scale = self.SCALES[unit] * opts.get('gear', 1) except KeyError as e: - print(repr(e)) raise ConfigError('unsupported unit: %s' % unit) super().__init__(name, logger, opts, srv) @@ -102,7 +101,7 @@ class Axis(HasTargetLimits, HasSimpleOffset, FreezeStatus, Drivable): start_events.queue(self.read_info) def check_value(self, value): - """check if value allows moving in current driection""" + """check if value allows moving in current direction""" if self._direction > 0: if value > self.target_limits[1]: raise BadValueError('above upper limit') @@ -139,6 +138,7 @@ class Axis(HasTargetLimits, HasSimpleOffset, FreezeStatus, Drivable): def write_output(self, value): self._hw.setAxisOutput(self.axis, enable=value, autoDisable=0) + return value def read_status(self): statusbits = self._hw.getAxisStatus(self.axis) @@ -166,16 +166,24 @@ class Axis(HasTargetLimits, HasSimpleOffset, FreezeStatus, Drivable): beg = self._history.pop(0) if abs(beg - self.target) < self.tolerance: # reset normal tolerance - self._hw.setTargetRange(self.axis, self.tolerance / self._scale) + self._stop() + self._idle_status = IDLE, 'in tolerance' + return self._idle_status + # self._hw.setTargetRange(self.axis, self.tolerance / self._scale) if (self.value - beg) * self._direction > 0: return BUSY, status_text - self._idle_status = ERROR, 'no progress' + self._try_count += 1 + if self._try_count < 10: + self.log.warn('no progress retry %d', self._try_count) + return BUSY, status_text + self._idle_status = WARN, 'no progress' if self._error_state: self._try_count += 1 if self._try_count < 10 and self._history is not None: + self.log.warn('end of travel retry %d', self._try_count) self.write_target(self.target) return Done - self._idle_status = ERROR, self._error_state + self._idle_status = WARN, self._error_state if self.status[0] != IDLE: self._stop() return self._idle_status @@ -192,8 +200,14 @@ class Axis(HasTargetLimits, HasSimpleOffset, FreezeStatus, Drivable): self.write_output(1) # try first with 50 % of tolerance self._hw.setTargetRange(self.axis, self.tolerance * 0.5 / self._scale) - self._hw.setTargetPosition(self.axis, value / self._scale) - self._hw.startAutoMove(self.axis, enable=1, relative=0) + for itry in range(5): + try: + self._hw.setTargetPosition(self.axis, value / self._scale) + self._hw.startAutoMove(self.axis, enable=1, relative=0) + except Exception as e: + if itry == 4: + raise + self.log.warn('%r', e) self._history = [self.value] self._idle_status = IDLE, '' self.freeze_status(1, BUSY, 'changed target') @@ -219,7 +233,14 @@ class Axis(HasTargetLimits, HasSimpleOffset, FreezeStatus, Drivable): def _stop(self): self._move_steps = 0 self._history = None - self._hw.startAutoMove(self.axis, enable=0, relative=0) + for _ in range(5): + try: + self._hw.startAutoMove(self.axis, enable=0, relative=0) + break + except Exception as e: + if itry == 4: + raise + self.log.warn('%r', e) self._hw.setTargetRange(self.axis, self.tolerance / self._scale) self.setFastPoll(False)