Merge branch 'wip' of gitlab.psi.ch-samenv:samenv/frappy into wip

This commit is contained in:
zolliker 2022-09-12 15:16:57 +02:00
commit 12cb0cdade
13 changed files with 108 additions and 156 deletions

9
cfg/stick/uniax.cfg Normal file
View File

@ -0,0 +1,9 @@
[NODE]
id = uniax stick
class = protocol.router.Router
description = router forwarding to linse-uniax apu
node = linse-uniax:5000
#[INTERFACE]
#uri=tcp://5002

View File

@ -18,7 +18,7 @@ io = drv_io
standby_current=0.1
maxcurrent=1.4
acceleration=150.
movelimit=360
move_limit=360
speed=40
encoder_tolerance=3.6
free_wheeling=0.1

View File

@ -10,6 +10,7 @@ description = force control
class = secop_psi.uniax.Uniax
motor = drv
transducer = transducer
force_offset = 15
#[drv_io]
#description =
@ -23,10 +24,10 @@ class = secop_psi.trinamic.Motor
# io = drv_io
uri = tcp://192.168.127.254:3002
standby_current=0.1
maxcurrent=0.2
maxcurrent=0.3
acceleration=150.
move_limit=5
safe_current=0.2
safe_current=0.3
speed=40
encoder_tolerance=3.6
free_wheeling=0.1
@ -39,6 +40,7 @@ class = secop_psi.dpm.DPM3
uri = tcp://192.168.127.254:3001
digits = 2
scale_factor = 0.0156
offset = 15
[res]
description = temperature on uniax stick

View File

@ -47,7 +47,7 @@ class SilentError(CommunicationFailedError):
class HasIO(Module):
"""Mixin for modules using a communicator"""
io = Attached()
io = Attached(mandatory=False)
uri = Property('uri for automatic creation of the attached communication module',
StringType(), default='')

View File

@ -18,83 +18,86 @@
# Module authors:
# Daniel Margineda <daniel.margineda@psi.ch>
# *****************************************************************************
"""WAVE FUNCTION LECROY XX: SIGNAL GENERATOR"""
"""WAVE FUNCTION LECROY XX: SIGNAL GENERATOR
modifications not tested!
"""
from secop.core import Readable, Parameter, FloatRange, \
IntRange, BoolType, EnumType, Module, Property
IntRange, BoolType, EnumType, Module, Property, HasIO
class Channel(Module):
class Channel(HasIO, Module):
channel = Property('choose channel to manipulate', IntRange(1, 2))
freq = Parameter('frequency', FloatRange(1e-6, 20e6, unit='Hz'),
poll=True, initwrite=True, default=1000)
initwrite=True, default=1000)
amp = Parameter('exc_volt_int', FloatRange(0.00, 5, unit='Vrms'),
poll=True, readonly=False, initwrite=True, default=0.1)
readonly=False, initwrite=True, default=0.1)
offset = Parameter('offset_volt_int', FloatRange(0.0, 10, unit='V'),
poll=True, readonly=False, initwrite=True, default=0.0)
readonly=False, initwrite=True, default=0.0)
wave = Parameter('type of wavefunction',
EnumType('WaveFunction', SINE=1, SQUARE=2, RAMP=3, PULSE=4, NOISE=5, ARB=6, DC=7),
poll=True, readonly=False, default='SINE')
readonly=False, default='SINE')
phase = Parameter('signal phase', FloatRange(0, 360, unit='deg'),
poll=True, readonly=False, initwrite=True, default=0)
readonly=False, initwrite=True, default=0)
enabled = Parameter('enable output channel', datatype=EnumType('OnOff', OFF=0, ON=1),
readonly=False, default='OFF')
symm = Parameter('wavefunction symmetry', FloatRange(0, 100, unit=''),
poll=True, readonly=False, default=0)
readonly=False, default=0)
def read_value(self):
return self.sendRecv('C%d:BSWV FRQ?' % self.channel)
return self.communicate('C%d:BSWV FRQ?' % self.channel)
def write_target(self, value):
self.sendRecv('C%d:BSWV FRQ, %gHz' % (self.channel, value))
self.communicate('C%d:BSWV FRQ, %gHz' % (self.channel, value))
return value
# signal wavefunction parameter
def read_wave(self):
return self.sendRecv('C%d:BSWV WVTP?' % self.channel)
return self.communicate('C%d:BSWV WVTP?' % self.channel)
def write_wave(self, value): # string value
self.sendRecv('C%d:BSWV WVTP, %s' % (self.channel, value.name))
self.communicate('C%d:BSWV WVTP, %s' % (self.channel, value.name))
return value
# signal amplitude parameter
def read_amp(self):
return self.sendRecv('C%d:BSWV AMP?' % self.channel)
return self.communicate('C%d:BSWV AMP?' % self.channel)
def write_amp(self, value):
self.sendRecv('C%d:BSWV AMP, %g' % (self.channel, value))
self.communicate('C%d:BSWV AMP, %g' % (self.channel, value))
return value
# offset value parameter
def read_offset(self):
return self.sendRecv('C%d:BSWV OFST?' % self.channel)
return self.communicate('C%d:BSWV OFST?' % self.channel)
def write_offset(self, value):
self.sendRecv('C%d:BSWV OFST %g' % (self.channel, value))
self.communicate('C%d:BSWV OFST %g' % (self.channel, value))
return value
# channel symmetry
def read_symm(self):
return self.sendRecv('C%d:BSWV SYM?' % self.channel)
return self.communicate('C%d:BSWV SYM?' % self.channel)
def write_symm(self, value):
self.sendRecv('C%d:BSWV SYM %g' % (self.channel, value))
self.communicate('C%d:BSWV SYM %g' % (self.channel, value))
return value
# wave phase parameter
def read_phase(self):
return self.sendRecv('C%d:BSWV PHSE?' % self.channel)
return self.communicate('C%d:BSWV PHSE?' % self.channel)
def write_phase(self, value):
self.sendRecv('C%d:BSWV PHSE %g' % (self.channel, value))
self.communicate('C%d:BSWV PHSE %g' % (self.channel, value))
return value
# dis/enable output channel
def read_enabled(self):
return self.sendRecv('C%d: OUTP?' % self.channel)
return self.communicate('C%d: OUTP?' % self.channel)
def write_enabled(self, value):
self.sendRecv('C%d: OUTP %s' % (self.channel, value.name))
self.communicate('C%d: OUTP %s' % (self.channel, value.name))
return value

