attocube: more robust moving

- try up to 10 times when end of travel or no more progress
- issue WARN instead of ERROR when moving did not work
This commit is contained in:
l_samenv
2022-12-02 10:37:45 +01:00
parent e668b6a439
commit a0d14c30be

View File

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