146146# #
147147using RobustAndOptimalControl
148148Ts = 0.05
149- N = 100
149+ N = 10
150150Pc = DemoSystems. double_mass_model (c0= 0.01 ,c1= 0.01 ,c2= 0.01 , outputs= 1 )
151151P = c2d (Pc, Ts)
152152P = add_input_integrator (P, 1 ; ϵ= 1e-3 )
@@ -166,7 +166,7 @@ Lmpc = MPCController2(P, Q1, Q2, N;
166166 x_max,
167167 u_min,
168168 u_max,
169- rho = 1 .0 ,
169+ rho = 2 .0 ,
170170 max_iter = 3500 ,
171171 abs_pri_tol = 1.0e-3 ,
172172 abs_dual_tol = 1.0e-3 ,
@@ -223,3 +223,72 @@ fig2 = scatter(1e3 .* Lmpc.t, title="TimyMPC execution time [ms]", label=false)
223223plot (fig1, fig2, layout= (1 ,2 ), size= (1200 , 1200 ))
224224display (current ())
225225
226+
227+ # # OSQP
228+
229+ using OSQP, SparseArrays
230+
231+ struct SimpleMPC2{M, L}
232+ m:: M
233+ l:: L
234+ u:: L
235+ end
236+
237+ function SimpleMPC2 (N)
238+ speye (N) = spdiagm (ones (N))
239+ Q = sparse (Q1)
240+ QN = are (P, Q1, Q2) |> sparse
241+ R = sparse (Q2)
242+
243+ (; nx, nu, A, B) = P
244+ Ad, Bd = A,B
245+
246+ # Initial and reference states
247+ xr = r[:, 1 ]
248+
249+ # Cast MPC problem to a QP: x = (x(0),x(1),...,x(N),u(0),...,u(N-1))
250+ # - quadratic objective
251+ H = blockdiag (kron (speye (N), Q), QN, kron (speye (N), R))
252+ # - linear objective
253+ q = [repeat (- Q * xr, N); - QN * xr; zeros (N* nu)]
254+ # - linear dynamics
255+ Ax = kron (speye (N + 1 ), - speye (nx)) + kron (spdiagm (- 1 => ones (N)), Ad)
256+ Bu = kron ([spzeros (1 , N); speye (N)], Bd)
257+ Aeq = [Ax Bu]
258+ leq = [- x0; zeros (N * nx)]
259+ ueq = leq
260+ # - input and state constraints
261+ Aineq = speye ((N + 1 ) * nx + N * nu)
262+ lineq = [repeat (x_min, N + 1 ); repeat (u_min, N)]
263+ uineq = [repeat (x_max, N + 1 ); repeat (u_max, N)]
264+ # - OSQP constraints
265+ A, l, u = [Aeq; Aineq], [leq; lineq], [ueq; uineq]
266+
267+ # Create an OSQP model
268+ m = OSQP. Model ()
269+
270+ # Setup workspace
271+ OSQP. setup! (m; P= H, q= q, A= A, l= l, u= u, warm_starting= true )
272+ SimpleMPC2 (m, l, u)
273+ end
274+
275+ function (c:: SimpleMPC2 )(x0, r = nothing )
276+ nx = length (x0)
277+ nu = 1
278+ (; m, l, u) = c
279+ l[1 : nx], u[1 : nx] = - x0, - x0
280+ OSQP. update! (m; l, u)
281+ res = OSQP. solve! (m)
282+ if res. info. status != :Solved
283+ error (" OSQP did not solve the problem!" )
284+ end
285+ ctrl = res. x[(N+ 1 )* nx+ 1 : (N+ 1 )* nx+ nu]
286+ ctrl
287+ end
288+
289+ m = SimpleMPC2 (100 )
290+
291+ osqp_fun = (x,t)-> clamp .(m (x), u_min[1 ], u_max[1 ])
292+
293+ @time res_osqp = lsim (P, osqp_fun, 5 ; x0= Float64 .(x0))
294+ plot (res_osqp, label= " OSQP" , plotu= true , plotx= false )
0 commit comments