fixes for attocube

Change-Id: Id5eeb749ba010fec59d1c2f8a3258ee34a47e246
This commit is contained in:
2024-03-20 16:59:04 +01:00
parent ea8570d422
commit 16b826394f
2 changed files with 19 additions and 50 deletions

View File

@ -7,9 +7,10 @@ Mod('r',
'frappy_psi.attocube.Axis',
'ANRv220-F3-02882',
axis = 1,
unit = 'deg',
value = Param(unit='deg'),
tolerance = 0.01,
target_limits = (0, 360),
target_min = 0,
target_max = 360
# gear = 1.2,
)

View File

@ -19,7 +19,8 @@
import sys
import time
from frappy.core import Drivable, Parameter, Command, Property, ERROR, WARN, BUSY, IDLE, Done, nopoll, TupleOf
from frappy.core import Drivable, Parameter, Command, Property, \
ERROR, WARN, BUSY, IDLE, Done, nopoll, Limit
# from frappy.features import HasSimpleOffset
from frappy.datatypes import IntRange, FloatRange, StringType, BoolType
from frappy.errors import ConfigError, BadValueError
@ -30,50 +31,18 @@ from PyANC350v4 import Positioner
DIRECTION_NAME = {1: 'forward', -1: 'backward'}
class FreezeStatus:
"""freeze status for some time
hardware quite often does not treat status correctly: on a target change it
may take some time to return the 'busy' status correctly.
in classes with this mixin, within :meth:`write_target` call
self.freeze_status(0.5, BUSY, 'changed target')
a wrapper around read_status will take care that the status will be the given value,
for at least the given delay. This does NOT cover the case when self.status is set
directly from an other method.
"""
__freeze_status_until = 0
def __init_subclass__(cls):
def wrapped(self, inner=cls.read_status):
if time.time() < self.__freeze_status_until:
return Done
return inner(self)
wrapped.poll = True
cls.read_status = wrapped
super().__init_subclass__()
def freeze_status(self, delay, code=BUSY, text='changed target'):
"""freezze status to the given value for the given delay"""
self.__freeze_status_until = time.time() + delay
self.status = code, text
class Axis(FreezeStatus, Drivable):
class Axis(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)
amplitude = Parameter('amplitude', FloatRange(0, unit='V'), readonly=False)
gear = Parameter('gear factor', FloatRange(), readonly=False, default=1)
gear = Parameter('gear factor', FloatRange(), readonly=False, value=1)
tolerance = Parameter('positioning tolerance', FloatRange(0, unit='$'), readonly=False, default=0.01)
output = Parameter('enable output', BoolType(), readonly=False)
info = Parameter('axis info', StringType())
statusbits = Parameter('status bits', StringType())
target_limits = Parameter('target limits', TupleOf(FloatRange(), FloatRange()), readonly=False)
target_min = Limit()
target_max = Limit()
_hw = Positioner()
_scale = 1 # scale for custom units
@ -85,16 +54,7 @@ class Axis(FreezeStatus, Drivable):
_history = None
_check_sensor = False
_try_count = 0
def __init__(self, name, logger, opts, srv):
unit = opts.pop('unit', 'deg')
# opts['value.unit'] = unit
try:
# self._scale = self.SCALES[unit] * opts.get('gear', 1)
self._scale = self.SCALES['deg'] * opts.get('gear', 1)
except KeyError as e:
raise ConfigError('unsupported unit: %s' % unit)
super().__init__(name, logger, opts, srv)
__freeze_until = 0
def write_gear(self, value):
self._scale = self.SCALES[self.parameters['value'].datatype.unit] * self.gear
@ -144,7 +104,15 @@ class Axis(FreezeStatus, Drivable):
self._hw.setAxisOutput(self.axis, enable=value, autoDisable=0)
return value
def freeze_status(self, delay, code=BUSY, text='changed target'):
"""freeze status to the given value for the given delay"""
self.__freeze_until = time.time() + delay
self.status = code, text
def read_status(self):
if time.time() < self.__freeze_until:
return self.status
self.__freeze_until = 0
statusbits = self._hw.getAxisStatus(self.axis)
sensor, self.output, moving, attarget, eot_fwd, eot_bwd, sensor_error = statusbits
self.statusbits = ''.join((k for k, v in zip('SOMTFBE', statusbits) if v))
@ -214,7 +182,7 @@ class Axis(FreezeStatus, Drivable):
self.log.warn('%r', e)
self._history = [self.value]
self._idle_status = IDLE, ''
self.freeze_status(1, BUSY, 'changed target')
self.freeze_status(1)
self.setFastPoll(True, 1)
return value