4444from arx_rls import ArxRls
4545from scipy .optimize import lsq_linear , minimize
4646
47+ class SysIdResult (object ):
48+ def __init__ (self , num , den , dt ):
49+ self .G_ = ctrl .TransferFunction (num , den , dt )
50+
4751class SystemIdentification (object ):
48- def __init__ (self , n = 2 , m = 2 , d = 1 ):
52+ def __init__ (self , n = 2 , m = 2 , d = 1 , dt = 0.0 ):
4953 self .n = n # order of the denominator (a_1,...,a_n)
5054 self .m = m # order of the numerator (b_0,...,b_m)
5155 self .d = d # number of delays
5256 self .forgetting_tc = 60.0 # forgetting factor for weighted RLS in seconds
5357 self .f_hp = 0.5 # high-pass filter cutoff frequency
5458 self .f_lp = 30.0 # low-pass filter cutoff frequency
59+ self .dt = dt
60+
61+ tau = 60.0 # forgetting period
62+ self .lbda = 1.0 - self .dt / tau
5563
56- def run (self , t , u , y ):
57- n_steps = len (t )
58- dt = t [1 ] - t [0 ]
64+ def fit (self , u , y ):
65+ n_steps = len (u )
5966
6067 # High-pass filter parameters
6168 if self .f_hp > 0.0 :
6269 tau_hp = 1 / (2 * np .pi * self .f_hp )
63- alpha_hp = tau_hp / (tau_hp + dt )
70+ alpha_hp = tau_hp / (tau_hp + self . dt )
6471 else :
6572 alpha_hp = 0.0
6673
@@ -71,7 +78,7 @@ def run(self, t, u, y):
7178
7279 # Low-pass filter parameters
7380 tau_lp = 1 / (2 * np .pi * self .f_lp )
74- alpha_lp = tau_lp / (tau_lp + dt )
81+ alpha_lp = tau_lp / (tau_lp + self . dt )
7582 u_lp = np .zeros (n_steps )
7683 y_lp = np .zeros (n_steps )
7784 u_lp [0 ] = u [0 ]
@@ -97,7 +104,7 @@ def run(self, t, u, y):
97104 use_rls = True
98105 if use_rls :
99106 # Identification
100- rls = ArxRls (self .n , self .m , self .d , lbda = (1 - dt / self .forgetting_tc ))
107+ rls = ArxRls (self .n , self .m , self .d , lbda = (1 - self . dt / self .forgetting_tc ))
101108
102109 for k in range (n_steps ):
103110 # Update model
@@ -126,7 +133,7 @@ def run(self, t, u, y):
126133 theta_hat = res .x
127134
128135 # Refine model using output-error optimization
129- J = lambda x : np .sum (np .power (abs (np .array (B )- self .simulateModel (x , u_lp , dt )), 2.0 )) # cost function
136+ J = lambda x : np .sum (np .power (abs (np .array (B )- self .simulateModel (x , u_lp , self . dt )), 2.0 )) # cost function
130137 x0 = np .append (res .x , 0 ) # initial conditions
131138 res = minimize (J , x0 , method = 'nelder-mead' , options = {'disp' : True })
132139 theta_hat = res .x
@@ -138,7 +145,8 @@ def run(self, t, u, y):
138145
139146 self .theta_hat = theta_hat
140147
141- return (theta_hat , a_coeffs , b_coeffs )
148+ estimate = SysIdResult (self .getNum (), self .getDen (), self .dt )
149+ return estimate
142150
143151 def simulateModel (self , x , u , dt ):
144152 a_coeffs = np .ones (self .n + 1 )
0 commit comments