-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathautotune.py
163 lines (131 loc) · 4.35 KB
/
autotune.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#translated from https://github.com/br3ttb/Arduino-PID-AutoTune-Library/blob/master/PID_AutoTune_v0/PID_AutoTune_v0.cpp
import time
class AutoTune(object):
def __init__(value, output):
self.value = value
self.output = output
self.controlType = 0 #default to PI
self.noiseband = 0.25
self.running = False
self.oStep = 30
self.nLookBack = 0
self.sampleTime = 0
SetLookbackSec(10)
self.lastTime = Time.time()
self.lastInputs[0,0]
###?
self.peaks = []
self.peakType = 0
self.peakCount = 0
justChanged = False
self.absMax = 0
self.absMin = 0
self.setpoint = 0
self.outputStart = self.output
def cancel(self):
self.running = False
def runtime(self):
#??
justevaled = False
if peakCount > 9 and self.running:
self.running = False
FinishUp() ######madness
return 1 #??????
now = Time.time()
#not sure about this one either
if (now - self.lastTime) < self.sampleTime:
return false
self.lastTime = now
refval = self.value
justevaled = True
if not self.running:
#init working vars
self.absMax = refval
self.absMin = refval
self.setpoint = refval
running = True
self.outputStart = self.output
self.output = self.outputStart + self.oStep
else:
if refVal > self.absMax:
self.absMax = refVal
if refVal < self.absMin:
self.absMin = refVal
#oscillate the output base on the input's relation to setpoint
if refVal > (setpoint + self.noiseBand):
self.output = outputStart - self.oStep
elif refVal < (setpoint - noiseBand):
self.output = outputStart + self.oStep
#weird spot for this..
isMax = refVal == max(self.lastInputs)
isMin = refVal == min(self.lastInputs)
self.lastInputs.append(refVal)
if len(lastInputs) > self.nLookBack:
self.lastInputs.pop(0)
#such bad
#uh, if lastInputs isn't full then don't do mathsz?
if len(self.lastInputs) < self.nLookBack:
return 0
if (isMax):
if self.peakType==0:
self.peakType = 1
if self.peakType ==-1:
self.peakType = 1
self.justchanged=True
self.peak2 = peak1
self.peak1 = now
self.peaks[self.peakCount] = refVal
elif (isMin):
if self.peakType == 0:
self.peakType = -1
if self.peaktype == 1:
self.peakType = -1
self.peakCount += 1
self.justchanged = True
if self.peakCount < 10:
self.peaks[self.peakCount] = refVal
if self.justchanged and self.peakCount > 2:
#try to tune
avgSeperation = (abs(self.peaks[self.peakCount-1]-self.peaks[self.peakCount-2]
#this doesn't make much sense either
def setLoopbackSec(self,value):
if value < 1:
value = 1
if value < 25:
self.nLookBack = value * 4
self.sampleTime = 250
else:
self.nLookBack = 100
self.sampleTime = value * 10
def getLoopbackSec(self):
return self.nLoopBack * self.sampleTime / 1000
def setNoiseBand(self,band):
self.noiseband = band
def getNoiseBand(self):
return self.noiseband
#why is this a magic number.. 0 = PI, 1 = PID
def setControlType(self,value):
self.controlType = value
def getControlType(self):
return self.controlType
def setOutputStep(self,step):
self.oStep = step
def getOutputStep(self):
return self.oStep
def getKp(self, ku):
if self.controlType == 1:
kp = 0.6 * ku
else:
kp = 0.4 * ku
return kp
def getKi(self,ku,pu):
if self.controlType == 1:
ki = 1.2 * ku / pu
else:
ki = 0.48 * ku / pu
return ki
def getKd(self, ku, pu):
if self.controlType == 1:
kd = 0.075 * ku * pu
else kd = 0
return kd