full_discretization_grid_base_se2.cpp
Go to the documentation of this file.
1 /*********************************************************************
2  *
3  * Software License Agreement
4  *
5  * Copyright (c) 2020, Christoph Rösmann, All rights reserved.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <https://www.gnu.org/licenses/>.
19  *
20  * Authors: Christoph Rösmann
21  *********************************************************************/
22 
24 
26 
28 
29 #include <corbo-communication/utilities.h>
30 #include <corbo-core/console.h>
31 
32 #include <algorithm>
33 #include <cmath>
34 #include <memory>
35 
36 namespace mpc_local_planner {
37 
40  SystemDynamicsInterface::Ptr dynamics, bool new_run, const corbo::Time& t,
41  ReferenceTrajectoryInterface* sref, const Eigen::VectorXd* prev_u, double prev_u_dt,
43 {
44  assert(x0.size() == dynamics->getStateDimension());
45  assert(xref.getDimension() == x0.size());
46  assert(uref.getDimension() == dynamics->getInputDimension());
47  assert(x0.size() >= 3); // SE2 version here
48 
50  _nlp_fun = &nlp_fun; // for bound access in e.g. resampleTrajectory()
51 
52  if (isGridAdaptActive() && !_first_run && !isEmpty()) // TODO(roesmann): this might not be efficient in case warm start is deactivated
53  {
54  // adapt grid if implemented by subclass
55  adaptGrid(new_run, nlp_fun); // note, isModified() should return true if something was changed!, we could also use the return value...
56  }
57 
58  // check if we need to cache the reference trajectory values // TODO(roesmann): we could restrict this to new_run==true only as long as we do not
59  // have a grid resize...
60  int n = std::max(std::max(getNRef(), getN()), _n_adapt);
61  if (_dt.value() <= 0) _dt.value() = _dt_ref; // initialize _dt to _dt_ref in case it has not been optimized before
62  if (!xref.isCached(getDt(), n, t)) xref.precompute(getDt(), n, t);
63  if (!uref.isCached(getDt(), n, t)) uref.precompute(getDt(), n, t);
64  if (sref && !sref->isCached(getDt(), n, t)) sref->precompute(getDt(), n, t);
65  if (xinit && !xinit->isCached(getDt(), n, t)) xinit->precompute(getDt(), n, t);
66  if (uinit && !uinit->isCached(getDt(), n, t)) uinit->precompute(getDt(), n, t);
67 
68  // set previous control which might be utilized by some edges
69  if (prev_u && prev_u->size() > 0)
70  setPreviousControl(*prev_u, prev_u_dt);
71  else
72  setPreviousControl(Eigen::VectorXd::Zero(dynamics->getInputDimension()), prev_u_dt);
73 
74  // set last control to uref
76 
77  // TODO(roesmann): we do not check if bounds in nlp_fun are updated
78  // updateBounds(); // calling this everytime is not efficient
79 
80  // initialize trajectories if empty or if the goal differs from the last one
81  // reinit if goal is far away
82  if (isEmpty()) // TODO(roesmann): threshold?: if (_cached_xf.rows() > 0 && (xf - _cached_xf).norm() > _warm_start_goal_dist_reinit)
83  {
84  if (xref.isStatic() && !xinit)
85  {
86  // TODO(roesmann): optional initialization references x_init, u_init
87  initializeSequences(x0, xref.getReferenceCached(n - 1), uinit ? *uinit : uref, nlp_fun);
88  }
89  else
90  {
91  initializeSequences(x0, xref.getReferenceCached(n - 1), xinit ? *xinit : xref, uinit ? *uinit : uref, nlp_fun);
92  }
93  }
94  else
95  {
96  if (new_run && isMovingHorizonWarmStartActive())
97  {
98  // warm_start
100  }
101  if (new_run)
102  {
103  // make sure to always overwrite the start with the actual (measured) values
104  _x_seq.front().values() = x0;
105  // update fixed goal states
106  for (int i = 0; i < _xf_fixed.size(); ++i)
107  {
108  if (_xf_fixed[i]) _xf.values()[i] = xref.getReferenceCached(getN() - 1)[i];
109  }
110  }
111  }
112 
113  result.vertices_updated = isModified(); // isModified() returns if the underlying vertex set is updated
114 
115  if (new_run || result.updated()) // new run -> new t
116  {
117  // update NLP functions w.r.t. the current discretization
118  result.edges_updated =
119  nlp_fun.update(getN(), t.toSec(), xref, uref, sref, hasSingleDt(), x0, {getDt()}, this); // returns true if edge dimensions changed
120  // TODO(roesmann): sref is not yet implemented for testing, add this later...
121  // TODO(roesmann): we do not yet check if dt was updated, this might affect nlp update
122  }
123 
124  if (result.updated()) // vertices or eges updated
125  {
126  // create grid specific edges
127  // TODO(roesmann): for now, we assume that we are the only maintainer of the edge set (which might be not true generally!)
128  // so we clear the edge set whenever we want
129  createEdges(nlp_fun, edges, dynamics);
130  result.edges_updated = true; // now we definitely updated the edgeset
131  }
132  _first_run = false;
133  return result;
134 }
135 
136 void FullDiscretizationGridBaseSE2::initializeSequences(const Eigen::VectorXd& x0, const Eigen::VectorXd& xf, ReferenceTrajectoryInterface& uref,
137  NlpFunctions& nlp_fun)
138 {
139  assert(x0.size() >= 3);
140 
141  // clear(); // make sure everything is cleared
142  _x_seq.clear();
143  _u_seq.clear();
144  _xf.clear();
145  _active_vertices.clear();
146 
147  // check or initalize bounds if empty
148  nlp_fun.checkAndInitializeBoundDimensions(x0.size(), uref.getDimension());
149 
150  // check x_fixed
152 
153  int n_init = _n_adapt > 0 ? _n_adapt : _n_ref;
154 
155  int num_intervals = n_init - 1;
156 
157  // we initialize the state trajectory linearly
158  Eigen::VectorXd dir = xf - x0;
159  double dist = dir.norm();
160  if (dist != 0) dir /= dist;
161  double step = dist / num_intervals;
162 
163  // For the SE2 case here, we set the third state (orientation) to the goal heading
164  double orient_init = std::atan2(dir[1], dir[0]);
165  // but check if goal is behind start pose (w.r.t. start orientation)
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);
167 
168  for (int k = 0; k < num_intervals; ++k)
169  {
170  // add new state by linear interpolation
171  Eigen::VectorXd new_x = x0 + (double)k * step * dir;
172  if (k > 0) new_x[2] = orient_init; // but do not overwrite start orientation
173  _x_seq.emplace_back(new_x, nlp_fun.x_lb, nlp_fun.x_ub);
174  // add new constant control (assume u0 to hold
175  _u_seq.emplace_back(uref.getReferenceCached(k), nlp_fun.u_lb, nlp_fun.u_ub);
176  }
177  // add final state
178  _xf.set(xf, nlp_fun.x_lb, nlp_fun.x_ub, _xf_fixed);
179 
180  // set first state as fixed
181  _x_seq.front().setFixed(true);
182 
183  // set dt
185 
186  assert(_x_seq.size() > 0);
187 
188  // notify graph that vertices are changed
189  setModified(true);
190 }
191 
192 void FullDiscretizationGridBaseSE2::initializeSequences(const Eigen::VectorXd& x0, const Eigen::VectorXd& xf, ReferenceTrajectoryInterface& xref,
194 {
195  // clear(); // make sure everything is cleared
196  _x_seq.clear();
197  _u_seq.clear();
198  _xf.clear();
199  _active_vertices.clear();
200 
201  // TODO(roesmann): check if this is ever needed in any pracital realization:
202  // if ((x0 - xref.getReferenceCached(0)).norm() > _non_static_ref_dist_threshold)
203  // {
204  // initializeSequences(x0, xref.getReferenceCached(getN() - 1), uref, nlp_fun);
205  // }
206 
207  // check or initalize bounds if empty
208  nlp_fun.checkAndInitializeBoundDimensions(x0.size(), uref.getDimension());
209 
210  // check x_fixed
212 
213  int n_init = _n_adapt > 0 ? _n_adapt : _n_ref;
214 
215  int num_intervals = n_init - 1;
216 
217  _x_seq.emplace_back(x0, nlp_fun.x_lb, nlp_fun.x_ub); // always add the (exact) x0
218  _u_seq.emplace_back(uref.getReferenceCached(0), nlp_fun.u_lb, nlp_fun.u_ub);
219  for (int k = 1; k < num_intervals; ++k)
220  {
221  // add new state by linear interpolation
222  _x_seq.emplace_back(xref.getReferenceCached(k), nlp_fun.x_lb, nlp_fun.x_ub);
223  // add new constant control (assume u0 to hold
224  _u_seq.emplace_back(uref.getReferenceCached(k), nlp_fun.u_lb, nlp_fun.u_ub);
225  }
226  // add final state
227  _xf.set(xf, nlp_fun.x_lb, nlp_fun.x_ub, _xf_fixed);
228 
229  // set first state as fixed
230  _x_seq.front().setFixed(true);
231 
232  // set dt
234 
235  assert(_x_seq.size() > 1);
236 
237  // notify graph that vertices are changed
238  setModified(true);
239 }
240 
242 {
243  // find nearest state to x0 (ideally it is the second one in _x_seq).
244  int num_shift = findNearestState(x0);
245  if (num_shift <= 0) return;
246 
247  if (num_shift > getN() - 2)
248  {
249  PRINT_ERROR_NAMED("Cannot shift if num_shift > N-2");
250  return;
251  }
252 
253  // the simplest strategy would be to just remove remove x_seq[0], append xf to x_seq and replace xf (num_shift=1)
254  // however, this requries to change the structure which always triggers an edge recreation and so the solver must reallocate memory.
255  // TOOD(roesmann): for time-optimal stuff, if we are sure that we resize the grid, it is then more efficent to implement the strategy above...
256 
257  // shift from end to front:
258  for (int i = 0; i < getN() - num_shift; ++i)
259  {
260  int idx = i + num_shift;
261  if (idx == getN() - 1)
262  {
263  // final state reached
264  _x_seq[i].values() = _xf.values();
265  }
266  else
267  {
268  _x_seq[i].values() = _x_seq[idx].values();
269  _u_seq[i].values() = _u_seq[idx].values();
270  }
271  }
272 
273  int idx = getN() - num_shift;
274  if (idx < 0)
275  {
276  PRINT_ERROR_NAMED("idx < 0...");
277  return;
278  }
279  for (int i = 0; i < num_shift; ++i, ++idx)
280  {
281  // now extrapolate
282  assert(idx > 1);
283 
284  // linearly extrapolate states
285  if (i == num_shift - 1) // consider xf
286  {
287  _xf.values() = _x_seq[idx - 2].values() + 2.0 * (_x_seq[idx - 1].values() - _x_seq[idx - 2].values());
288  // TODO(roesmann): we could avoid computing the third row in the previous command, however, the code
289  // increases if we support additional states
290  _xf.values()[2] = interpolate_angle(_x_seq[idx - 2].values()[2], _x_seq[idx - 1].values()[2], 2.0);
291  }
292  else
293  {
294  // TODO(roesmann) multiply by fraction of last dt and _dt
295  _x_seq[idx].values() = _x_seq[idx - 2].values() + 2.0 * (_x_seq[idx - 1].values() - _x_seq[idx - 2].values());
296  // TODO(roesmann): we could avoid computing the third row in the previous command, however, the code
297  // increases if we support additional states
298  _x_seq[idx].values()[2] = interpolate_angle(_x_seq[idx - 2].values()[2], _x_seq[idx - 1].values()[2], 2.0);
299  }
300  _u_seq[idx - 1].values() = _u_seq[idx - 2].values();
301  }
302 }
303 
305 {
306  assert(!isEmpty());
307  assert(isValid());
308 
309  // same start as before
310  double first_dist = (x0 - _x_seq.front().values()).norm();
311  if (std::abs(first_dist) < 1e-12) return 0;
312 
313  // find nearest state (using l2-norm) in order to prune the trajectory
314  // (remove already passed states, should be 1 if the sampling times of the planning and controller call match, but could be higher if rates
315  // differ)
316 
317  int num_interv = getN() - 1;
318 
319  double dist_cache = first_dist;
320  double dist;
321  int num_keep_interv = 1; // std::max(1, _num_states_min - 1); // we need to keep at least this number of intervals in the trajectory
322  int lookahead = std::min(num_interv - num_keep_interv, 20); // max 20 samples
323 
324  int nearest_idx = 0;
325 
326  for (int i = 1; i <= lookahead; ++i)
327  {
328  dist = (x0 - _x_seq[i].values()).norm();
329  if (dist < dist_cache)
330  {
331  dist_cache = dist;
332  nearest_idx = i;
333  }
334  else
335  break;
336  }
337 
338  return nearest_idx;
339 }
340 
342 {
343  if (isEmpty() || !isValid()) return false;
344  assert(!_u_seq.empty());
345 
346  u0 = _u_seq.front().values();
347  return true;
348 }
349 
351 {
352  // clear grid if we change n
353  if (n != getN()) clear();
354  if (n < 2)
355  {
356  PRINT_ERROR_NAMED("Number of states must be n>1.");
357  _n_ref = 2;
358  return;
359  }
360  _n_ref = n;
361  _n_adapt = 0;
362 }
363 
364 int FullDiscretizationGridBaseSE2::findClosestPose(double x_ref, double y_ref, int start_idx, double* distance) const
365 {
366  double min_dist = std::numeric_limits<double>::max();
367  int min_idx = -1;
368 
369  for (int i = start_idx; i < (int)_x_seq.size(); ++i)
370  {
371  double dist = distance_points2d(x_ref, y_ref, _x_seq[i].values()[0], _x_seq[i].values()[1]);
372  if (dist < min_dist)
373  {
374  min_dist = dist;
375  min_idx = i;
376  }
377  }
378  double dist = distance_points2d(x_ref, y_ref, _xf.values()[0], _xf.values()[1]);
379  if (dist < min_dist)
380  {
381  min_dist = dist;
382  min_idx = (int)_x_seq.size();
383  }
384 
385  if (distance) *distance = min_dist;
386 
387  return min_idx;
388 }
389 
391 {
392  if (_xf_fixed.size() == 0)
393  {
394  _xf_fixed.setConstant(dim_x, false);
395  return true;
396  }
397  else if (_xf_fixed.size() == dim_x)
398  return true;
399 
400  PRINT_ERROR_NAMED("Dimensions mismatch between xf_fixed and xf. Setting xf_fixed to false.");
401  _xf_fixed.setConstant(dim_x, false);
402  return false;
403 }
404 
406 {
407  if (isEmpty()) return;
408  for (VectorVertexSE2& vtx : _x_seq)
409  {
410  if (vtx.getDimension() == nlp_fun.x_lb.size())
411  vtx.setLowerBounds(nlp_fun.x_lb);
412  else
413  PRINT_ERROR_NAMED("Cannot update lower state bounds due to dimensions mismatch");
414 
415  if (vtx.getDimension() == nlp_fun.x_ub.size())
416  vtx.setUpperBounds(nlp_fun.u_ub);
417  else
418  PRINT_ERROR_NAMED("Cannot update upper state bounds due to dimensions mismatch");
419  }
420 
421  for (VectorVertex& vtx : _u_seq)
422  {
423  if (vtx.getDimension() == nlp_fun.u_lb.size())
424  vtx.setLowerBounds(nlp_fun.u_lb);
425  else
426  PRINT_ERROR_NAMED("Cannot update lower control input bounds due to dimensions mismatch");
427 
428  if (vtx.getDimension() == nlp_fun.u_ub.size())
429  vtx.setUpperBounds(nlp_fun.u_ub);
430  else
431  PRINT_ERROR_NAMED("Cannot update upper control input bounds due to dimensions mismatch");
432  }
433 
436 
437  _nlp_fun = &nlp_fun; // for bound access in e.g. resampleTrajectory()
438 }
439 
441 {
442  assert(isValid());
443  int n = getN();
444  if (n == n_new) return;
445 
446  if (!_nlp_fun)
447  {
448  PRINT_ERROR_NAMED("We currently need _nlp_fun to be valid in order to retrieve bounds");
449  }
450 
451  // copy vertices (vertices itself are shared pointers)
454  TimeSeries::Ptr ts_states_old = std::make_shared<TimeSeries>();
455  TimeSeries::Ptr ts_controls_old = std::make_shared<TimeSeries>();
456  getStateAndControlTimeSeries(ts_states_old, ts_controls_old);
457 
458  TimeSeries::ValuesMatMap x_seq_old = ts_states_old->getValuesMatrixView();
459  TimeSeries::ValuesMatMap u_seq_old = ts_controls_old->getValuesMatrixView();
460 
461  int num_interv = n - 1;
462 
463  double dt_old = getDt();
464  // compute new time diff
465  double dt_new = dt_old * double(n - 1) / double(n_new - 1);
466 
467  double t_new;
468  int idx_old = 1;
469  double t_old_p1 = dt_old; // time for old sample with index idx_old (acutally its the subsequent time step w.r.t t_new)
470 
471  for (int idx_new = 1; idx_new < n_new - 1; ++idx_new) // n_new-1 since last state is identical and copied later. idx_new=1, since start
472  // sample is already valid (we do not touch it)
473  // we allow a small mismatch for the control u_1 and let the optimizer correct it later
474  {
475  t_new = dt_new * double(idx_new);
476  while (t_new > double(idx_old) * dt_old && idx_old < n)
477  {
478  ++idx_old;
479  }; // find idx_old that represents the state subsequent to the new one (w.r.t. time)
480  t_old_p1 = double(idx_old) * dt_old;
481 
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();
484 
485  if (idx_new < num_interv)
486  {
487  // states
488  _x_seq[idx_new].values() = x_prev + (t_new - (t_old_p1 - dt_old)) / dt_old * (x_cur - x_prev);
489  // overwrite angle (since we are in SE2, at least the first three states are SE2)
490  // TODO(roesmann): we could avoid computing the third row in the previous command, however, the code
491  // increases if we support additional states
492  _x_seq[idx_new].values()[2] = interpolate_angle(x_prev[2], x_cur[2], (t_new - (t_old_p1 - dt_old)) / dt_old);
493 
494  // controls
495  // TODO(roesmann): we do not have a valid control (u_f), so hold last
496  _u_seq[idx_new].values() = u_seq_old.col(idx_old - 1);
497  }
498  else
499  {
500  // add new pair
501  _x_seq.emplace_back(x_prev + (t_new - (t_old_p1 - dt_old)) / dt_old * (x_cur - x_prev), _nlp_fun->x_lb, _nlp_fun->x_ub);
502  // TODO(roesmann): we could avoid computing the third row in the previous command, however, the code
503  // increases if we support additional states
504  _x_seq.back().values()[2] = interpolate_angle(x_prev[2], x_cur[2], (t_new - (t_old_p1 - dt_old)) / dt_old);
505  _u_seq.emplace_back(u_seq_old.col(idx_old - 1), _nlp_fun->u_lb, _nlp_fun->u_ub);
506  }
507  }
508 
509  // clear invalid states
510  if (n_new < n)
511  {
512  _x_seq.resize(n_new - 1);
513  _u_seq.resize(n_new - 1);
514  }
515 
516  // save new dt
517  _dt.value() = dt_new;
518 
519  // set first vertex always to fixed
520  // _x_seq.front().setFixed(true); // should not be necessary here (we just change values in the first node)
521 
522  // notify graph that vertices are changed
523  setModified(true);
524 }
525 
527 {
528  _x_seq.clear();
529  _u_seq.clear();
530  _xf.clear();
531  _active_vertices.clear();
532  _nlp_fun = nullptr;
533  _n_adapt = 0;
534  _first_run = true;
535  setModified(true);
536 }
537 
538 void FullDiscretizationGridBaseSE2::setN(int n, bool try_resample)
539 {
540  if (try_resample && _nlp_fun && !isEmpty())
541  {
543  }
544  else
545  {
546  clear(); // resampling not yet implemented
547  }
548  setNRef(n);
549 }
550 
551 void FullDiscretizationGridBaseSE2::getVertices(std::vector<VertexInterface*>& vertices)
552 {
553  vertices.clear();
554  // order doesn't matter here
555  for (VectorVertexSE2& vtx : _x_seq) vertices.push_back(&vtx);
556  for (VectorVertex& vtx : _u_seq) vertices.push_back(&vtx);
557  vertices.push_back(&_xf);
558  vertices.push_back(&_dt); // make sure to make it fixed if desired in any subclass
559  vertices.push_back(&_u_prev); // always fixed...
560  vertices.push_back(&_u_prev_dt); // always fixed...
561  vertices.push_back(&_u_ref); // always fixed...
562 }
563 
565 {
566  _active_vertices.clear();
567  assert(isValid());
568  int n = getN();
569 
570  for (int i = 0; i < n - 1; ++i)
571  {
572  if (!_x_seq[i].isFixed()) _active_vertices.push_back(&_x_seq[i]);
573  if (!_u_seq[i].isFixed()) _active_vertices.push_back(&_u_seq[i]);
574  }
575  if (!_xf.isFixed()) _active_vertices.push_back(&_xf);
576  if (!_dt.isFixed()) _active_vertices.push_back(&_dt);
577 }
578 
580 {
581  if (x_sequence) x_sequence->clear();
582  if (u_sequence) u_sequence->clear();
583 
584  if (isEmpty()) return;
585  assert(isValid());
586 
587  PRINT_ERROR_COND_NAMED(t_max < 0, "t_max >= 0 required");
588 
589  double dt = getDt();
590 
591  if (x_sequence)
592  {
593  double t = 0;
594  for (int i = 0; i < _x_seq.size(); ++i)
595  {
596  x_sequence->add(t, _x_seq[i].values());
597  t += dt;
598  if (t > t_max) break;
599  }
600  if (t <= t_max) x_sequence->add(t, _xf.values());
601  }
602 
603  if (u_sequence)
604  {
605  double t = 0;
606  for (int i = 0; i < _u_seq.size(); ++i)
607  {
608  u_sequence->add(t, _u_seq[i].values());
609  t += dt;
610  if (t > t_max) break;
611  }
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());
614  }
615 }
616 
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...
Eigen::VectorXd x_lb
#define PRINT_ERROR_COND_NAMED(cond, msg)
return int(ret)+1
std::vector< double > values
void setPreviousControl(const Eigen::VectorXd &prev_u, double prev_u_dt)
Eigen::VectorXd u_ub
virtual bool adaptGrid(bool new_run, NlpFunctions &nlp_fun)
void getVertices(std::vector< VertexInterface *> &vertices) override
virtual bool isFixed() const
void checkAndInitializeBoundDimensions(int x_dim, int u_dim)
virtual int getDimension() const=0
Eigen::VectorXd u_lb
virtual bool isStatic() const=0
virtual const OutputVector & getReferenceCached(int k) const=0
Vertex specialization for vectors in SE2.
Eigen::VectorXd x_ub
double interpolate_angle(double angle1, double angle2, double factor)
Return the interpolated angle between two angles [rad].
Definition: math_utils.h:100
virtual void createEdges(NlpFunctions &nlp_fun, OptimizationEdgeSet &edges, SystemDynamicsInterface::Ptr dynamics)=0
int getN() const override
get current horizon length
void setModified(bool modified)
EIGEN_DEVICE_FUNC Derived & setConstant(Index size, const Scalar &val)
void clear() 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.
Definition: math_utils.h:56
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.
unsigned int step
double toSec() const
double normalize_theta(double theta)
normalize angle to interval [-pi, pi)
Definition: math_utils.h:81
void setLowerBound(double lb)
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
const Eigen::VectorXd & values() const
std::shared_ptr< TimeSeries > Ptr
virtual void precompute(double dt, int n, Time t)=0
PlainMatrixType mat * n
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)
std::shared_ptr< SystemDynamicsInterface > Ptr


mpc_local_planner
Author(s): Christoph Rösmann
autogenerated on Mon Feb 28 2022 22:53:18