improve readability be renaming PARAMS,PROPS,CMDS

and others.

Change-Id: Ie37768ed813acdf0cb0707c70ff63397ec8bfbf1
Reviewed-on: https://forge.frm2.tum.de/review/17320
Tested-by: JenkinsCodeReview <bjoern_pedersen@frm2.tum.de>
Reviewed-by: Enrico Faulhaber <enrico.faulhaber@frm2.tum.de>
This commit is contained in:
Enrico Faulhaber
2018-02-14 13:32:19 +01:00
parent aba67dde7f
commit f54e8ccb45
9 changed files with 372 additions and 427 deletions

View File

@ -23,9 +23,8 @@
from math import atan
import time
import random
import threading
from secop.modules import Drivable, CMD, PARAM
from secop.modules import Drivable, Command, Param
from secop.protocol import status
from secop.datatypes import FloatRange, EnumType, TupleOf
from secop.lib import clamp, mkthread
@ -42,90 +41,90 @@ class Cryostat(CryoBase):
- cooling power
- thermal transfer between regulation and samplen
"""
PARAMS = dict(
jitter=PARAM("amount of random noise on readout values",
parameters = dict(
jitter=Param("amount of random noise on readout values",
datatype=FloatRange(0, 1), unit="K",
default=0.1, readonly=False, export=False,
),
T_start=PARAM("starting temperature for simulation",
T_start=Param("starting temperature for simulation",
datatype=FloatRange(0), default=10,
export=False,
),
looptime=PARAM("timestep for simulation",
looptime=Param("timestep for simulation",
datatype=FloatRange(0.01, 10), unit="s", default=1,
readonly=False, export=False,
),
ramp=PARAM("ramping speed of the setpoint",
ramp=Param("ramping speed of the setpoint",
datatype=FloatRange(0, 1e3), unit="K/min", default=1,
readonly=False,
),
setpoint=PARAM("current setpoint during ramping else target",
setpoint=Param("current setpoint during ramping else target",
datatype=FloatRange(), default=1, unit='K',
),
maxpower=PARAM("Maximum heater power",
maxpower=Param("Maximum heater power",
datatype=FloatRange(0), default=1, unit="W",
readonly=False,
group='heater_settings',
),
heater=PARAM("current heater setting",
heater=Param("current heater setting",
datatype=FloatRange(0, 100), default=0, unit="%",
group='heater_settings',
),
heaterpower=PARAM("current heater power",
heaterpower=Param("current heater power",
datatype=FloatRange(0), default=0, unit="W",
group='heater_settings',
),
target=PARAM("target temperature",
target=Param("target temperature",
datatype=FloatRange(0), default=0, unit="K",
readonly=False,
),
value=PARAM("regulation temperature",
value=Param("regulation temperature",
datatype=FloatRange(0), default=0, unit="K",
),
pid=PARAM("regulation coefficients",
pid=Param("regulation coefficients",
datatype=TupleOf(FloatRange(0), FloatRange(0, 100),
FloatRange(0, 100)),
default=(40, 10, 2), readonly=False,
group='pid',
),
p=PARAM("regulation coefficient 'p'",
p=Param("regulation coefficient 'p'",
datatype=FloatRange(0), default=40, unit="%/K", readonly=False,
group='pid',
),
i=PARAM("regulation coefficient 'i'",
i=Param("regulation coefficient 'i'",
datatype=FloatRange(0, 100), default=10, readonly=False,
group='pid',
),
d=PARAM("regulation coefficient 'd'",
d=Param("regulation coefficient 'd'",
datatype=FloatRange(0, 100), default=2, readonly=False,
group='pid',
),
mode=PARAM("mode of regulation",
mode=Param("mode of regulation",
datatype=EnumType('ramp', 'pid', 'openloop'),
default='ramp',
readonly=False,
),
pollinterval=PARAM("polling interval",
pollinterval=Param("polling interval",
datatype=FloatRange(0), default=5,
),
tolerance=PARAM("temperature range for stability checking",
tolerance=Param("temperature range for stability checking",
datatype=FloatRange(0, 100), default=0.1, unit='K',
readonly=False,
group='stability',
),
window=PARAM("time window for stability checking",
window=Param("time window for stability checking",
datatype=FloatRange(1, 900), default=30, unit='s',
readonly=False,
group='stability',
),
timeout=PARAM("max waiting time for stabilisation check",
timeout=Param("max waiting time for stabilisation check",
datatype=FloatRange(1, 36000), default=900, unit='s',
readonly=False,
group='stability',
),
)
CMDS = dict(
stop=CMD(
commands = dict(
stop=Command(
"Stop ramping the setpoint\n\nby setting the current setpoint as new target",
[],
None),
@ -236,7 +235,7 @@ class Cryostat(CryoBase):
lastflow = 0
last_heaters = (0, 0)
delta = 0
I = D = 0
_I = _D = 0
lastD = 0
damper = 1
lastmode = self.mode
@ -283,32 +282,32 @@ class Cryostat(CryoBase):
kp = self.p / 10. # LakeShore P = 10*k_p
ki = kp * abs(self.i) / 500. # LakeShore I = 500/T_i
kd = kp * abs(self.d) / 2. # LakeShore D = 2*T_d
P = kp * error
I += ki * error * h
D = kd * delta / h
_P = kp * error
_I += ki * error * h
_D = kd * delta / h
# avoid reset windup
I = clamp(I, 0., 100.) # I is in %
_I = clamp(_I, 0., 100.) # _I is in %
# avoid jumping heaterpower if switching back to pid mode
if lastmode != self.mode:
# adjust some values upon switching back on
I = self.heater - P - D
_I = self.heater - _P - _D
v = P + I + D
v = _P + _I + _D
# in damping mode, use a weighted sum of old + new heaterpower
if damper > 1:
v = ((damper**2 - 1) * self.heater + v) / damper**2
# damp oscillations due to D switching signs
if D * lastD < -0.2:
if _D * lastD < -0.2:
v = (v + heater) / 2.
# clamp new heater power to 0..100%
heater = clamp(v, 0., 100.)
lastD = D
lastD = _D
self.log.debug('PID: P = %.2f, I = %.2f, D = %.2f, '
'heater = %.2f' % (P, I, D, heater))
'heater = %.2f' % (_P, _I, _D, heater))
# check for turn-around points to detect oscillations ->
# increase damper
@ -351,9 +350,9 @@ class Cryostat(CryoBase):
window.pop(0)
# obtain min/max
deviation = 0
for _, T in window:
if abs(T - self.target) > deviation:
deviation = abs(T - self.target)
for _, _T in window:
if abs(_T - self.target) > deviation:
deviation = abs(_T - self.target)
if (len(window) < 3) or deviation > self.tolerance:
self.status = status.BUSY, 'unstable'
elif self.setpoint == self.target:

View File

@ -24,7 +24,7 @@ import time
import random
import threading
from secop.modules import Readable, Drivable, PARAM
from secop.modules import Readable, Drivable, Param
from secop.datatypes import EnumType, FloatRange, IntRange, ArrayOf, StringType, TupleOf, StructOf, BoolType
from secop.protocol import status
@ -32,19 +32,19 @@ from secop.protocol import status
class Switch(Drivable):
"""switch it on or off....
"""
PARAMS = {
'value': PARAM('current state (on or off)',
parameters = {
'value': Param('current state (on or off)',
datatype=EnumType(on=1, off=0), default=0,
),
'target': PARAM('wanted state (on or off)',
'target': Param('wanted state (on or off)',
datatype=EnumType(on=1, off=0), default=0,
readonly=False,
),
'switch_on_time': PARAM('seconds to wait after activating the switch',
'switch_on_time': Param('seconds to wait after activating the switch',
datatype=FloatRange(0, 60), unit='s',
default=10, export=False,
),
'switch_off_time': PARAM('cool-down time in seconds',
'switch_off_time': Param('cool-down time in seconds',
datatype=FloatRange(0, 60), unit='s',
default=10, export=False,
),
@ -77,7 +77,7 @@ class Switch(Drivable):
return status.BUSY, info
def _update(self):
started = self.PARAMS['target'].timestamp
started = self.parameters['target'].timestamp
info = ''
if self.target > self.value:
info = 'waiting for ON'
@ -97,23 +97,23 @@ class Switch(Drivable):
class MagneticField(Drivable):
"""a liquid magnet
"""
PARAMS = {
'value': PARAM('current field in T',
parameters = {
'value': Param('current field in T',
unit='T', datatype=FloatRange(-15, 15), default=0,
),
'target': PARAM('target field in T',
'target': Param('target field in T',
unit='T', datatype=FloatRange(-15, 15), default=0,
readonly=False,
),
'ramp': PARAM('ramping speed',
'ramp': Param('ramping speed',
unit='T/min', datatype=FloatRange(0, 1), default=0.1,
readonly=False,
),
'mode': PARAM('what to do after changing field',
'mode': Param('what to do after changing field',
default=1, datatype=EnumType(persistent=1, hold=0),
readonly=False,
),
'heatswitch': PARAM('name of heat switch device',
'heatswitch': Param('name of heat switch device',
datatype=StringType(), export=False,
),
}
@ -184,11 +184,11 @@ class MagneticField(Drivable):
class CoilTemp(Readable):
"""a coil temperature
"""
PARAMS = {
'value': PARAM('Coil temperatur',
parameters = {
'value': Param('Coil temperatur',
unit='K', datatype=FloatRange(), default=0,
),
'sensor': PARAM("Sensor number or calibration id",
'sensor': Param("Sensor number or calibration id",
datatype=StringType(), readonly=True,
),
}
@ -200,14 +200,14 @@ class CoilTemp(Readable):
class SampleTemp(Drivable):
"""a sample temperature
"""
PARAMS = {
'value': PARAM('Sample temperature',
parameters = {
'value': Param('Sample temperature',
unit='K', datatype=FloatRange(), default=10,
),
'sensor': PARAM("Sensor number or calibration id",
'sensor': Param("Sensor number or calibration id",
datatype=StringType(), readonly=True,
),
'ramp': PARAM('moving speed in K/min',
'ramp': Param('moving speed in K/min',
datatype=FloatRange(0, 100), unit='K/min', default=0.1,
readonly=False,
),
@ -241,20 +241,23 @@ class SampleTemp(Drivable):
class Label(Readable):
"""
"""Displays the status of a cryomagnet
by composing its (stringtype) value from the status/value
of several subdevices. used for demoing connections between
modules.
"""
PARAMS = {
'system': PARAM("Name of the magnet system",
parameters = {
'system': Param("Name of the magnet system",
datatype=StringType, export=False,
),
'subdev_mf': PARAM("name of subdevice for magnet status",
'subdev_mf': Param("name of subdevice for magnet status",
datatype=StringType, export=False,
),
'subdev_ts': PARAM("name of subdevice for sample temp",
'subdev_ts': Param("name of subdevice for sample temp",
datatype=StringType, export=False,
),
'value': PARAM("final value of label string",
'value': Param("final value of label string",
datatype=StringType,
),
}
@ -265,7 +268,7 @@ class Label(Readable):
dev_ts = self.DISPATCHER.get_module(self.subdev_ts)
if dev_ts:
strings.append('at %.3f %s' %
(dev_ts.read_value(), dev_ts.PARAMS['value'].unit))
(dev_ts.read_value(), dev_ts.parameters['value'].unit))
else:
strings.append('No connection to sample temp!')
@ -274,7 +277,7 @@ class Label(Readable):
mf_stat = dev_mf.read_status()
mf_mode = dev_mf.mode
mf_val = dev_mf.value
mf_unit = dev_mf.PARAMS['value'].unit
mf_unit = dev_mf.parameters['value'].unit
if mf_stat[0] == status.OK:
state = 'Persistent' if mf_mode else 'Non-persistent'
else:
@ -287,21 +290,28 @@ class Label(Readable):
class DatatypesTest(Readable):
"""for demoing all datatypes
"""
"""
PARAMS = {
'enum': PARAM(
parameters = {
'enum': Param(
'enum', datatype=EnumType(
'boo', 'faar', z=9), readonly=False, default=1), 'tupleof': PARAM(
'boo', 'faar', z=9), readonly=False, default=1), 'tupleof': Param(
'tuple of int, float and str', datatype=TupleOf(
IntRange(), FloatRange(), StringType()), readonly=False, default=(
1, 2.3, 'a')), 'arrayof': PARAM(
1, 2.3, 'a')), 'arrayof': Param(
'array: 2..3 times bool', datatype=ArrayOf(
BoolType(), 2, 3), readonly=False, default=[
1, 0, 1]), 'intrange': PARAM(
1, 0, 1]), 'intrange': Param(
'intrange', datatype=IntRange(
2, 9), readonly=False, default=4), 'floatrange': PARAM(
2, 9), readonly=False, default=4), 'floatrange': Param(
'floatrange', datatype=FloatRange(
-1, 1), readonly=False, default=0, ), 'struct': PARAM(
-1, 1), readonly=False, default=0, ), 'struct': Param(
'struct(a=str, b=int, c=bool)', datatype=StructOf(
a=StringType(), b=IntRange(), c=BoolType()), ), }
class ArrayTest(Readable):
parameters = {
"x" : Param('value', datatype=ArrayOf(FloatRange(),100000,100000),
default = 100000 * [0]),
}

View File

@ -22,7 +22,7 @@
import random
from secop.modules import Readable, Drivable, Communicator, PARAM
from secop.modules import Readable, Drivable, Communicator, Param
from secop.datatypes import FloatRange, StringType
@ -43,8 +43,8 @@ class Heater(Drivable):
class name indicates it to be some heating element,
but the implementation may do anything
"""
PARAMS = {
'maxheaterpower': PARAM('maximum allowed heater power',
parameters = {
'maxheaterpower': Param('maximum allowed heater power',
datatype=FloatRange(0, 100), unit='W',
),
}
@ -62,15 +62,15 @@ class Temp(Drivable):
class name indicates it to be some temperature controller,
but the implementation may do anything
"""
PARAMS = {
'sensor': PARAM(
parameters = {
'sensor': Param(
"Sensor number or calibration id",
datatype=StringType(
8,
16),
readonly=True,
),
'target': PARAM(
'target': Param(
"Target temperature",
default=300.0,
datatype=FloatRange(0),