diff --git a/Project.toml b/Project.toml index bf0edac7..024b55ed 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ModelPredictiveControl" uuid = "61f9bdb8-6ae4-484a-811f-bbf86720c31c" authors = ["Francis Gagnon"] -version = "1.3.1" +version = "1.3.2" [deps] ControlSystemsBase = "aaaaaaaa-a6ca-5380-bf3e-84a91bcd477e" diff --git a/src/controller/execute.jl b/src/controller/execute.jl index 65aaa821..20537603 100644 --- a/src/controller/execute.jl +++ b/src/controller/execute.jl @@ -585,11 +585,11 @@ Call `savetime!(mpc.estim.model)` and return the time `t`. savetime!(mpc::PredictiveController) = savetime!(mpc.estim.model) """ - periodsleep(mpc::PredictiveController) -> nothing + periodsleep(mpc::PredictiveController, busywait=false) -> nothing Call `periodsleep(mpc.estim.model)`. """ -periodsleep(mpc::PredictiveController) = periodsleep(mpc.estim.model) +periodsleep(mpc::PredictiveController, busywait=false) = periodsleep(mpc.estim.model, busywait) """ setstate!(mpc::PredictiveController, x̂) -> mpc diff --git a/src/estimator/execute.jl b/src/estimator/execute.jl index cd6cc160..e451f520 100644 --- a/src/estimator/execute.jl +++ b/src/estimator/execute.jl @@ -291,11 +291,11 @@ Call `savetime!(estim.model)` and return the time `t`. savetime!(estim::StateEstimator) = savetime!(estim.model) """ - periodsleep(estim::StateEstimator) -> nothing + periodsleep(estim::StateEstimator, busywait=false) -> nothing Call `periodsleep(estim.model)`. """ -periodsleep(estim::StateEstimator) = periodsleep(estim.model) +periodsleep(estim::StateEstimator, busywait=false) = periodsleep(estim.model, busywait) """ diff --git a/test/0_test_module.jl b/test/0_test_module.jl new file mode 100644 index 00000000..134060ac --- /dev/null +++ b/test/0_test_module.jl @@ -0,0 +1,10 @@ +@testmodule SetupMPCtests begin + using ControlSystemsBase + Ts = 400.0 + sys = [ tf(1.90,[1800.0,1]) tf(1.90,[1800.0,1]) tf(1.90,[1800.0,1]); + tf(-0.74,[800.0,1]) tf(0.74,[800.0,1]) tf(-0.74,[800.0,1]) ] + sys_ss = minreal(ss(sys)) + Gss = c2d(sys_ss[:,1:2], Ts, :zoh) + Gss2 = c2d(sys_ss[:,1:2], 0.5Ts, :zoh) + export Ts, sys, sys_ss, Gss, Gss2 +end \ No newline at end of file diff --git a/test/test_sim_model.jl b/test/1_test_sim_model.jl similarity index 95% rename from test/test_sim_model.jl rename to test/1_test_sim_model.jl index 24fc3586..d0f1cd12 100644 --- a/test/test_sim_model.jl +++ b/test/1_test_sim_model.jl @@ -1,4 +1,5 @@ @testitem "LinModel construction" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = LinModel(sys, Ts, i_u=1:2) @test linmodel1.nx == 2 @test linmodel1.nu == 2 @@ -97,6 +98,7 @@ end @testitem "LinModel sim methods" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase linmodel1 = setop!(LinModel(Gss), uop=[10,50], yop=[50,30]) @test updatestate!(linmodel1, [10, 50]) ≈ zeros(2) @test updatestate!(linmodel1, [10, 50], Float64[]) ≈ zeros(2) @@ -117,25 +119,27 @@ end end @testitem "LinModel real time simulations" setup=[SetupMPCtests] begin - linmodel1 = LinModel(tf(2, [10, 1]), 0.1) + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra + linmodel1 = LinModel(tf(2, [10, 1]), 0.25) times1 = zeros(5) for i=1:5 times1[i] = savetime!(linmodel1) updatestate!(linmodel1, [1]) periodsleep(linmodel1) end - @test all(isapprox.(diff(times1[2:end]), 0.1, atol=0.01)) - linmodel2 = LinModel(tf(2, [0.1, 1]), 0.001) + @test all(isapprox.(diff(times1[2:end]), 0.25, atol=0.01)) + linmodel2 = LinModel(tf(2, [0.1, 1]), 0.25) times2 = zeros(5) for i=1:5 times2[i] = savetime!(linmodel2) updatestate!(linmodel2, [1]) periodsleep(linmodel2, true) end - @test all(isapprox.(diff(times2[2:end]), 0.001, atol=0.0001)) + @test all(isapprox.(diff(times2[2:end]), 0.25, atol=0.0001)) end @testitem "NonLinModel construction" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = LinModel(sys,Ts,i_u=[1,2]) f1(x,u,_,model) = model.A*x + model.Bu*u h1(x,_,model) = model.C*x @@ -243,6 +247,7 @@ end end @testitem "NonLinModel sim methods" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = LinModel(sys,Ts,i_u=[1,2]) f1(x,u,_,model) = model.A*x + model.Bu*u h1(x,_,model) = model.C*x @@ -262,6 +267,7 @@ end end @testitem "NonLinModel linearization" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra, ForwardDiff Ts = 1.0 f1(x,u,d,_) = x.^5 + u.^4 + d.^3 h1(x,d,_) = x.^2 + d @@ -317,6 +323,7 @@ end end @testitem "NonLinModel real time simulations" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = LinModel(tf(2, [10, 1]), 0.1) nonlinmodel1 = NonLinModel( (x,u,_,_)->linmodel1.A*x + linmodel1.Bu*u, diff --git a/test/test_state_estim.jl b/test/2_test_state_estim.jl similarity index 96% rename from test/test_state_estim.jl rename to test/2_test_state_estim.jl index c56a2f9e..3d83166f 100644 --- a/test/test_state_estim.jl +++ b/test/2_test_state_estim.jl @@ -1,4 +1,5 @@ @testitem "SteadyKalmanFilter construction" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = LinModel(sys,Ts,i_u=[1,2]) skalmanfilter1 = SteadyKalmanFilter(linmodel1) @test skalmanfilter1.nym == 2 @@ -61,6 +62,7 @@ end @testitem "SteadyKalmanFilter estimator methods" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = setop!(LinModel(sys,Ts,i_u=[1,2]), uop=[10,50], yop=[50,30]) skalmanfilter1 = SteadyKalmanFilter(linmodel1, nint_ym=[1, 1]) preparestate!(skalmanfilter1, [50, 30]) @@ -112,6 +114,7 @@ end end @testitem "SteadyKalmanFilter set model" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel = LinModel(ss(0.5, 0.3, 1.0, 0, 10.0)) linmodel = setop!(linmodel, uop=[2.0], yop=[50.0], xop=[3.0], fop=[3.0]) skalmanfilter = SteadyKalmanFilter(linmodel, nint_ym=0) @@ -122,19 +125,21 @@ end end @testitem "SteadyKalmanFilter real-time simulations" setup=[SetupMPCtests] begin - linmodel1 = LinModel(tf(2, [10, 1]), 0.1) + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra + linmodel1 = LinModel(tf(2, [10, 1]), 0.25) skalmanfilter1 = SteadyKalmanFilter(linmodel1) times1 = zeros(5) for i=1:5 times1[i] = savetime!(skalmanfilter1) preparestate!(skalmanfilter1, [1]) updatestate!(skalmanfilter1, [1], [1]) - periodsleep(skalmanfilter1) + periodsleep(skalmanfilter1, true) end - @test all(isapprox.(diff(times1[2:end]), 0.1, atol=0.01)) + @test all(isapprox.(diff(times1[2:end]), 0.25, atol=0.01)) end @testitem "KalmanFilter construction" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = setop!(LinModel(sys,Ts,i_u=[1,2]), uop=[10,50], yop=[50,30]) kalmanfilter1 = KalmanFilter(linmodel1) @test kalmanfilter1.nym == 2 @@ -186,6 +191,7 @@ end end @testitem "KalmanFilter estimator methods" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = setop!(LinModel(sys,Ts,i_u=[1,2]), uop=[10,50], yop=[50,30]) kalmanfilter1 = KalmanFilter(linmodel1) preparestate!(kalmanfilter1, [50, 30]) @@ -232,6 +238,7 @@ end end @testitem "KalmanFilter set model" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel = LinModel(ss(0.5, 0.3, 1.0, 0, 10.0)) linmodel = setop!(linmodel, uop=[2.0], yop=[50.0], xop=[3.0], fop=[3.0]) kalmanfilter = KalmanFilter(linmodel, nint_ym=0) @@ -260,6 +267,7 @@ end end @testitem "Luenberger construction" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = LinModel(sys,Ts,i_u=[1,2]) lo1 = Luenberger(linmodel1) @test lo1.nym == 2 @@ -300,6 +308,7 @@ end end @testitem "Luenberger estimator methods" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = setop!(LinModel(sys,Ts,i_u=[1,2]), uop=[10,50], yop=[50,30]) lo1 = Luenberger(linmodel1, nint_ym=[1, 1]) preparestate!(lo1, [50, 30]) @@ -345,6 +354,7 @@ end end @testitem "Luenberger set model" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel = LinModel(ss(0.5, 0.3, 1.0, 0, 10.0)) linmodel = setop!(linmodel, uop=[2.0], yop=[50.0], xop=[3.0], fop=[3.0]) lo = Luenberger(linmodel, nint_ym=0) @@ -353,6 +363,7 @@ end end @testitem "InternalModel construction" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = LinModel(sys,Ts,i_u=[1,2]) internalmodel1 = InternalModel(linmodel1) @test internalmodel1.nym == 2 @@ -422,6 +433,7 @@ end end @testitem "InternalModel estimator methods" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = setop!(LinModel(sys,Ts,i_u=[1,2]) , uop=[10,50], yop=[50,30]) internalmodel1 = InternalModel(linmodel1) preparestate!(internalmodel1, [50, 30] .+ 1) @@ -459,6 +471,7 @@ end end @testitem "InternalModel set model" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel = LinModel(ss(0.5, 0.3, 1.0, 0, 10.0)) linmodel = setop!(linmodel, uop=[2.0], yop=[50.0], xop=[3.0], fop=[3.0]) internalmodel = InternalModel(linmodel) @@ -484,6 +497,7 @@ end end @testitem "UnscentedKalmanFilter construction" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = LinModel(sys,Ts,i_d=[3]) f(x,u,d,_) = linmodel1.A*x + linmodel1.Bu*u + linmodel1.Bd*d h(x,d,_) = linmodel1.C*x + linmodel1.Du*d @@ -541,6 +555,7 @@ end end @testitem "UnscentedKalmanFilter estimator methods" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = LinModel(sys,Ts,i_u=[1,2]) f(x,u,_,_) = linmodel1.A*x + linmodel1.Bu*u h(x,_,_) = linmodel1.C*x @@ -589,6 +604,7 @@ end end @testitem "UnscentedKalmanFilter set model" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel = LinModel(ss(0.5, 0.3, 1.0, 0, 10.0)) linmodel = setop!(linmodel, uop=[2.0], yop=[50.0], xop=[3.0], fop=[3.0]) ukf1 = UnscentedKalmanFilter(linmodel, nint_ym=0) @@ -625,6 +641,7 @@ end end @testitem "ExtendedKalmanFilter construction" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = LinModel(sys,Ts,i_d=[3]) f(x,u,d,_) = linmodel1.A*x + linmodel1.Bu*u + linmodel1.Bd*d h(x,d,_) = linmodel1.C*x + linmodel1.Du*d @@ -678,6 +695,7 @@ end end @testitem "ExtendedKalmanFilter estimator methods" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = LinModel(sys,Ts,i_u=[1,2]) f(x,u,_,_) = linmodel1.A*x + linmodel1.Bu*u h(x,_,_) = linmodel1.C*x @@ -726,6 +744,7 @@ end end @testitem "ExtendedKalmanFilter set model" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel = LinModel(ss(0.5, 0.3, 1.0, 0, 10.0)) linmodel = setop!(linmodel, uop=[2.0], yop=[50.0], xop=[3.0], fop=[3.0]) ekf1 = ExtendedKalmanFilter(linmodel, nint_ym=0) @@ -762,6 +781,7 @@ end end @testitem "MovingHorizonEstimator construction" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra, JuMP, Ipopt linmodel1 = LinModel(sys,Ts,i_d=[3]) f(x,u,d,_) = linmodel1.A*x + linmodel1.Bu*u + linmodel1.Bd*d h(x,d,_) = linmodel1.C*x + linmodel1.Du*d @@ -843,6 +863,7 @@ end end @testitem "MovingHorizonEstimator estimation and getinfo" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra, JuMP, Ipopt, ForwardDiff linmodel1 = setop!(LinModel(sys,Ts,i_u=[1,2], i_d=[3]), uop=[10,50], yop=[50,30], dop=[5]) f(x,u,d,_) = linmodel1.A*x + linmodel1.Bu*u + linmodel1.Bd*d h(x,d,_) = linmodel1.C*x + linmodel1.Dd*d @@ -935,12 +956,12 @@ end preparestate!(mhe2, [50, 30], [5]) updatestate!(mhe2, [11, 52], [50, 30], [5]) end - @test mhe2([5]) ≈ [50, 30] atol=1e-3 + @test mhe2([5]) ≈ [50, 30] atol=1e-2 for i in 1:40 preparestate!(mhe2, [51, 32], [5]) updatestate!(mhe2, [10, 50], [51, 32], [5]) end - @test mhe2([5]) ≈ [51, 32] atol=1e-3 + @test mhe2([5]) ≈ [51, 32] atol=1e-2 linmodel3 = LinModel{Float32}(0.5*ones(1,1), ones(1,1), ones(1,1), zeros(1,0), zeros(1,0), 1.0) mhe3 = MovingHorizonEstimator(linmodel3, He=1) preparestate!(mhe3, [0]) @@ -973,6 +994,7 @@ end end @testitem "MovingHorizonEstimator fallbacks for arrival covariance estimation" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel = setop!(LinModel(sys,Ts,i_u=[1,2], i_d=[3]), uop=[10,50], yop=[50,30], dop=[5]) f(x,u,d,_) = linmodel.A*x + linmodel.Bu*u + linmodel.Bd*d h(x,d,_) = linmodel.C*x + linmodel.Dd*d @@ -1017,6 +1039,7 @@ end end @testitem "MovingHorizonEstimator set constraints" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = setop!(LinModel(sys,Ts,i_u=[1,2]), uop=[10,50], yop=[50,30]) mhe1 = MovingHorizonEstimator(linmodel1, He=1, nint_ym=0, Cwt=1e3) setconstraint!(mhe1, x̂min=[-51,-52], x̂max=[53,54]) @@ -1098,6 +1121,7 @@ end end @testitem "MovingHorizonEstimator constraint violation" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = setop!(LinModel(sys,Ts,i_u=[1,2]), uop=[10,50], yop=[50,30]) mhe = MovingHorizonEstimator(linmodel1, He=1, nint_ym=0) @@ -1196,6 +1220,7 @@ end end @testitem "MovingHorizonEstimator set model" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel = LinModel(ss(0.5, 0.3, 1.0, 0, 10.0)) linmodel = setop!(linmodel, uop=[2.0], yop=[50.0], xop=[3.0], fop=[3.0]) mhe = MovingHorizonEstimator(linmodel, He=1, nint_ym=0, direct=false) @@ -1240,6 +1265,7 @@ end end @testitem "MovingHorizonEstimator v.s. Kalman filters" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = setop!(LinModel(sys,Ts,i_d=[3]), uop=[10,50], yop=[50,30], dop=[20]) mhe = MovingHorizonEstimator(linmodel1, He=3, nint_ym=0, direct=false) kf = KalmanFilter(linmodel1, nint_ym=0, direct=false) @@ -1316,6 +1342,7 @@ end end @testitem "MovingHorizonEstimator LinModel v.s. NonLinModel" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra, JuMP, Ipopt linmodel = setop!(LinModel(sys,Ts,i_d=[3]), uop=[10,50], yop=[50,30], dop=[20]) f = (x,u,d,_) -> linmodel.A*x + linmodel.Bu*u + linmodel.Bd*d h = (x,d,_) -> linmodel.C*x + linmodel.Dd*d diff --git a/test/test_predictive_control.jl b/test/3_test_predictive_control.jl similarity index 95% rename from test/test_predictive_control.jl rename to test/3_test_predictive_control.jl index ed6145aa..89047f71 100644 --- a/test/test_predictive_control.jl +++ b/test/3_test_predictive_control.jl @@ -1,4 +1,5 @@ @testitem "LinMPC construction" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra, JuMP, DAQP model = LinModel(sys, Ts, i_d=[3]) mpc1 = LinMPC(model, Hp=15) @test isa(mpc1.estim, SteadyKalmanFilter) @@ -55,6 +56,8 @@ end @testitem "LinMPC moves and getinfo" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel = setop!(LinModel(tf(5, [2, 1]), 3), yop=[10]) mpc1 = LinMPC(linmodel, Nwt=[0], Hp=1000, Hc=1) r = [15] @@ -88,6 +91,7 @@ end end @testitem "LinMPC step disturbance rejection" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel = setop!(LinModel(tf(5, [2, 1]), 3.0), yop=[10]) r = [15] outdist = [5] @@ -130,6 +134,7 @@ end end @testitem "LinMPC other methods" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = setop!(LinModel(sys,Ts,i_u=[1,2]), uop=[10,50], yop=[50,30]) mpc1 = LinMPC(linmodel1) @test initstate!(mpc1, [10, 50], [50, 30+1]) ≈ [zeros(3); [1]] @@ -148,6 +153,7 @@ end end @testitem "LinMPC set constraints" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra model = LinModel(sys, Ts, i_d=[3]) mpc = LinMPC(model, Hp=1, Hc=1) @@ -215,6 +221,7 @@ end end @testitem "LinMPC constraint violation" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra model = LinModel(tf([2], [10, 1]), 3.0) mpc = LinMPC(model, Hp=50, Hc=5) @@ -273,6 +280,7 @@ end end @testitem "LinMPC terminal cost" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra model = LinModel(ss([0.5 -0.4;0.6 0.5], [1 0;0 1], [1 0; 0 1], 0, 1)) K = lqr(Discrete, model.A, model.Bu, I, 0.5I) M_end = ControlSystemsBase.are(Discrete, model.A, model.Bu, I, 0.5I) @@ -300,6 +308,7 @@ end end @testitem "LinMPC set model" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra estim = KalmanFilter(setop!(LinModel(tf(5, [2, 1]), 3), yop=[10], uop=[1])) mpc = LinMPC(estim, Nwt=[0], Cwt=1e4, Hp=1000, Hc=1) mpc = setconstraint!(mpc, umin=[-24], umax=[26]) @@ -339,6 +348,7 @@ end end @testitem "LinMPC real-time simulations" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = LinModel(tf(2, [10, 1]), 0.1) mpc1 = LinMPC(linmodel1) times1 = zeros(5) @@ -346,12 +356,13 @@ end times1[i] = savetime!(mpc1) preparestate!(mpc1, [1]) updatestate!(mpc1, [1], [1]) - periodsleep(mpc1) + periodsleep(mpc1, true) end @test all(isapprox.(diff(times1[2:end]), 0.1, atol=0.01)) end @testitem "ExplicitMPC construction" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra model = LinModel(sys, Ts, i_d=[3]) mpc1 = ExplicitMPC(model, Hp=15) @test isa(mpc1.estim, SteadyKalmanFilter) @@ -382,6 +393,7 @@ end end @testitem "ExplicitMPC moves and getinfo" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra mpc1 = ExplicitMPC(LinModel(tf(5, [2, 1]), 3), Nwt=[0], Hp=1000, Hc=1) r = [5] preparestate!(mpc1, [0]) @@ -409,6 +421,7 @@ end @testitem "ExplicitMPC step disturbance rejection" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel = setop!(LinModel(tf(5, [2, 1]), 3.0), yop=[10]) r = [15] outdist = [5] @@ -451,6 +464,7 @@ end end @testitem "ExplicitMPC other methods" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = setop!(LinModel(sys,Ts,i_u=[1,2]), uop=[10,50], yop=[50,30]) mpc1 = ExplicitMPC(linmodel1) @test initstate!(mpc1, [10, 50], [50, 30+1]) ≈ [zeros(3); [1]] @@ -465,12 +479,14 @@ end end @testitem "ExplicitMPC constraints" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra model = LinModel(sys, Ts, i_d=[3]) mpc = ExplicitMPC(model, Hp=1, Hc=1) @test_throws ErrorException setconstraint!(mpc, umin=[0.0, 0.0]) end @testitem "ExplicitMPC set model" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra estim = KalmanFilter(setop!(LinModel(tf(5, [2, 1]), 3), yop=[10], uop=[1])) mpc = ExplicitMPC(estim, Nwt=[0], Hp=1000, Hc=1) @test mpc.Yop ≈ fill(10.0, 1000) @@ -500,6 +516,7 @@ end end @testitem "NonLinMPC construction" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra, JuMP, Ipopt linmodel1 = LinModel(sys,Ts,i_d=[3]) nmpc0 = NonLinMPC(linmodel1, Hp=15) @test isa(nmpc0.estim, SteadyKalmanFilter) @@ -563,6 +580,7 @@ end end @testitem "NonLinMPC moves and getinfo" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra, ForwardDiff linmodel = setop!(LinModel(tf(5, [2000, 1]), 3000.0), yop=[10]) Hp = 1000 nmpc_lin = NonLinMPC(linmodel, Nwt=[0], Hp=Hp, Hc=1) @@ -635,6 +653,7 @@ end end @testitem "NonLinMPC step disturbance rejection" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel = setop!(LinModel(tf(5, [2000, 1]), 3000.0), yop=[10]) r = [15] outdist = [5] @@ -677,6 +696,7 @@ end end @testitem "NonLinMPC other methods" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel = setop!(LinModel(sys,Ts,i_u=[1,2]), uop=[10,50], yop=[50,30]) f = (x,u,_,_) -> linmodel.A*x + linmodel.Bu*u h = (x,_,_) -> linmodel.C*x @@ -694,6 +714,7 @@ end end @testitem "NonLinMPC set constraints" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra linmodel1 = LinModel(sys,Ts,i_d=[3]) nmpc_lin = NonLinMPC(linmodel1, Hp=1, Hc=1) @@ -729,6 +750,7 @@ end end @testitem "NonLinMPC constraint violation" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra gc(Ue, Ŷe, _ ,p , ϵ) = [p[1]*(Ue[1:end-1] .- 4.2 .- ϵ); p[2]*(Ŷe[2:end] .- 3.14 .- ϵ)] Hp=50 @@ -737,7 +759,7 @@ end setconstraint!(nmpc_lin, x̂min=[-1e6,-Inf], x̂max=[1e6,+Inf]) setconstraint!(nmpc_lin, umin=[-10], umax=[10]) - setconstraint!(nmpc_lin, Δumin=[-15], Δumax=[15]) + setconstraint!(nmpc_lin, Δumin=[-1e6], Δumax=[1e6]) setconstraint!(nmpc_lin, ymin=[-100], ymax=[100]) preparestate!(nmpc_lin, [0]) @@ -805,8 +827,8 @@ end nonlinmodel = NonLinModel(f, h, linmodel.Ts, 1, 1, 1, solver=nothing, p=linmodel) nmpc = NonLinMPC(nonlinmodel, Hp=50, Hc=5, gc=gc, nc=2Hp, p=[0; 0]) - setconstraint!(nmpc, x̂min=[-1e6,-Inf], x̂max=[1e6,+Inf]) - setconstraint!(nmpc, umin=[-10], umax=[10]) + setconstraint!(nmpc, x̂min=[-1e6,-Inf], x̂max=[+1e6,+Inf]) + setconstraint!(nmpc, umin=[-1e6], umax=[+1e6]) setconstraint!(nmpc, Δumin=[-15], Δumax=[15]) setconstraint!(nmpc, ymin=[-100], ymax=[100]) preparestate!(nmpc, [0]) @@ -818,7 +840,7 @@ end moveinput!(nmpc, [100]) info = getinfo(nmpc) @test all(isapprox.(info[:U], 4; atol=1e-1)) - setconstraint!(nmpc, umin=[-10], umax=[10]) + setconstraint!(nmpc, umin=[-1e6], umax=[+1e6]) setconstraint!(nmpc, Δumin=[-1.5], Δumax=[1.25]) moveinput!(nmpc, [-100]) @@ -827,7 +849,7 @@ end moveinput!(nmpc, [100]) info = getinfo(nmpc) @test all(isapprox.(info[:ΔU], 1.25; atol=1e-1)) - setconstraint!(nmpc, Δumin=[-15], Δumax=[15]) + setconstraint!(nmpc, Δumin=[-1e6], Δumax=[+1e6]) setconstraint!(nmpc, ymin=[-0.5], ymax=[0.9]) moveinput!(nmpc, [-100]) @@ -839,13 +861,13 @@ end setconstraint!(nmpc, ymin=[-100], ymax=[100]) setconstraint!(nmpc, Ymin=[-0.5; fill(-100, Hp-1)], Ymax=[0.9; fill(+100, Hp-1)]) - moveinput!(nmpc, [-10]) + moveinput!(nmpc, [-200]) info = getinfo(nmpc) - @test info[:Ŷ][end] ≈ -10 atol=1e-1 + @test info[:Ŷ][end] ≈ -100 atol=1e-1 @test info[:Ŷ][begin] ≈ -0.5 atol=1e-1 - moveinput!(nmpc, [10]) + moveinput!(nmpc, [200]) info = getinfo(nmpc) - @test info[:Ŷ][end] ≈ 10 atol=1e-1 + @test info[:Ŷ][end] ≈ 100 atol=1e-1 @test info[:Ŷ][begin] ≈ 0.9 atol=1e-1 setconstraint!(nmpc, ymin=[-100], ymax=[100]) @@ -873,6 +895,7 @@ end end @testitem "NonLinMPC set model" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra estim = KalmanFilter(setop!(LinModel(tf(5, [200, 1]), 300), yop=[10], uop=[1])) mpc = NonLinMPC(estim, Nwt=[0], Cwt=1e4, Hp=1000, Hc=1) mpc = setconstraint!(mpc, umin=[-24], umax=[26]) @@ -925,6 +948,7 @@ end end @testitem "LinMPC v.s. NonLinMPC" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra, JuMP, Ipopt linmodel = setop!(LinModel(sys,Ts,i_d=[3]), uop=[10,50], yop=[50,30], dop=[20]) f = (x,u,d,_) -> linmodel.A*x + linmodel.Bu*u + linmodel.Bd*d h = (x,d,_) -> linmodel.C*x + linmodel.Dd*d diff --git a/test/test_plot_sim.jl b/test/4_test_plot_sim.jl similarity index 96% rename from test/test_plot_sim.jl rename to test/4_test_plot_sim.jl index dac5e971..93427ed0 100644 --- a/test/test_plot_sim.jl +++ b/test/4_test_plot_sim.jl @@ -1,4 +1,5 @@ @testitem "SimModel quick simulation" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra model = LinModel(sys, Ts, i_d=[3]) res = sim!(model, 15) display(res) @@ -18,6 +19,7 @@ end @testitem "SimModel Plots" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra, Plots model = LinModel(sys, Ts, i_d=[3]) res = sim!(model, 15, [1, 3], [-10]) p = plot(res, plotx=true) @@ -42,6 +44,7 @@ end end @testitem "StateEstimator quick simulation" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra estim = SteadyKalmanFilter(LinModel(sys, Ts, i_d=[3])) res = sim!(estim, 15) @test isa(res.obj, SteadyKalmanFilter) @@ -64,6 +67,7 @@ end end @testitem "StateEstimator Plots" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra, Plots estim = MovingHorizonEstimator(LinModel(sys, Ts, i_d=[3]), He=5) estim = setconstraint!(estim, x̂min=[-100,-101,-102,-103,-Inf,-Inf]) estim = setconstraint!(estim, x̂max=[+100,+101,+102,+103,+Inf,+Inf]) @@ -121,6 +125,7 @@ end end @testitem "PredictiveController quick simulation" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra mpc1 = LinMPC(LinModel(sys, Ts, i_d=[3])) res = sim!(mpc1, 15) @test isa(res.obj, LinMPC) @@ -155,6 +160,7 @@ end end @testitem "PredictiveController Plots" setup=[SetupMPCtests] begin + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra, Plots estim = MovingHorizonEstimator(LinModel(sys, Ts, i_d=[3]), He=5) estim = setconstraint!(estim, x̂min=[-100,-101,-102,-103,-104,-105]) estim = setconstraint!(estim, x̂max=[+100,+101,+102,+103,+104,+105]) diff --git a/test/runtests.jl b/test/runtests.jl index c2efcd98..8b7ecf40 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -11,26 +11,11 @@ using Test, TestItemRunner @run_package_tests -#@testitem "ModelPredictiveControl.jl" begin - -@testsnippet SetupMPCtests begin - using ControlSystemsBase, LinearAlgebra - using Random: randn - using JuMP, OSQP, Ipopt, DAQP, ForwardDiff - using Plots - Ts = 400.0 - sys = [ tf(1.90,[1800.0,1]) tf(1.90,[1800.0,1]) tf(1.90,[1800.0,1]); - tf(-0.74,[800.0,1]) tf(0.74,[800.0,1]) tf(-0.74,[800.0,1]) ] - sys_ss = minreal(ss(sys)) - Gss = c2d(sys_ss[:,1:2], Ts, :zoh) - Gss2 = c2d(sys_ss[:,1:2], 0.5Ts, :zoh) -end - - -include("test_sim_model.jl") -include("test_state_estim.jl") -include("test_predictive_control.jl") -include("test_plot_sim.jl") +include("0_test_module.jl") +include("1_test_sim_model.jl") +include("2_test_state_estim.jl") +include("3_test_predictive_control.jl") +include("4_test_plot_sim.jl") old_debug_level = get(ENV, "JULIA_DEBUG", "") DocMeta.setdocmeta!( @@ -46,6 +31,4 @@ DocMeta.setdocmeta!( doctest(ModelPredictiveControl, testset="DocTest") ENV["JULIA_DEBUG"] = old_debug_level -#end; - nothing \ No newline at end of file