43 assert(x0.size() == dynamics->getStateDimension());
45 assert(uref.
getDimension() == dynamics->getInputDimension());
67 if (prev_u && prev_u->size() > 0)
101 _x_seq.front().values() = x0;
103 for (
int i = 0; i <
_xf_fixed.size(); ++i)
112 if (new_run || result.updated())
122 if (result.updated())
128 result.edges_updated =
true;
151 int num_intervals = n_init - 1;
154 Eigen::VectorXd dir = xf - x0;
155 double dist = dir.norm();
156 if (dist != 0) dir /= dist;
157 double step = dist / num_intervals;
159 for (
int k = 0; k < num_intervals; ++k)
162 _x_seq.emplace_back(x0 + (
double)k * step * dir, nlp_fun.
x_lb, nlp_fun.
x_ub);
170 _x_seq.front().setFixed(
true);
175 assert(
_x_seq.size() > 0);
204 int num_intervals = n_init - 1;
208 for (
int k = 1; k < num_intervals; ++k)
219 _x_seq.front().setFixed(
true);
224 assert(
_x_seq.size() > 1);
234 if (num_shift <= 0)
return;
236 if (num_shift >
getN() - 2)
247 for (
int i = 0; i <
getN() - num_shift; ++i)
249 int idx = i + num_shift;
250 if (idx ==
getN() - 1)
262 int idx =
getN() - num_shift;
268 for (
int i = 0; i < num_shift; ++i, ++idx)
274 if (i == num_shift - 1)
293 double first_dist = (x0 -
_x_seq.front().values()).norm();
294 if (
std::abs(first_dist) < 1e-12)
return 0;
300 int num_interv =
getN() - 1;
302 double dist_cache = first_dist;
304 int num_keep_interv = 1;
305 int lookahead =
std::min(num_interv - num_keep_interv, 20);
309 for (
int i = 1; i <= lookahead; ++i)
311 dist = (x0 -
_x_seq[i].values()).norm();
312 if (dist < dist_cache)
329 u0 =
_u_seq.front().values();
357 PRINT_ERROR_NAMED(
"Dimensions mismatch between xf_fixed and xf. Setting xf_fixed to false.");
367 if (vtx.getDimension() == nlp_fun.
x_lb.size())
368 vtx.setLowerBounds(nlp_fun.
x_lb);
370 PRINT_ERROR_NAMED(
"Cannot update lower state bounds due to dimensions mismatch");
372 if (vtx.getDimension() == nlp_fun.
x_ub.size())
373 vtx.setUpperBounds(nlp_fun.
u_ub);
375 PRINT_ERROR_NAMED(
"Cannot update upper state bounds due to dimensions mismatch");
380 if (vtx.getDimension() == nlp_fun.
u_lb.size())
381 vtx.setLowerBounds(nlp_fun.
u_lb);
383 PRINT_ERROR_NAMED(
"Cannot update lower control input bounds due to dimensions mismatch");
385 if (vtx.getDimension() == nlp_fun.
u_ub.size())
386 vtx.setUpperBounds(nlp_fun.
u_ub);
388 PRINT_ERROR_NAMED(
"Cannot update upper control input bounds due to dimensions mismatch");
401 if (n == n_new)
return;
405 PRINT_ERROR_NAMED(
"We currently need _nlp_fun to be valid in order to retrieve bounds");
418 int num_interv = n - 1;
420 double dt_old =
getDt();
422 double dt_new = dt_old * double(n - 1) / double(n_new - 1);
426 double t_old_p1 = dt_old;
428 for (
int idx_new = 1; idx_new < n_new - 1; ++idx_new)
432 t_new = dt_new * double(idx_new);
433 while (t_new >
double(idx_old) * dt_old && idx_old < n)
437 t_old_p1 = double(idx_old) * dt_old;
439 const Eigen::VectorXd& x_prev = x_seq_old.col(idx_old - 1);
440 const Eigen::VectorXd& x_cur = (idx_old < n - 1) ? x_seq_old.col(idx_old) :
_xf.
values();
442 if (idx_new < num_interv)
445 _x_seq[idx_new].values() = x_prev + (t_new - (t_old_p1 - dt_old)) / dt_old * (x_cur - x_prev);
449 _u_seq[idx_new].values() = u_seq_old.col(idx_old - 1);
507 vertices.push_back(&
_xf);
508 vertices.push_back(&
_dt);
510 vertices.push_back(&
_u_ref);
520 for (
int i = 0; i < n - 1; ++i)
531 if (x_sequence) x_sequence->clear();
532 if (u_sequence) u_sequence->clear();
544 for (int i = 0; i < _x_seq.size(); ++i) 546 x_sequence->add(t, _x_seq[i].values()); 548 if (t > t_max) break; 550 if (t <= t_max) x_sequence->add(t, _xf.values()); 556 for (int i = 0; i < _u_seq.size(); ++i) 558 u_sequence->add(t, _u_seq[i].values()); 560 if (t > t_max) break; 562 // duplicate last u to have the sampe time stamps as x_sequence 563 if (t <= t_max) u_sequence->add(t, _u_seq.back().values()); #define PRINT_ERROR_NAMED(msg)
virtual void resampleTrajectory(int n_new)
int findNearestState(const Eigen::VectorXd &x0)
#define PRINT_ERROR_COND_NAMED(cond, msg)
std::vector< VertexInterface * > _active_vertices
void setPreviousControl(const Eigen::VectorXd &prev_u, double prev_u_dt)
A matrix or vector expression mapping an existing array of data.
int getN() const override
virtual bool isFixed() const
Check if all components are fixed.
void checkAndInitializeBoundDimensions(int x_dim, int u_dim)
virtual int getDimension() const =0
virtual bool isMovingHorizonWarmStartActive() const
virtual void createEdges(NlpFunctions &nlp_fun, OptimizationEdgeSet &edges, SystemDynamicsInterface::Ptr dynamics)=0
virtual bool isStatic() const =0
Representation of time stamps.
PartiallyFixedVectorVertex _xf
virtual const OutputVector & getReferenceCached(int k) const =0
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const AbsReturnType abs() const
virtual bool adaptGrid(bool new_run, NlpFunctions &nlp_fun)
void computeActiveVertices() override
void setN(int n, bool try_resample=true) override
Return dimension of the control input dimension in the grid.
bool isEmpty() const override
virtual void initializeSequences(const Eigen::VectorXd &x0, const Eigen::VectorXd &xf, ReferenceTrajectoryInterface &uref, NlpFunctions &nlp_fun)
virtual bool isValid() const
void getVertices(std::vector< VertexInterface *> &vertices) override
void setModified(bool modified)
EIGEN_DEVICE_FUNC Derived & setConstant(Index size, const Scalar &val)
void clear() override
Clear complete backup container.
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.
const double & value() const
Get underlying value.
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
void setUpperBound(double ub)
Set upper bound.
bool getFirstControlInput(Eigen::VectorXd &u0) override
double toSec() const
Cast time stamp to seconds.
virtual void warmStartShifting(const Eigen::VectorXd &x0)
Interface class for reference trajectories.
std::vector< VectorVertex > _u_seq
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)
bool hasSingleDt() const override
virtual bool isCached(double dt, int n, Time t) const =0
Eigen::Matrix< bool, -1, 1 > _xf_fixed
const Eigen::VectorXd & values() const
Read-access to the underlying value vector.
void updateBounds(const NlpFunctions &nlp_fun)
std::vector< VectorVertex > _x_seq
const NlpFunctions * _nlp_fun
std::shared_ptr< TimeSeries > Ptr
virtual void precompute(double dt, int n, Time t)=0
bool checkAndInitializeXfFixedFlags(int dim_x)
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)
virtual bool isGridAdaptActive() const
void set(double value, double lb, double ub, bool fixed)
virtual bool isDtFixedIntended() const
std::shared_ptr< SystemDynamicsInterface > Ptr