View File

@ -21,7 +21,7 @@
"""Signal Recovery SR7270: lockin amplifier for AC susceptibility"""
from secop.core import Readable, Parameter, Command, FloatRange, TupleOf, \
HasIodev, StringIO, Attached, IntRange, BoolType, EnumType
HasIO, StringIO, Attached, IntRange, BoolType, EnumType
class SR7270(StringIO):
@ -33,7 +33,7 @@ class SR7270(StringIO):
return reply + ';%d;%d' % tuple(status)
class XY(HasIodev, Readable):
class XY(HasIO, Readable):
x = Attached()
y = Attached()
freq_arg = Attached()
@ -46,29 +46,29 @@ class XY(HasIodev, Readable):
value = Parameter('X, Y', datatype=TupleOf(FloatRange(unit='V'), FloatRange(unit='V')))
freq = Parameter('exc_freq_int',
FloatRange(0.001, 250e3, unit='Hz'),
poll=True, readonly=False, initwrite=True, default=1000)
readonly=False, initwrite=True, default=1000)
amp = Parameter('exc_volt_int',
FloatRange(0.00, 5, unit='Vrms'),
poll=True, readonly=False, initwrite=True, default=0.1)
range = Parameter('sensitivity value', FloatRange(0.00, 1, unit='V'), poll=True, default=1)
irange = Parameter('sensitivity index', IntRange(0, 27), poll=True, readonly=False, default=25)
readonly=False, initwrite=True, default=0.1)
range = Parameter('sensitivity value', FloatRange(0.00, 1, unit='V'), default=1)
irange = Parameter('sensitivity index', IntRange(0, 27), readonly=False, default=25)
autorange = Parameter('autorange_on', EnumType('autorange', off=0, soft=1, hard=2),
readonly=False, default=0, initwrite=True)
tc = Parameter('time constant value', FloatRange(10e-6, 100, unit='s'), poll=True, default=0.1)
itc = Parameter('time constant index', IntRange(0, 30), poll=True, readonly=False, initwrite=True, default=14)
tc = Parameter('time constant value', FloatRange(10e-6, 100, unit='s'), default=0.1)
itc = Parameter('time constant index', IntRange(0, 30), readonly=False, initwrite=True, default=14)
nm = Parameter('noise mode', BoolType(), readonly=False, default=0)
phase = Parameter('Reference phase control', FloatRange(-360, 360, unit='deg'),
poll=True, readonly=False, initwrite=True, default=0)
readonly=False, initwrite=True, default=0)
vmode = Parameter('Voltage input configuration', IntRange(0, 3), readonly=False, default=3),
# dac = Parameter('output DAC channel value', datatype=TupleOf(IntRange(1, 4), FloatRange(0.0, 5000, unit='mV')),
# poll=True, readonly=False, initwrite=True, default=(3,0))
# readonly=False, initwrite=True, default=(3,0))
dac = Parameter('output DAC channel value', FloatRange(-10000, 10000, unit='mV'),
poll=True, readonly=False, initwrite=True, default=0)
readonly=False, initwrite=True, default=0)
iodevClass = SR7270
ioClass = SR7270
def comm(self, command):
reply, status, overload = self.sendRecv(command).split(';')
reply, status, overload = self.communicate(command).split(';')
if overload != '0':
self.status = self.Status.WARN, 'overload %s' % overload
else:
@ -200,10 +200,10 @@ class XY(HasIodev, Readable):
class Comp(Readable):
pollerClass = None
enablePoll = False
value = Parameter(datatype=FloatRange(unit='V'))
class arg(Readable):
pollerClass = None
enablePoll = False
value = Parameter(datatype=FloatRange(unit=''))

