diff --git a/docs/src/manual/linmpc.md b/docs/src/manual/linmpc.md index 69edb189b..8d11aa9fa 100644 --- a/docs/src/manual/linmpc.md +++ b/docs/src/manual/linmpc.md @@ -78,8 +78,9 @@ mpc = setconstraint!(mpc, ymin=[48, -Inf]) in which `Hp` and `Hc` keyword arguments are respectively the predictive and control horizons, and `Mwt` and `Nwt`, the output setpoint tracking and move suppression weights. By -default, [`LinMPC`](@ref) controllers use [`OSQP`](https://osqp.org/) to solve the problem, -soft constraints on output predictions ``\mathbf{ŷ}`` to ensure feasibility, and a +default, [`LinMPC`](@ref) controllers use [`OSQP`](https://osqp.org/) and a direct +[`SingleShooting`](@ref) transcription method to solve the optimal control problem, soft +constraints on output predictions ``\mathbf{ŷ}`` to ensure feasibility, and a [`SteadyKalmanFilter`](@ref) to estimate the plant states[^1]. An attentive reader will also notice that the Kalman filter estimates two additional states compared to the plant model. These are the integrating states for the unmeasured plant disturbances, and they are diff --git a/docs/src/manual/nonlinmpc.md b/docs/src/manual/nonlinmpc.md index 1c5032b3b..8f8f8102f 100644 --- a/docs/src/manual/nonlinmpc.md +++ b/docs/src/manual/nonlinmpc.md @@ -119,8 +119,10 @@ umin, umax = [-1.5], [+1.5] nmpc = setconstraint!(nmpc; umin, umax) ``` -The option `Cwt=Inf` disables the slack variable `ϵ` for constraint softening. We test `mpc` -performance on `plant` by imposing an angular setpoint of 180° (inverted position): +The option `Cwt=Inf` disables the slack variable `ϵ` for constraint softening. By default, +[`NonLinMPC`](@ref) controllers use [`Ipopt`](https://coin-or.github.io/Ipopt/) and a direct +[`SingleShooting`](@ref) transcription method to solve the optimal control problem. We test +`mpc` performance on `plant` by imposing an angular setpoint of 180° (inverted position): ```@example man_nonlin using JuMP; unset_time_limit_sec(nmpc.optim) # hide diff --git a/src/controller/construct.jl b/src/controller/construct.jl index 711cb3040..012ad5954 100644 --- a/src/controller/construct.jl +++ b/src/controller/construct.jl @@ -221,7 +221,7 @@ constraints are all soft by default. See Extended Help for time-varying constrai julia> mpc = LinMPC(setop!(LinModel(tf(3, [30, 1]), 4), uop=[50], yop=[25])); julia> mpc = setconstraint!(mpc, umin=[0], umax=[100], Δumin=[-10], Δumax=[+10]) -LinMPC controller with a sample time Ts = 4.0 s, OSQP optimizer, SteadyKalmanFilter estimator and: +LinMPC controller with a sample time Ts = 4.0 s, OSQP optimizer, SingleShooting transcription, SteadyKalmanFilter estimator and: 10 prediction steps Hp 2 control steps Hc 1 slack variable ϵ (control constraints) diff --git a/src/controller/linmpc.jl b/src/controller/linmpc.jl index edc906d0a..3b1fc1c95 100644 --- a/src/controller/linmpc.jl +++ b/src/controller/linmpc.jl @@ -167,7 +167,7 @@ arguments. This controller allocates memory at each time step for the optimizati julia> model = LinModel([tf(3, [30, 1]); tf(-2, [5, 1])], 4); julia> mpc = LinMPC(model, Mwt=[0, 1], Nwt=[0.5], Hp=30, Hc=1) -LinMPC controller with a sample time Ts = 4.0 s, OSQP optimizer, SteadyKalmanFilter estimator and: +LinMPC controller with a sample time Ts = 4.0 s, OSQP optimizer, SingleShooting transcription, SteadyKalmanFilter estimator and: 30 prediction steps Hp 1 control steps Hc 1 slack variable ϵ (control constraints) @@ -237,7 +237,7 @@ Use custom state estimator `estim` to construct `LinMPC`. julia> estim = KalmanFilter(LinModel([tf(3, [30, 1]); tf(-2, [5, 1])], 4), i_ym=[2]); julia> mpc = LinMPC(estim, Mwt=[0, 1], Nwt=[0.5], Hp=30, Hc=1) -LinMPC controller with a sample time Ts = 4.0 s, OSQP optimizer, KalmanFilter estimator and: +LinMPC controller with a sample time Ts = 4.0 s, OSQP optimizer, SingleShooting transcription, KalmanFilter estimator and: 30 prediction steps Hp 1 control steps Hc 1 slack variable ϵ (control constraints) diff --git a/src/controller/nonlinmpc.jl b/src/controller/nonlinmpc.jl index 5b5d2050a..7b950f88a 100644 --- a/src/controller/nonlinmpc.jl +++ b/src/controller/nonlinmpc.jl @@ -223,7 +223,7 @@ This controller allocates memory at each time step for the optimization. julia> model = NonLinModel((x,u,_,_)->0.5x+u, (x,_,_)->2x, 10.0, 1, 1, 1, solver=nothing); julia> mpc = NonLinMPC(model, Hp=20, Hc=1, Cwt=1e6) -NonLinMPC controller with a sample time Ts = 10.0 s, Ipopt optimizer, UnscentedKalmanFilter estimator and: +NonLinMPC controller with a sample time Ts = 10.0 s, Ipopt optimizer, SingleShooting transcription, UnscentedKalmanFilter estimator and: 20 prediction steps Hp 1 control steps Hc 1 slack variable ϵ (control constraints) @@ -327,7 +327,7 @@ julia> model = NonLinModel((x,u,_,_)->0.5x+u, (x,_,_)->2x, 10.0, 1, 1, 1, solver julia> estim = UnscentedKalmanFilter(model, σQint_ym=[0.05]); julia> mpc = NonLinMPC(estim, Hp=20, Hc=1, Cwt=1e6) -NonLinMPC controller with a sample time Ts = 10.0 s, Ipopt optimizer, UnscentedKalmanFilter estimator and: +NonLinMPC controller with a sample time Ts = 10.0 s, Ipopt optimizer, SingleShooting transcription, UnscentedKalmanFilter estimator and: 20 prediction steps Hp 1 control steps Hc 1 slack variable ϵ (control constraints) diff --git a/src/predictive_control.jl b/src/predictive_control.jl index e88cab888..6c9c35f7b 100644 --- a/src/predictive_control.jl +++ b/src/predictive_control.jl @@ -33,6 +33,7 @@ function Base.show(io::IO, mpc::PredictiveController) n = maximum(ndigits.((Hp, Hc, nu, nx̂, nym, nyu, nd))) + 1 println(io, "$(typeof(mpc).name.name) controller with a sample time Ts = "* "$(mpc.estim.model.Ts) s, $(JuMP.solver_name(mpc.optim)) optimizer, "* + "$(typeof(mpc.transcription).name.name) transcription, "* "$(typeof(mpc.estim).name.name) estimator and:") println(io, "$(lpad(Hp, n)) prediction steps Hp") println(io, "$(lpad(Hc, n)) control steps Hc")