numerical.py (3516B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\script\util\numerical.py 2 from carbon.common.script.util import linalg 3 import log 4 from eveprefs import prefs 5 6 class KalmanFilter(object): 7 __slots__ = ['A', 8 'B', 9 'B1', 10 'C', 11 'M', 12 'q'] 13 14 def __init__(self, A, B, B1, C): 15 self.A, self.B, self.B1, self.C = (A, 16 B, 17 B1, 18 C) 19 self.M = linalg.Matrix.I(A.dim[0]) 20 self.q = linalg.Matrix.Ones((A.dim[0], 1)) 21 22 def NextG(self, Rv, Rw): 23 G = self.M * self.C.Trans() / (self.C * self.M * self.C.Trans() + Rv) 24 P = self.M - G * self.C * self.M 25 self.M = self.A * P * self.A.Trans() + self.B1 * Rw * self.B1.Trans() 26 return G 27 28 def StepG(self, y, u, G): 29 if self.B: 30 qbar = self.A * self.q + self.B * u 31 else: 32 qbar = self.A * self.q 33 self.q = qbar + G * (y - self.C * qbar) 34 return self.q 35 36 def Step(self, y, u, Rv, Rw): 37 return self.StepG(y, u, self.NextG(Rv, Rw)) 38 39 40 class KalmanFilterSS(KalmanFilter): 41 __slots__ = ['G'] 42 43 def __init__(self, A, B, B1, C, Rv, Rw, n = 100, f = 0.001): 44 KalmanFilter.__init__(self, A, B, B1, C) 45 self.G = self.SteadyG(Rv, Rw, n) 46 47 def SteadyG(self, Rv, Rw, n = 100, f = 0.001): 48 self.G = self.NextG(Rv, Rw) 49 for i in xrange(n): 50 old = self.G 51 self.G = self.NextG(Rv, Rw) 52 d = old - self.G 53 if abs(d) <= f * abs(self.G): 54 break 55 56 return self.G 57 58 def Step(self, y, u): 59 return self.StepG(y, u, self.G) 60 61 62 import blue 63 64 class FrameClock(object): 65 __slots__ = ['factor', 66 'threshold', 67 'filter', 68 '__t0', 69 'lastTime', 70 'value', 71 'step'] 72 73 def __init__(self): 74 A = linalg.Matrix((2, 2), [1.0, 75 1.0, 76 0.0, 77 1.0]) 78 B = None 79 B1 = linalg.Matrix((2, 1), [1.0, 1.0]) 80 C = linalg.Matrix((1, 2), [1.0, 0.0]) 81 self.factor = prefs.GetValue('frameClockFactor', 100000.0) 82 self.threshold = prefs.GetValue('frameClockThreshold', 1.0) 83 self.threshold = long(self.threshold * 10000000.0) 84 self.filter = KalmanFilterSS(A, B, B1, C, self.factor, 1.0) 85 self.t0 = blue.os.GetWallclockTimeNow() 86 self.lastTime = 0 87 self.step = 0 88 self.filter.q[0] = 0.0 89 self.filter.q[1] = 1.0 / 50 90 91 @property 92 def t0(self): 93 return self.__t0 94 95 @t0.setter 96 def t0(self, value): 97 if not isinstance(value, long): 98 log.LogTraceback('Tried to set t0 to something else than long') 99 value = long(value) 100 self.__t0 = value 101 102 def Rebase(self, t = None): 103 self.t0 = t or blue.os.GetWallclockTimeNow() 104 self.filter.q[0] = 0.0 105 self.lastTime = self.t0 106 107 def Sample(self): 108 rt = blue.os.GetWallclockTimeNow() 109 t = (rt - self.t0) * 1e-07 110 q = self.filter.Step(t, None) 111 self.step += 1 112 t = self.t0 + long(q[0] * 10000000.0) 113 if self.step < 20: 114 t = rt 115 elif rt - t > self.threshold: 116 t = rt 117 self.Rebase(rt) 118 if t < self.lastTime: 119 t = self.lastTime 120 self.lastTime = t 121 self.value = (t, 1.0 / q[1]) 122 return self.value 123 124 def SetFactor(self, factor): 125 self.factor = factor 126 self.filter.SteadyG(self.factor, 1.0) 127 128 def GetFactor(self): 129 return self.factor