|
| 1 | +@testitem "LinearMPCext extension" setup=[SetupMPCtests] begin |
| 2 | + using .SetupMPCtests, ControlSystemsBase, LinearAlgebra, JuMP, DAQP |
| 3 | + import LinearMPC |
| 4 | + model = LinModel(sys, Ts, i_u=1:2) |
| 5 | + model = setop!(model, uop=[20, 20], yop=[50, 30]) |
| 6 | + optim = JuMP.Model(DAQP.Optimizer) |
| 7 | + mpc1 = LinMPC(model, Hp=15, Hc=[2, 3, 10], optim=optim) |
| 8 | + mpc1 = setconstraint!(mpc1, ymin=[48, -Inf], umax=[Inf, 30]) |
| 9 | + mpc2 = LinearMPC.MPC(mpc1) |
| 10 | + function sim_both(model, mpc1, mpc2, N) |
| 11 | + r = [55.0; 30.0] |
| 12 | + u1 = [20.0, 20.0] |
| 13 | + u2 = [20.0, 20.0] |
| 14 | + model.x0 .= 0 |
| 15 | + y_data = zeros(model.ny, N) |
| 16 | + u_data1, u_data2 = zeros(model.nu, N), zeros(model.nu, N) |
| 17 | + for k in 0:N-1 |
| 18 | + k == 10 && (r .= [45; 30.0]) |
| 19 | + k == 25 && (r .= [50; 45.0]) |
| 20 | + y = model() |
| 21 | + y_data[:, k+1] = y |
| 22 | + preparestate!(mpc1, y) |
| 23 | + x̂ = LinearMPC.correct_state!(mpc2, y) |
| 24 | + u1 = moveinput!(mpc1, r) |
| 25 | + u2 = LinearMPC.compute_control(mpc2, x̂, r=r, uprev=u2) |
| 26 | + u_data1[:, k+1], u_data2[:, k+1] = u1, u2 |
| 27 | + updatestate!(model, u1) |
| 28 | + updatestate!(mpc1, u1, y) |
| 29 | + LinearMPC.predict_state!(mpc2, u2) |
| 30 | + end |
| 31 | + return y_data, u_data1, u_data2 |
| 32 | + end |
| 33 | + N = 50 |
| 34 | + y_data, u_data1, u_data2 = sim_both(model, mpc1, mpc2, N) |
| 35 | + @test u_data1 ≈ u_data2 atol=1e-6 |
| 36 | + |
| 37 | + mpc_ms = LinMPC(model; transcription=MultipleShooting(), optim) |
| 38 | + @test_throws ErrorException LinearMPC.MPC(mpc_ms) |
| 39 | + mpc_kf = LinMPC(KalmanFilter(model, direct=false); optim) |
| 40 | + @test_throws ErrorException LinearMPC.MPC(mpc_kf) |
| 41 | + mpc_osqp = LinMPC(model) |
| 42 | + "LinearMPC relies on DAQP, and the solver in the mpc object " * |
| 43 | + "is currently $(JuMP.solver_name(mpc.optim)).\n" * |
| 44 | + "The results in closed-loop may be different." |
| 45 | + @test_logs( |
| 46 | + (:warn, "LinearMPC relies on DAQP, and the solver in the mpc object is currently "* |
| 47 | + "OSQP.\nThe results in closed-loop may be different."), |
| 48 | + LinearMPC.MPC(mpc_osqp) |
| 49 | + ) |
| 50 | +end |
0 commit comments