edge8.hpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Software License Agreement (BSD License) *
3  * Copyright (C) 2017 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 
33 #ifndef EDGE8_HPP
34 #define EDGE8_HPP
35 
38 #include <tuw_control/utils.h>
39 
40 namespace tuw
41 {
42 namespace Edge8
43 {
44 template <class TNumType, class TLeafType>
45 class StateNm : public StateMapArray<TNumType, TLeafType, 3>
46 {
47 public:
49 
50 public:
51  auto& x()
52  {
53  return this->template sub<0>();
54  }
55 
56 public:
57  const auto& x() const
58  {
59  return this->template sub<0>();
60  }
61 
62 public:
63  auto& y()
64  {
65  return this->template sub<1>();
66  }
67 
68 public:
69  const auto& y() const
70  {
71  return this->template sub<1>();
72  }
73 
74 public:
75  auto& theta()
76  {
77  return this->template sub<2>();
78  }
79 
80 public:
81  const auto& theta() const
82  {
83  return this->template sub<2>();
84  }
85 
86 public:
87  auto& state()
88  {
89  return *this;
90  }
91 
92 public:
93  const auto& state() const
94  {
95  return *this;
96  }
97 };
98 
99 template <class TNumType, class TLeafType>
101 {
102 public:
104 
105 public:
106  auto& L()
107  {
108  return this->template sub<0>();
109  }
110 
111 public:
112  const auto& L() const
113  {
114  return this->template sub<0>();
115  }
116 
117 public:
118  auto& x()
119  {
120  return this->template sub<1>();
121  }
122 
123 public:
124  const auto& x() const
125  {
126  return this->template sub<1>();
127  }
128 
129 public:
130  auto& y()
131  {
132  return this->template sub<2>();
133  }
134 
135 public:
136  const auto& y() const
137  {
138  return this->template sub<2>();
139  }
140 
141 public:
142  auto& theta()
143  {
144  return this->template sub<3>();
145  }
146 
147 public:
148  const auto& theta() const
149  {
150  return this->template sub<3>();
151  }
152 
153 public:
154  auto& state()
155  {
156  return *this;
157  }
158 
159 public:
160  const auto& state() const
161  {
162  return *this;
163  }
164 };
165 
166 template <class TNumType, class TLeafType>
168 {
169 public:
171 
172 public:
173  auto& v()
174  {
175  return this->template sub<0>();
176  }
177 
178 public:
179  const auto& v() const
180  {
181  return this->template sub<0>();
182  }
183 
184 public:
185  auto& phi()
186  {
187  return this->template sub<1>();
188  }
189 
190 public:
191  const auto& phi() const
192  {
193  return this->template sub<1>();
194  }
195 
196 public:
197  auto& vDot()
198  {
199  return this->template sub<2>();
200  }
201 
202 public:
203  const auto& vDot() const
204  {
205  return this->template sub<2>();
206  }
207 
208 public:
209  auto& phiDot()
210  {
211  return this->template sub<3>();
212  }
213 
214 public:
215  const auto& phiDot() const
216  {
217  return this->template sub<3>();
218  }
219 
220 public:
221  auto& t()
222  {
223  return this->template sub<4>();
224  }
225 
226 public:
227  const auto& t() const
228  {
229  return this->template sub<4>();
230  }
231 
232 public:
233  auto& s()
234  {
235  return this->template sub<5>();
236  }
237 
238 public:
239  const auto& s() const
240  {
241  return this->template sub<5>();
242  }
243 };
244 
245 static constexpr const size_t optParamBlockSize = 4;
246 
247 template <class TNumType, typename TLeafType>
249 {
250 public:
252 
253 public:
254  auto& optParamV()
255  {
256  return this->template sub<1>();
257  } // parameters influencing linear velocity
258 public:
259  const auto& optParamV() const
260  {
261  return this->template sub<1>();
262  }
263 
264 public:
265  auto& optParamTV()
266  {
267  return this->template sub<3>();
268  } // parameters influencing temporal location of previous parameters
269 public:
270  const auto& optParamTV() const
271  {
272  return this->template sub<3>();
273  }
274 
275 public:
276  auto& optParamP()
277  {
278  return this->template sub<0>();
279  } // parameters influencing angular velocity
280 public:
281  const auto& optParamP() const
282  {
283  return this->template sub<0>();
284  }
285 
286 public:
287  auto& optParamTP()
288  {
289  return this->template sub<2>();
290  } // parameters influencing temporal location of previous parameters
291 public:
292  const auto& optParamTP() const
293  {
294  return this->template sub<2>();
295  }
296 };
297 
298 template <class TNumType>
300 template <class TNumType>
302 template <class TNumType>
304 template <class TNumType>
306 
307 template <class TNumType, class TCfDataType>
308 struct ParamType
309 {
312  TCfDataType cfData;
313  enum class ParamFuncVars
314  {
315  V,
316  Phi
317  };
318 
319  TNumType lB;
320 };
321 
322 template <class TNumType, class MapDataType, class TStateType, template <class> class TDiscretizationType,
323  class... TFuncsType>
325  : public StateSimBase<StateSimE8Base<TNumType, MapDataType, TStateType, TDiscretizationType, TFuncsType...>,
326  ParamType<TNumType, MapDataType>, TStateType, TDiscretizationType, TFuncsType...>
327 {
329 
330 public:
331  void adjustXSizeImpl(auto& _XNm, auto& _XCf)
332  {
333  this->paramStruct->paramFuncs.precompute();
334  }
335 
336 private:
337  void setXCfNmStep(auto& _XCf, const TNumType& _arc, const PfEaG& _eAG)
338  {
339  if ((arcCfNmStepCache_ == _arc) && (_eAG == PfEaG::NEAR_LAST))
340  {
341  return;
342  }
343  arcCfNmStepCache_ = _arc;
344  auto& paramFuncs = this->paramStruct->paramFuncs;
345  paramFuncs.setEvalArc(_arc, _eAG);
346 
347  _XCf.v() = paramFuncs.computeFuncVal(asInt(PFV::V));
348  _XCf.phi() = paramFuncs.computeFuncVal(asInt(PFV::Phi));
349  }
350 
351 public:
352  void setXCfImpl(auto& _XCf, const TNumType& _arc, const PfEaG& _eAG)
353  {
354  setXCfNmStep(_XCf, _arc, _eAG);
355  auto& paramFuncs = this->paramStruct->paramFuncs;
356  _XCf.vDot() = paramFuncs.computeFuncDiff1(asInt(PFV::V));
357  _XCf.phiDot() = paramFuncs.computeFuncDiff1(asInt(PFV::Phi));
358  _XCf.t() = _arc;
359  _XCf.s() = paramFuncs.computeS();
360  }
361 
362 public:
363  void setXCfDotImpl(auto& _XCfDot, const auto& _XCf, const TNumType& _arc, const PfEaG& _eAG) const
364  {
365  _XCfDot.v() = _XCf.vDot();
366  _XCfDot.phi() = _XCf.phiDot();
367  _XCfDot.vDot() = 0;
368  _XCfDot.phiDot() = 0;
369  _XCfDot.t() = 1.;
370  _XCfDot.s() = fabs(_XCf.v());
371  }
372 
373 public:
374  void setXNm0Impl(auto& _XNm0)
375  {
376  for (int i = 0; i < _XNm0.data().size(); ++i)
377  {
378  _XNm0.data()(i) = 0;
379  }
380  _XNm0.x() = this->paramStruct->state0.stateNm().x();
381  _XNm0.y() = this->paramStruct->state0.stateNm().y();
382  _XNm0.theta() = this->paramStruct->state0.stateNm().theta();
383  }
384 
385 public:
386  void setXNmDotImpl(auto& _XNmDot, auto& _stateCf, const auto& _stateNm, const TNumType& _arc, const PfEaG& _eAG)
387  {
388  setXCfNmStep(_stateCf, _arc, _eAG);
389  if ((arcNmDotCache_ == _arc) && (_eAG == PfEaG::NEAR_LAST))
390  {
391  }
392  else
393  {
394  tanPhi_ = tan(_stateCf.phi());
395  arcNmDotCache_ = _arc;
396  }
397  _XNmDot.x() = _stateCf.v() * cos(_stateNm.theta());
398  _XNmDot.y() = _stateCf.v() * sin(_stateNm.theta());
399  _XNmDot.theta() = _stateCf.v() * tanPhi_ / this->paramStruct->lB;
400  }
401 
403 
404 public:
405  void setGradXNm0Impl(auto& _gradXNm0, const auto& _XNm0)
406  {
407  for (int i = 0; i < _gradXNm0.data().size(); ++i)
408  {
409  _gradXNm0.data()(i) = 0;
410  }
411  }
412 
413 public:
414  void adjustGradXSizeImpl(auto& _gradXNm, auto& _gradXCf)
415  {
416  auto& paramFuncs = this->paramStruct->paramFuncs;
417  int ctrlPtOptNr = paramFuncs.funcCtrlPtSize(0) - 1;
418  if (_gradXNm.sub(0).sub(0).data().size() != ctrlPtOptNr)
419  {
420  for (size_t i = 0; i < _gradXNm.subSize(); ++i)
421  {
422  for (size_t j = 0; j < _gradXNm.sub(i).subSize(); ++j)
423  {
424  if (j != 2)
425  {
426  _gradXNm.sub(i).sub(j).subResize(ctrlPtOptNr);
427  }
428  else
429  {
430  _gradXNm.sub(i).sub(j).subResize(ctrlPtOptNr - 1);
431  }
432  }
433  }
434  for (size_t i = 0; i < _gradXCf.subSize(); ++i)
435  {
436  for (size_t j = 0; j < _gradXCf.sub(i).subSize(); ++j)
437  {
438  if (j != 2)
439  {
440  _gradXCf.sub(i).sub(j).subResize(ctrlPtOptNr);
441  }
442  else
443  {
444  _gradXCf.sub(i).sub(j).subResize(ctrlPtOptNr - 1);
445  }
446  }
447  }
448  }
449  }
450 
451 public:
452  void setGradXCfImpl(auto& _gradXCf, const auto& _XCf, const TNumType& _arc, const PfEaG& _eAG)
453  {
454  setGradXCfNmStep(_gradXCf, _XCf, _arc, _eAG);
455 
456  auto& paramFuncs = this->paramStruct->paramFuncs;
457 
458  auto& dSdParamV = _gradXCf.s().optParamV();
459  for (size_t i = 0; i < dSdParamV.subSize(); ++i)
460  {
461  auto& dSdParamVI = dSdParamV.sub(i);
462 
463  if (i + 1 < dSdParamV.subSize())
464  {
465  const TNumType& evalArcAbove = paramFuncs.ctrlPtVal(0, i + 2, CtrlPtDim::ARC);
466  const TNumType& evalArcBelow = paramFuncs.ctrlPtVal(0, i + 1, CtrlPtDim::ARC);
467  if (_arc > evalArcBelow)
468  {
469  const TNumType arcIntEnd = fmin(_arc, evalArcAbove);
470  const TNumType deltaEvalArc = evalArcAbove - evalArcBelow;
471  dSdParamVI = +(arcIntEnd - evalArcBelow) * (evalArcBelow - 2. * _arc + arcIntEnd) / (2. * deltaEvalArc);
472  }
473  }
474  const TNumType& evalArcAbove = paramFuncs.ctrlPtVal(0, i + 1, CtrlPtDim::ARC);
475  const TNumType& evalArcBelow = paramFuncs.ctrlPtVal(0, i, CtrlPtDim::ARC);
476  if (_arc > evalArcBelow)
477  {
478  const TNumType arcIntEnd = fmin(_arc, evalArcAbove);
479  const TNumType deltaEvalArc = evalArcAbove - evalArcBelow;
480  dSdParamVI += -(arcIntEnd - evalArcBelow) * (evalArcBelow - 2. * _arc + arcIntEnd) / (2. * deltaEvalArc);
481  }
482  }
483 
484  auto& dSdParamT = _gradXCf.s().optParamTV();
485  auto& dAVdParamV = _gradXCf.vDot().optParamV();
486  auto& dAPdParamP = _gradXCf.phiDot().optParamP();
487  auto& dAVdParamT = _gradXCf.vDot().optParamTV();
488  for (size_t i = 0; i < dSdParamT.subSize(); ++i)
489  {
490  auto& dSdParamTI = dSdParamT.sub(i);
491  auto& dAVdParamVI = dAVdParamV.sub(i);
492  auto& dAPdParamPI = dAPdParamP.sub(i);
493  auto& dAVdParamTI = dAVdParamT.sub(i);
494  if (i + 1 < paramFuncs.funcCtrlPtSize(0))
495  {
496  const TNumType& evalArcAbove = paramFuncs.ctrlPtVal(0, i + 1, CtrlPtDim::ARC);
497  const TNumType& evalArcBelow = paramFuncs.ctrlPtVal(0, i, CtrlPtDim::ARC);
498  const TNumType& evalArcAboveP = paramFuncs.ctrlPtVal(1, i + 1, CtrlPtDim::ARC);
499  const TNumType& evalArcBelowP = paramFuncs.ctrlPtVal(1, i, CtrlPtDim::ARC);
500  if ((_arc <= evalArcAbove) && (_arc > evalArcBelow))
501  {
502  const TNumType& vP = paramFuncs.ctrlPtVal(0, i + 1, CtrlPtDim::VAL);
503  const TNumType& vM = paramFuncs.ctrlPtVal(0, i + 0, CtrlPtDim::VAL);
504  const TNumType arcIntEnd = fmin(_arc, evalArcAbove);
505  const TNumType deltaEvalArc = evalArcAbove - evalArcBelow;
506  const TNumType deltaEvalArcSqr = deltaEvalArc * deltaEvalArc;
507  const TNumType deltaArcIntBound = arcIntEnd - evalArcBelow;
508  dAVdParamTI = -(vP - vM) / deltaEvalArcSqr;
509  dAVdParamVI = +1. / deltaEvalArc;
510  dSdParamTI = +deltaArcIntBound * (vP - vM) * (evalArcBelow - 2. * _arc + arcIntEnd) / (2. * deltaEvalArcSqr);
511  }
512  else if ((_arc > evalArcBelow) && (i + 1 < dSdParamT.subSize()))
513  {
514  const TNumType& evalArcAbove2 = paramFuncs.ctrlPtVal(0, i + 2, CtrlPtDim::ARC);
515  const TNumType deltaEvalArc = evalArcAbove2 - evalArcAbove;
516  const TNumType deltaEvalArcSqr = deltaEvalArc * deltaEvalArc;
517  if (_arc <= evalArcAbove2)
518  {
519  dAVdParamVI = -1. / deltaEvalArc;
520  const TNumType& vP = paramFuncs.ctrlPtVal(0, i + 2, CtrlPtDim::VAL);
521  const TNumType& vM = paramFuncs.ctrlPtVal(0, i + 1, CtrlPtDim::VAL);
522  dAVdParamTI = +(vP - vM) / deltaEvalArcSqr;
523  }
524  if (_arc < evalArcAbove2)
525  {
526  const TNumType& vP = paramFuncs.ctrlPtVal(0, i + 2, CtrlPtDim::VAL);
527  const TNumType& vM = paramFuncs.ctrlPtVal(0, i + 1, CtrlPtDim::VAL);
528  const TNumType& vMM = paramFuncs.ctrlPtVal(0, i + 0, CtrlPtDim::VAL);
529  const TNumType arcIntEnd = fmin(_arc, evalArcAbove2);
530  dSdParamTI = -(+(vM - vMM) * evalArcAbove2 * evalArcAbove2 +
531  (vP - vMM) * (evalArcAbove * evalArcAbove - 2. * evalArcAbove * evalArcAbove2) +
532  (vP - vM) * (arcIntEnd * arcIntEnd + 2. * _arc * (evalArcAbove2 - arcIntEnd))) /
533  (2. * deltaEvalArcSqr);
534  }
535  else
536  {
537  const TNumType& vP = paramFuncs.ctrlPtVal(0, i + 2, CtrlPtDim::VAL);
538  const TNumType& vM = paramFuncs.ctrlPtVal(0, i + 0, CtrlPtDim::VAL);
539  dSdParamTI = -(vP - vM) / 2.;
540  }
541  }
542  else if (_arc > evalArcBelow)
543  {
544  const TNumType& vP = paramFuncs.ctrlPtVal(0, i + 1, CtrlPtDim::VAL);
545  const TNumType& vM = paramFuncs.ctrlPtVal(0, i + 0, CtrlPtDim::VAL);
546  dSdParamTI = -(vP - vM) / 2.;
547  }
548 
549  if ((_arc <= evalArcAboveP) && (_arc > evalArcBelowP))
550  {
551  dAPdParamPI = +1. / (evalArcAboveP - evalArcBelowP);
552  }
553  else if ((_arc > evalArcBelowP) && (i + 1 < dSdParamT.subSize()))
554  {
555  const TNumType& evalArcAbove2P = paramFuncs.ctrlPtVal(1, i + 2, CtrlPtDim::ARC);
556  const TNumType deltaEvalArcP = evalArcAbove2P - evalArcAboveP;
557  if (_arc <= evalArcAbove2P)
558  {
559  dAPdParamPI = -1. / deltaEvalArcP;
560  }
561  }
562  }
563  }
564 
565  auto& dAPdParamT = _gradXCf.phiDot().optParamTP();
566  for (size_t i = 0; i < dAPdParamT.subSize(); ++i)
567  {
568  auto& dAPdParamTI = dAPdParamT.sub(i);
569  if (i + 1 < paramFuncs.funcCtrlPtSize(1))
570  {
571  const TNumType& evalArcAbove = paramFuncs.ctrlPtVal(1, i + 1, CtrlPtDim::ARC);
572  const TNumType& evalArcBelow = paramFuncs.ctrlPtVal(1, i, CtrlPtDim::ARC);
573  if ((_arc <= evalArcAbove) && (_arc > evalArcBelow))
574  {
575  const TNumType& wP = paramFuncs.ctrlPtVal(1, i + 1, CtrlPtDim::VAL);
576  const TNumType& wM = paramFuncs.ctrlPtVal(1, i + 0, CtrlPtDim::VAL);
577  const TNumType deltaEvalArc = evalArcAbove - evalArcBelow;
578  const TNumType deltaEvalArcSqr = deltaEvalArc * deltaEvalArc;
579  dAPdParamTI = -(wP - wM) / deltaEvalArcSqr;
580  }
581  else if ((_arc > evalArcBelow) && (i + 1 < dAPdParamT.subSize() + 1))
582  {
583  const TNumType& evalArcAbove2 = paramFuncs.ctrlPtVal(1, i + 2, CtrlPtDim::ARC);
584  const TNumType deltaEvalArc = evalArcAbove2 - evalArcAbove;
585  const TNumType deltaEvalArcSqr = deltaEvalArc * deltaEvalArc;
586  if (_arc <= evalArcAbove2)
587  {
588  const TNumType& wP = paramFuncs.ctrlPtVal(1, i + 2, CtrlPtDim::VAL);
589  const TNumType& wM = paramFuncs.ctrlPtVal(1, i + 1, CtrlPtDim::VAL);
590  dAPdParamTI = +(wP - wM) / deltaEvalArcSqr;
591  }
592  }
593  }
594  }
595  }
596 
597 private:
598  void setGradXCfNmStep(auto& _gradXCf, const auto& _XCf, const TNumType& _arc, const PfEaG& _eAG)
599  {
600  if ((arcGradCache_ == _arc) && (_eAG == PfEaG::NEAR_LAST))
601  {
602  return;
603  }
604  arcGradCache_ = _arc;
605  auto& paramFuncs = this->paramStruct->paramFuncs;
606 
607  _gradXCf.data().setZero();
608  auto& dVdParamV = _gradXCf.v().optParamV();
609  for (size_t i = 0; i < dVdParamV.subSize(); ++i)
610  {
611  auto& dVdParamVI = dVdParamV.sub(i);
612 
613  if (i + 1 < dVdParamV.subSize())
614  {
615  const TNumType& evalArcAbove = paramFuncs.ctrlPtVal(0, i + 2, CtrlPtDim::ARC);
616  const TNumType& evalArcBelow = paramFuncs.ctrlPtVal(0, i + 1, CtrlPtDim::ARC);
617  if (_arc > evalArcBelow)
618  {
619  const TNumType arcIntEnd = fmin(_arc, evalArcAbove);
620  const TNumType deltaEvalArc = evalArcAbove - evalArcBelow;
621  dVdParamVI = -(arcIntEnd - evalArcBelow) / deltaEvalArc;
622  }
623  }
624  const TNumType& evalArcAbove = paramFuncs.ctrlPtVal(0, i + 1, CtrlPtDim::ARC);
625  const TNumType& evalArcBelow = paramFuncs.ctrlPtVal(0, i, CtrlPtDim::ARC);
626  if (_arc > evalArcBelow)
627  {
628  const TNumType arcIntEnd = fmin(_arc, evalArcAbove);
629  const TNumType deltaEvalArc = evalArcAbove - evalArcBelow;
630  dVdParamVI += +(arcIntEnd - evalArcBelow) / deltaEvalArc;
631  }
632  }
633 
634  auto& dPdParamP = _gradXCf.phi().optParamP();
635  for (size_t i = 0; i < dPdParamP.subSize(); ++i)
636  {
637  auto& dPdParamPI = dPdParamP.sub(i);
638  if (i + 1 < dPdParamP.subSize())
639  {
640  const TNumType& evalArcAbove = paramFuncs.ctrlPtVal(1, i + 2, CtrlPtDim::ARC);
641  const TNumType& evalArcBelow = paramFuncs.ctrlPtVal(1, i + 1, CtrlPtDim::ARC);
642  if (_arc > evalArcBelow)
643  {
644  const TNumType arcIntEnd = fmin(_arc, evalArcAbove);
645  const TNumType deltaEvalArc = evalArcAbove - evalArcBelow;
646  dPdParamPI = -(arcIntEnd - evalArcBelow) / deltaEvalArc;
647  }
648  }
649  const TNumType& evalArcAbove = paramFuncs.ctrlPtVal(1, i + 1, CtrlPtDim::ARC);
650  const TNumType& evalArcBelow = paramFuncs.ctrlPtVal(1, i, CtrlPtDim::ARC);
651  if (_arc > evalArcBelow)
652  {
653  const TNumType arcIntEnd = fmin(_arc, evalArcAbove);
654  const TNumType deltaEvalArc = evalArcAbove - evalArcBelow;
655  dPdParamPI += +(arcIntEnd - evalArcBelow) / deltaEvalArc;
656  }
657  }
658 
659  auto& dVdParamT = _gradXCf.v().optParamTV();
660  for (size_t i = 0; i < dVdParamT.subSize(); ++i)
661  {
662  auto& dVdParamTI = dVdParamT.sub(i);
663  if (i + 1 < paramFuncs.funcCtrlPtSize(0))
664  {
665  const TNumType& evalArcAbove = paramFuncs.ctrlPtVal(0, i + 1, CtrlPtDim::ARC);
666  const TNumType& evalArcBelow = paramFuncs.ctrlPtVal(0, i, CtrlPtDim::ARC);
667  if ((_arc <= evalArcAbove) && (_arc > evalArcBelow))
668  {
669  const TNumType& vP = paramFuncs.ctrlPtVal(0, i + 1, CtrlPtDim::VAL);
670  const TNumType& vM = paramFuncs.ctrlPtVal(0, i + 0, CtrlPtDim::VAL);
671  const TNumType arcIntEnd = fmin(_arc, evalArcAbove);
672  const TNumType deltaEvalArc = evalArcAbove - evalArcBelow;
673  const TNumType deltaEvalArcSqr = deltaEvalArc * deltaEvalArc;
674  const TNumType deltaArcIntBound = arcIntEnd - evalArcBelow;
675  dVdParamTI = -deltaArcIntBound * (vP - vM) / deltaEvalArcSqr;
676  }
677  else if ((_arc > evalArcBelow) && (i + 1 < dVdParamT.subSize()))
678  {
679  const TNumType& evalArcAbove2 = paramFuncs.ctrlPtVal(0, i + 2, CtrlPtDim::ARC);
680  const TNumType deltaEvalArc = evalArcAbove2 - evalArcAbove;
681  const TNumType deltaEvalArcSqr = deltaEvalArc * deltaEvalArc;
682  if (_arc < evalArcAbove2)
683  {
684  const TNumType& vP = paramFuncs.ctrlPtVal(0, i + 2, CtrlPtDim::VAL);
685  const TNumType& vM = paramFuncs.ctrlPtVal(0, i + 1, CtrlPtDim::VAL);
686  const TNumType arcIntEnd = fmin(_arc, evalArcAbove2);
687 
688  const TNumType deltaArcIntBound = evalArcAbove2 - arcIntEnd;
689  dVdParamTI = -deltaArcIntBound * (vP - vM) / deltaEvalArcSqr;
690  }
691  }
692  }
693  }
694 
695  auto& dPdParamT = _gradXCf.phi().optParamTP();
696  for (size_t i = 0; i < dPdParamT.subSize(); ++i)
697  {
698  auto& dPdParamTI = dPdParamT.sub(i);
699  if (i + 1 < paramFuncs.funcCtrlPtSize(1))
700  {
701  const TNumType& evalArcAbove = paramFuncs.ctrlPtVal(1, i + 1, CtrlPtDim::ARC);
702  const TNumType& evalArcBelow = paramFuncs.ctrlPtVal(1, i, CtrlPtDim::ARC);
703  if ((_arc <= evalArcAbove) && (_arc > evalArcBelow))
704  {
705  const TNumType& wP = paramFuncs.ctrlPtVal(1, i + 1, CtrlPtDim::VAL);
706  const TNumType& wM = paramFuncs.ctrlPtVal(1, i + 0, CtrlPtDim::VAL);
707  const TNumType arcIntEnd = fmin(_arc, evalArcAbove);
708  const TNumType deltaEvalArc = evalArcAbove - evalArcBelow;
709  const TNumType deltaEvalArcSqr = deltaEvalArc * deltaEvalArc;
710  const TNumType deltaArcIntBound = arcIntEnd - evalArcBelow;
711  dPdParamTI = -deltaArcIntBound * (wP - wM) / deltaEvalArcSqr;
712  }
713  else if ((_arc > evalArcBelow) && (i + 1 < dPdParamT.subSize() + 1))
714  {
715  const TNumType& evalArcAbove2 = paramFuncs.ctrlPtVal(1, i + 2, CtrlPtDim::ARC);
716  const TNumType deltaEvalArc = evalArcAbove2 - evalArcAbove;
717  const TNumType deltaEvalArcSqr = deltaEvalArc * deltaEvalArc;
718  if (_arc < evalArcAbove2)
719  {
720  const TNumType& wP = paramFuncs.ctrlPtVal(1, i + 2, CtrlPtDim::VAL);
721  const TNumType& wM = paramFuncs.ctrlPtVal(1, i + 1, CtrlPtDim::VAL);
722  const TNumType arcIntEnd = fmin(_arc, evalArcAbove2);
723 
724  const TNumType deltaArcIntBound = evalArcAbove2 - arcIntEnd;
725  dPdParamTI = -deltaArcIntBound * (wP - wM) / deltaEvalArcSqr;
726  }
727  }
728  }
729  }
730  }
731 
732 public:
733  void setGradXNmDotImpl(auto& _gradXNmDot, auto& _XGradXCf, const auto& _XGradXNm, const TNumType& _arc,
734  const PfEaG& _eAG)
735  {
736  if ((arcGradNmStepCache_ == _arc) && (_eAG == PfEaG::NEAR_LAST))
737  {
738  return;
739  }
740  arcGradNmStepCache_ = _arc;
741 
742  auto& gradXCf = _XGradXCf.stateGrad();
743  const auto& XCf = _XGradXCf.state();
744  setGradXCfNmStep(gradXCf, XCf, _arc, _eAG);
745 
746  // combining dfdx * GradX + dfdu * dudp
747  static Eigen::Matrix<TNumType, 2, 1> dfduX;
748  static Eigen::Matrix<TNumType, 2, 1> dfdTh;
749  const TNumType vPhiSqrForm = XCf.v() * (1 + tanPhi_ * tanPhi_);
750 
751  cosTheta_ = cos(_XGradXNm.state().theta());
752  sinTheta_ = sin(_XGradXNm.state().theta());
753 
754  dfduX(0) = cosTheta_;
755  dfduX(1) = sinTheta_;
756 
757  dfdTh(0) = -XCf.v() * sinTheta_;
758  dfdTh(1) = +XCf.v() * cosTheta_;
759 
760  auto& dXdParamV = _gradXNmDot.x().optParamV().data();
761  auto& dYdParamV = _gradXNmDot.y().optParamV().data();
762  auto& dThdParamV = _gradXNmDot.theta().optParamV().data();
763  auto& dXdParamP = _gradXNmDot.x().optParamP().data();
764  auto& dYdParamP = _gradXNmDot.y().optParamP().data();
765  auto& dThdParamP = _gradXNmDot.theta().optParamP().data();
766 
767  auto& dXdParamTV = _gradXNmDot.x().optParamTV().data();
768  auto& dYdParamTV = _gradXNmDot.y().optParamTV().data();
769  auto& dThdParamTV = _gradXNmDot.theta().optParamTV().data();
770 
771  auto& dXdParamTP = _gradXNmDot.x().optParamTP().data();
772  auto& dYdParamTP = _gradXNmDot.y().optParamTP().data();
773  auto& dThdParamTP = _gradXNmDot.theta().optParamTP().data();
774 
775  const auto& stateGradCfParamVIV = gradXCf.v().optParamV();
776  const auto& stateGradCfParamWIPhi = gradXCf.phi().optParamP();
777 
778  const auto& stateGradCfParamTVIV = gradXCf.v().optParamTV();
779  const auto& stateGradCfParamTPIV = gradXCf.v().optParamTP();
780  const auto& stateGradCfParamTVIPhi = gradXCf.phi().optParamTV();
781  const auto& stateGradCfParamTPIPhi = gradXCf.phi().optParamTP();
782 
783  auto& gradXNm = _XGradXNm.stateGrad();
784  const auto& stateGradNmParamVITh = gradXNm.theta().optParamV();
785  const auto& stateGradNmParamPITh = gradXNm.theta().optParamP();
786  const auto& stateGradNmParamTVITh = gradXNm.theta().optParamTV();
787  const auto& stateGradNmParamTPITh = gradXNm.theta().optParamTP();
788 
789  for (int i = 0; i < dXdParamV.size(); ++i)
790  {
791  const auto& stateGradCfParamVIVI = stateGradCfParamVIV.sub(i);
792  const auto& stateGradCfParamWIPhiI = stateGradCfParamWIPhi.sub(i);
793 
794  const auto& stateGradNmParamVIThI = stateGradNmParamVITh.sub(i);
795  const auto& stateGradNmParamPIThI = stateGradNmParamPITh.sub(i);
796 
797  const auto& stateGradCfParamTVIVI = stateGradCfParamTVIV.sub(i);
798  const auto& stateGradCfParamTVIPhiI = stateGradCfParamTVIPhi.sub(i);
799  const auto& stateGradNmParamTVIThI = stateGradNmParamTVITh.sub(i);
800 
801  dXdParamV(i) = dfduX(0) * stateGradCfParamVIVI + dfdTh(0) * stateGradNmParamVIThI;
802  dYdParamV(i) = dfduX(1) * stateGradCfParamVIVI + dfdTh(1) * stateGradNmParamVIThI;
803 
804  dXdParamP(i) = +dfdTh(0) * stateGradNmParamPIThI;
805  dYdParamP(i) = +dfdTh(1) * stateGradNmParamPIThI;
806 
807  dXdParamTV(i) = dfduX(0) * stateGradCfParamTVIVI + dfdTh(0) * stateGradNmParamTVIThI;
808  dYdParamTV(i) = dfduX(1) * stateGradCfParamTVIVI + dfdTh(1) * stateGradNmParamTVIThI;
809 
810  dThdParamV(i) = (stateGradCfParamVIVI * tanPhi_) / this->paramStruct->lB;
811 
812  dThdParamP(i) = (vPhiSqrForm * stateGradCfParamWIPhiI) / this->paramStruct->lB;
813 
814  dThdParamTV(i) =
815  (vPhiSqrForm * stateGradCfParamTVIPhiI + stateGradCfParamTVIVI * tanPhi_) / this->paramStruct->lB;
816  }
817  for (int i = 0; i < dXdParamV.size() - 1; ++i)
818  {
819  const auto& stateGradCfParamTPIPhiI = stateGradCfParamTPIPhi.sub(i);
820  const auto& stateGradCfParamTPIVI = stateGradCfParamTPIV.sub(i);
821  const auto& stateGradNmParamTPIThI = stateGradNmParamTPITh.sub(i);
822 
823  dXdParamTP(i) = dfduX(0) * stateGradCfParamTPIVI + dfdTh(0) * stateGradNmParamTPIThI;
824  dYdParamTP(i) = dfduX(1) * stateGradCfParamTPIVI + dfdTh(1) * stateGradNmParamTPIThI;
825 
826  dThdParamTP(i) =
827  (vPhiSqrForm * stateGradCfParamTPIPhiI + stateGradCfParamTPIVI * tanPhi_) / this->paramStruct->lB;
828  }
829  }
830 
831  // internal helper variables
832 protected:
833  TNumType tanPhi_;
834 
835 protected:
836  TNumType cosTheta_;
837 
838 protected:
839  TNumType sinTheta_;
840 
841 protected:
843 
844 protected:
845  TNumType arcNmDotCache_;
846 
847 protected:
848  TNumType arcGradCache_;
849 
850 protected:
852 };
853 //---------------------------------------------------------------------Optimization parameters
854 
855 template <class TNumType, class TParamStructType>
857 {
858  static void setOptVar(TParamStructType& _paramStruct, const Eigen::Matrix<TNumType, -1, 1>& _optVarExt)
859  {
860  auto& paramFuncs = _paramStruct.paramFuncs;
861  size_t idxOptVec = 0;
862  for (int i = paramFuncs.funcsSize() - 1; i >= 0; --i)
863  {
864  for (size_t j = 1; j < paramFuncs.funcCtrlPtSize(i); ++j)
865  {
866  paramFuncs.ctrlPtVal(i, j, CtrlPtDim::VAL) = _optVarExt(idxOptVec++);
867  }
868  }
869  for (size_t j = 1; j < paramFuncs.funcsArcSize(1) - 1; ++j)
870  {
871  paramFuncs.funcsArc(1, j) = _optVarExt(idxOptVec++);
872  }
873  for (size_t j = 1; j < paramFuncs.funcsArcSize(0); ++j)
874  {
875  paramFuncs.funcsArc(0, j) = _optVarExt(idxOptVec++);
876  }
877  }
878  static void getOptVar(Eigen::Matrix<TNumType, -1, 1>& _optVarExt, const TParamStructType& _paramStruct)
879  {
880  auto& paramFuncs = _paramStruct.paramFuncs;
881  int newSize = paramFuncs.funcsSize() * (paramFuncs.funcCtrlPtSize(0) - 1) + (paramFuncs.funcsArcSize(0) - 1) +
882  (paramFuncs.funcsArcSize(1) - 2);
883  if (newSize != _optVarExt.size())
884  {
885  _optVarExt.resize(newSize);
886  }
887  size_t idxOptVec = 0;
888  for (int i = paramFuncs.funcsSize() - 1; i >= 0; --i)
889  {
890  for (size_t j = 1; j < paramFuncs.funcCtrlPtSize(i); ++j)
891  {
892  _optVarExt(idxOptVec++) = paramFuncs.ctrlPtVal(i, j, CtrlPtDim::VAL);
893  }
894  }
895  for (size_t j = 1; j < paramFuncs.funcsArcSize(1) - 1; ++j)
896  {
897  _optVarExt(idxOptVec++) = paramFuncs.funcsArc(1, j);
898  }
899  for (size_t j = 1; j < paramFuncs.funcsArcSize(0); ++j)
900  {
901  _optVarExt(idxOptVec++) = paramFuncs.funcsArc(0, j);
902  }
903  }
904 };
905 
906 template <class TNumType, class TMapDataType, template <class> class TDiscretizationType>
907 class StateSimVW : public StateSimE8Base<TNumType, TMapDataType, StateE8<TNumType>, TDiscretizationType>
908 {
909 };
910 
911 template <class TNumType, class TMapDataType, template <class> class TDiscretizationType, class... TCostFuncType>
913  : public StateSimE8Base<TNumType, TMapDataType, StateWithLE8<TNumType>, TDiscretizationType, TCostFuncType...>
914 {
915 };
916 
917 template <class TNumType, class TMapDataType, template <class> class TDiscretizationType>
918 class StateWithGradSimVW : public StateSimE8Base<TNumType, TMapDataType, StateWithGradE8<TNumType>, TDiscretizationType>
919 {
920 };
921 
922 template <class TNumType, class TMapDataType, template <class> class TDiscretizationType, class... TCostFuncType>
923 class StateWithLWithGradSimVW : public StateSimE8Base<TNumType, TMapDataType, StateWithLWithGradE8<TNumType>,
924  TDiscretizationType, TCostFuncType...>
925 {
926 };
927 }
928 }
929 
930 #endif // EDGE8_HPP
void adjustGradXSizeImpl(auto &_gradXNm, auto &_gradXCf)
Definition: edge8.hpp:414
const auto & optParamTV() const
Definition: edge8.hpp:270
const auto & y() const
Definition: edge8.hpp:69
void setXCfImpl(auto &_XCf, const TNumType &_arc, const PfEaG &_eAG)
Definition: edge8.hpp:352
const auto & x() const
Definition: edge8.hpp:57
static void getOptVar(Eigen::Matrix< TNumType,-1, 1 > &_optVarExt, const TParamStructType &_paramStruct)
Definition: edge8.hpp:878
const auto & s() const
Definition: edge8.hpp:239
control point value
void setGradXNm0Impl(auto &_gradXNm0, const auto &_XNm0)
--------------------------------—Gradient information--------------------------------—/// ...
Definition: edge8.hpp:405
void adjustXSizeImpl(auto &_XNm, auto &_XCf)
Definition: edge8.hpp:331
auto & phiDot()
Definition: edge8.hpp:209
const auto & theta() const
Definition: edge8.hpp:148
const auto & optParamP() const
Definition: edge8.hpp:281
control point arc parameter
const auto & optParamTP() const
Definition: edge8.hpp:292
const auto & L() const
Definition: edge8.hpp:112
ParamFuncsSpline0Dist< TNumType, 2, 2 > paramFuncs
Definition: edge8.hpp:310
static constexpr const size_t optParamBlockSize
Definition: edge8.hpp:245
constexpr auto asInt(Enumeration const value) -> typename std::underlying_type< Enumeration >::type
Definition: utils.h:87
const auto & t() const
Definition: edge8.hpp:227
const auto & phi() const
Definition: edge8.hpp:191
const auto & state() const
Definition: edge8.hpp:93
void setXCfNmStep(auto &_XCf, const TNumType &_arc, const PfEaG &_eAG)
Definition: edge8.hpp:337
auto & state()
Definition: edge8.hpp:87
const auto & vDot() const
Definition: edge8.hpp:203
TCfDataType cfData
Definition: edge8.hpp:312
auto & theta()
Definition: edge8.hpp:75
static void setOptVar(TParamStructType &_paramStruct, const Eigen::Matrix< TNumType,-1, 1 > &_optVarExt)
Definition: edge8.hpp:858
agent base center linear velocity is parametric function
const auto & optParamV() const
Definition: edge8.hpp:259
const auto & phiDot() const
Definition: edge8.hpp:215
void setGradXCfNmStep(auto &_gradXCf, const auto &_XCf, const TNumType &_arc, const PfEaG &_eAG)
Definition: edge8.hpp:598
const auto & theta() const
Definition: edge8.hpp:81
TNumType arcGradNmStepCache_
Definition: edge8.hpp:851
const auto & y() const
Definition: edge8.hpp:136
const auto & x() const
Definition: edge8.hpp:124
StateE8< TNumType > state0
Definition: edge8.hpp:311
void setXNm0Impl(auto &_XNm0)
Definition: edge8.hpp:374
close to previous evaluation arc
void setGradXNmDotImpl(auto &_gradXNmDot, auto &_XGradXCf, const auto &_XGradXNm, const TNumType &_arc, const PfEaG &_eAG)
Definition: edge8.hpp:733
void setXNmDotImpl(auto &_XNmDot, auto &_stateCf, const auto &_stateNm, const TNumType &_arc, const PfEaG &_eAG)
Definition: edge8.hpp:386
const auto & state() const
Definition: edge8.hpp:160
typename ParamType< TNumType, TMapDataType >::ParamFuncVars PFV
Definition: edge8.hpp:328
void setGradXCfImpl(auto &_gradXCf, const auto &_XCf, const TNumType &_arc, const PfEaG &_eAG)
Definition: edge8.hpp:452
const auto & v() const
Definition: edge8.hpp:179
void setXCfDotImpl(auto &_XCfDot, const auto &_XCf, const TNumType &_arc, const PfEaG &_eAG) const
Definition: edge8.hpp:363


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