alpaqa 0.0.1
Nonconvex constrained optimization
bicycle-obstacle-avoidance-mpc.py
Go to the documentation of this file.
1## @example mpc/python/bicycle/bicycle-obstacle-avoidance-mpc.py
2# This example shows how to call the alpaqa solver from Python code, applied
3# to a simple model predictive control problem.
4
5#%% Import necessary libraries and generate the MPC problem
6
7import casadi as cs
8import numpy as np
9import time
10import matplotlib.pyplot as plt
11from datetime import timedelta
12import os
13import sys
14
15sys.path.append(os.path.dirname(__file__))
16
17from bicycle_model import generate_problem
18
19Ts = 0.05 # Sampling time
20N_hor = 18 # Horizon length
21N_sim = 80 # Length of the simulation
22
23multipleshooting = False
24R_obstacle = 2
25
26f, nlp, bounds, n_states, n_inputs, first_input_idx = generate_problem(
27 Ts, N_hor, R_obstacle, multipleshooting
28)
29
30# %% Build the problem for PANOC+ALM
31
32import panocpy as pa
33from tempfile import TemporaryDirectory
34
35name = "mpcproblem"
36f_prob = cs.Function("f", [nlp["x"], nlp["p"]], [nlp["f"]])
37g_prob = cs.Function("g", [nlp["x"], nlp["p"]], [nlp["g"]])
38prob = pa.generate_and_compile_casadi_problem(f_prob, g_prob, name=name)
39
40prob.C.lowerbound = bounds["lbx"]
41prob.C.upperbound = bounds["ubx"]
42prob.D.lowerbound = bounds["lbg"]
43prob.D.upperbound = bounds["ubg"]
44
45#%% PANOC params
46
47lbfgsmem = N_hor
48tol = 1e-5
49verbose = False
50
51panocparams = {
52 "max_iter": 1000,
53 "max_time": timedelta(seconds=0.5),
54 "print_interval": 10 if verbose else 0,
55 "stop_crit": pa.PANOCStopCrit.ProjGradUnitNorm,
56 "update_lipschitz_in_linesearch": True,
57}
58
59innersolver = pa.PANOCSolver(
60 pa.PANOCParams(**panocparams),
61 pa.LBFGSParams(memory=lbfgsmem),
62)
63
64almparams = pa.ALMParams(
65 max_iter=20,
66 max_time=timedelta(seconds=1),
67 print_interval=1 if verbose else 0,
68 preconditioning=False,
69 ε=tol,
70 δ=tol,
71 Δ=5,
72 Σ_0=4e5,
73 Σ_max=1e12,
74)
75
76#%% Simulate MPC
77
78solver = pa.ALMSolver(almparams, innersolver)
79
80state = np.array([-5, 0, 0, 0])
81dest = np.array([5, 0.1, 0, 0])
82
83if multipleshooting:
84 x_sol = np.concatenate((np.tile(state, N_hor), np.zeros((n_inputs * N_hor,))))
85else:
86 x_sol = np.zeros((prob.n,))
87assert x_sol.size == prob.n
88y_sol = np.zeros((prob.m,))
89
90
91def solve_ocp(state, y_sol, x_sol):
92 state = np.reshape(state, (n_states,))
93 prob.param = np.concatenate((state, dest))
94 t0 = time.perf_counter()
95 x_sol, y_sol, stats = solver(problem=prob, x=x_sol, y=y_sol)
96 t1 = time.perf_counter()
97 return t1 - t0, stats, state, y_sol, x_sol
98
99
100xs = np.zeros((N_sim, n_states))
101times = np.zeros((N_sim,))
102for k in range(N_sim):
103 t, stats, state, y_sol, x_sol = solve_ocp(state, y_sol, x_sol)
104 times[k] = t
105 xs[k] = state
106 print(
107 stats["status"],
108 stats["elapsed_time"],
109 stats["outer_iterations"],
110 stats["inner"]["iterations"],
111 )
112 input = x_sol[first_input_idx : first_input_idx + n_inputs]
113 state += Ts * f(state, input)
114
115#%% Plot
116
117fig_trajectory, ax = plt.subplots(1, 1)
118c = plt.Circle((0, 0), R_obstacle)
119ax.set_aspect(1)
120ax.add_artist(c)
121ax.plot(xs[:, 0], xs[:, 1], "r.-")
122ax.set_title('Trajectory')
123
124fig_time, ax = plt.subplots(1, 1)
125ax.plot(times)
126ax.set_title("Run time")
127ax.set_xlabel("MPC time step")
128ax.set_ylabel("Run time [s]")
129
130plt.show()
131
132# %%
def generate_problem(Ts, N_hor, R_obstacle, multipleshooting)