67 OCP(
int num_states,
int num_inputs, std::chrono::duration<double> dt,
72 DynamicsType dynamics_type = DynamicsType::EXPLICIT_ODE,
73 TimestepMethod timestep_method = TimestepMethod::FIXED,
74 TranscriptionMethod transcription_method =
75 TranscriptionMethod::DIRECT_TRANSCRIPTION)
84 return dynamics(x, u);
88 transcription_method} {}
107 OCP(
int num_states,
int num_inputs, std::chrono::duration<double> dt,
112 DynamicsType dynamics_type = DynamicsType::EXPLICIT_ODE,
113 TimestepMethod timestep_method = TimestepMethod::FIXED,
114 TranscriptionMethod transcription_method =
115 TranscriptionMethod::DIRECT_TRANSCRIPTION)
116 : m_num_steps{num_steps},
117 m_dynamics{std::move(dynamics)},
118 m_dynamics_type{dynamics_type} {
120 m_U = decision_variable(num_inputs, m_num_steps + 1);
122 if (timestep_method == TimestepMethod::FIXED) {
124 for (
int i = 0; i < num_steps + 1; ++i) {
125 m_DT[0, i] = dt.count();
127 }
else if (timestep_method == TimestepMethod::VARIABLE_SINGLE) {
128 Variable single_dt = decision_variable();
133 for (
int i = 0; i < num_steps + 1; ++i) {
134 m_DT[0, i] = single_dt;
136 }
else if (timestep_method == TimestepMethod::VARIABLE) {
137 m_DT = decision_variable(1, m_num_steps + 1);
138 for (
int i = 0; i < num_steps + 1; ++i) {
139 m_DT[0, i].set_value(dt.count());
143 if (transcription_method == TranscriptionMethod::DIRECT_TRANSCRIPTION) {
144 m_X = decision_variable(num_states, m_num_steps + 1);
145 constrain_direct_transcription();
146 }
else if (transcription_method ==
147 TranscriptionMethod::DIRECT_COLLOCATION) {
148 m_X = decision_variable(num_states, m_num_steps + 1);
149 constrain_direct_collocation();
150 }
else if (transcription_method == TranscriptionMethod::SINGLE_SHOOTING) {
154 constrain_single_shooting();
163 template <
typename T>
166 subject_to(this->initial_state() == initial_state);
174 template <
typename T>
177 subject_to(this->final_state() == final_state);
191 for (
int i = 0; i < m_num_steps + 1; ++i) {
212 for (
int i = 0; i < m_num_steps + 1; ++i) {
215 auto dt = this->dt()[0, i];
216 callback(time, x, u, dt);
228 template <
typename T>
231 for (
int i = 0; i < m_num_steps + 1; ++i) {
232 subject_to(U().col(i) >= lower_bound);
242 template <
typename T>
245 for (
int i = 0; i < m_num_steps + 1; ++i) {
246 subject_to(U().col(i) <= upper_bound);
256 subject_to(dt() >= min_timestep.count());
265 subject_to(dt() <= max_timestep.count());
320 DynamicsType m_dynamics_type;
335 template <
typename F,
typename State,
typename Input,
typename Time>
336 State rk4(F&& f, State x, Input u, Time t0, Time dt) {
337 auto halfdt = dt * 0.5;
338 State k1 = f(t0, x, u, dt);
339 State k2 = f(t0 + halfdt, x + k1 * halfdt, u, dt);
340 State k3 = f(t0 + halfdt, x + k2 * halfdt, u, dt);
341 State k4 = f(t0 + dt, x + k3 * dt, u, dt);
343 return x + (k1 + k2 * 2.0 + k3 * 2.0 + k4) * (dt / 6.0);
349 void constrain_direct_collocation() {
350 slp_assert(m_dynamics_type == DynamicsType::EXPLICIT_ODE);
355 for (
int i = 0; i < m_num_steps; ++i) {
356 Variable h = dt()[0, i];
358 auto& f = m_dynamics;
361 auto t_end = t_begin + h;
363 auto x_begin = X().col(i);
364 auto x_end = X().col(i + 1);
366 auto u_begin = U().col(i);
367 auto u_end = U().col(i + 1);
369 auto xdot_begin = f(t_begin, x_begin, u_begin, h);
370 auto xdot_end = f(t_end, x_end, u_end, h);
372 -3 / (2 * h) * (x_begin - x_end) - 0.25 * (xdot_begin + xdot_end);
374 auto t_c = t_begin + 0.5 * h;
375 auto x_c = 0.5 * (x_begin + x_end) + h / 8 * (xdot_begin - xdot_end);
376 auto u_c = 0.5 * (u_begin + u_end);
378 subject_to(xdot_c == f(t_c, x_c, u_c, h));
387 void constrain_direct_transcription() {
390 for (
int i = 0; i < m_num_steps; ++i) {
391 auto x_begin = X().col(i);
392 auto x_end = X().col(i + 1);
394 Variable dt = this->dt()[0, i];
396 if (m_dynamics_type == DynamicsType::EXPLICIT_ODE) {
397 subject_to(x_end == rk4<
const decltype(m_dynamics)&, VariableMatrix,
398 VariableMatrix, Variable>(m_dynamics, x_begin,
400 }
else if (m_dynamics_type == DynamicsType::DISCRETE) {
401 subject_to(x_end == m_dynamics(time, x_begin, u, dt));
411 void constrain_single_shooting() {
414 for (
int i = 0; i < m_num_steps; ++i) {
415 auto x_begin = X().col(i);
416 auto x_end = X().col(i + 1);
418 Variable dt = this->dt()[0, i];
420 if (m_dynamics_type == DynamicsType::EXPLICIT_ODE) {
421 x_end = rk4<
const decltype(m_dynamics)&, VariableMatrix, VariableMatrix,
422 Variable>(m_dynamics, x_begin, u, time, dt);
423 }
else if (m_dynamics_type == DynamicsType::DISCRETE) {
424 x_end = m_dynamics(time, x_begin, u, dt);
OCP(int num_states, int num_inputs, std::chrono::duration< double > dt, int num_steps, function_ref< VariableMatrix(const VariableMatrix &x, const VariableMatrix &u)> dynamics, DynamicsType dynamics_type=DynamicsType::EXPLICIT_ODE, TimestepMethod timestep_method=TimestepMethod::FIXED, TranscriptionMethod transcription_method=TranscriptionMethod::DIRECT_TRANSCRIPTION)
Definition ocp.hpp:67
OCP(int num_states, int num_inputs, std::chrono::duration< double > dt, int num_steps, function_ref< VariableMatrix(const Variable &t, const VariableMatrix &x, const VariableMatrix &u, const Variable &dt)> dynamics, DynamicsType dynamics_type=DynamicsType::EXPLICIT_ODE, TimestepMethod timestep_method=TimestepMethod::FIXED, TranscriptionMethod transcription_method=TranscriptionMethod::DIRECT_TRANSCRIPTION)
Definition ocp.hpp:107