Go to the documentation of this file.
31 if (x_sequence) x_sequence->clear();
32 if (u_sequence) u_sequence->clear();
44 for (int i = 0; i < _x_seq.size(); ++i)
46 x_sequence->add(t, _x_seq[i].values());
50 if (t <= t_max) x_sequence->add(t, _xf.values());
56 for (int i = 0; i < _u_seq.size(); ++i)
58 // Use blocking vector to reconstruct valid time series
59 for (int j = 0; j < _blocking_vector(i); ++j)
61 u_sequence->add(t, _u_seq[i].values());
66 // duplicate last u to have the sampe time stamps as x_sequence
67 if (t <= t_max) u_sequence->add(t, _u_seq.back().values());
71 bool FullDiscretizationGridMoveBlockingBase::isValid() const
73 // Check for consistent blocking vector and correct, implicit u sequence
74 return (_u_seq.size() == _blocking_vector.size()) && (_blocking_vector.sum() == _x_seq.size());
77 void FullDiscretizationGridMoveBlockingBase::initializeSequences(const Eigen::VectorXd& x0, const Eigen::VectorXd& xf,
78 ReferenceTrajectoryInterface& uref, NlpFunctions& nlp_fun)
80 // clear(); // make sure everything is cleared
84 _active_vertices.clear();
86 // check or initalize bounds if empty
87 nlp_fun.checkAndInitializeBoundDimensions(x0.size(), uref.getDimension());
90 checkAndInitializeXfFixedFlags(x0.size());
92 int n_init = _n_adapt > 0 ? _n_adapt : _n_ref;
94 int num_intervals = n_init - 1;
96 // we initialize the state trajectory linearly
97 Eigen::VectorXd dir = xf - x0;
98 double dist = dir.norm();
99 if (dist != 0) dir /= dist;
100 double step = dist / num_intervals;
102 for (int k = 0; k < num_intervals; ++k)
104 // add new state by linear interpolation
105 _x_seq.emplace_back(x0 + (double)k * step * dir, nlp_fun.x_lb, nlp_fun.x_ub);
109 for (int k = 0; k < _blocking_vector.size(); ++k)
111 // add new control according to blocking vector
112 _u_seq.emplace_back(uref.getReferenceCached(ref_id), nlp_fun.u_lb, nlp_fun.u_ub);
113 ref_id += _blocking_vector(k);
117 _xf.set(xf, nlp_fun.x_lb, nlp_fun.x_ub, _xf_fixed);
119 // set first state as fixed
120 _x_seq.front().setFixed(true);
123 _dt.set(_dt_ref, _dt_lb, _dt_ub, isDtFixedIntended());
125 assert(_x_seq.size() > 0);
127 // notify graph that vertices are changed
131 void FullDiscretizationGridMoveBlockingBase::initializeSequences(const Eigen::VectorXd& x0, const Eigen::VectorXd& xf,
132 ReferenceTrajectoryInterface& xref, ReferenceTrajectoryInterface& uref,
133 NlpFunctions& nlp_fun)
135 // clear(); // make sure everything is cleared
139 _active_vertices.clear();
141 // TODO(roesmann): check if this is ever needed in any pracital realization:
142 // if ((x0 - xref.getReferenceCached(0)).norm() > _non_static_ref_dist_threshold)
144 // initializeSequences(x0, xref.getReferenceCached(getN() - 1), uref, nlp_fun);
147 // check or initalize bounds if empty
148 nlp_fun.checkAndInitializeBoundDimensions(x0.size(), uref.getDimension());
151 checkAndInitializeXfFixedFlags(x0.size());
153 int n_init = _n_adapt > 0 ? _n_adapt : _n_ref;
155 int num_intervals = n_init - 1;
157 _x_seq.emplace_back(x0, nlp_fun.x_lb, nlp_fun.x_ub); // always add the (exact) x0
158 for (int k = 1; k < num_intervals; ++k)
160 // add new state by linear interpolation
161 _x_seq.emplace_back(xref.getReferenceCached(k), nlp_fun.x_lb, nlp_fun.x_ub);
165 for (int k = 0; k < _blocking_vector.size(); ++k)
167 // add new control according to blocking vector
168 _u_seq.emplace_back(uref.getReferenceCached(ref_id), nlp_fun.u_lb, nlp_fun.u_ub);
169 ref_id += _blocking_vector(k);
173 _xf.set(xf, nlp_fun.x_lb, nlp_fun.x_ub, _xf_fixed);
175 // set first state as fixed
176 _x_seq.front().setFixed(true);
179 _dt.set(_dt_ref, _dt_lb, _dt_ub, isDtFixedIntended());
181 assert(_x_seq.size() > 1);
183 // notify graph that vertices are changed
187 void FullDiscretizationGridMoveBlockingBase::warmStartShifting(const Eigen::VectorXd& x0)
189 // find nearest state to x0 (ideally it is the second one in _x_seq).
190 int num_shift = findNearestState(x0);
191 if (num_shift <= 0) return;
193 if (num_shift > getN() - 2)
195 PRINT_ERROR_NAMED("Cannot shift
if num_shift >
N-2
");
199 // the simplest strategy would be to just remove remove x_seq[0], append xf to x_seq and replace xf (num_shift=1)
200 // however, this requries to change the structure which always triggers an edge recreation and so the solver must reallocate memory.
201 // 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...
203 // shift from end to front:
204 for (int i = 0; i < getN() - num_shift; ++i)
206 int idx = i + num_shift;
207 if (idx == getN() - 1)
209 // final state reached
210 _x_seq[i].values() = _xf.values();
214 _x_seq[i].values() = _x_seq[idx].values();
218 if (_warm_start_shift_u)
225 for (; block_idx < _blocking_vector.size(); ++block_idx)
227 for (; k < _blocking_vector.size(); ++k)
229 if (u_idx + _blocking_vector(k) > num_shift + i)
231 _u_seq[block_idx].values() = _u_seq[k].values();
236 u_idx += _blocking_vector(k);
239 if (k == _blocking_vector.size())
244 i += _blocking_vector(block_idx);
246 for (int j = block_idx; j < _blocking_vector.size(); ++j)
248 _u_seq[j].values() = _u_seq[j - 1].values();
252 int idx = getN() - num_shift;
255 PRINT_ERROR_NAMED("idx < 0...
");
258 for (int i = 0; i < num_shift; ++i, ++idx)
263 // linearly extrapolate states
264 if (i == num_shift - 1) // consider xf
266 _xf.values() = _x_seq[idx - 2].values() + 2.0 * (_x_seq[idx - 1].values() - _x_seq[idx - 2].values());
270 _x_seq[idx].values() = _x_seq[idx - 2].values() + 2.0 * (_x_seq[idx - 1].values() - _x_seq[idx - 2].values());
271 // TODO(roesmann) multiply by fraction of last dt and _dt
276 void FullDiscretizationGridMoveBlockingBase::resampleTrajectory(int n_new) { PRINT_ERROR_NAMED("Not supported
for move blocking
"); }
278 void FullDiscretizationGridMoveBlockingBase::computeActiveVertices()
280 _active_vertices.clear();
286 for (int i = 0; i < n - 1; ++i)
288 if (!_x_seq[i].isFixed()) _active_vertices.push_back(&_x_seq[i]);
289 if ((i == u_idx) && (!_u_seq[block_idx].isFixed()))
291 _active_vertices.push_back(&_u_seq[block_idx]);
293 u_idx += _blocking_vector(block_idx);
294 ++block_idx; // TODO(kraemer) increment on fixed
298 if (!_xf.isFixed()) _active_vertices.push_back(&_xf);
299 if (!_dt.isFixed()) _active_vertices.push_back(&_dt);
#define PRINT_ERROR_COND_NAMED(cond, msg)
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)
bool isEmpty() const override
std::shared_ptr< TimeSeries > Ptr
bool isValid() const override
control_box_rst
Author(s): Christoph Rösmann
autogenerated on Wed Mar 2 2022 00:05:45