View File

@ -22,7 +22,7 @@
"""driver for cryotel stirling cryocooler"""
from secop.core import Command, EnumType, FloatRange, HasIodev, Parameter, Drivable, StringIO, StringType
from secop.core import Command, EnumType, FloatRange, HasIO, Parameter, Drivable, StringIO, StringType
from secop.errors import CommunicationFailedError, HardwareError
@ -48,27 +48,27 @@ class CryotelIO(StringIO):
return reply
class Cryo(HasIodev, Drivable):
class Cryo(HasIO, Drivable):
value = Parameter('current temperature', FloatRange(unit='deg'))
target = Parameter('target temperature', FloatRange(unit='deg'), readonly=False)
mode = Parameter('control mode', EnumType('mode', off=0, power=1, temperature=2), readonly=False, poll=True)
power = Parameter('power', FloatRange(unit='W'), poll=True)
mode = Parameter('control mode', EnumType('mode', off=0, power=1, temperature=2), readonly=False)
power = Parameter('power', FloatRange(unit='W'))
setpower = Parameter('requested power', FloatRange(unit='W'), default=0)
cool_power = Parameter('power for cooling', FloatRange(unit='W'), default=240, readonly=False)
hold_power = Parameter('power for holding T', FloatRange(unit='W'), default=120, readonly=False)
cool_threshold = Parameter('switch to cool_power once above this value', FloatRange(unit='K'), default=100, readonly=False)
hold_threshold = Parameter('switch to hold_power once below this value', FloatRange(unit='K'), default=95, readonly=False)
iodevClass = CryotelIO
ioClass = CryotelIO
cnt_inside = 0
def get(self, cmd):
return float(self._iodev.communicate(cmd))
return float(self.communicate(cmd))
def set(self, cmd, value, check=False):
setcmd = '%s=%.2f' % (cmd, value)
self._iodev.communicate(setcmd)
reply = float(self._iodev.communicate(cmd))
self.communicate(setcmd)
reply = float(self.communicate(cmd))
if check:
if value != reply:
raise HardwareError('illegal reply from %s: %g' % (cmd, reply))

View File

