Skip to content

Commit 86ce3f6

Browse files
committed
debug Luenburger default poles
1 parent 50a7ab8 commit 86ce3f6

File tree

2 files changed

+145
-31
lines changed

2 files changed

+145
-31
lines changed

src/estimator/luenberger.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ end
5151
i_ym = 1:model.ny,
5252
nint_u = 0,
5353
nint_ym = default_nint(model, i_ym),
54-
p̂ = 1e-3*(0:(model.nx + sum(nint_ym)-1)) .+ 0.5)
54+
p̂ = 1e-3*(1:(model.nx + sum(nint_u) + sum(nint_ym))) .+ 0.5
5555
)
5656
5757
Construct a Luenberger observer with the [`LinModel`](@ref) `model`.
@@ -81,10 +81,10 @@ function Luenberger(
8181
i_ym::IntRangeOrVector = 1:model.ny,
8282
nint_u ::IntVectorOrInt = 0,
8383
nint_ym::IntVectorOrInt = default_nint(model, i_ym, nint_u),
84-
= 1e-3*(0:(model.nx + sum(nint_ym)-1)) .+ 0.5
84+
= 1e-3*(1:(model.nx + sum(nint_u) + sum(nint_ym))) .+ 0.5
8585
)
8686
nx = model.nx
87-
if length(p̂) model.nx + sum(nint_ym)
87+
if length(p̂) model.nx + sum(nint_u) + sum(nint_ym)
8888
error("p̂ length ($(length(p̂))) ≠ nx ($nx) + integrator quantity ($(sum(nint_ym)))")
8989
end
9090
any(abs.(p̂) .≥ 1) && error("Observer poles p̂ should be inside the unit circles.")

test/test_state_estim.jl

