step_size instead of speed_factor

no longer need to pre configure a speed_factor,
the proper units of speed and accel are taken from
the hardware
This commit is contained in:
2022-06-14 15:03:53 +02:00
parent f855b9db40
commit 54b58f2188

View File

@ -37,7 +37,7 @@ class PhytronIO(StringIO):
def communicate(self, command, expect_response=True): def communicate(self, command, expect_response=True):
for ntry in range(5, 0, -1): for ntry in range(5, 0, -1):
try: try:
head, _, reply = super().communicate('\x02' + command).partition('\x02') _, _, reply = super().communicate('\x02' + command).partition('\x02')
if reply[0] == '\x06': # ACK if reply[0] == '\x06': # ACK
if len(reply) == 1 and expect_response: if len(reply) == 1 and expect_response:
raise CommunicationFailedError('empty response') raise CommunicationFailedError('empty response')
@ -53,7 +53,6 @@ class PhytronIO(StringIO):
class Motor(PersistentMixin, HasIO, Drivable): class Motor(PersistentMixin, HasIO, Drivable):
axis = Property('motor axis X or Y', StringType(), default='X') axis = Property('motor axis X or Y', StringType(), default='X')
address = Property('address', IntRange(0, 15), default=0) address = Property('address', IntRange(0, 15), default=0)
speed_factor = Property('steps / degree', FloatRange(0, None), default=2000)
encoder_mode = Parameter('how to treat the encoder', EnumType('encoder', NO=0, READ=1, CHECK=2), encoder_mode = Parameter('how to treat the encoder', EnumType('encoder', NO=0, READ=1, CHECK=2),
default=1, readonly=False) default=1, readonly=False)
@ -78,6 +77,7 @@ class Motor(PersistentMixin, HasIO, Drivable):
_backlash_pending = False _backlash_pending = False
_mismatch_count = 0 _mismatch_count = 0
_rawlimits = None _rawlimits = None
_step_size = None
def earlyInit(self): def earlyInit(self):
super().earlyInit() super().earlyInit()
@ -147,29 +147,39 @@ class Motor(PersistentMixin, HasIO, Drivable):
return self.value return self.value
return float(self.get('P22R')) * self.sign - self.offset return float(self.get('P22R')) * self.sign - self.offset
def write_sign(self, value):
self.sign = value
self.saveParameters()
return Done
def get_step_size(self):
self._step_size = float(self.get('P03R'))
def read_speed(self): def read_speed(self):
return float(self.get('P14R')) / self.speed_factor if self._step_size is None:
# avoid repeatedly reading step size, as this is polled and will not change
self.get_step_size()
return float(self.get('P14R')) * self._step_size
def write_speed(self, value): def write_speed(self, value):
inv_factor = float(self.get('P03R')) self.get_step_size() # read step size anyway, it does not harm
if abs(inv_factor * self.speed_factor - 1) > 0.001: return float(self.set_get('P14S', round(value / self._step_size), 'P14R')) * self._step_size
raise HardwareError('speed factor does not match %g' % (1.0 / inv_factor))
return float(self.set_get('P14S', int(value * self.speed_factor), 'P14R')) / self.speed_factor
def read_accel(self): def read_accel(self):
return float(self.get('P15R')) / self.speed_factor if not self._step_size:
self.get_step_size()
return float(self.get('P15R')) * self._step_size
def write_accel(self, value): def write_accel(self, value):
if abs(float(self.get('P03R')) * self.speed_factor - 1) > 0.001: self.get_step_size()
raise HardwareError('speed factor does not match') return float(self.set_get('P15S', round(value / self._step_size), 'P15R')) * self._step_size
return float(self.set_get('P15S', int(value * self.speed_factor), 'P15R')) / self.speed_factor
def _check_limits(self, *values): def _check_limits(self, *values):
for name, (mn, mx) in ('user', self._rawlimits), ('abs', self.abslimits): for name, (mn, mx) in ('user', self._rawlimits), ('abs', self.abslimits):
mn -= self.offset mn -= self.offset
mx -= self.offset mx -= self.offset
for v in values: for v in values:
if not (mn <= v <= mx): if not mn <= v <= mx:
raise BadValueError('%s limits violation: %g <= %g <= %g' % (name, mn, v, mx)) raise BadValueError('%s limits violation: %g <= %g <= %g' % (name, mn, v, mx))
v += self.offset v += self.offset