Skip to content

Commit 6980f69

Browse files
committed
test: NonLinMPC construction with JE and gc keyword argument
1 parent be57e4a commit 6980f69

File tree

2 files changed

+32
-11
lines changed

2 files changed

+32
-11
lines changed

src/controller/nonlinmpc.jl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -406,13 +406,14 @@ should ease troubleshooting of simple bugs e.g.: the user forgets to set the `nc
406406
function test_custom_functions(NT, model::SimModel, JE, gc!, nc, Uop, Yop, Dop, p)
407407
uop, dop, yop = model.uop, model.dop, model.yop
408408
Ue, Ŷe, D̂e = [Uop; uop], [yop; Yop], [dop; Dop]
409-
try
410-
JE(Ue, Ŷe, D̂e, p)
409+
try
410+
val::NT = JE(Ue, Ŷe, D̂e, p)
411411
catch err
412412
@warn(
413413
"""
414414
Calling the JE function with Ue, Ŷe, D̂e arguments fixed at uop=$uop,
415-
yop=$yop, dop=$dop failed with the following stacktrace.
415+
yop=$yop, dop=$dop failed with the following stacktrace. Did you forget
416+
to set the keyword argument p?
416417
""",
417418
exception=(err, catch_backtrace())
418419
)
@@ -425,7 +426,7 @@ function test_custom_functions(NT, model::SimModel, JE, gc!, nc, Uop, Yop, Dop,
425426
"""
426427
Calling the gc function with Ue, Ŷe, D̂e, ϵ arguments fixed at uop=$uop,
427428
yop=$yop, dop=$dop, ϵ=0 failed with the following stacktrace. Did you
428-
forget to set the keyword argument nc?
429+
forget to set the keyword argument p or nc?
429430
""",
430431
exception=(err, catch_backtrace())
431432
)

test/test_predictive_control.jl

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ sys = [ tf(1.90,[1800.0,1]) tf(1.90,[1800.0,1]) tf(1.90,[1800.0,1]);
1818
@test mpc5.Ñ_Hc Diagonal(diagm([repeat(Float64[3, 4], 5); [1e3]]))
1919
mpc6 = LinMPC(model, Lwt=[0,1], Hp=15)
2020
@test mpc6.L_Hp Diagonal(diagm(repeat(Float64[0, 1], 15)))
21-
mpc7 = LinMPC(model, optim=JuMP.Model(DAQP.Optimizer))
21+
mpc7 = @test_logs(
22+
(:warn, "Solving time limit is not supported by the optimizer."),
23+
LinMPC(model, optim=JuMP.Model(DAQP.Optimizer))
24+
)
2225
@test solver_name(mpc7.optim) == "DAQP"
2326
kf = KalmanFilter(model)
2427
mpc8 = LinMPC(kf)
@@ -37,7 +40,12 @@ sys = [ tf(1.90,[1800.0,1]) tf(1.90,[1800.0,1]) tf(1.90,[1800.0,1]);
3740
@test isa(mpc13, LinMPC{Float32})
3841
@test isa(mpc13.optim, JuMP.GenericModel{Float64}) # OSQP does not support Float32
3942

40-
@test_throws ArgumentError LinMPC(model, Hp=0)
43+
@test_logs(
44+
(:warn,
45+
"prediction horizon Hp (0) ≤ estimated number of delays in model (0), the "*
46+
"closed-loop system may be unstable or zero-gain (unresponsive)"),
47+
@test_throws ArgumentError LinMPC(model, Hp=0)
48+
)
4149
@test_throws ArgumentError LinMPC(model, Hc=0)
4250
@test_throws ArgumentError LinMPC(model, Hp=1, Hc=2)
4351
@test_throws ArgumentError LinMPC(model, Mwt=[1])
@@ -134,8 +142,11 @@ end
134142
preparestate!(mpc1, [50, 30])
135143
updatestate!(mpc1, mpc1.estim.model.uop, [50, 30])
136144
@test mpc1.estim.x̂0 [0,0,0,0]
137-
# do not call preparestate! before moveinput! for the warning:
138-
moveinput!(mpc1, [10, 50])
145+
@test_logs(
146+
(:warn, "preparestate! should be called before moveinput! with current estimators"),
147+
(:warn, "preparestate! should be called before evaloutput with current estimators"),
148+
moveinput!(mpc1, [10, 50])
149+
)
139150
@test_throws ArgumentError updatestate!(mpc1, [0,0])
140151
end
141152

@@ -491,9 +502,9 @@ end
491502
@test nmpc5.Ñ_Hc Diagonal(diagm([repeat(Float64[3, 4], 5); [1e3]]))
492503
nmpc6 = NonLinMPC(nonlinmodel, Hp=15, Lwt=[0,1])
493504
@test nmpc6.L_Hp Diagonal(diagm(repeat(Float64[0, 1], 15)))
494-
nmpc7 = NonLinMPC(nonlinmodel, Hp=15, Ewt=1e-3, JE=(Ue,Ŷe,D̂e,p) -> p*Ue.*Ŷe.*D̂e, p=2)
505+
nmpc7 = NonLinMPC(nonlinmodel, Hp=15, Ewt=1e-3, JE=(Ue,Ŷe,D̂e,p) -> p*dot(Ue,Ŷe)+sum(D̂e), p=10)
495506
@test nmpc7.E == 1e-3
496-
@test nmpc7.JE([1,2],[3,4],[4,6],2) == 2*[1,2].*[3,4].*[4,6]
507+
@test nmpc7.JE([1,2],[3,4],[4,6],10) == 10*dot([1,2],[3,4])+sum([4,6])
497508
optim = JuMP.Model(optimizer_with_attributes(Ipopt.Optimizer, "nlp_scaling_max_gradient"=>1.0))
498509
nmpc8 = NonLinMPC(nonlinmodel, Hp=15, optim=optim)
499510
@test solver_name(nmpc8.optim) == "Ipopt"
@@ -513,6 +524,10 @@ end
513524
@test nmpc13.Ñ_Hc Diagonal([0.1,0.11,0.12,0.13])
514525
nmcp14 = NonLinMPC(nonlinmodel, Hp=10, L_Hp=Diagonal(collect(0.001:0.001:0.02)))
515526
@test nmcp14.L_Hp Diagonal(collect(0.001:0.001:0.02))
527+
nmpc15 = NonLinMPC(nonlinmodel, Hp=10, gc=(Ue,Ŷe,D̂e,p,ϵ)-> [p*dot(Ue,Ŷe)+sum(D̂e)+ϵ], nc=1, p=10)
528+
LHS = zeros(1)
529+
nmpc15.con.gc!(LHS,[1,2],[3,4],[4,6],10,0.1)
530+
@test LHS [10*dot([1,2],[3,4])+sum([4,6])+0.1]
516531

517532
nonlinmodel2 = NonLinModel{Float32}(f, h, Ts, 2, 4, 2, 1, solver=nothing)
518533
nmpc15 = NonLinMPC(nonlinmodel2, Hp=15)
@@ -521,7 +536,12 @@ end
521536

522537
@test_throws ArgumentError NonLinMPC(nonlinmodel, Hp=15, Ewt=[1, 1])
523538
@test_throws ArgumentError NonLinMPC(nonlinmodel)
524-
@test_throws ErrorException NonLinMPC(nonlinmodel, Hp=15, JE=(_,_,_)->0.0)
539+
@test_throws ErrorException NonLinMPC(nonlinmodel, Hp=15, JE = (_,_,_)->0.0)
540+
@test_throws ErrorException NonLinMPC(nonlinmodel, Hp=15, gc = (_,_,_,_)->[0.0], nc=1)
541+
@test_throws ErrorException NonLinMPC(nonlinmodel, Hp=15, gc! = (_,_,_,_)->[0.0], nc=1)
542+
543+
@test_logs (:warn, Regex(".*")) NonLinMPC(nonlinmodel, Hp=15, JE=(Ue,_,_,_)->Ue)
544+
@test_logs (:warn, Regex(".*")) NonLinMPC(nonlinmodel, Hp=15, gc=(Ue,_,_,_,_)->Ue, nc=0)
525545
end
526546

527547
@testset "NonLinMPC moves and getinfo" begin

0 commit comments

Comments
 (0)