Lines changed: 142 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ sys = [ tf(1.90,[18.0,1]) tf(1.90,[18.0,1]) tf(1.90,[18.0,1]);
3838
@test skalmanfilter6.nx̂ == 5
3939
@test skalmanfilter6.nint_ym == [0, 1, 1]
4040

41+
skalmanfilter7 = SteadyKalmanFilter(linmodel1, nint_u=[1,1])
42+
@test skalmanfilter7.nxs == 2
43+
@test skalmanfilter7.nx̂ == 4
44+
@test skalmanfilter7.nint_u == [1, 1]
45+
@test skalmanfilter7.nint_ym == [0, 0]
46+
4147
@test_throws ErrorException SteadyKalmanFilter(linmodel1, nint_ym=[1,1,1])
4248
@test_throws ErrorException SteadyKalmanFilter(linmodel1, nint_ym=[-1,0])
4349
@test_throws ErrorException SteadyKalmanFilter(linmodel1, nint_ym=0, σQ=[1])
@@ -51,7 +57,7 @@ end
5157

5258
@testset "SteadyKalmanFilter estimator methods" begin
5359
linmodel1 = setop!(LinModel(sys,Ts,i_u=[1,2]), uop=[10,50], yop=[50,30])
54-
skalmanfilter1 = SteadyKalmanFilter(linmodel1)
60+
skalmanfilter1 = SteadyKalmanFilter(linmodel1, nint_ym=[1, 1])
5561
@test updatestate!(skalmanfilter1, [10, 50], [50, 30]) zeros(4)
5662
@test updatestate!(skalmanfilter1, [10, 50], [50, 30], Float64[]) zeros(4)
5763
@test skalmanfilter1. zeros(4)
@@ -60,6 +66,23 @@ end
6066
@test initstate!(skalmanfilter1, [10, 50], [50, 30+1]) [zeros(3); [1]]
6167
setstate!(skalmanfilter1, [1,2,3,4])
6268
@test skalmanfilter1. [1,2,3,4]
69+
for i in 1:1000
70+
updatestate!(skalmanfilter1, [11, 52], [50, 30])
71+
end
72+
@test skalmanfilter1() [50, 30] atol=1e-3
73+
for i in 1:1000
74+
updatestate!(skalmanfilter1, [10, 50], [51, 32])
75+
end
76+
@test skalmanfilter1() [51, 32] atol=1e-3
77+
skalmanfilter2 = SteadyKalmanFilter(linmodel1, nint_u=[1, 1])
78+
for i in 1:1000
79+
updatestate!(skalmanfilter2, [11, 52], [50, 30])
80+
end
81+
@test skalmanfilter2() [50, 30] atol=1e-3
82+
for i in 1:1000
83+
updatestate!(skalmanfilter2, [10, 50], [51, 32])
84+
end
85+
@test skalmanfilter2() [51, 32] atol=1e-3
6386
@test_throws ArgumentError updatestate!(skalmanfilter1, [10, 50])
6487
end
6588

@@ -70,6 +93,7 @@ end
7093
@test kalmanfilter1.nyu == 0
7194
@test kalmanfilter1.nxs == 2
7295
@test kalmanfilter1.nx̂ == 4
96+
@test kalmanfilter1.nint_ym == [1, 1]
7397

7498
linmodel2 = LinModel(sys,Ts,i_d=[3])
7599
kalmanfilter2 = KalmanFilter(linmodel2, i_ym=[2])
@@ -95,20 +119,44 @@ end
95119
@test kalmanfilter6. Hermitian(diagm(Float64[1, 4, 9 ,16, 25, 36]))
96120
@test kalmanfilter6.P̂0 !== kalmanfilter6.
97121

122+
kalmanfilter7 = KalmanFilter(linmodel1, nint_u=[1,1])
123+
@test kalmanfilter7.nxs == 2
124+
@test kalmanfilter7.nx̂ == 4
125+
@test kalmanfilter7.nint_u == [1, 1]
126+
@test kalmanfilter7.nint_ym == [0, 0]
127+
98128
@test_throws ErrorException KalmanFilter(linmodel1, nint_ym=0, σP0=[1])
99129
end
100130

101131
@testset "KalmanFilter estimator methods" begin
102132
linmodel1 = setop!(LinModel(sys,Ts,i_u=[1,2]), uop=[10,50], yop=[50,30])
103-
kalmanfilter1 = KalmanFilter(linmodel1)
104-
@test updatestate!(kalmanfilter1, [10, 50], [50, 30]) zeros(4)
105-
@test updatestate!(kalmanfilter1, [10, 50], [50, 30], Float64[]) zeros(4)
106-
@test kalmanfilter1. zeros(4)
107-
@test evaloutput(kalmanfilter1) kalmanfilter1() [50, 30]
108-
@test evaloutput(kalmanfilter1, Float64[]) kalmanfilter1(Float64[]) [50, 30]
109-
@test initstate!(kalmanfilter1, [10, 50], [50, 30+1]) [zeros(3); [1]]
110-
setstate!(kalmanfilter1, [1,2,3,4])
111-
@test kalmanfilter1. [1,2,3,4]
133+
lo1 = KalmanFilter(linmodel1)
134+
@test updatestate!(lo1, [10, 50], [50, 30]) zeros(4)
135+
@test updatestate!(lo1, [10, 50], [50, 30], Float64[]) zeros(4)
136+
@test lo1. zeros(4)
137+
@test evaloutput(lo1) lo1() [50, 30]
138+
@test evaloutput(lo1, Float64[]) lo1(Float64[]) [50, 30]
139+
@test initstate!(lo1, [10, 50], [50, 30+1]) [zeros(3); [1]]
140+
setstate!(lo1, [1,2,3,4])
141+
@test lo1. [1,2,3,4]
142+
for i in 1:1000
143+
updatestate!(lo1, [11, 52], [50, 30])
144+
end
145+
@test lo1() [50, 30] atol=1e-3
146+
for i in 1:1000
147+
updatestate!(lo1, [10, 50], [51, 32])
148+
end
149+
@test lo1() [51, 32] atol=1e-3
150+
kalmanfilter2 = KalmanFilter(linmodel1, nint_u=[1, 1])
151+
for i in 1:1000
152+
updatestate!(kalmanfilter2, [11, 52], [50, 30])
153+
end
154+
@test kalmanfilter2() [50, 30] atol=1e-3
155+
for i in 1:1000
156+
updatestate!(kalmanfilter2, [10, 50], [51, 32])
157+
end
158+
@test kalmanfilter2() [51, 32] atol=1e-3
159+
@test_throws ArgumentError updatestate!(lo1, [10, 50])
112160
end
113161

114162
@testset "Luenberger construction" begin
@@ -134,6 +182,12 @@ end
134182
@test lo4.nxs == 4
135183
@test lo4.nx̂ == 6
136184

185+
lo5 = Luenberger(linmodel1, nint_u=[1,1])
186+
@test lo5.nxs == 2
187+
@test lo5.nx̂ == 4
188+
@test lo5.nint_u == [1, 1]
189+
@test lo5.nint_ym == [0, 0]
190+
137191
@test_throws ErrorException Luenberger(linmodel1, nint_ym=[1,1,1])
138192
@test_throws ErrorException Luenberger(linmodel1, nint_ym=[-1,0])
139193
@test_throws ErrorException Luenberger(linmodel1, p̂=[0.5])
@@ -143,15 +197,31 @@ end
143197

144198
@testset "Luenberger estimator methods" begin
145199
linmodel1 = setop!(LinModel(sys,Ts,i_u=[1,2]), uop=[10,50], yop=[50,30])
146-
lo1 = Luenberger(linmodel1)
147-
@test updatestate!(lo1, [10, 50], [50, 30]) zeros(4)
148-
@test updatestate!(lo1, [10, 50], [50, 30], Float64[]) zeros(4)
149-
@test lo1. zeros(4)
150-
@test evaloutput(lo1) lo1() [50, 30]
151-
@test evaloutput(lo1, Float64[]) lo1(Float64[]) [50, 30]
152-
@test initstate!(lo1, [10, 50], [50, 30+1]) [zeros(3); [1]]
153-
setstate!(lo1, [1,2,3,4])
154-
@test lo1. [1,2,3,4]
200+
ukf1 = Luenberger(linmodel1, nint_ym=[1, 1])
201+
@test updatestate!(ukf1, [10, 50], [50, 30]) zeros(4)
202+
@test updatestate!(ukf1, [10, 50], [50, 30], Float64[]) zeros(4)
203+
@test ukf1. zeros(4)
204+
@test evaloutput(ukf1) ukf1() [50, 30]
205+
@test evaloutput(ukf1, Float64[]) ukf1(Float64[]) [50, 30]
206+
@test initstate!(ukf1, [10, 50], [50, 30+1]) [zeros(3); [1]]
207+
setstate!(ukf1, [1,2,3,4])
208+
@test ukf1. [1,2,3,4]
209+
for i in 1:1000
210+
updatestate!(ukf1, [11, 52], [50, 30])
211+
end
212+
@test ukf1() [50, 30] atol=1e-3
213+
for i in 1:1000
214+
updatestate!(ukf1, [10, 50], [51, 32])
215+
end
216+
@test ukf1() [51, 32] atol=1e-3
217+
lo2 = Luenberger(linmodel1, nint_u=[1, 1])
218+
for i in 1:1000
219+
updatestate!(lo2, [11, 52], [50, 30])
220+
end
221+
@test lo2() [50, 30] atol=1e-3
222+
for i in 1:1000
223+
updatestate!(lo2, [10, 50], [51, 32])
224+
end
155225
end
156226

157227
@testset "InternalModel construction" begin
@@ -274,22 +344,44 @@ end
274344
ukf7 = UnscentedKalmanFilter(nonlinmodel, α=0.1, β=4, κ=0.2)
275345
@test ukf7.γ 0.1*√(ukf7.nx̂+0.2)
276346
@test ukf7.Ŝ[1, 1] 2 - 0.1^2 + 4 - ukf7.nx̂/(ukf7.γ^2)
347+
348+
ukf8 = UnscentedKalmanFilter(nonlinmodel, nint_u=[1, 1], nint_ym=[0, 0])
349+
@test ukf8.nxs == 2
350+
@test ukf8.nx̂ == 6
351+
@test ukf8.nint_u == [1, 1]
352+
@test ukf8.nint_ym == [0, 0]
277353
end
278354

279355
@testset "UnscentedKalmanFilter estimator methods" begin
280356
linmodel1 = LinModel(sys,Ts,i_u=[1,2])
281357
f(x,u,_) = linmodel1.A*x + linmodel1.Bu*u
282358
h(x,_) = linmodel1.C*x
283359
nonlinmodel = setop!(NonLinModel(f, h, Ts, 2, 2, 2), uop=[10,50], yop=[50,30])
284-
ukf1 = UnscentedKalmanFilter(nonlinmodel)
285-
@test updatestate!(ukf1, [10, 50], [50, 30]) zeros(4) atol=1e-9
286-
@test updatestate!(ukf1, [10, 50], [50, 30], Float64[]) zeros(4) atol=1e-9
287-
@test ukf1. zeros(4) atol=1e-9
288-
@test evaloutput(ukf1) ukf1() [50, 30]
289-
@test evaloutput(ukf1, Float64[]) ukf1(Float64[]) [50, 30]
290-
@test initstate!(ukf1, [10, 50], [50, 30+1]) [zeros(3); [1]]
291-
setstate!(ukf1, [1,2,3,4])
292-
@test ukf1. [1,2,3,4]
360+
ekf1 = UnscentedKalmanFilter(nonlinmodel)
361+
@test updatestate!(ekf1, [10, 50], [50, 30]) zeros(4) atol=1e-9
362+
@test updatestate!(ekf1, [10, 50], [50, 30], Float64[]) zeros(4) atol=1e-9
363+
@test ekf1. zeros(4) atol=1e-9
364+
@test evaloutput(ekf1) ekf1() [50, 30]
365+
@test evaloutput(ekf1, Float64[]) ekf1(Float64[]) [50, 30]
366+
@test initstate!(ekf1, [10, 50], [50, 30+1]) [zeros(3); [1]]
367+
setstate!(ekf1, [1,2,3,4])
368+
@test ekf1. [1,2,3,4]
369+
for i in 1:1000
370+
updatestate!(ekf1, [11, 52], [50, 30])
371+
end
372+
@test ekf1() [50, 30] atol=1e-3
373+
for i in 1:1000
374+
updatestate!(ekf1, [10, 50], [51, 32])
375+
end
376+
@test ekf1() [51, 32] atol=1e-3
377+
ukf2 = UnscentedKalmanFilter(linmodel1, nint_u=[1, 1], nint_ym=[0, 0])
378+
for i in 1:1000
379+
updatestate!(ukf2, [11, 52], [50, 30])
380+
end
381+
@test ukf2() [50, 30] atol=1e-3
382+
for i in 1:1000
383+
updatestate!(ukf2, [10, 50], [51, 32])
384+
end
293385
end
294386

295387
@testset "ExtendedKalmanFilter construction" begin
@@ -328,6 +420,12 @@ end
328420
@test ekf6.P̂0 Hermitian(diagm(Float64[1, 4, 9 ,16, 25, 36]))
329421
@test ekf6. Hermitian(diagm(Float64[1, 4, 9 ,16, 25, 36]))
330422
@test ekf6.P̂0 !== ekf6.
423+
424+
ekf7 = ExtendedKalmanFilter(nonlinmodel, nint_u=[1,1], nint_ym=[0,0])
425+
@test ekf7.nxs == 2
426+
@test ekf7.nx̂ == 6
427+
@test ekf7.nint_u == [1, 1]
428+
@test ekf7.nint_ym == [0, 0]
331429
end
332430

333431
@testset "ExtendedKalmanFilter estimator methods" begin
@@ -344,4 +442,20 @@ end
344442
@test initstate!(ekf1, [10, 50], [50, 30+1]) [zeros(3); [1]]
345443
setstate!(ekf1, [1,2,3,4])
346444
@test ekf1. [1,2,3,4]
445+
for i in 1:1000
446+
updatestate!(ekf1, [11, 52], [50, 30])
447+
end
448+
@test ekf1() [50, 30] atol=1e-3
449+
for i in 1:1000
450+
updatestate!(ekf1, [10, 50], [51, 32])
451+
end
452+
@test ekf1() [51, 32] atol=1e-3
453+
ekf2 = ExtendedKalmanFilter(linmodel1, nint_u=[1, 1], nint_ym=[0, 0])
454+
for i in 1:1000
455+
updatestate!(ekf2, [11, 52], [50, 30])
456+
end
457+
@test ekf2() [50, 30] atol=1e-3
458+
for i in 1:1000
459+
updatestate!(ekf2, [10, 50], [51, 32])
460+
end
347461
end

0 commit comments

Comments
 (0)