39 bool new_run,
const Time& t, ReferenceTrajectoryInterface* sref,
const Eigen::VectorXd* prev_u,
40 double prev_u_dt, ReferenceTrajectoryInterface* xinit, ReferenceTrajectoryInterface* uinit)
42 assert(x0.size() == dynamics->getStateDimension());
43 assert(xref.getDimension() == x0.size());
44 assert(uref.getDimension() == dynamics->getInputDimension());
46 GridUpdateResult result;
58 std::vector<double> dts;
59 if (!xref.isStatic() || !uref.isStatic() || (sref && !sref->isStatic()) || (xinit && !xinit->isStatic()) || (uinit && !uinit->isStatic()))
65 if (!xref.isStatic() && !xref.isCached(dts, t))
66 xref.precompute(dts, t);
67 if (!uref.isStatic() && !uref.isCached(dts, t)) uref.precompute(dts, t);
69 if (sref && !sref->isStatic() && !sref->isCached(dts, t)) sref->precompute(dts, t);
70 if (xinit && !xinit->isStatic() && !xinit->isCached(dts, t)) xinit->precompute(dts, t);
71 if (uinit && !uinit->isStatic() && !uinit->isCached(dts, t)) uinit->precompute(dts, t);
75 if (prev_u && prev_u->size() > 0)
93 if (xref.isStatic() && !xinit)
99 initializeSequences(x0, xref.getReferenceCached(
n - 1), xinit ? *xinit : xref, uinit ? *uinit : uref, nlp_fun);
114 for (
int i = 0; i <
_xf_fixed.size(); ++i)
123 if (new_run || result.updated())
126 result.edges_updated =
127 nlp_fun.update(
getN(), t.toSec(), xref, uref, sref,
hasSingleDt(), x0, dts,
this);
133 if (result.updated())
139 result.edges_updated =
true;
147 NlpFunctions& nlp_fun)
155 nlp_fun.checkAndInitializeBoundDimensions(x0.size(), uref.getDimension());
162 int num_normal_intervals;
163 int add_controls_last_interval;
167 num_normal_intervals = n_init - 1;
168 add_controls_last_interval = 0;
173 num_normal_intervals = interv_div.quot;
174 add_controls_last_interval = interv_div.rem;
178 Eigen::VectorXd dir = xf - x0;
179 double dist = dir.norm();
180 if (dist != 0) dir /= dist;
181 double step = dist / (n_init - 1);
184 for (
int i = 0; i < num_normal_intervals; ++i)
188 _intervals.back().s.set(x0 + (
double)k * step * dir, nlp_fun.x_lb, nlp_fun.x_ub);
192 _intervals.back().u_seq.emplace_back(uref.getReferenceCached(k), nlp_fun.u_lb, nlp_fun.u_ub);
200 if (add_controls_last_interval > 0)
203 _intervals.back().s.set(x0 + (
double)k * step * dir, nlp_fun.x_lb, nlp_fun.x_ub);
205 for (
int j = 0; j < add_controls_last_interval; ++j)
207 _intervals.back().u_seq.emplace_back(uref.getReferenceCached(k + j), nlp_fun.u_lb, nlp_fun.u_ub);
225 ReferenceTrajectoryInterface& uref, NlpFunctions& nlp_fun)
239 nlp_fun.checkAndInitializeBoundDimensions(x0.size(), uref.getDimension());
246 int num_normal_intervals;
247 int add_controls_last_interval;
251 num_normal_intervals = n_init - 1;
252 add_controls_last_interval = 0;
257 num_normal_intervals = interv_div.quot;
258 add_controls_last_interval = interv_div.rem;
262 for (
int i = 0; i < num_normal_intervals; ++i)
266 _intervals.back().s.set(xref.getReferenceCached(k), nlp_fun.x_lb, nlp_fun.x_ub);
270 _intervals.back().u_seq.emplace_back(uref.getReferenceCached(k + j), nlp_fun.u_lb, nlp_fun.u_ub);
278 if (add_controls_last_interval > 0)
281 _intervals.back().s.set(xref.getReferenceCached(k), nlp_fun.x_lb, nlp_fun.x_ub);
283 for (
int j = 0; j < add_controls_last_interval; ++j)
285 _intervals.back().u_seq.emplace_back(uref.getReferenceCached(k + j), nlp_fun.u_lb, nlp_fun.u_ub);
306 if (num_shift <= 0)
return;
310 if (num_shift >
getN() - 2)
321 for (
int i = 0; i <
getN() - num_shift; ++i)
323 int idx = i + num_shift;
337 int idx =
getN() - num_shift;
343 for (
int i = 0; i < num_shift; ++i, ++idx)
349 if (i == num_shift - 1)
364 PRINT_WARNING_ONCE(
"Shifting for shooting grids with more than 1 control per interval not yet implemented.");
374 double first_dist = (x0 -
_intervals.front().s.values()).norm();
375 if (
std::abs(first_dist) < 1e-12)
return 0;
383 double dist_cache = first_dist;
385 int num_keep_interv = 1;
386 int lookahead =
std::min(num_interv - num_keep_interv, 20);
390 for (
int i = 1; i <= lookahead; ++i)
392 dist = (x0 -
_intervals[i].s.values()).norm();
393 if (dist < dist_cache)
408 for (
const ShootingInterval& interv :
_intervals)
410 for (
const ScalarVertex& dt : interv.dt_seq) t += dt.value();
419 u0 =
_intervals.front().u_seq.front().values();
429 n += interv.u_seq.size();
451 for (
const ShootingInterval& interv :
_intervals)
467 PRINT_ERROR_NAMED(
"Dimensions mismatch between xf_fixed and xf. Setting xf_fixed to false.");
477 if (interv.s.getDimension() == nlp_fun.
x_lb.size())
478 interv.s.setLowerBounds(nlp_fun.
x_lb);
480 PRINT_ERROR_NAMED(
"Cannot update lower state bounds due to dimensions mismatch");
482 if (interv.s.getDimension() == nlp_fun.
x_ub.size())
483 interv.s.setUpperBounds(nlp_fun.
u_ub);
485 PRINT_ERROR_NAMED(
"Cannot update upper state bounds due to dimensions mismatch");
492 PRINT_ERROR_NAMED(
"Cannot update lower control input bounds due to dimensions mismatch");
497 PRINT_ERROR_NAMED(
"Cannot update upper control input bounds due to dimensions mismatch");
524 vertices.push_back(&interv.s);
525 assert(interv.u_seq.size() == interv.dt_seq.size());
526 for (
int i = 0; i < (
int)interv.u_seq.size(); ++i)
528 vertices.push_back(&interv.u_seq[i]);
529 vertices.push_back(&interv.dt_seq[i]);
534 vertices.push_back(&
_u_ref);
546 assert(interv.u_seq.size() == interv.dt_seq.size());
547 for (
int i = 0; i < (
int)interv.u_seq.size(); ++i)
549 if (!interv.u_seq[i].isFixed())
_active_vertices.push_back(&interv.u_seq[i]);
550 if (!interv.dt_seq[i].isFixed())
_active_vertices.push_back(&interv.dt_seq[i]);
558 if (x_sequence) x_sequence->clear();
559 if (u_sequence) u_sequence->clear();
567 for (const ShootingInterval& interv : _intervals)
569 if (x_sequence) x_sequence->add(t, interv.s.values());
572 assert(interv.u_seq.size() == interv.dt_seq.size());
573 for (int i = 0; i < interv.u_seq.size(); ++i)
575 u_sequence->add(t, interv.u_seq[i].values());
576 t += interv.dt_seq[i].value();
577 if (t > t_max) break;
582 t += interv.getIntervalLength();
583 if (t > t_max) break;
586 if (t <= t_max && isXfShootingNode())
588 if (x_sequence && t <= t_max) x_sequence->add(t, _xf.values());
589 // duplicate last u to have the sampe time stamps as x_sequence
590 if (u_sequence) u_sequence->add(t, _intervals.back().u_seq.back().values());