@ -21,10 +21,8 @@
# *****************************************************************************
"""transducer DPM3 read out"""
import time
from secop.core import Readable, Parameter, FloatRange, StringIO,\
HasIodev, IntRange, Done
HasIO, IntRange, Done
class DPM3IO(StringIO):
@ -47,22 +45,22 @@ def float2hex(value, digits):
return '%06X' % intvalue
class DPM3(HasIodev, Readable):
class DPM3(HasIO, 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}
iodevClass = DPM3IO
ioClass = DPM3IO
value = Parameter(datatype=FloatRange(unit='N'))
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)
scale_factor = Parameter('', FloatRange(-1e5, 1e5, unit='input_units/N'), readonly=False, poll=True)
offset = Parameter('', FloatRange(-1e5, 1e5), readonly=False)
scale_factor = Parameter('', FloatRange(-1e5, 1e5, unit='input_units/N'), readonly=False)
def query(self, adr, value=None):
if value is not None:
@ -87,7 +85,7 @@ class DPM3(HasIodev, Readable):
else:
cmd = ""
cmd = cmd + '*1G3%02X' % adr
hexvalue = self._iodev.communicate(cmd)
hexvalue = self.communicate(cmd)
if adr == self.SCALE:
mag = self.MAGNITUDE[hexvalue[0:1]]
value = int(hexvalue[1:], 16)
@ -97,7 +95,7 @@ class DPM3(HasIodev, Readable):
def write_digits(self, value):
# value defines the number of digits
back_value = self._iodev.communicate('*1F135%02X\r*1G135' % (value + 1))
back_value = self.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)
@ -105,11 +103,11 @@ class DPM3(HasIodev, Readable):
return Done
def read_digits(self):
back_value = self._iodev.communicate('*1G135')
back_value = self.communicate('*1G135')
return int(back_value,16) - 1
def read_value(self):
return float(self._iodev.communicate('*1B1'))
return float(self.communicate('*1B1'))
def read_offset(self):
reply = self.query(self.OFFSET)

View File

@ -24,7 +24,7 @@ import time
from secop.datatypes import StringType, FloatRange
from secop.modules import Parameter, Property, Readable
from secop.io import HasIodev, StringIO
from secop.io import HasIO, StringIO
class LscIO(StringIO):
@ -33,13 +33,13 @@ class LscIO(StringIO):
wait_before = 0.05
class ResChannel(HasIodev, Readable):
class ResChannel(HasIO, Readable):
"""temperature channel on Lakeshore 340"""
iodevClass = LscIO
ioClass = LscIO
value = Parameter(datatype=FloatRange(unit='Ohm'))
channel = Property('the channel A,B,C or D', StringType())
def read_value(self):
return self._iodev.communicate('SRDG?%s' % self.channel)
return float(self.communicate('SRDG?%s' % self.channel))

View File

@ -1,61 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# *****************************************************************************
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation; either version 2 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Module authors:
# Markus Zolliker <markus.zolliker@psi.ch>
# *****************************************************************************
"""PPMS mf proxy"""
import secop_psi.ppms
from secop.core import Drivable, Enum, EnumType, FloatRange, Override, Parameter
from secop.datatypes import StatusType
from secop.proxy import proxy_class
class Field(proxy_class(secop_psi.ppms.Field)):
"""magnetic field"""
# pylint: disable=invalid-name
Status = Enum(Drivable.Status,
PREPARED = 150,
PREPARING = 340,
RAMPING = 370,
FINALIZING = 390,
)
# pylint: disable=invalid-name
PersistentMode = Enum('PersistentMode', persistent=0, driven=1)
ApproachMode = Enum('ApproachMode', linear=0, no_overshoot=1, oscillate=2)
remoteParameters = {
'value':
Override(datatype=FloatRange(-1, 1, unit='T'), poll=True),
'status':
Override(datatype=StatusType(Status), poll=True),
'target':
Override(datatype=FloatRange(-15, 15, unit='T'), poll=True),
'ramp':
Parameter('ramping speed', readonly=False,
datatype=FloatRange(0.064, 1.19, unit='T/min'), poll=True),
'approachmode':
Parameter('how to approach target', readonly=False,
datatype=EnumType(ApproachMode), poll=True),
'persistentmode':
Parameter('what to do after changing field', readonly=False,
datatype=EnumType(PersistentMode), poll=True),
'pollinterval':
Override(visibility=3),
}

View File

