mupd: various fixes frappy_psi.dpm/trinamic
- make sure motor is stopped even when the wring limit switch is hit - poll load_cell sensors at he same interval as the drive motor
This commit is contained in:
+47
-30
@@ -3,13 +3,13 @@ Node('mupd.psi.ch',
|
||||
interface='tcp://5000',
|
||||
)
|
||||
|
||||
usb_sample = 'serial:///dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3.4:1.0-port0'
|
||||
usb_displacement = 'serial:///dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3.1:1.0-port0'
|
||||
usb_displacement = 'serial:///dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3.4:1.0-port0'
|
||||
usb_pillars = 'serial:///dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3.1:1.0-port0'
|
||||
usb_load_cell = 'serial:///dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3.2:1.0-port0'
|
||||
usb_drv = 'serial:///dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3.3:1.0-port0?baudrate=38400'
|
||||
usb_drv = 'serial:///dev/serial/by-path/platform-fd500000.pcie-pci-0000:01:00.0-usb-0:1.3.3:1.0-port0?baudrate=9600'
|
||||
|
||||
|
||||
if not 'drv':
|
||||
if 'drv':
|
||||
Mod('drv',
|
||||
'frappy_psi.trinamic.Motor',
|
||||
'trinamic motor test',
|
||||
@@ -25,39 +25,56 @@ if not 'drv':
|
||||
power_down_delay=0.1,
|
||||
has_limit_switches=True,
|
||||
has_home=True,
|
||||
fast_poll = 0.1,
|
||||
)
|
||||
|
||||
Mod('F_sample',
|
||||
'frappy_psi.dpm.DPM3',
|
||||
'DPM driver to read out the transducer value, write and read the offset and scale factor',
|
||||
# drive='drv',
|
||||
value=Param(unit='N'),
|
||||
uri=usb_sample,
|
||||
digits=3,
|
||||
scale_factor=100,
|
||||
offset=0,
|
||||
)
|
||||
if not 'pillars':
|
||||
Mod('pillars',
|
||||
'frappy_psi.dpm.DPM3',
|
||||
'DPM driver to read out the transducer value, write and read the offset and scale factor',
|
||||
drive='drv',
|
||||
value=Param(unit='N'),
|
||||
uri=usb_pillars,
|
||||
digits=1,
|
||||
scale_factor=100,
|
||||
offset=0,
|
||||
alarm_limit=2000,
|
||||
)
|
||||
|
||||
Mod('F_displacement',
|
||||
'frappy_psi.dpm.DPM3',
|
||||
'DPM driver to read out the transducer value, write and read the offset and scale factor',
|
||||
# drive='drv',
|
||||
value=Param(unit='mV'),
|
||||
uri=usb_displacement,
|
||||
digits=3,
|
||||
scale_factor=100,
|
||||
offset=0,
|
||||
)
|
||||
if not 'displacement':
|
||||
Mod('displacement',
|
||||
'frappy_psi.dpm.DPM3',
|
||||
'DPM driver to read out the transducer value, write and read the offset and scale factor',
|
||||
drive='drv',
|
||||
value=Param(unit='mV'),
|
||||
uri=usb_displacement,
|
||||
digits=3,
|
||||
scale_factor=100,
|
||||
offset=0,
|
||||
alarm_limit=2000,
|
||||
)
|
||||
|
||||
Mod('F_load_cell',
|
||||
Mod('load_cell',
|
||||
'frappy_psi.dpm.DPM3',
|
||||
'DPM driver to read out the transducer value, write and read the offset and scale factor',
|
||||
# drive='drv',
|
||||
drive='drv',
|
||||
value=Param(unit='N'),
|
||||
uri=usb_load_cell,
|
||||
digits=3,
|
||||
scale_factor=25696, # value at=s on the device, but without dec.pnt.
|
||||
offset=64.53,
|
||||
digits=1,
|
||||
#scale_factor=25696, # value at=s on the device, but without dec.pnt.
|
||||
#scale_factor=25696*2*10,
|
||||
#scale_factor=10000,
|
||||
scale_factor=-105.775*1000,
|
||||
offset=65.66,
|
||||
#offset=0,
|
||||
alarm_limit=200,
|
||||
)
|
||||
|
||||
|
||||
Mod('force',
|
||||
'frappy_psi.uniax.Uniax',
|
||||
'force control',
|
||||
motor='drv',
|
||||
transducer='load_cell',
|
||||
limit=200,
|
||||
pollinterval = 0.1,
|
||||
)
|
||||
|
||||
+17
-14
@@ -59,24 +59,16 @@ class DPM3(HasIO, Readable):
|
||||
|
||||
value = Parameter(datatype=FloatRange(unit='N'))
|
||||
digits = Parameter('number of digits for value', IntRange(0, 5), value=2, readonly=False)
|
||||
# Note: we have to treat the units properly.
|
||||
# We got an output of 150 for 10N. The maximal force we want to deal with is 100N,
|
||||
# thus a maximal output of 1500. 10=150/f
|
||||
offset = Parameter('', FloatRange(-1e5, 1e5), readonly=False)
|
||||
scale_factor = Parameter('all shown digits in the device menu, but without dec.pt.',
|
||||
FloatRange(-1e6, 1e6), readonly=False)
|
||||
alarm_limit = Parameter('alarm limit', FloatRange(unit='N'), readonly=False, default=2000)
|
||||
_offset_done = 0
|
||||
_offset_changed = 0
|
||||
|
||||
def doPoll(self):
|
||||
if time.time() < self._offset_done:
|
||||
offset = self.query(self.OFFSET)
|
||||
if offset != self.offset:
|
||||
self.log.info('offset has changed: %g, set back', offset)
|
||||
self.query(self.OFFSET, offset)
|
||||
self._offset_done = 0
|
||||
return
|
||||
super().doPoll()
|
||||
def initModule(self):
|
||||
super().initModule()
|
||||
if self.drive:
|
||||
self.drive.register_interlock(self)
|
||||
|
||||
def writeInitParams(self):
|
||||
for param in 'digits', 'offset', 'scale_factor':
|
||||
@@ -119,6 +111,15 @@ class DPM3(HasIO, Readable):
|
||||
return hex2float(hexvalue, self.digits)
|
||||
|
||||
def read_value(self):
|
||||
if self._offset_changed:
|
||||
if time.time() > self._offset_changed:
|
||||
self._offset_changed = 0
|
||||
else:
|
||||
offset = self.query(self.OFFSET)
|
||||
if offset != self.offset:
|
||||
self.log.info('offset has changed: %g, set back to %g', offset, self.offset)
|
||||
self.query(self.OFFSET, self.offset)
|
||||
self._offset_changed = 0
|
||||
value = float(self.communicate('*1B1'))
|
||||
if abs(value) > self.alarm_limit:
|
||||
if self.drive:
|
||||
@@ -132,7 +133,7 @@ class DPM3(HasIO, Readable):
|
||||
self.communicate('*1F135%02X\r*1G135' % (digits + 1))
|
||||
self.query(self.SCALE, scale * 10 ** (digits - 6))
|
||||
self.query(self.OFFSET, offset)
|
||||
self._offset_done = time.time() + 10
|
||||
self._offset_changed = time.time() + 30
|
||||
|
||||
def read_digits(self):
|
||||
back_value = self.communicate('*1G135')
|
||||
@@ -143,6 +144,8 @@ class DPM3(HasIO, Readable):
|
||||
return digits
|
||||
|
||||
def read_offset(self):
|
||||
if self._offset_changed:
|
||||
return self.offset
|
||||
reply = self.query(self.OFFSET)
|
||||
return reply
|
||||
|
||||
|
||||
+28
-9
@@ -166,13 +166,14 @@ class Motor(PersistentMixin, HasIO, Drivable):
|
||||
pullup_inputs = Parameter('activate pullup', BoolType(), group='more', default=False)
|
||||
interlock_reason = Parameter('external interlock', StringType(),
|
||||
group='more', readonly=False, default='')
|
||||
fast_poll = Parameter('poll interval while driving', FloatRange(0),
|
||||
group='more', readonly=False, default=0.5)
|
||||
|
||||
pollinterval = Parameter(group='more')
|
||||
target_min = Limit()
|
||||
target_max = Limit()
|
||||
|
||||
ioClass = BytesIO
|
||||
fast_poll = 0.5
|
||||
_run_mode = RUN_IDLE
|
||||
_calc_timeout = True
|
||||
_need_reset = None
|
||||
@@ -181,6 +182,7 @@ class Motor(PersistentMixin, HasIO, Drivable):
|
||||
_drv_try = 0
|
||||
_limit_error_state = 0
|
||||
_idle_status = IDLE, ''
|
||||
_interlock_sensors = None
|
||||
|
||||
def comm(self, cmd, adr, value=0, bank=0):
|
||||
"""set or get a parameter
|
||||
@@ -266,6 +268,11 @@ class Motor(PersistentMixin, HasIO, Drivable):
|
||||
self.status = self._idle_status = ERROR, 'saved encoder value does not match reading'
|
||||
self._write_axispar(adjusted_encoder - self.zero, ENCODER_ADR, ANGLE_SCALE, readback=False)
|
||||
|
||||
def register_interlock(self, sensor):
|
||||
if self._interlock_sensors is None:
|
||||
self._interlock_sensors = {}
|
||||
self._interlock_sensors[sensor.name] = sensor
|
||||
|
||||
def _read_axispar(self, adr, scale=1):
|
||||
value = self.comm(GET_AXIS_PAR, adr)
|
||||
# do not apply scale when 1 (datatype might not be float)
|
||||
@@ -304,6 +311,8 @@ class Motor(PersistentMixin, HasIO, Drivable):
|
||||
return self._write_axispar(value, *HW_ARGS[pname])
|
||||
|
||||
def doPoll(self):
|
||||
for sensor in self._interlock_sensors.values():
|
||||
sensor.doPoll()
|
||||
self.read_status() # read_value is called by read_status
|
||||
|
||||
def read_value(self):
|
||||
@@ -368,15 +377,11 @@ class Motor(PersistentMixin, HasIO, Drivable):
|
||||
return WARN, LIMITS_PAST[self._limit_error_state]
|
||||
return self._idle_status
|
||||
if self.interlock_reason:
|
||||
self._run_mode = RUN_IDLE
|
||||
return ERROR, self.interlock_reason
|
||||
now = time.time()
|
||||
if self.steppos != oldpos:
|
||||
self._last_change = now
|
||||
if now < self._last_change + 0.25 + self.fast_poll:
|
||||
if not self.read_target_reached():
|
||||
if self.status[0] == BUSY:
|
||||
return self.status
|
||||
return BUSY, 'moving'
|
||||
if self.has_limit_switches:
|
||||
bits = self.read_input_bits()
|
||||
if self._run_mode == RUN_DRIVE:
|
||||
@@ -388,6 +393,11 @@ class Motor(PersistentMixin, HasIO, Drivable):
|
||||
self._idle_status = ERROR, lim_text
|
||||
self._stop_motor(lim_text)
|
||||
return self.status
|
||||
if now < self._last_change + 0.25 + self.fast_poll:
|
||||
if not self.read_target_reached():
|
||||
if self.status[0] == BUSY and not self.status[1].startswith('changed'):
|
||||
return self.status
|
||||
return BUSY, 'moving'
|
||||
reason = ''
|
||||
if self.read_move_status():
|
||||
reason = self.move_status.name
|
||||
@@ -462,7 +472,11 @@ class Motor(PersistentMixin, HasIO, Drivable):
|
||||
self._limit_error_state = 0
|
||||
self._limits_check_mask = LIMITS_MASK
|
||||
if self.interlock_reason:
|
||||
raise ImpossibleError(self.interlock_reason)
|
||||
if self.auto_reset:
|
||||
self.write_interlock_reason('')
|
||||
self.doPoll()
|
||||
if self.interlock_reason:
|
||||
raise ImpossibleError(self.interlock_reason)
|
||||
limit_state = self.read_input_bits() & LIMITS_MASK
|
||||
if limit_state:
|
||||
diff = target - self.steppos
|
||||
@@ -481,7 +495,7 @@ class Motor(PersistentMixin, HasIO, Drivable):
|
||||
self._drv_try = 0
|
||||
self._stable_since = 0
|
||||
self.start_motor(target)
|
||||
self.status = BUSY, 'changed target'
|
||||
self.status = BUSY, f'changed target {self._limits_check_mask}'
|
||||
|
||||
def write_zero(self, value):
|
||||
self.zero = value
|
||||
@@ -530,8 +544,13 @@ class Motor(PersistentMixin, HasIO, Drivable):
|
||||
@Command()
|
||||
def reset(self):
|
||||
"""set steppos to encoder value, if not within tolerance"""
|
||||
self.write_interlock_reason('')
|
||||
if self._run_mode:
|
||||
raise IsBusyError('can not reset while moving')
|
||||
if self._run_mode == RUN_DRIVE:
|
||||
raise IsBusyError(f'can not reset while moving {self._run_mode}')
|
||||
self.doPoll() # read sensors again
|
||||
if self.interlock_reason:
|
||||
raise IsBusyError(f'can not reset {self.interlock_reason}')
|
||||
tol = ENCODER_RESOLUTION * 1.1
|
||||
for itry in range(10):
|
||||
diff = self.read_encoder() - self.read_steppos()
|
||||
|
||||
Reference in New Issue
Block a user