10from os.path
import join, dirname
13sys.path.append(dirname(__file__))
14from hanging_chain_dynamics
import HangingChain
23f_d = model.dynamics(Ts)
24y_null, u_null = model.initial_state()
26param = [0.03, 1.6, 0.033 / N]
31u_dist = [-0.5, 0.5, 0.5]
if dim == 3
else [-0.5, 0.5]
32y_dist = model.simulate(N_dist, y_null, u_dist, param)
33y_dist = np.hstack((np.array([y_null]).T, y_dist))
38y_sim = model.simulate(N_sim, y_dist[:, -1], u_null, param)
39y_sim = np.hstack((y_dist, y_sim))
45L_cost = model.generate_cost_fun()
46y_init = cs.SX.sym(
"y_init", *y_null.shape)
47U = cs.SX.sym(
"U", dim * N_horiz)
48constr_param = cs.SX.sym(
"c", 3)
49mpc_param = cs.vertcat(y_init, model.params, constr_param)
50U_mat = model.input_to_matrix(U)
53mpc_sim = model.simulate(N_horiz, y_init, U_mat, model.params)
55for n
in range(N_horiz):
58 mpc_cost +=
L_cost(y_n, u_n)
59mpc_cost_fun = cs.Function(
'f_mpc', [U, mpc_param], [mpc_cost])
62g_constr =
lambda c, x: c[0] * x**3 + c[1] * x**2 + c[2] * x
64for n
in range(N_horiz):
68 yy_n = y_n[dim * i + dim - 1]
69 constr += [yy_n -
g_constr(constr_param, yx_n)]
70 constr += [y_n[-1] -
g_constr(constr_param, y_n[-dim])]
71mpc_constr_fun = cs.Function(
"g", [U, mpc_param], [cs.vertcat(*constr)])
74a, b, c, d = 0.6, -1.4, 5, 2.2
75constr_coeff = [c, -3 * a * c, 3 * a * a * c + d]
76constr_lb = b - c * a**3 - d * a
81prob = pa.generate_and_compile_casadi_problem(mpc_cost_fun, mpc_constr_fun)
82prob.C.lowerbound = -1 * np.ones((dim * N_horiz, ))
83prob.C.upperbound = +1 * np.ones((dim * N_horiz, ))
84prob.D.lowerbound = constr_lb * np.ones((len(constr), ))
87from datetime
import timedelta
94 'max_time': timedelta(seconds=0.5),
96 inner_solver=pa.StructuredPANOCLBFGSSolver(
98 'stop_crit': pa.ProjGradNorm2,
99 'max_time': timedelta(seconds=0.2),
100 'hessian_step_size_heuristic': 15,
102 lbfgs_params={
'memory': N_horiz},
112 U = np.zeros((N_horiz * dim, ))
113 λ = np.zeros(((N + 1) * N_horiz, ))
115 def __init__(self, model, problem):
119 def __call__(self, y_n):
120 y_n = np.array(y_n).ravel()
122 self.
problemproblem.param[:y_n.shape[0]] = y_n
127 print(stats[
'status'], stats[
'outer_iterations'],
128 stats[
'inner'][
'iterations'], stats[
'elapsed_time'],
129 stats[
'inner_convergence_failures'])
130 self.
tot_ittot_it += stats[
'inner'][
'iterations']
131 self.
failuresfailures += stats[
'status'] != pa.SolverStatus.Converged
133 print(np.linalg.norm(self.
λλ))
135 return self.
modelmodel.input_to_matrix(self.
UU)[:, 0]
140y_n = np.array(y_dist[:, -1]).ravel()
141n_state = y_n.shape[0]
142prob.param = np.concatenate((y_n, param, constr_coeff))
144y_mpc = np.empty((n_state, N_sim))
146for n
in range(N_sim):
151 y_n = model.simulate(1, y_n, u_n, param).T
153y_mpc = np.hstack((y_dist, y_mpc))
155print(controller.tot_it, controller.failures)
159import matplotlib.pyplot
as plt
160import matplotlib
as mpl
161from matplotlib
import patheffects
163mpl.rcParams[
'animation.frame_format'] =
'svg'
165fig, ax = plt.subplots()
166x, y, z = model.state_to_pos(y_null)
167line, = ax.plot(x, y,
'-o', label=
'Without MPC')
168line_ctrl, = ax.plot(x, y,
'-o', label=
'With MPC')
171plt.xlim([-0.25, 1.25])
173x = np.linspace(-0.25, 1.25, 256)
174y = np.linspace(-2.5, 1, 256)
175X, Y = np.meshgrid(x, y)
178fx = [patheffects.withTickedStroke(spacing=7, linewidth=0.8)]
179cgc = plt.contour(X, Y, Z, [0], colors=
'tab:green', linewidths=0.8)
180plt.setp(cgc.collections, path_effects=fx)
186 def __call__(self, i):
187 x, y, z = model.state_to_pos(y_sim[:, i])
193 viol = y -
g_constr(constr_coeff, x) + 1e-5 < constr_lb
195 self.
pointspointspoints += ax.plot(x[viol], y[viol],
'rx', markersize=12)
196 x, y, z = model.state_to_pos(y_mpc[:, i])
197 line_ctrl.set_xdata(x)
198 line_ctrl.set_ydata(y)
199 viol = y -
g_constr(constr_coeff, x) + 1e-5 < constr_lb
201 self.
pointspointspoints += ax.plot(x[viol], y[viol],
'rx', markersize=12)
205ani = mpl.animation.FuncAnimation(fig,
210 frames=1 + N_dist + N_sim)
213out = join(dirname(__file__),
'..',
'..',
'..',
'..',
'sphinx',
'source',
214 'sphinxstatic',
'hanging-chain.html')
215os.makedirs(dirname(out), exist_ok=
True)
216with open(out,
"w")
as f:
218 f.write(ani.to_jshtml())