@ -32,20 +32,20 @@ from secop.core import Attached, BoolType, FloatRange, IntRange, \
class Temperature(Readable):
pollerClass = None
enablePoll = False
value = Parameter(datatype=FloatRange(unit='degC'))
class Bcomp(Readable):
pollerClass = None
enablePoll = False
value = Parameter(datatype=FloatRange(unit='T'))
range = Parameter('working range', FloatRange(unit='T'), default=0)
class Raw(Readable):
pollerClass = None
enablePoll = False
value = Parameter(datatype=FloatRange())
@ -62,7 +62,7 @@ class TeslameterBase(Readable):
y = Attached()
z = Attached()
value = Parameter('B vector', poll=True,
value = Parameter('B vector',
datatype=TupleOf(FloatRange(unit='T'), FloatRange(unit='T'), FloatRange(unit='T')))
usb = Parameter('usb device', StringType(), readonly=False)
enabled = Parameter('enable data acq', datatype=BoolType(), readonly=False, default=True)
@ -152,7 +152,7 @@ class Teslameter3MH6(TeslameterBase):
range = Parameter('range or 0 for autorange', FloatRange(0, 20, unit='T'), readonly=False, default=0)
rate = Parameter('sampling rate', datatype=FloatRange(10, 15000, unit='Hz'),
readonly=False, poll=True)
readonly=False)
avtime = Parameter('data acquisition time', FloatRange(), default=0)
SAMPLING_RATES = {0xe0: 15000, 0xd0: 7500, 0xc0: 3750, 0xb0: 2000, 0xa1: 1000,

View File

@ -22,17 +22,17 @@
from secop.datatypes import FloatRange, IntRange, StringType
from secop.modules import Drivable, Parameter, Readable
from secop.io import HasIodev
from secop.io import HasIO
Status = Drivable.Status
class TempLoop(HasIodev, Drivable):
class TempLoop(HasIO, Drivable):
"""temperature channel on Lakeshore 336"""
value = Parameter(datatype=FloatRange(unit='K'), default=0, poll=True)
value = Parameter(datatype=FloatRange(unit='K'), default=0)
status = Parameter(poll=False)
target = Parameter(datatype=FloatRange(1.0, 402.0, unit='K'), default=1.3, poll=True)
target = Parameter(datatype=FloatRange(1.0, 402.0, unit='K'), default=1.3)
tolerance = Parameter('the tolerance', FloatRange(-400, 400), default=1, readonly=False)
pollinterval = Parameter(visibility=3)
channel = Parameter('the Lakeshore channel', datatype=StringType(), export=False)

View File

@ -32,7 +32,7 @@ class Uniax(PersistentMixin, Drivable):
value = Parameter(unit='N')
motor = Attached()
transducer = Attached()
limit = Parameter('abs limit of force', FloatRange(0, 150, unit='N'), readonly=False, default=150)
limit = Parameter('abs limit of force', FloatRange(0, 190, unit='N'), readonly=False, default=150)
tolerance = Parameter('force tolerance', FloatRange(0, 10, unit='N'), readonly=False, default=0.1)
slope = PersistentParam('spring constant', FloatRange(unit='deg/N'), readonly=False,
default=0.5, persistent='auto')
@ -41,7 +41,7 @@ class Uniax(PersistentMixin, Drivable):
current_step = Parameter('', FloatRange(unit='deg'), default=0)
force_offset = PersistentParam('transducer offset', FloatRange(unit='N'), readonly=False, default=0,
initwrite=True, persistent='auto')
hysteresis = PersistentParam('force hysteresis', FloatRange(0, 150, unit='N'), readonly=False, default=5,
hysteresis = PersistentParam('force hysteresis', FloatRange(0, 190, unit='N'), readonly=False, default=5,
persistent='auto')
adjusting = Parameter('', BoolType(), readonly=False, default=False, initwrite=True)
adjusting_current = PersistentParam('current when adjusting force', FloatRange(0, 2.8, unit='A'), readonly=False,
@ -71,19 +71,20 @@ class Uniax(PersistentMixin, Drivable):
_find_target = 0
def earlyInit(self):
super().earlyInit()
self._zero_pos_tol = {}
self._action = self.idle
def drive_relative(self, step, ntry=3):
"""drive relative, try 3 times"""
mot = self._motor
mot = self.motor
mot.read_value() # make sure motor value is fresh
if self.adjusting and abs(step) > self.safe_step:
step = math.copysign(self.safe_step, step)
self.current_step = step
for _ in range(ntry):
try:
self._mot_target = self._motor.write_target(mot.value + step)
self._mot_target = self.motor.write_target(mot.value + step)
self._cnt_wrerr = max(0, self._cnt_wrerr - 1)
return True
except Exception as e:
@ -92,7 +93,7 @@ class Uniax(PersistentMixin, Drivable):
if self._cnt_wrerr > 5:
raise
self.log.warning('motor reset')
self._motor.reset()
self.motor.reset()
return False
def reset_filter(self, now=0.0):
@ -100,7 +101,7 @@ class Uniax(PersistentMixin, Drivable):
self._filter_start = now or time.time()
def motor_busy(self):
mot = self._motor
mot = self.motor
if mot.isBusy():
if mot.target != self._mot_target:
self.action = self.idle
@ -162,12 +163,12 @@ class Uniax(PersistentMixin, Drivable):
if force * sign > self.hysteresis or force * sign > target * sign:
if self.motor_busy():
self.log.info('motor stopped - substantial force detected: %g', force)
self._motor.stop()
self.motor.stop()
elif self.init_action():
self.next_action(self.adjust)
return
if abs(force) > self.hysteresis:
self.set_zero_pos(force, self._motor.read_value())
self.set_zero_pos(force, self.motor.read_value())
self.next_action(self.adjust)
return
if force * sign < -self.hysteresis:
@ -176,7 +177,7 @@ class Uniax(PersistentMixin, Drivable):
return
if self.motor_busy():
if sign * self._find_target < 0: # target sign changed
self._motor.stop()
self.motor.stop()
self.next_action(self.find) # restart find
return
else:
@ -184,26 +185,26 @@ class Uniax(PersistentMixin, Drivable):
zero_pos = self.zero_pos(target)
side_name = 'positive' if target > 0 else 'negative'
if not self.init_action():
if abs(self._motor.target - self._motor.value) > self._motor.tolerance:
if abs(self.motor.target - self.motor.value) > self.motor.tolerance:
# no success on last find try, try short and strong step
self.write_adjusting(True)
self.log.info('one step to %g', self._motor.value + self.safe_step)
self.log.info('one step to %g', self.motor.value + self.safe_step)
self.drive_relative(sign * self.safe_step)
return
if zero_pos is not None:
self.status = 'BUSY', 'change to %s side' % side_name
zero_pos += sign * (self.hysteresis * self.slope - self._motor.tolerance)
if (self._motor.value - zero_pos) * sign < -self._motor.tolerance:
zero_pos += sign * (self.hysteresis * self.slope - self.motor.tolerance)
if (self.motor.value - zero_pos) * sign < -self.motor.tolerance:
self.write_adjusting(False)
self.log.info('change side to %g', zero_pos)
self.drive_relative(zero_pos - self._motor.value)
self.drive_relative(zero_pos - self.motor.value)
return
# we are already at or beyond zero_pos
self.next_action(self.adjust)
return
self.write_adjusting(False)
self.status = 'BUSY', 'find %s side' % side_name
self.log.info('one turn to %g', self._motor.value + sign * 360)
self.log.info('one turn to %g', self.motor.value + sign * 360)
self.drive_relative(sign * 360)
def free(self, force, target):
@ -293,7 +294,7 @@ class Uniax(PersistentMixin, Drivable):
def read_value(self):
try:
force = self._transducer.read_value()
force = self.transducer.read_value()
self._cnt_rderr = max(0, self._cnt_rderr - 1)
except Exception as e:
self._cnt_rderr += 1
@ -323,7 +324,7 @@ class Uniax(PersistentMixin, Drivable):
self.log.error(self.status[1])
return Done
if self.zero_pos(force) is None and abs(force) > self.hysteresis and self._filtered:
self.set_zero_pos(force, self._motor.read_value())
self.set_zero_pos(force, self.motor.read_value())
self._action(self.value, self.target)
return Done
@ -351,18 +352,18 @@ class Uniax(PersistentMixin, Drivable):
@Command()
def stop(self):
self._action = self.idle
if self._motor.isBusy():
if self.motor.isBusy():
self.log.info('stop motor')
self._motor.stop()
self.motor.stop()
self.next_action(self.idle)
def write_force_offset(self, value):
self.force_offset = value
self._transducer.write_offset(value)
self.transducer.write_offset(value)
return Done
def write_adjusting(self, value):
mot = self._motor
mot = self.motor
if value:
mot_current = self.adjusting_current
mot.write_move_limit(self.safe_step)