uniax: added force control as seperate module
Change-Id: I8b14fc90f5885834e342f6bc5e5dd0ea711b27ea
This commit is contained in:
@ -21,8 +21,10 @@
|
||||
# *****************************************************************************
|
||||
"""transducer DPM3 read out"""
|
||||
|
||||
from secop.core import Drivable, Parameter, FloatRange, BoolType, StringIO,\
|
||||
HasIodev, IntRange, Done, Attached, Command
|
||||
import time
|
||||
|
||||
from secop.core import Readable, Parameter, FloatRange, StringIO,\
|
||||
HasIodev, IntRange, Done
|
||||
|
||||
|
||||
class DPM3IO(StringIO):
|
||||
@ -45,30 +47,22 @@ def float2hex(value, digits):
|
||||
return '%06X' % intvalue
|
||||
|
||||
|
||||
class DPM3(HasIodev, Drivable):
|
||||
class DPM3(HasIodev, Readable):
|
||||
OFFSET = 0x8f
|
||||
SCALE = 0x8c
|
||||
|
||||
MAGNITUDE = {'1': 1, '2': 10, '3': 100, '4': 1e3, '5': 1e4, '6': 1e5,
|
||||
'9':-1, 'A':-10, 'B':-100, 'C':-1e3, 'D':-1e4, 'E':-1e5}
|
||||
MAGNITUDE = {'1': 1, '2': 10, '3': 100, '4': 1e3, '5': 1e4, '6': 1e5,
|
||||
'9': -1, 'A': -10, 'B': -100, 'C': -1e3, 'D': -1e4, 'E': -1e5}
|
||||
|
||||
iodevClass = DPM3IO
|
||||
|
||||
motor = Attached()
|
||||
digits = Parameter('number of digits for value', IntRange(0, 5), initwrite=True, readonly=False)
|
||||
value = Parameter(datatype=FloatRange(unit='N'))
|
||||
target = Parameter(datatype=FloatRange(unit='N'))
|
||||
step = Parameter('maximum motor step', FloatRange(unit='deg'), default=5, readonly=False)
|
||||
|
||||
digits = Parameter('number of digits for value', IntRange(0, 5), initwrite=True, 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, poll=True)
|
||||
|
||||
#Note: we have tro treat the units properly.
|
||||
""" We got an output of 150 for 10N. The maximal force we want to deal with is 100N,
|
||||
thus a maximl output of 1500. 10=150/f
|
||||
"""
|
||||
scale_factor = Parameter('', FloatRange(-1e5, 1e5, unit='input_units/N'), readonly=False, poll=True)
|
||||
_target = None
|
||||
fast_pollfactor = 0.01
|
||||
scale_factor = Parameter('', FloatRange(-1e5, 1e5, unit='input_units/N'), readonly=False, poll=True)
|
||||
|
||||
def query(self, adr, value=None):
|
||||
if value is not None:
|
||||
@ -78,11 +72,11 @@ class DPM3(HasIodev, Drivable):
|
||||
if 10000 <= round(value * mag, 0) <= 99999:
|
||||
break
|
||||
else:
|
||||
# not suitable range found
|
||||
# no suitable range found
|
||||
if absval >= 99999.5: # overrange
|
||||
raise ValueError('%s is out of range' % value)
|
||||
# underrange: take lowest
|
||||
nibble = '9' if value < 0 else '1'
|
||||
nibble = '9' if value < 0 else '1'
|
||||
mag = self.MAGNITUDE[nibble]
|
||||
hex_val = nibble + '%05X' % int(round(value * mag, 0))
|
||||
if hex_val[1:] == '00000':
|
||||
@ -103,9 +97,9 @@ class DPM3(HasIodev, Drivable):
|
||||
|
||||
def write_digits(self, value):
|
||||
# value defines the number of digits
|
||||
back_value=self._iodev.communicate('*1F135%02X\r*1G135' % (value + 1))
|
||||
self.digits = int(back_value,16) - 1
|
||||
# realculate proper scale and offset
|
||||
back_value = self._iodev.communicate('*1F135%02X\r*1G135' % (value + 1))
|
||||
self.digits = int(back_value, 16) - 1
|
||||
# recalculate proper scale and offset
|
||||
self.write_scale_factor(self.scale_factor)
|
||||
self.write_offset(self.offset)
|
||||
return Done
|
||||
@ -115,44 +109,7 @@ class DPM3(HasIodev, Drivable):
|
||||
return int(back_value,16) - 1
|
||||
|
||||
def read_value(self):
|
||||
value = float(self._iodev.communicate('*1B1'))
|
||||
mot = self._motor
|
||||
if self._target is None:
|
||||
if mot.isBusy():
|
||||
self.status = self.Status.IDLE, 'stopping'
|
||||
else:
|
||||
self.status = self.Status.IDLE, ''
|
||||
else:
|
||||
if self._direction * (self._target - value) > 0:
|
||||
if self._mot_target != mot.target:
|
||||
self.stop()
|
||||
self.status = self.Status.IDLE, 'motor was stopped'
|
||||
elif not mot.isBusy():
|
||||
step = self.step * self._direction
|
||||
mot_target = mot.value + step
|
||||
self._mot_target = mot.write_target(mot_target)
|
||||
else:
|
||||
self.stop()
|
||||
self.status = self.Status.IDLE, 'target reached'
|
||||
return value
|
||||
|
||||
def write_target(self, target):
|
||||
self._target = target
|
||||
if target - self.value > 0:
|
||||
self._direction = 1
|
||||
else:
|
||||
self._direction = -1
|
||||
self.status = self.Status.BUSY, 'moving motor'
|
||||
if self._motor.status[0] == self.Status.ERROR:
|
||||
self._motor.reset()
|
||||
self._mot_target = self._motor.target
|
||||
return target
|
||||
|
||||
@Command()
|
||||
def stop(self):
|
||||
self._target = None
|
||||
self._motor.stop()
|
||||
self.status = self.Status.IDLE, 'stopped'
|
||||
return float(self._iodev.communicate('*1B1'))
|
||||
|
||||
def read_offset(self):
|
||||
reply = self.query(self.OFFSET)
|
||||
|
Reference in New Issue
Block a user