param_func_spline0_dist.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Software License Agreement (BSD License) *
3  * Copyright (C) 2016 by Horatiu George Todoran <todorangrg@gmail.com> *
4  * *
5  * Redistribution and use in source and binary forms, with or without *
6  * modification, are permitted provided that the following conditions *
7  * are met: *
8  * *
9  * 1. Redistributions of source code must retain the above copyright *
10  * notice, this list of conditions and the following disclaimer. *
11  * 2. Redistributions in binary form must reproduce the above copyright *
12  * notice, this list of conditions and the following disclaimer in *
13  * the documentation and/or other materials provided with the *
14  * distribution. *
15  * 3. Neither the name of the copyright holder nor the names of its *
16  * contributors may be used to endorse or promote products derived *
17  * from this software without specific prior written permission. *
18  * *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *
23  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY *
29  * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
30  * POSSIBILITY OF SUCH DAMAGE. *
31  ***************************************************************************/
32 
34 #include <tuw_control/utils.h>
35 
36 #include <float.h>
37 #include <math.h>
38 #include <algorithm>
39 
40 #include <iostream>
41 
42 using namespace tuw;
43 using namespace std;
44 
46 
47 void ParamFuncsSpline0Dist::setDistCfMode(TraveledDistCfMode _distCfMode, const vector<std::size_t>& _distRelFuncIdx)
48 {
49  distCfMode_ = _distCfMode;
50  distRelFuncIdx_ = _distRelFuncIdx;
51  switch (distCfMode_)
52  {
53  case TDM::NONE:
54  break;
55  case TDM::V:
56  distLinkedFuncIdx_.resize(1, _distRelFuncIdx[0]);
57  distEvalCache_.resize(funcCtrlPt_[_distRelFuncIdx[0]].size(), 0);
58  computeSFuncPtr_ = &ParamFuncsSpline0Dist::computeS_V;
59  computeDs2DtPtr_ = &ParamFuncsSpline0Dist::computeT_V;
60  distLinkedArcIdx_ = func2Arc_[_distRelFuncIdx[0]];
61  break;
62  case TDM::AV:
63  distLinkedFuncIdx_.resize(1, _distRelFuncIdx[0]);
64  distEvalCache_.resize(funcCtrlPt_[_distRelFuncIdx[0]].size(), 0);
65  computeSFuncPtr_ = &ParamFuncsSpline0Dist::computeS_AV;
66  computeDs2DtPtr_ = &ParamFuncsSpline0Dist::computeT_AV;
67  distLinkedArcIdx_ = func2Arc_[_distRelFuncIdx[0]];
68  break;
69  }
70 }
71 
73 {
74  initImpl();
76 }
78 {
81  return *this;
82 }
83 
85 {
86  if (distCfMode_ == TDM::NONE)
87  {
88  return;
89  }
90 
91  const size_t& func0Idx = distLinkedFuncIdx_[0];
92  const size_t ctrlPtSize = funcCtrlPt_[func0Idx].size() - 1;
93  distEvalCache_[0] = 0;
94  for (size_t funcCtrlPtIdx = 0; funcCtrlPtIdx < ctrlPtSize; ++funcCtrlPtIdx)
95  {
96  funcsArcEval_ = ctrlPtVal(func0Idx, funcCtrlPtIdx + 1, CtrlPtDim::ARC);
98  distEvalCache_[funcCtrlPtIdx + 1] = computeS();
99  }
101 }
102 
104 {
105  return (this->*computeSFuncPtr_)();
106 }
108 {
109  const size_t& funcIdx = distLinkedFuncIdx_[0];
110  const FuncCacheData& cacheData =
111  funcEvalCache_[funcIdx][funcEvalArcCacheIdxUnder_[func2Arc_[funcIdx]]]; //*funcEvalCacheIter_[funcIdx];
113  computeDeltaS_V_AV(funcsArcEval_ - cacheData.arc, cacheData.val, computeFuncDiff1(funcIdx));
114 }
115 
117 {
118  const size_t& funcIdx = distLinkedFuncIdx_[0];
119  const FuncCacheData& cacheData =
120  funcEvalCache_[funcIdx][funcEvalArcCacheIdxUnder_[func2Arc_[funcIdx]]]; //*funcEvalCacheIter_[funcIdx];
122  computeDeltaS_V_AV(funcsArcEval_ - cacheData.arc, computeFuncInt1(funcIdx), cacheData.val);
123 }
124 
125 void ParamFuncsSpline0Dist::computeS2TLattice(const double& _arc0, const double& _ds, vector<double>& _tLattice)
126 {
128  size_t iEnd = distEvalCache_.back() / _ds;
129  if (((double)iEnd < distEvalCache_.back() / _ds))
130  {
131  iEnd++;
132  }
133  _tLattice.clear();
134  _tLattice.reserve(iEnd + 2);
135  const int idxBeforeStart = static_cast<int>(computeS() / _ds);
136 
137  setEvalDist(_ds * (idxBeforeStart), EvalArcGuarantee::AFTER_LAST);
138  _tLattice.emplace_back(fmin(funcsArcEval_, funcsArcEnd_));
139  for (size_t i = idxBeforeStart + 1; i < iEnd; ++i)
140  {
142  _tLattice.emplace_back(
143  fmin(fmax(funcsArcEval_, nextafterf(_tLattice.back(), FLT_MAX)), nextafterf(funcsArcEnd_, -FLT_MAX)));
144  }
145  if (_tLattice.back() < funcsArcEnd_)
146  {
147  _tLattice.emplace_back(funcsArcEnd_);
148  }
150 }
151 
152 void ParamFuncsSpline0Dist::computeS2TLattice(const vector<double>& _sLattice, vector<double>& _tLattice)
153 {
154  const size_t slSize = _sLattice.size();
155  _tLattice.clear();
156  _tLattice.reserve(_sLattice.size());
157 
158  if (slSize > 0)
159  {
160  size_t i = 0;
161  setEvalDist(_sLattice[i], EvalArcGuarantee::NONE);
162  while ((funcsArcEval_ < funcsArcEnd_) && (i + 1 < slSize))
163  {
164  _tLattice.emplace_back(funcsArcEval_);
165  setEvalDist(_sLattice[++i], EvalArcGuarantee::AFTER_LAST);
166  }
167  }
168  _tLattice.emplace_back(funcsArcEnd_);
170 }
171 void ParamFuncsSpline0Dist::setEvalDist(const double& _funcsDistEval, const EvalArcGuarantee& _evalArcGuarantee)
172 {
173  setEvalArc(computeTImpl(_funcsDistEval, _evalArcGuarantee), _evalArcGuarantee);
174 }
175 
176 double ParamFuncsSpline0Dist::computeT(const double& _s, const EvalArcGuarantee& _evalArcGuarantee)
177 {
179 
180  const size_t cacheCtrlPtIdxRestore = arcIdx;
181  const size_t cacheArcEvalRestore = funcsArcEval_;
182 
183  double resultT = computeTImpl(_s, _evalArcGuarantee);
184 
185  arcIdx = cacheCtrlPtIdxRestore;
186  funcsArcEval_ = cacheArcEvalRestore;
187 
188  return resultT;
189 }
190 
191 double ParamFuncsSpline0Dist::computeTImpl(const double& _s, const EvalArcGuarantee& _evalArcGuarantee)
192 {
193  using eag = EvalArcGuarantee;
194  size_t& arcCacheIdx = funcEvalArcCacheIdxUnder_[distLinkedArcIdx_];
195  const size_t ctrlPtSize = funcCtrlPt_[distLinkedFuncIdx_[0]].size();
196 
197  switch (_evalArcGuarantee)
198  {
199  case eag::AFTER_LAST:
200  while (distEvalCache_[arcCacheIdx] <= _s)
201  {
202  if (++arcCacheIdx >= ctrlPtSize)
203  {
204  break;
205  }
206  }
207  --arcCacheIdx;
208  break;
209  case eag::AT_BEGIN:
210  arcCacheIdx = 0;
211  break;
212  case eag::AT_END:
213  arcCacheIdx = funcCtrlPt_[distLinkedFuncIdx_[0]].size() - 1;
214  break;
215  case eag::NONE:
216  arcCacheIdx = distance(distEvalCache_.begin(), upper_bound(distEvalCache_.begin(), distEvalCache_.end(), _s)) - 1;
217  break;
218  case eag::BEFORE_LAST:
219  while (distEvalCache_[arcCacheIdx] > _s)
220  {
221  if (arcCacheIdx == 0)
222  {
223  break;
224  }
225  --arcCacheIdx;
226  }
227  break;
228  }
230  const double ds = _s - distEvalCache_[arcCacheIdx];
231  const double retVal = funcsArcEval_ + (this->*computeDs2DtPtr_)(ds);
232  return retVal;
233 }
234 double ParamFuncsSpline0Dist::computeT_V(const double& _ds) const
235 {
236  const size_t& funcIdx = distLinkedFuncIdx_[0];
237  return computeDeltaT_V_AV(_ds, computeFuncVal(funcIdx), computeFuncDiff1(funcIdx));
238 }
239 double ParamFuncsSpline0Dist::computeT_AV(const double& _ds) const
240 {
241  const size_t& funcIdx = distLinkedFuncIdx_[0];
242  return computeDeltaT_V_AV(_ds, computeFuncInt1(funcIdx), computeFuncVal(funcIdx));
243 }
244 
245 double ParamFuncsSpline0Dist::computeDeltaS_V_AV(const double& _dt, const double& _v0, const double& _av)
246 {
247  const double dtAbs = fabs(_dt);
248  if (dtAbs < 10 * FLT_MIN)
249  {
250  return 0;
251  }
252  const double vAbs = fabs(_v0);
253  if (fabs(_av) < 10 * FLT_MIN)
254  {
255  return vAbs * _dt;
256  }
257  const double v1 = _v0 + _av * dtAbs;
258  if (signum(v1) == signum(_v0))
259  {
260  return fabs(_v0 + v1) * _dt / 2.;
261  }
262  else
263  {
264  int retSign = 1;
265  if (_dt < 0)
266  {
267  retSign = -1;
268  }
269  double dt1 = -_v0 / _av;
270  return retSign * (vAbs * dt1 + fabs(v1) * (dtAbs - dt1)) / 2.;
271  }
272 }
273 double ParamFuncsSpline0Dist::computeDeltaT_V_AV(const double& _ds, const double& _v0, const double& _av)
274 {
275  double v0 = _v0, av = _av;
276  if (v0 < 0)
277  {
278  av *= -1;
279  v0 *= -1;
280  }
281  if (fabs(av) < 10 * FLT_MIN)
282  {
283  return _ds / v0;
284  }
285 
286  int retSign = -1;
287  if (_ds < 0)
288  {
289  retSign = +1;
290  }
291  const double v0v0 = v0 * v0;
292 
293  double delta = v0v0 + 2. * av * fabs(_ds);
294  if (delta < 0)
295  {
296  return retSign * (+v0 + sqrt(-delta)) / av;
297  }
298  else
299  {
300  return retSign * (+v0 - sqrt(delta)) / av;
301  }
302 }
TraveledDistCfMode distCfMode_
Closed form distance computation mode.
TraveledDistCfMode
Required type of traveled distance computation relative to the parametric function.
void setDistCfMode(TraveledDistCfMode _distCfMode, const std::vector< std::size_t > &_distRelFuncIdx) override
control point arc parameter
previous evaluation arc <= this evaluation arc
std::vector< std::size_t > distLinkedFuncIdx_
Indexes of parametric functions used for computing the traveled distance.
this evaluation arc is at the arc parametrization begin
TNumType funcsArcEnd_
Arc parametrization at the end of the functions domain definitions (common for all functions)...
virtual void initImpl() override
Called at end of init. To be used by extended classes.
Helper function needed to upgrade c++ 2011.
Definition: utils.h:193
std::vector< std::vector< FuncCtrlPt > > funcCtrlPt_
Stores the control points for all the parametrized functions.
Definition: param_func.h:237
std::vector< double > distEvalCache_
Cached values of traveled distance computation.
ParamFuncsDist & operator=(const ParamFuncsDist &_other)=default
std::size_t distLinkedArcIdx_
Index of the parametrized function that relates to distance computation.
TNumType funcsArcBegin_
Arc parametrization at the beginning of the functions domain definitions (common for all functions)...
double computeT(const double &_s, const EvalArcGuarantee &_evalArcGuarantee=EvalArcGuarantee::NONE) override
double computeS_AV() const
Computes distance on a piecewise linear function describing the center linear acceleration.
double computeT_V(const double &_ds) const
Computes arc parametrization on a piecewise linear function describing the center linear velocity at ...
std::vector< std::size_t > func2Arc_
Maps the parametrized functions to their afferent arc parametrizations.
Definition: param_func.h:243
ParamFuncsSpline0Dist & operator=(const ParamFuncsSpline0Dist &)
EvalArcGuarantee
Flags if any guarantees about evaluation arc relative to last evaluation arc are present.
Definition: param_func.h:80
agent base center linear velocity is parametric function
virtual double computeFuncInt1(const std::size_t &_funcIdx) const override
Computes integral of parametric function with index _funcIdx on interval [funcsArcBegin_, funcsArcEnd_].
agent base center linear acceleration is parametric function
Structure referencing a control point and storing cached relevant function evaluation data (derivativ...
ParamFuncsSpline0Dist::TraveledDistCfMode TDM
double & ctrlPtVal(const std::size_t &_funcIdx, const std::size_t &_funcCtrlPtIdx, const CtrlPtDim &_ctrlPtDim=CtrlPtDim::VAL)
Access of a parametric function control point dimension.
std::vector< std::vector< FuncCacheData > > funcEvalCache_
Cached values of the used function evaluation modes.
void setEvalArc(const double &_funcsArcEval, const EvalArcGuarantee &_evalArcGuarantee=EvalArcGuarantee::NONE) override
Sets parametric function evaluation arc.
static double computeDeltaT_V_AV(const double &_ds, const double &_v0, const double &_av)
Helper function that computes deltaT (from the evalArc_ position) operating on one function control p...
Extends manipulation of parametric functions collection with closed-form arc length (distance) comput...
constexpr int signum(T x, std::false_type is_signed)
Definition: utils.h:45
std::vector< std::size_t > funcEvalArcCacheIdxUnder_
Contains the index of the <u>next</u> control point relative to the last evaluation point...
no closed-form distance computation mode
void setEvalDist(const double &_funcsDistEval, const EvalArcGuarantee &_evalArcGuarantee=EvalArcGuarantee::NONE) override
Moves to evaluation arc at which the traveled distance _funcsDistEval is achieved.
virtual double computeFuncDiff1(const std::size_t &_funcIdx) const override
Computes 1st derivative of parametric function with index _funcIdx at parametric arc set by setEvalAr...
virtual double computeFuncVal(const std::size_t &_funcIdx) const override
Computes value of parametric function with index _funcIdx at parametric arc set by setEvalArc...
static double computeDeltaS_V_AV(const double &_dt, const double &_v0, const double &_av)
Helper function that computes deltaS (from the evalArc_ position) operating on one function control p...
void precomputeDist()
Precomputes distance invervals.
double computeS_V() const
Computes distance on a piecewise linear function describing the center linear velocity.
double computeTImpl(const double &_s, const EvalArcGuarantee &_evalArcGuarantee)
Internal implementation of computing the arc parametrization given a distance _s. ...
double computeT_AV(const double &_ds) const
Computes arc parametrization on a piecewise linear function describing the center linear acceleration...
std::vector< std::size_t > distRelFuncIdx_
this evaluation arc is at the arc parametrization begin
this evaluation arc is at the arc parametrization end
void computeS2TLattice(const std::vector< double > &_sLattice, std::vector< double > &_tLattice) override
Computes arc parametrization lattice given a distance-parametrized lattice.


tuw_control
Author(s): George Todoran
autogenerated on Mon Jun 10 2019 15:27:21