phytron next version

with adaption of HasStates

Change-Id: I167ac8031bc5f7120c30031e7cfcb7587b42b61d
This commit is contained in:
2023-05-15 11:12:52 +02:00
parent df4a37085a
commit 050a2dc8dc
2 changed files with 38 additions and 32 deletions

View File

@ -77,11 +77,11 @@ class Motor(HasOffset, HasStates, PersistentMixin, HasIO, Drivable):
target_max = Limit()
alive_time = PersistentParam('alive time for detecting restarts',
FloatRange(), default=0, export=False)
sim_error = Parameter('run time error simulation', StringType(), readonly=False, default='')
ioClass = PhytronIO
_step_size = None # degree / step
_reset_needed = False
_blocking_error = None # None or a string indicating the reason of an error needing reset
_running = False # status indicates motor is running
STATUS_MAP = {
'08': (IDLE, ''),
@ -119,7 +119,7 @@ class Motor(HasOffset, HasStates, PersistentMixin, HasIO, Drivable):
self.set('P37S', axisbit | active_axes) # activate axis
if now < self.alive_time + 7 * 24 * 3600: # the device was running within last week
# inform the user about the loss of position by the need of doing reset_error
self._reset_needed = True
self._blocking_error = 'lost position'
else: # do reset silently
self.reset_error()
self.alive_time = now
@ -167,9 +167,8 @@ class Motor(HasOffset, HasStates, PersistentMixin, HasIO, Drivable):
def write_target(self, value):
self.read_alive_time()
if self._reset_needed:
if not self.status[1].startswith('reset needed'):
self.status = ERROR, 'reset needed after ' + self.status[1]
if self._blocking_error:
self.status = ERROR, 'reset needed after ' + self._blocking_error
raise HardwareError(self.status[1])
self.saveParameters()
if self.backlash:
@ -180,17 +179,16 @@ class Motor(HasOffset, HasStates, PersistentMixin, HasIO, Drivable):
else:
self.set('A', self.sign * value)
self.start_machine(self.driving)
self._running = True
return value
def read_status(self):
if self.sim_error:
sysstatus = self.sim_error
else:
sysstatus = self.communicate(f'{self.address:x}SE')
sysstatus = sysstatus[2:4] if self.axis == 'X' else sysstatus[6:8]
status = self.STATUS_MAP.get(sysstatus) or (ERROR, f'unknown error {sysstatus}')
sysstatus = self.communicate(f'{self.address:x}SE')
sysstatus = sysstatus[1:4] if self.axis == 'X' else sysstatus[5:8]
self._running = sysstatus[0] != '1'
status = self.STATUS_MAP.get(sysstatus[1:]) or (ERROR, f'unknown error {sysstatus[1:]}')
if status[0] == ERROR:
self._reset_needed = True
self._blocking_error = status[1]
return status
return super().read_status() # status from state machine
@ -200,8 +198,7 @@ class Motor(HasOffset, HasStates, PersistentMixin, HasIO, Drivable):
enc = self.read_encoder()
else:
enc = self.value
status = self.get('=H')
if status != 'N': # at target
if not self._running: # at target
return False
if self.encoder_mode != 'CHECK':
return True
@ -212,8 +209,8 @@ class Motor(HasOffset, HasStates, PersistentMixin, HasIO, Drivable):
self.value, e1, e2)
self.get('S') # stop
self.saveParameters()
self._reset_needed = True
raise HardwareError('encoder lag error')
self._blocking_error = 'encoder lag error'
raise HardwareError(self._blocking_error)
@status_code(BUSY)
def driving(self, sm):
@ -243,21 +240,29 @@ class Motor(HasOffset, HasStates, PersistentMixin, HasIO, Drivable):
if sm.mismatch_count > 2:
self.log.error('encoder mismatch: abs(%g - %g) < %g',
enc, pos, self.encoder_tolerance)
self._reset_needed = True
raise HardwareError('encoder does not match pos')
self._blocking_error = 'encoder does not match pos'
raise HardwareError(self._blocking_error)
sm.mismatch_count += 1
return Retry
self.saveParameters()
return self.final_status(IDLE, '')
@status_code(BUSY)
def stopping(self, sm):
if self._running:
return Retry
return self.final_status(IDLE, 'stopped')
@Command
def stop(self):
self.get('S')
self.start_machine(self.stopping, status=(BUSY, 'stopping0'))
@Command
def reset_error(self):
"""Reset error, set position to encoder"""
self.read_value()
if self._reset_needed:
if self._blocking_error:
newenc = enc = self.read_encoder()
pos = self.value
if abs(enc - pos) > self.encoder_tolerance or self.encoder_mode == 'NO':
@ -278,7 +283,7 @@ class Motor(HasOffset, HasStates, PersistentMixin, HasIO, Drivable):
self.set('P20S', newenc * self.sign) # set pos to encoder
self.read_value()
self.status = 'IDLE', 'after error reset'
self._reset_needed = False
self._blocking_error = None
# TODO:
# '=E' electronics status