aligator  0.10.0
A primal-dual augmented Lagrangian-type solver for nonlinear trajectory optimization.
Loading...
Searching...
No Matches
plotting.py
Go to the documentation of this file.
1import matplotlib.pyplot as plt
2import numpy as np
3
4from aligator import HistoryCallback, Results
5
6
8 cb: HistoryCallback,
9 ax: plt.Axes,
10 res: Results = None,
11 *,
12 show_al_iters=False,
13 legend_kwargs={},
14):
15 from proxsuite_nlp.utils import plot_pd_errs
16
17 prim_infeas = cb.prim_infeas.tolist()
18 dual_infeas = cb.dual_infeas.tolist()
19 if res is not None:
20 prim_infeas.append(res.primal_infeas)
21 dual_infeas.append(res.dual_infeas)
22 plot_pd_errs(ax, prim_infeas, dual_infeas)
23 ax.grid(axis="y", which="major")
24 handles, labels = ax.get_legend_handles_labels()
25 labels += [
26 "Prim. err $p$",
27 "Dual err $d$",
28 ]
29 if show_al_iters:
30 prim_tols = np.array(cb.prim_tols)
31 al_iters = np.array(cb.al_index)
32 labels.append("$\\eta_k$")
33
34 itrange = np.arange(len(al_iters))
35 if itrange.size > 0:
36 if al_iters.max() > 0:
37 labels.append("AL iters")
38 ax.step(itrange, prim_tols, c="green", alpha=0.9, lw=1.1)
39 al_change = al_iters[1:] - al_iters[:-1]
40 al_change_idx = itrange[:-1][al_change > 0]
41
42 ax.vlines(al_change_idx, *ax.get_ylim(), colors="gray", lw=4.0, alpha=0.5)
43
44 ax.legend(labels=labels, **legend_kwargs)
45 return labels
46
47
49 q: np.ndarray, ax: plt.Axes, alpha=0.5, fc="tab:blue"
50) -> plt.Rectangle:
51 from matplotlib import transforms
52
53 w = 1.0
54 h = 0.4
55 center = (q[0] - 0.5 * w, q[1] - 0.5 * h)
56 rect = plt.Rectangle(center, w, h, fc=fc, alpha=alpha)
57 theta = np.arctan2(q[3], q[2])
58 transform_ = transforms.Affine2D().rotate_around(*q[:2], -theta) + ax.transData
59 rect.set_transform(transform_)
60 ax.add_patch(rect)
61 return rect
62
63
64def _axes_flatten_if_ndarray(axes) -> list[plt.Axes]:
65 if isinstance(axes, np.ndarray):
66 axes = axes.flatten()
67 elif not isinstance(axes, list):
68 axes = [axes]
69 return axes
70
71
73 times,
74 us,
75 ncols=2,
76 axes=None,
77 effort_limit=None,
78 joint_names=None,
79 rmodel=None,
80 figsize=(6.4, 6.4),
81 xlabel="Time (s)",
82) -> tuple[plt.Figure, list[plt.Axes]]:
83 t0 = times[0]
84 tf = times[-1]
85 us = np.asarray(us)
86 nu = us.shape[1]
87 nrows, r = divmod(nu, ncols)
88 nrows += int(r > 0)
89
90 make_new_plot = axes is None
91 if make_new_plot:
92 fig, axes = plt.subplots(nrows, ncols, sharex="col", figsize=figsize)
93 else:
94 fig = axes.flat[0].get_figure()
95 axes = _axes_flatten_if_ndarray(axes)
96
97 if rmodel is not None:
98 effort_limit = rmodel.effortLimit
99 joint_names = rmodel.names
100
101 for i in range(nu):
102 ax: plt.Axes = axes[i]
103 ax.step(times[:-1], us[:, i])
104 if effort_limit is not None:
105 ylim = ax.get_ylim()
106 ax.hlines(-effort_limit[i], t0, tf, colors="k", linestyles="--")
107 ax.hlines(+effort_limit[i], t0, tf, colors="r", linestyles="dashdot")
108 ax.set_ylim(*ylim)
109 if joint_names is not None:
110 joint_name = joint_names[i].lower()
111 ax.set_title(joint_name, fontsize=8)
112 if nu > 1:
113 fig.supxlabel(xlabel)
114 fig.suptitle("Control trajectories")
115 else:
116 axes[0].set_xlabel(xlabel)
117 axes[0].set_title("Control trajectories")
118 fig.tight_layout()
119 return fig, axes
120
121
123 times,
124 vs,
125 rmodel,
126 axes=None,
127 ncols=2,
128 vel_limit=None,
129 figsize=(6.4, 6.4),
130 xlabel="Time (s)",
131) -> tuple[plt.Figure, list[plt.Axes]]:
132 vs = np.asarray(vs)
133 nv = rmodel.nv
134 assert nv == vs.shape[1]
135 if vel_limit is not None:
136 assert nv == vel_limit.shape[0]
137 idx_to_joint_id_map = {}
138 jid = 0
139 for i in range(nv):
140 if i in rmodel.idx_vs.tolist():
141 jid += 1
142 idx_to_joint_id_map[i] = jid
143 nrows, r = divmod(nv, ncols)
144 nrows += int(r > 0)
145
146 t0 = times[0]
147 tf = times[-1]
148
149 if axes is None:
150 fig, axes = plt.subplots(nrows, ncols, sharex=True, figsize=figsize)
151 fig: plt.Figure
152 else:
153 fig = axes.flat[0].get_figure()
154 axes = _axes_flatten_if_ndarray(axes)
155
156 for i in range(nv):
157 ax: plt.Axes = axes[i]
158 ax.plot(times, vs[:, i])
159 jid = idx_to_joint_id_map[i]
160 joint_name = rmodel.names[jid].lower()
161 if vel_limit is not None:
162 ylim = ax.get_ylim()
163 ax.hlines(-vel_limit[i], t0, tf, colors="k", linestyles="--")
164 ax.hlines(+vel_limit[i], t0, tf, colors="r", linestyles="dashdot")
165 ax.set_ylim(*ylim)
166 ax.set_title(joint_name, fontsize=8)
167
168 fig.supxlabel(xlabel)
169 fig.suptitle("Velocity trajectories")
170 fig.tight_layout()
171 return fig, axes
plt.Rectangle plot_se2_pose(np.ndarray q, plt.Axes ax, alpha=0.5, fc="tab:blue")
Definition plotting.py:50
plot_convergence(HistoryCallback cb, plt.Axes ax, Results res=None, *, show_al_iters=False, legend_kwargs={})
Definition plotting.py:14
tuple[plt.Figure, list[plt.Axes]] plot_controls_traj(times, us, ncols=2, axes=None, effort_limit=None, joint_names=None, rmodel=None, figsize=(6.4, 6.4), xlabel="Time (s)")
Definition plotting.py:82
tuple[plt.Figure, list[plt.Axes]] plot_velocity_traj(times, vs, rmodel, axes=None, ncols=2, vel_limit=None, figsize=(6.4, 6.4), xlabel="Time (s)")
Definition plotting.py:131
list[plt.Axes] _axes_flatten_if_ndarray(axes)
Definition plotting.py:64