cyqlone develop
Fast, parallel and vectorized solver for linear systems with optimal control structure.
Loading...
Searching...
No Matches
platooning.cpp
Go to the documentation of this file.
4#include <guanaqo/eigen/view.hpp>
5
6#include <algorithm>
7#include <limits>
8
9namespace CYQLONE_NS(cyqlone::qpalm::problems) {
10
12 using guanaqo::as_view;
13 const auto inf = std::numeric_limits<real_t>::infinity();
14
15 auto n_vehicle = static_cast<index_t>(p.masses.size());
16 LinearOCPStorage ocp{.dim{
17 .N_horiz = p.N_horiz,
18 .nx = 2 * n_vehicle,
19 .nu = n_vehicle,
20 .ny = 2 * n_vehicle + (n_vehicle - 1),
21 .ny_N = n_vehicle + (n_vehicle - 1),
22 }};
23 auto [N, nx, nu, ny, ny_N] = ocp.dim;
24
25 // Continuous-time dynamics
26 eigen_mat A = eigen_mat::Zero(nx, nx), B = eigen_mat::Zero(nx, nu);
27 for (Eigen::Index v = 0; v < n_vehicle; ++v) {
28 A(2 * v, 2 * v + 1) = 1; // Velocity → position
29 A(2 * v + 1, 2 * v + 1) = -p.friction; // Friction
30 B(2 * v + 1, v) = 1 / p.masses[v]; // Accel → velocity
31 }
32 auto Ts = p.T_horiz / static_cast<real_t>(p.N_horiz);
33 auto [Ad, Bd] = discretize_zoh(A, B, Ts);
34 real_t scal = p.scale_cost / static_cast<real_t>(p.N_horiz);
35
36 // Constraints rhs
37 ocp.b().set_constant(0);
38 for (index_t v = 0; v < n_vehicle; ++v)
39 ocp.b(0)(2 * v, 0) = -static_cast<real_t>(v) * p.dist_init;
40 ocp.b_min().set_constant(-inf);
41 ocp.b_max().set_constant(+inf);
42
43 // Dynamics and constraint matrices
44 for (index_t i = 0; i < N; ++i) {
45 auto Ai = ocp.A(i), Bi = ocp.B(i), Ci = ocp.C(i), Di = ocp.D(i);
46 auto Qi = ocp.Q(i), Ri = ocp.R(i);
47 auto lbi = ocp.b_min(i), ubi = ocp.b_max(i);
48 for (index_t v = 0; v < n_vehicle; ++v) {
49 Ai = as_view(Ad);
50 Bi = as_view(Bd);
51 Ci(v, 2 * v + 1) = 1; // Measure velocity
52 lbi(v, 0) = -p.v_max;
53 ubi(v, 0) = +p.v_max;
54 Di(2 * n_vehicle - 1 + v, v) = 1; // Measure input
55 lbi(2 * n_vehicle - 1 + v, 0) = -p.F_max;
56 ubi(2 * n_vehicle - 1 + v, 0) = +p.F_max;
57 if (v > 0) {
58 // p[0] + Ts v[0] ≥ p[1] + v[1] + d
59 // p[v] - p[v-1] + Ts (v[k] - v[k-1]) ≤ -d
60 Ci(n_vehicle + v - 1, 2 * v) = 1;
61 Ci(n_vehicle + v - 1, 2 * (v - 1)) = -1;
62 Ci(n_vehicle + v - 1, 2 * v + 1) = Ts;
63 Ci(n_vehicle + v - 1, 2 * (v - 1) + 1) = -Ts;
64 lbi(n_vehicle + v - 1, 0) = -inf;
65 ubi(n_vehicle + v - 1, 0) = -p.dist_min;
66 }
67 Qi(2 * v, 2 * v) = scal * 10;
68 Qi(2 * v + 1, 2 * v + 1) = scal * 1;
69 Ri(v, v) = scal * 5;
70 }
71 }
72 auto Ci = ocp.C(N), Qi = ocp.Q(N);
73 auto lbi = ocp.b_min(N), ubi = ocp.b_max(N);
74 for (index_t v = 0; v < n_vehicle; ++v) {
75 Ci(v, 2 * v + 1) = 1; // Measure velocity
76 lbi(v, 0) = -p.v_max;
77 ubi(v, 0) = +p.v_max;
78 if (v > 0) {
79 // p[v] - p[v-1] + Ts (v[k] - v[k-1]) ≤ -d
80 Ci(n_vehicle + v - 1, 2 * v) = 1;
81 Ci(n_vehicle + v - 1, 2 * (v - 1)) = -1;
82 Ci(n_vehicle + v - 1, 2 * v + 1) = Ts;
83 Ci(n_vehicle + v - 1, 2 * (v - 1) + 1) = -Ts;
84 lbi(n_vehicle + v - 1, 0) = -inf;
85 ubi(n_vehicle + v - 1, 0) = -p.dist_min;
86 }
87 Qi(2 * v, 2 * v) = scal * 100;
88 Qi(2 * v + 1, 2 * v + 1) = scal * 1;
89 }
90 std::vector<real_t> ref(nx + nu + nx);
91 for (index_t v = 0; v < n_vehicle; ++v) {
92 ref[2 * v] = p.p_target;
93 ref[2 * v + nx + nu] = p.p_target;
94 }
95 reference_to_gradient(ocp, ref);
96
97 return {
98 .ocp = std::move(ocp),
99 .ref = std::move(ref),
100 };
101}
102
103} // namespace CYQLONE_NS(cyqlone::qpalm::problems)
#define CYQLONE_NS(ns)
Definition config.hpp:10
Conversion utilities for optimal control problems.
auto as_view(Eigen::DenseBase< Derived > &M, with_index_type_t< I >={})
void reference_to_gradient(const LinearOCPStorage &ocp, std::span< const real_t > ref, std::span< real_t > qr)
Simply computes the gradient of the quadratic cost , with , with the Hessian .
Definition conversion.cpp:9
Eigen::MatrixX< real_t > eigen_mat
Definition zoh.hpp:9
PlatooningProblem platooning(PlatooningParams p)
std::tuple< eigen_mat, eigen_mat > discretize_zoh(const Eigen::Ref< const eigen_mat > &A, const Eigen::Ref< const eigen_mat > &B, real_t Ts)
Definition zoh.hpp:11
constexpr index_t v
Storage for a linear-quadratic OCP of the form.
Definition ocp.hpp:37
guanaqo::MatrixView< real_t, index_t > B(index_t i)
Definition ocp.hpp:132
guanaqo::MatrixView< real_t, index_t > D(index_t i)
Definition ocp.hpp:111
guanaqo::MatrixView< real_t, index_t > b_min()
Definition ocp.hpp:267
guanaqo::MatrixView< real_t, index_t > b()
Definition ocp.hpp:251
guanaqo::MatrixView< real_t, index_t > R(index_t i)
Definition ocp.hpp:80
guanaqo::MatrixView< real_t, index_t > C(index_t i)
Definition ocp.hpp:106
guanaqo::MatrixView< real_t, index_t > Q(index_t i)
Definition ocp.hpp:75
guanaqo::MatrixView< real_t, index_t > A(index_t i)
Definition ocp.hpp:127
guanaqo::MatrixView< real_t, index_t > b_max()
Definition ocp.hpp:283