@@ -112,7 +112,7 @@ struct LinMPC <: PredictiveController
112112 ŷ, Ŷ = copy (model. yop), repeat (model. yop, Hp)
113113 ŷs, Ŷs = zeros (ny), zeros (ny* Hp)
114114 nvar = size (P̃, 1 )
115- optmodel = Model (OSQP. MathOptInterfaceOSQP. Optimizer) # default to OSQP solver
115+ optmodel = Model (OSQP. MathOptInterfaceOSQP. Optimizer, add_bridges = false ) # default to OSQP solver
116116 set_silent (optmodel)
117117 @variable (optmodel, ΔŨ[1 : nvar])
118118 # dummy q̃ value (the vector is updated just before optimization):
@@ -385,6 +385,7 @@ function setconstraint!(
385385end
386386
387387
388+
388389@doc raw """
389390 moveinput!(
390391 mpc::PredictiveController,
@@ -576,9 +577,10 @@ function optim_objective!(mpc::LinMPC, b, q̃, p)
576577 ϵ = isinf (mpc. C) ? nothing : ΔŨ[end ]
577578 J = objective_value (mpc. optim. model) + p # optimal objective value by adding constant p
578579 status = termination_status (mpc. optim. model)
579- status ≠ OPTIMAL && @warn " MPC termination status not optimal ($status )"
580- if any (status .== [INFEASIBLE, DUAL_INFEASIBLE, SLOW_PROGRESS, INVALID_MODEL,
581- INVALID_OPTION, INTERRUPTED, OTHER_ERROR])
580+ if ! (status == OPTIMAL || status == LOCALLY_SOLVED)
581+ @warn " MPC termination status not OPTIMAL or LOCALLY_SOLVER ($status )"
582+ end
583+ if isfatal (status)
582584 # if error, we take last value :
583585 ΔŨ = ΔŨ0
584586 end
588590"""
589591 write_optimdata!(mpc::LinMPC, ΔŨ, ϵ, J, info, ŷs, Ŷs, lastu, F, ym, d)
590592
591- Write `mpc.optim` with the [`LinMPC`](@ref) optimzation results.
593+ Write `mpc.optim` with the [`LinMPC`](@ref) optimization results.
592594"""
593595function write_optimdata! (mpc:: LinMPC , ΔŨ, ϵ, J, ŷs, Ŷs, lastu, F, ym, d)
594596 mpc. optim. ΔŨ = ΔŨ
@@ -956,6 +958,16 @@ function validate_weights(model, Hp, Hc, Mwt, Nwt, Lwt, Cwt, ru)
956958 Cwt < 0 && error (" Cwt weight should be ≥ 0" )
957959end
958960
961+ " Verify that the solver termination status means 'no solution available'."
962+ function isfatal (status:: MOI.TerminationStatusCode )
963+ fatalstatuses = [
964+ INFEASIBLE, DUAL_INFEASIBLE, LOCALLY_INFEASIBLE, INFEASIBLE_OR_UNBOUNDED,
965+ SLOW_PROGRESS, NUMERICAL_ERROR, INVALID_MODEL, INVALID_OPTION, INTERRUPTED,
966+ OTHER_ERROR
967+ ]
968+ return any (status .== fatalstatuses)
969+ end
970+
959971" Generate a block diagonal matrix repeating `n` times the matrix `A`."
960972repeatdiag (A, n:: Int ) = kron (I (n), A)
961973
0 commit comments