@@ -68,11 +68,12 @@ We design our [`LinMPC`](@ref) controllers by including the level constraint wit
6868mpc = setconstraint!(LinMPC(model, Hp=15, Hc=2), ŷmin=[45, -Inf])
6969```
7070
71- By default, [ ` LinMPC ` ] ( @ref ) controllers use a [ ` SteadyKalmanFilter ` ] ( @ref ) to estimate the
72- plant states. Before closing the loop, we call [ ` initstate! ` ] ( @ref ) with the actual plant
73- inputs and measurements to ensure a bumpless transfer. Since ` model ` simulates our plant
74- here, its output will initialize the states. [ ` LinModel ` ] ( @ref ) objects are callable for
75- this purpose (an alias for [ ` evaloutput ` ] ( @ref ) ):
71+ By default, [ ` LinMPC ` ] ( @ref ) controllers use [ ` OSQP ` ] ( https://osqp.org/ ) to solve the
72+ problem and a [ ` SteadyKalmanFilter ` ] ( @ref ) to estimate the plant states. Before closing the
73+ loop, we call [ ` initstate! ` ] ( @ref ) with the actual plant inputs and measurements to ensure a
74+ bumpless transfer. Since ` model ` simulates our plant here, its output will initialize the
75+ states. [ ` LinModel ` ] ( @ref ) objects are callable for this purpose (an alias for
76+ [ ` evaloutput ` ] ( @ref ) ):
7677
7778``` @example 1
7879u = model.uop
@@ -120,12 +121,34 @@ Lastly, we plot the closed-loop test with the `Plots` package:
120121
121122``` @example 1
122123using Plots
123- p1 = plot(t_data, y_data[1,:], label="level"); ylabel!("level")
124- plot!(t_data, ry_data[1,:], label="setpoint", linestyle=:dash, linetype=:steppost)
125- plot!(t_data, fill(45,size(t_data)), label="min", linestyle=:dot, linetype=:steppost)
126- p2 = plot(t_data, y_data[2,:], label="temp."); ylabel!("temp.")
127- plot!(t_data, ry_data[2,:],label="setpoint", linestyle=:dash, linetype=:steppost)
128- p3 = plot(t_data,u_data[1,:],label="cold", linetype=:steppost); ylabel!("flow rate")
129- plot!(t_data,u_data[2,:],label="hot", linetype=:steppost); xlabel!("time (s)")
130- p = plot(p1, p2, p3, layout=(3,1), fmt=:svg)
124+ function plot_data(t_data, u_data, y_data, ry_data)
125+ p1 = plot(t_data, y_data[1,:], label="level"); ylabel!("level")
126+ plot!(t_data, ry_data[1,:], label="setpoint", linestyle=:dash, linetype=:steppost)
127+ plot!(t_data, fill(45,size(t_data)), label="min", linestyle=:dot, linewidth=1.5)
128+ p2 = plot(t_data, y_data[2,:], label="temp."); ylabel!("temp.")
129+ plot!(t_data, ry_data[2,:],label="setpoint", linestyle=:dash, linetype=:steppost)
130+ p3 = plot(t_data,u_data[1,:],label="cold", linetype=:steppost); ylabel!("flow rate")
131+ plot!(t_data,u_data[2,:],label="hot", linetype=:steppost); xlabel!("time (s)")
132+ return plot(p1, p2, p3, layout=(3,1), fmt=:svg)
133+ end
134+ plot_data(t_data, u_data, y_data, ry_data)
135+ ```
136+
137+ For some situations, when [ ` LinMPC ` ] ( @ref ) matrices are small/medium and dense, [ ` DAQP ` ] ( https://darnstrom.github.io/daqp/ )
138+ optimizer may be more efficient. To install it, run:
139+
140+ ``` julia
141+ using Pkg; Pkg. add (" DAQP" )
142+ ```
143+
144+ Constructing a [ ` LinMPC ` ] ( @ref ) with ` DAQP ` leads to identical results here:
145+
146+ ``` @example 1
147+ using JuMP, DAQP
148+ daqp = Model(DAQP.Optimizer)
149+ mpc2 = setconstraint!(LinMPC(model, Hp=15, Hc=2, optim=daqp), ŷmin=[45, -Inf])
150+ setstate!(model, zeros(model.nx))
151+ initstate!(mpc2, model.uop, model())
152+ u_data2, y_data2, ry_data2 = test_mpc(mpc2, model)
153+ plot_data(t_data, u_data2, y_data2, ry_data2)
131154```
0 commit comments