Janus 2.0.0
High-performance C++20 dual-mode numerical framework
Loading...
Searching...
No Matches
Collocation.hpp
Go to the documentation of this file.
1
5
6#pragma once
7
10#include <tuple>
11
12namespace janus {
13
21
31
38class DirectCollocation : public TranscriptionBase<DirectCollocation> {
40
41 public:
47
57 std::tuple<SymbolicMatrix, SymbolicMatrix, NumericVector>
58 setup(int n_states, int n_controls, double t0, double tf, const CollocationOptions &opts = {}) {
59 if (opts.n_nodes < 2) {
60 throw InvalidArgument("DirectCollocation: n_nodes must be >= 2");
61 }
62 if (n_states < 1) {
63 throw InvalidArgument("DirectCollocation: n_states must be >= 1");
64 }
65 if (n_controls < 0) {
66 throw InvalidArgument("DirectCollocation: n_controls must be >= 0");
67 }
68
71 n_nodes_ = opts.n_nodes;
72 scheme_ = opts.scheme;
73 t0_ = t0;
74 tf_fixed_ = tf;
75 tf_is_variable_ = false;
76
77 tau_ = linspace(0.0, 1.0, n_nodes_);
78
80 for (int k = 0; k < n_nodes_; ++k) {
81 for (int i = 0; i < n_states_; ++i) {
82 states_(k, i) = opti_.variable(0.0);
83 }
84 }
85
87 for (int k = 0; k < n_nodes_; ++k) {
88 for (int i = 0; i < n_controls_; ++i) {
89 controls_(k, i) = opti_.variable(0.0);
90 }
91 }
92
93 setup_complete_ = true;
94 dynamics_set_ = false;
96 return {states_, controls_, tau_};
97 }
98
108 std::tuple<SymbolicMatrix, SymbolicMatrix, NumericVector>
109 setup(int n_states, int n_controls, double t0, const SymbolicScalar &tf,
110 const CollocationOptions &opts = {}) {
111 auto result = setup(n_states, n_controls, t0, 1.0, opts);
112 tf_symbolic_ = tf;
113 tf_is_variable_ = true;
114 return result;
115 }
116
127 SymbolicScalar quadrature(const SymbolicVector &integrand) const {
128 if (!setup_complete_) {
129 throw RuntimeError("DirectCollocation: call setup() before quadrature()");
130 }
131 if (integrand.size() != n_nodes_) {
132 throw InvalidArgument("DirectCollocation: integrand size mismatch");
133 }
134 if (n_nodes_ < 2) {
135 throw RuntimeError("DirectCollocation: need at least 2 nodes for quadrature");
136 }
137
138 const SymbolicScalar h = get_duration() / static_cast<double>(n_nodes_ - 1);
140
141 if (scheme_ == CollocationScheme::HermiteSimpson && ((n_nodes_ - 1) % 2 == 0)) {
142 sum = integrand(0) + integrand(n_nodes_ - 1);
143 for (int k = 1; k < n_nodes_ - 1; ++k) {
144 sum = sum + ((k % 2 == 0) ? 2.0 : 4.0) * integrand(k);
145 }
146 return h / 3.0 * sum;
147 }
148
149 sum = 0.5 * (integrand(0) + integrand(n_nodes_ - 1));
150 for (int k = 1; k < n_nodes_ - 1; ++k) {
151 sum = sum + integrand(k);
152 }
153 return h * sum;
154 }
155
158 int n_intervals() const { return n_nodes_ - 1; }
159
160 private:
162
163 void add_dynamics_constraints_impl() {
164 if (!dynamics_set_) {
165 throw RuntimeError(
166 "DirectCollocation: call set_dynamics() before add_dynamics_constraints()");
167 }
168
169 SymbolicScalar dt = get_duration() / static_cast<double>(n_nodes_ - 1);
170
171 for (int k = 0; k < n_nodes_ - 1; ++k) {
173 SymbolicVector x_kp1 = get_state_at_node(k + 1);
175 SymbolicVector u_kp1 = get_control_at_node(k + 1);
176
178 SymbolicScalar t_kp1 = get_time_at_node(k + 1);
179
180 SymbolicVector f_k = dynamics_(x_k, u_k, t_k);
181 SymbolicVector f_kp1 = dynamics_(x_kp1, u_kp1, t_kp1);
182
183 switch (scheme_) {
185 add_trapezoidal_constraints(x_k, x_kp1, f_k, f_kp1, dt);
186 break;
188 add_hermite_simpson_constraints(x_k, x_kp1, u_k, u_kp1, f_k, f_kp1, t_k, t_kp1, dt);
189 break;
190 default:
191 throw RuntimeError("DirectCollocation: unsupported CollocationScheme value");
192 }
193 }
194 }
195
196 void add_trapezoidal_constraints(const SymbolicVector &x_k, const SymbolicVector &x_kp1,
197 const SymbolicVector &f_k, const SymbolicVector &f_kp1,
198 const SymbolicScalar &dt) {
199 for (int i = 0; i < n_states_; ++i) {
200 SymbolicScalar defect = x_kp1(i) - x_k(i) - 0.5 * dt * (f_k(i) + f_kp1(i));
201 opti_.subject_to(defect == 0.0);
202 }
203 }
204
205 void add_hermite_simpson_constraints(const SymbolicVector &x_k, const SymbolicVector &x_kp1,
206 const SymbolicVector &u_k, const SymbolicVector &u_kp1,
207 const SymbolicVector &f_k, const SymbolicVector &f_kp1,
208 const SymbolicScalar &t_k, const SymbolicScalar &t_kp1,
209 const SymbolicScalar &dt) {
211 for (int i = 0; i < n_states_; ++i) {
212 x_mid(i) = 0.5 * (x_k(i) + x_kp1(i)) + dt / 8.0 * (f_k(i) - f_kp1(i));
213 }
214
216 for (int i = 0; i < n_controls_; ++i) {
217 u_mid(i) = 0.5 * (u_k(i) + u_kp1(i));
218 }
219
220 SymbolicScalar t_mid = 0.5 * (t_k + t_kp1);
221 SymbolicVector f_mid = dynamics_(x_mid, u_mid, t_mid);
222
223 for (int i = 0; i < n_states_; ++i) {
224 SymbolicScalar defect =
225 x_kp1(i) - x_k(i) - dt / 6.0 * (f_k(i) + 4.0 * f_mid(i) + f_kp1(i));
226 opti_.subject_to(defect == 0.0);
227 }
228 }
229};
230
231} // namespace janus
Point distribution generators (linspace, cosine, sine, log, geometric).
Shared CRTP base for trajectory transcription methods.
std::tuple< SymbolicMatrix, SymbolicMatrix, NumericVector > setup(int n_states, int n_controls, double t0, const SymbolicScalar &tf, const CollocationOptions &opts={})
Set up the collocation problem with variable final time.
Definition Collocation.hpp:109
int n_intervals() const
Get the number of collocation intervals.
Definition Collocation.hpp:158
std::tuple< SymbolicMatrix, SymbolicMatrix, NumericVector > setup(int n_states, int n_controls, double t0, double tf, const CollocationOptions &opts={})
Set up the collocation problem with fixed final time.
Definition Collocation.hpp:58
SymbolicScalar quadrature(const SymbolicVector &integrand) const
Composite quadrature for an integrand sampled at collocation nodes.
Definition Collocation.hpp:127
DirectCollocation(Opti &opti)
Construct with a reference to the optimization environment.
Definition Collocation.hpp:46
Input validation failed (e.g., mismatched sizes, invalid parameters).
Definition JanusError.hpp:31
Main optimization environment class.
Definition Opti.hpp:167
Operation failed at runtime (e.g., CasADi eval with free variables).
Definition JanusError.hpp:41
bool tf_is_variable_
Definition TranscriptionBase.hpp:161
SymbolicMatrix controls_
Definition TranscriptionBase.hpp:169
int n_controls_
Definition TranscriptionBase.hpp:155
int n_controls() const
Definition TranscriptionBase.hpp:136
int n_states_
Definition TranscriptionBase.hpp:154
double t0_
Definition TranscriptionBase.hpp:158
int n_states() const
Definition TranscriptionBase.hpp:133
NumericVector tau_
Definition TranscriptionBase.hpp:167
TranscriptionBase(Opti &opti)
Definition TranscriptionBase.hpp:34
double tf_fixed_
Definition TranscriptionBase.hpp:159
std::function< SymbolicVector(const SymbolicVector &, const SymbolicVector &, const SymbolicScalar &)> dynamics_
Definition TranscriptionBase.hpp:173
SymbolicScalar tf_symbolic_
Definition TranscriptionBase.hpp:160
SymbolicMatrix states_
Definition TranscriptionBase.hpp:168
bool setup_complete_
Definition TranscriptionBase.hpp:163
int n_nodes_
Definition TranscriptionBase.hpp:156
SymbolicVector get_state_at_node(int k) const
Definition TranscriptionBase.hpp:189
SymbolicScalar get_duration() const
Definition TranscriptionBase.hpp:175
SymbolicVector get_control_at_node(int k) const
Definition TranscriptionBase.hpp:200
bool dynamics_constraints_added_
Definition TranscriptionBase.hpp:165
SymbolicScalar get_time_at_node(int k) const
Definition TranscriptionBase.hpp:182
bool dynamics_set_
Definition TranscriptionBase.hpp:164
Opti & opti_
Definition TranscriptionBase.hpp:153
Definition Diagnostics.hpp:19
JanusVector< SymbolicScalar > SymbolicVector
Eigen vector of MX elements.
Definition JanusTypes.hpp:72
JanusMatrix< SymbolicScalar > SymbolicMatrix
Eigen matrix of MX elements.
Definition JanusTypes.hpp:71
@ Trapezoidal
Second-order trapezoidal: x[i+1] - x[i] = 0.5 * (xdot[i] + xdot[i+1]) * dt.
Definition FiniteDifference.hpp:27
JanusVector< T > linspace(const T &start, const T &end, int n)
Generates linearly spaced vector.
Definition Spacing.hpp:26
casadi::MX SymbolicScalar
CasADi MX symbolic scalar.
Definition JanusTypes.hpp:70
CollocationScheme
Collocation scheme for dynamics discretization.
Definition Collocation.hpp:17
@ HermiteSimpson
4th order, uses midpoint interpolation
Definition Collocation.hpp:19
@ Trapezoidal
2nd order, implicit midpoint rule
Definition Collocation.hpp:18
Options for DirectCollocation setup.
Definition Collocation.hpp:27
CollocationScheme scheme
Definition Collocation.hpp:28
int n_nodes
Number of discretization nodes (including endpoints).
Definition Collocation.hpp:29
JanusVector< SymbolicScalar > SymbolicVector
Eigen vector of MX elements.
Definition JanusTypes.hpp:72
casadi::MX SymbolicScalar
CasADi MX symbolic scalar.
Definition JanusTypes.hpp:70