29 #include <corbo-communication/utilities.h> 44 assert(x0.size() == dynamics->getStateDimension());
46 assert(uref.
getDimension() == dynamics->getInputDimension());
47 assert(x0.size() >= 3);
69 if (prev_u && prev_u->size() > 0)
104 _x_seq.front().values() = x0;
106 for (
int i = 0; i <
_xf_fixed.size(); ++i)
115 if (new_run || result.updated())
118 result.edges_updated =
124 if (result.updated())
130 result.edges_updated =
true;
139 assert(x0.size() >= 3);
155 int num_intervals = n_init - 1;
158 Eigen::VectorXd dir = xf - x0;
159 double dist = dir.norm();
160 if (dist != 0) dir /= dist;
161 double step = dist / num_intervals;
164 double orient_init = std::atan2(dir[1], dir[0]);
166 if (dir.head(2).dot(Eigen::Vector2d(std::cos(x0[2]), std::sin(x0[2]))) < 0) orient_init =
normalize_theta(orient_init + M_PI);
168 for (
int k = 0; k < num_intervals; ++k)
171 Eigen::VectorXd new_x = x0 + (double)k * step * dir;
172 if (k > 0) new_x[2] = orient_init;
181 _x_seq.front().setFixed(
true);
186 assert(
_x_seq.size() > 0);
215 int num_intervals = n_init - 1;
219 for (
int k = 1; k < num_intervals; ++k)
230 _x_seq.front().setFixed(
true);
235 assert(
_x_seq.size() > 1);
245 if (num_shift <= 0)
return;
247 if (num_shift >
getN() - 2)
258 for (
int i = 0; i <
getN() - num_shift; ++i)
260 int idx = i + num_shift;
261 if (idx ==
getN() - 1)
273 int idx =
getN() - num_shift;
279 for (
int i = 0; i < num_shift; ++i, ++idx)
285 if (i == num_shift - 1)
310 double first_dist = (x0 -
_x_seq.front().values()).norm();
311 if (std::abs(first_dist) < 1e-12)
return 0;
317 int num_interv =
getN() - 1;
319 double dist_cache = first_dist;
321 int num_keep_interv = 1;
322 int lookahead = std::min(num_interv - num_keep_interv, 20);
326 for (
int i = 1; i <= lookahead; ++i)
328 dist = (x0 -
_x_seq[i].values()).norm();
329 if (dist < dist_cache)
346 u0 =
_u_seq.front().values();
366 double min_dist = std::numeric_limits<double>::max();
369 for (
int i = start_idx; i < (
int)
_x_seq.size(); ++i)
385 if (distance) *distance = min_dist;
400 PRINT_ERROR_NAMED(
"Dimensions mismatch between xf_fixed and xf. Setting xf_fixed to false.");
410 if (vtx.getDimension() == nlp_fun.
x_lb.size())
411 vtx.setLowerBounds(nlp_fun.
x_lb);
413 PRINT_ERROR_NAMED(
"Cannot update lower state bounds due to dimensions mismatch");
415 if (vtx.getDimension() == nlp_fun.
x_ub.size())
416 vtx.setUpperBounds(nlp_fun.
u_ub);
418 PRINT_ERROR_NAMED(
"Cannot update upper state bounds due to dimensions mismatch");
423 if (vtx.getDimension() == nlp_fun.
u_lb.size())
424 vtx.setLowerBounds(nlp_fun.
u_lb);
426 PRINT_ERROR_NAMED(
"Cannot update lower control input bounds due to dimensions mismatch");
428 if (vtx.getDimension() == nlp_fun.
u_ub.size())
429 vtx.setUpperBounds(nlp_fun.
u_ub);
431 PRINT_ERROR_NAMED(
"Cannot update upper control input bounds due to dimensions mismatch");
444 if (n == n_new)
return;
448 PRINT_ERROR_NAMED(
"We currently need _nlp_fun to be valid in order to retrieve bounds");
461 int num_interv = n - 1;
463 double dt_old =
getDt();
465 double dt_new = dt_old * double(n - 1) / double(n_new - 1);
469 double t_old_p1 = dt_old;
471 for (
int idx_new = 1; idx_new < n_new - 1; ++idx_new)
475 t_new = dt_new * double(idx_new);
476 while (t_new >
double(idx_old) * dt_old && idx_old < n)
480 t_old_p1 = double(idx_old) * dt_old;
482 const Eigen::VectorXd& x_prev = x_seq_old.col(idx_old - 1);
483 const Eigen::VectorXd& x_cur = (idx_old < n - 1) ? x_seq_old.col(idx_old) :
_xf.
values();
485 if (idx_new < num_interv)
488 _x_seq[idx_new].values() = x_prev + (t_new - (t_old_p1 - dt_old)) / dt_old * (x_cur - x_prev);
496 _u_seq[idx_new].values() = u_seq_old.col(idx_old - 1);
557 vertices.push_back(&
_xf);
558 vertices.push_back(&
_dt);
561 vertices.push_back(&
_u_ref);
570 for (
int i = 0; i < n - 1; ++i)
581 if (x_sequence) x_sequence->clear();
582 if (u_sequence) u_sequence->clear();
594 for (int i = 0; i < _x_seq.size(); ++i) 596 x_sequence->add(t, _x_seq[i].values()); 598 if (t > t_max) break; 600 if (t <= t_max) x_sequence->add(t, _xf.values()); 606 for (int i = 0; i < _u_seq.size(); ++i) 608 u_sequence->add(t, _u_seq[i].values()); 610 if (t > t_max) break; 612 // duplicate last u to have the sampe time stamps as x_sequence 613 if (t <= t_max) u_sequence->add(t, _u_seq.back().values()); 617 } // namespace mpc_local_planner
#define PRINT_ERROR_NAMED(msg)
int findClosestPose(double x_ref, double y_ref, int start_idx=0, double *distance=nullptr) const
Find the closest pose (first part of the state vector) on the grid w.r.t. to a provided reference poi...
PartiallyFixedVectorVertexSE2 _xf
#define PRINT_ERROR_COND_NAMED(cond, msg)
virtual bool isDtFixedIntended() const
std::vector< double > values
void setPreviousControl(const Eigen::VectorXd &prev_u, double prev_u_dt)
virtual bool isValid() const
void computeActiveVertices() override
virtual bool adaptGrid(bool new_run, NlpFunctions &nlp_fun)
Eigen::Matrix< bool, -1, 1 > _xf_fixed
void setNRef(int n)
set reference horizon length
void getVertices(std::vector< VertexInterface *> &vertices) override
virtual bool isFixed() const
void checkAndInitializeBoundDimensions(int x_dim, int u_dim)
virtual int getDimension() const=0
std::vector< VectorVertex > _u_seq
void updateBounds(const NlpFunctions &nlp_fun)
virtual bool isStatic() const=0
virtual void warmStartShifting(const Eigen::VectorXd &x0)
virtual const OutputVector & getReferenceCached(int k) const=0
Vertex specialization for vectors in SE2.
std::vector< VectorVertexSE2 > _x_seq
double interpolate_angle(double angle1, double angle2, double factor)
Return the interpolated angle between two angles [rad].
const NlpFunctions * _nlp_fun
virtual void createEdges(NlpFunctions &nlp_fun, OptimizationEdgeSet &edges, SystemDynamicsInterface::Ptr dynamics)=0
int getN() const override
get current horizon length
virtual void resampleTrajectory(int n_new)
void setModified(bool modified)
EIGEN_DEVICE_FUNC Derived & setConstant(Index size, const Scalar &val)
bool isEmpty() const override
void setLastControlRef(const Eigen::VectorXd &last_u_ref)
const double & value() const
corbo::GridUpdateResult update(const Eigen::VectorXd &x0, ReferenceTrajectoryInterface &xref, ReferenceTrajectoryInterface &uref, NlpFunctions &nlp_fun, OptimizationEdgeSet &edges, SystemDynamicsInterface::Ptr dynamics, bool new_run, const corbo::Time &t, ReferenceTrajectoryInterface *sref=nullptr, const Eigen::VectorXd *prev_u=nullptr, double prev_u_dt=0, ReferenceTrajectoryInterface *xinit=nullptr, ReferenceTrajectoryInterface *uinit=nullptr) override
double distance_points2d(const P1 &point1, const P2 &point2)
Calculate Euclidean distance between two 2D point datatypes.
void setUpperBound(double ub)
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.
std::vector< VertexInterface * > _active_vertices
int findNearestState(const Eigen::VectorXd &x0)
virtual bool isGridAdaptActive() const
double normalize_theta(double theta)
normalize angle to interval [-pi, pi)
void setLowerBound(double lb)
bool getFirstControlInput(Eigen::VectorXd &u0) override
bool hasSingleDt() const override
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)
double getDt() const
get current temporal resolution
virtual void initializeSequences(const Eigen::VectorXd &x0, const Eigen::VectorXd &xf, ReferenceTrajectoryInterface &uref, NlpFunctions &nlp_fun)
virtual bool isCached(double dt, int n, Time t) const=0
virtual bool isMovingHorizonWarmStartActive() const
bool checkAndInitializeXfFixedFlags(int dim_x)
const Eigen::VectorXd & values() const
std::shared_ptr< TimeSeries > Ptr
virtual void precompute(double dt, int n, Time t)=0
int getNRef() const
get reference horizon length
void getStateAndControlTimeSeries(TimeSeries::Ptr x_sequence, TimeSeries::Ptr u_sequence, double t_max=corbo::CORBO_INF_DBL) const override
void set(double value, double lb, double ub, bool fixed)
void setN(int n, bool try_resample=true) override
std::shared_ptr< SystemDynamicsInterface > Ptr