44 assert(x0.size() == dynamics->getStateDimension());
46 assert(uref.
getDimension() == dynamics->getInputDimension());
67 if (prev_u && prev_u->size() > 0)
109 for (
int i = 0; i <
_xf_fixed.size(); ++i)
118 if (new_run || result.updated())
121 result.edges_updated =
128 if (result.updated())
134 result.edges_updated =
true;
158 int num_normal_intervals;
159 int add_controls_last_interval;
163 num_normal_intervals = n_init - 1;
164 add_controls_last_interval = 0;
169 num_normal_intervals = interv_div.quot;
170 add_controls_last_interval = interv_div.rem;
174 Eigen::VectorXd dir = xf - x0;
175 double dist = dir.norm();
176 if (dist != 0) dir /= dist;
177 double step = dist / (n_init - 1);
180 for (
int i = 0; i < num_normal_intervals; ++i)
192 if (add_controls_last_interval > 0)
197 for (
int j = 0; j < add_controls_last_interval; ++j)
239 int num_normal_intervals;
240 int add_controls_last_interval;
244 num_normal_intervals = n_init - 1;
245 add_controls_last_interval = 0;
250 num_normal_intervals = interv_div.quot;
251 add_controls_last_interval = interv_div.rem;
255 for (
int i = 0; i < num_normal_intervals; ++i)
268 if (add_controls_last_interval > 0)
273 for (
int j = 0; j < add_controls_last_interval; ++j)
296 if (num_shift <= 0)
return;
300 if (num_shift >
getN() - 2)
311 for (
int i = 0; i <
getN() - num_shift; ++i)
313 int idx = i + num_shift;
314 if (idx ==
getN() - 1)
326 int idx =
getN() - num_shift;
332 for (
int i = 0; i < num_shift; ++i, ++idx)
338 if (i == num_shift - 1)
352 PRINT_WARNING_ONCE(
"Shifting for shooting grids with more than 1 control per interval not yet implemented.");
362 double first_dist = (x0 -
_intervals.front().s.values()).norm();
363 if (
std::abs(first_dist) < 1e-12)
return 0;
371 double dist_cache = first_dist;
373 int num_keep_interv = 1;
374 int lookahead =
std::min(num_interv - num_keep_interv, 20);
378 for (
int i = 1; i <= lookahead; ++i)
380 dist = (x0 -
_intervals[i].s.values()).norm();
381 if (dist < dist_cache)
397 u0 =
_intervals.front().u_seq.front().values();
407 n += interv.u_seq.size();
436 PRINT_ERROR_NAMED(
"Dimensions mismatch between xf_fixed and xf. Setting xf_fixed to false.");
446 if (interv.s.getDimension() == nlp_fun.
x_lb.size())
447 interv.s.setLowerBounds(nlp_fun.
x_lb);
449 PRINT_ERROR_NAMED(
"Cannot update lower state bounds due to dimensions mismatch");
451 if (interv.s.getDimension() == nlp_fun.
x_ub.size())
452 interv.s.setUpperBounds(nlp_fun.
u_ub);
454 PRINT_ERROR_NAMED(
"Cannot update upper state bounds due to dimensions mismatch");
461 PRINT_ERROR_NAMED(
"Cannot update lower control input bounds due to dimensions mismatch");
466 PRINT_ERROR_NAMED(
"Cannot update upper control input bounds due to dimensions mismatch");
479 if (n == n_new)
return;
491 int num_interv = n - 1;
493 double dt_old =
getDt();
495 double dt_new = dt_old * double(n - 1) / double(n_new - 1);
499 double t_old_p1 = dt_old;
501 for (
int idx_new = 1; idx_new < n_new - 1; ++idx_new)
505 t_new = dt_new * double(idx_new);
506 while (t_new >
double(idx_old) * dt_old && idx_old < n)
510 t_old_p1 = double(idx_old) * dt_old;
512 const Eigen::VectorXd& x_prev = x_seq_old.col(idx_old - 1);
513 const Eigen::VectorXd& x_cur = (idx_old < n - 1) ? x_seq_old.col(idx_old) :
_xf.
values();
515 if (idx_new < num_interv)
518 _intervals[idx_new].s.values() = x_prev + (t_new - (t_old_p1 - dt_old)) / dt_old * (x_cur - x_prev);
522 _intervals[idx_new].u_seq.front().values() = u_seq_old.col(idx_old - 1);
528 _intervals.back().s.set(x_prev + (t_new - (t_old_p1 - dt_old)) / dt_old * (x_cur - x_prev), nlp_fun.
x_lb, nlp_fun.
x_ub);
529 _intervals.back().u_seq.emplace_back(u_seq_old.col(idx_old - 1), nlp_fun.
u_lb, nlp_fun.
u_ub);
550 PRINT_WARNING_ONCE(
"Resampling for shooting grids with more than 1 control per interval not yet implemented.");
573 vertices.push_back(&interv.s);
574 for (
VectorVertex& u_vtx : interv.u_seq) vertices.push_back(&u_vtx);
577 vertices.push_back(&
_dt);
579 vertices.push_back(&
_u_ref);
602 if (x_sequence) x_sequence->clear();
603 if (u_sequence) u_sequence->clear();
613 for (const ShootingInterval& interv : _intervals) 615 if (x_sequence) x_sequence->add(t, interv.s.values()); 618 for (const VectorVertex& u_vtx : interv.u_seq) 620 u_sequence->add(t, u_vtx.values()); 622 if (t > t_max) break; 627 t += dt * (double)interv.u_seq.size(); 628 if (t > t_max) break; 631 if (t <= t_max && isXfShootingNode()) 633 if (x_sequence && t <= t_max) x_sequence->add(t, _xf.values()); 634 // duplicate last u to have the sampe time stamps as x_sequence 635 if (u_sequence) u_sequence->add(t, _intervals.back().u_seq.back().values()); virtual bool isDtFixedIntended() const
void getStateAndControlTimeSeries(TimeSeries::Ptr x_sequence, TimeSeries::Ptr u_sequence, double t_max=CORBO_INF_DBL) const override
Return state and control trajectory as time series object (shared instance)
#define PRINT_ERROR_NAMED(msg)
#define PRINT_WARNING_ONCE(msg)
Print msg-stream only once.
#define PRINT_ERROR_COND_NAMED(cond, msg)
void computeActiveVertices() override
void setPreviousControl(const Eigen::VectorXd &prev_u, double prev_u_dt)
A matrix or vector expression mapping an existing array of data.
virtual bool isFixed() const
Check if all components are fixed.
bool isEmpty() const override
virtual bool adaptGrid(bool new_run, NlpFunctions &nlp_fun)
void checkAndInitializeBoundDimensions(int x_dim, int u_dim)
virtual int getDimension() const =0
bool hasSingleDt() const override
bool _full_discretization
virtual bool isStatic() const =0
void updateBounds(const NlpFunctions &nlp_fun)
Representation of time stamps.
void resampleTrajectory(int n_new, NlpFunctions &nlp_fun)
virtual const OutputVector & getReferenceCached(int k) const =0
Eigen::Matrix< bool, -1, 1 > _xf_fixed
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const AbsReturnType abs() const
std::vector< VertexInterface * > _active_vertices
GridUpdateResult update(const Eigen::VectorXd &x0, ReferenceTrajectoryInterface &xref, ReferenceTrajectoryInterface &uref, NlpFunctions &nlp_fun, OptimizationEdgeSet &edges, SystemDynamicsInterface::Ptr dynamics, bool new_run, const Time &t, ReferenceTrajectoryInterface *sref=nullptr, const Eigen::VectorXd *prev_u=nullptr, double prev_u_dt=0, ReferenceTrajectoryInterface *xinit=nullptr, ReferenceTrajectoryInterface *uinit=nullptr) override
std::vector< ShootingInterval > _intervals
void setModified(bool modified)
void getVertices(std::vector< VertexInterface *> &vertices) override
void setUpperBounds(const Eigen::Ref< const Eigen::VectorXd > &ub) override
Define upper bounds on the vertex values [getDimension() x 1].
int _num_u_per_interv_ref
EIGEN_DEVICE_FUNC Derived & setConstant(Index size, const Scalar &val)
void clear() override
Clear complete backup container.
int getN() const override
int getDimension() const override
Return number of elements/values/components stored in this vertex.
void setLastControlRef(const Eigen::VectorXd &last_u_ref)
void set(const Eigen::Ref< const Eigen::VectorXd > &values, const Eigen::Ref< const Eigen::VectorXd > &lb, const Eigen::Ref< const Eigen::VectorXd > &ub, bool fixed=false) override
Set values and bounds at once.
int findNearestShootingInterval(const Eigen::VectorXd &x0)
const double & value() const
Get underlying value.
void clear() override
Clear complete backup container.
void setUpperBound(double ub)
Set upper bound.
double toSec() const
Cast time stamp to seconds.
bool checkAndInitializeXfFixedFlags(int dim_x)
virtual void createEdges(NlpFunctions &nlp_fun, OptimizationEdgeSet &edges, SystemDynamicsInterface::Ptr dynamics)=0
Interface class for reference trajectories.
virtual bool isGridAdaptActive() const
void initializeSequences(const Eigen::VectorXd &x0, const Eigen::VectorXd &xf, ReferenceTrajectoryInterface &uref, NlpFunctions &nlp_fun)
void setLowerBounds(const Eigen::Ref< const Eigen::VectorXd > &lb) override
Define lower bounds on the vertex values [getDimension() x 1].
virtual bool isXfShootingNode() const
void setLowerBound(double lb)
Set lower bound.
Vertex implementation that stores an Eigen::VectorXd (dynamic dimension)
bool update(int n, double t, ReferenceTrajectoryInterface &xref, ReferenceTrajectoryInterface &uref, ReferenceTrajectoryInterface *sref, bool single_dt, const Eigen::VectorXd &x0, const std::vector< double > &dts, const DiscretizationGridInterface *grid)
virtual bool isCached(double dt, int n, Time t) const =0
const Eigen::VectorXd & values() const
Read-access to the underlying value vector.
std::shared_ptr< TimeSeries > Ptr
bool getFirstControlInput(Eigen::VectorXd &u0) override
PartiallyFixedVectorVertex _xf
void warmStartShifting(const Eigen::VectorXd &x0)
virtual void precompute(double dt, int n, Time t)=0
void set(double value, double lb, double ub, bool fixed)
std::shared_ptr< SystemDynamicsInterface > Ptr
virtual bool isMovingHorizonWarmStartActive() const