Skip to content

Commit 683c12c

Browse files
committed
tweaks
1 parent e74066e commit 683c12c

File tree

1 file changed

+71
-2
lines changed

1 file changed

+71
-2
lines changed

src/mpc.jl

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ end
146146
##
147147
using RobustAndOptimalControl
148148
Ts = 0.05
149-
N = 100
149+
N = 10
150150
Pc = DemoSystems.double_mass_model(c0=0.01,c1=0.01,c2=0.01, outputs=1)
151151
P = c2d(Pc, Ts)
152152
P = 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)
223223
plot(fig1, fig2, layout=(1,2), size=(1200, 1200))
224224
display(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

Comments
 (0)