test_trajectory_optimizer.cpp
Go to the documentation of this file.
1 
2 #include "gtest/gtest.h"
3 #include <array>
4 #include <boost/concept_check.hpp>
9 
12 
13 using namespace tuw;
14 using namespace std;
15 
16 namespace tuw
17 {
18 namespace cost_functions
19 {
20 template <typename MapData>
21 class CFLatMap1Weight<TrajectorySimulator::LatticeVec, MapData>
22  : public CFLatMap1WeightBase<TrajectorySimulator::LatticeVec, MapData>
23 {
24 public:
26  {
27  this->arcAcc = [this](const size_t& _i)
28  {
29  return this->latticePtr_->at(_i).arc;
30  };
31  }
32 };
33 }
34 }
35 
36 namespace
37 {
38 class StateSimTest : public StateSimTemplate<7, 3>
39 {
40 public:
41  enum class StateVars
42  {
43  X,
44  Y,
45  THETA,
46  V,
47  W,
48  T,
49  S
50  };
51 
52 public:
53  enum class StateNmVars
54  {
55  X,
56  Y,
57  THETA
58  };
59 
60 public:
61  enum class StateCfVars
62  {
63  V,
64  W,
65  T,
66  S
67  };
68 
69 public:
70  enum class ParamFuncVars
71  {
72  V,
73  W
74  };
75 
76 public:
77  enum class ParamFuncLattices
78  {
79  T
80  };
81 
82 public:
83  StateSimTest()
84  {
85  }
86 
87 public:
88  StateSimUPtr cloneStateSim() const override
89  {
90  return StateSimUPtr(new StateSimTest(*this)); /*::make_unique< StateSimTest >(*this);*/
91  }
92 
93 public:
94  double stateArc() const override
95  {
96  return stateCf_.value(asInt(StateCfVars::T));
97  }
98 
99 public:
100  double stateDist() const override
101  {
102  return stateCf_.value(asInt(StateCfVars::S));
103  }
104 
105 public:
106  ParamFuncs* paramFuncs() override
107  {
108  return &paramFuncs_;
109  }
110 
111 public:
112  ParamFuncsDist* paramFuncsDist() override
113  {
114  return &paramFuncs_;
115  }
116 
117 private:
118  void setStateCf(const double& _arc, const ParamFuncs::EvalArcGuarantee& _evalArcGuarantee =
120  {
121  paramFuncs_.setEvalArc(_arc, _evalArcGuarantee);
122  stateCf_.value(asInt(StateCfVars::T)) = _arc;
123  stateCf_.value(asInt(StateCfVars::V)) = paramFuncs_.computeFuncVal(asInt(ParamFuncVars::V));
124  stateCf_.value(asInt(StateCfVars::W)) = paramFuncs_.computeFuncVal(asInt(ParamFuncVars::W));
125  stateCf_.value(asInt(StateCfVars::S)) = paramFuncs_.computeS();
126  }
127 
128 private:
129  State& stateNmDot() override
130  {
131  stateNmDotCache_.value(asInt(StateNmVars::X)) =
132  stateCf_.value(asInt(StateCfVars::V)) * cos(stateNm_.value(asInt(StateNmVars::THETA)));
133  stateNmDotCache_.value(asInt(StateNmVars::Y)) =
134  stateCf_.value(asInt(StateCfVars::V)) * sin(stateNm_.value(asInt(StateNmVars::THETA)));
135  stateNmDotCache_.value(asInt(StateNmVars::THETA)) = stateCf_.value(asInt(StateCfVars::W));
136  return stateNmDotCache_;
137  }
138 
139 private:
140  State& stateNmDelta(const double& _dArc) override
141  {
142  const double& v = stateCf_.value(asInt(StateCfVars::V));
143  const double& w = stateCf_.value(asInt(StateCfVars::W));
144  const double& theta = stateNm_.value(asInt(StateNmVars::THETA));
145  double& dx = stateNmDotCache_.value(asInt(StateNmVars::X));
146  double& dy = stateNmDotCache_.value(asInt(StateNmVars::Y));
147  double& da = stateNmDotCache_.value(asInt(StateNmVars::THETA));
148 
149  if (fabs(w) > FLT_MIN)
150  {
151  const double r = v / w;
152  dx = (-r * sin(theta) + r * sin(theta + w * _dArc));
153  dy = (+r * cos(theta) - r * cos(theta + w * _dArc));
154  da = w * _dArc;
155  }
156  else
157  {
158  dx = v * _dArc * cos(theta);
159  dy = v * _dArc * sin(theta);
160  da = 0.0;
161  }
162  return stateNmDotCache_;
163  }
164 
165 private:
166  ParamFuncsSpline0Dist paramFuncs_;
167 };
168 
169 using SNF = StateSimTest::StateVars;
170 using SNV = StateSimTest::StateNmVars;
171 using SCF = StateSimTest::StateCfVars;
172 using PFV = StateSimTest::ParamFuncVars;
173 
174 // void coutCostEvalCosts(TrajectorySimGradeSPtr trajSimGrade) {
175 // cout<<"Cost Functions:"<<endl;
176 // cout<<"f = "<<trajSimGrade->trajSim()->costsEvaluator_->f<<endl<<"h = ";
177 // for(size_t i = 0; i < trajSimGrade->trajSim()->costsEvaluator_->h.size(); ++i) {
178 // cout<<trajSimGrade->trajSim()->costsEvaluator_->h[i]<<", "; } cout<<endl;
179 // cout<<"gradF = ";
180 // for(size_t i = 0; i < trajSimGrade->trajSim()->costsEvaluator_->gradF.size(); ++i) {
181 // cout<<trajSimGrade->trajSim()->costsEvaluator_->gradF[i]<<", "; } cout<<endl;
182 // cout<<"gradH = "<<endl<<trajSimGrade->trajSim()->costsEvaluator_->gradH<<endl;
183 // }
184 
185 // The fixture for testing class Foo.
186 class TrajOptTest : public ::testing::Test
187 {
188 protected:
189  // You can remove any or all of the following functions if its body
190  // is empty.
191 
192  TrajOptTest()
193  {
194  dummyMapData = shared_ptr<double>(new double(0));
195 
196  // initialize parametric functions structure
198  using PfCpD = ParamFuncs::CtrlPtDim;
199  using FeM = ParamFuncs::FuncEvalMode; // using EaG = ParamFuncs::EvalArcGuarantee;
200  size_t funcIdx = 0;
201  vector<PFS> pf(2, PFS());
202  static constexpr const int paramFuncArcRefIdxAll = 0;
203  pf[0].ctrlPtsSize = 5;
204  pf[0].ctrlPtsArcRefIdx = paramFuncArcRefIdxAll;
205  pf[1].ctrlPtsSize = 5;
206  pf[1].ctrlPtsArcRefIdx = paramFuncArcRefIdxAll;
207  pf[0].evalReq[asInt(FeM::INT1)] = false;
208  pf[0].evalReq[asInt(FeM::INT2)] = false;
209 
210  // construct stateSim object and initalize the parametric functions object
211  stateSimPtr = std::shared_ptr<StateSimTest>(new StateSimTest);
212  stateSimPtr->paramFuncs()->init(pf);
213  stateSimPtr->paramFuncsDist()->setDistCfMode(ParamFuncsDist::TraveledDistCfMode::V, vector<size_t>(1, 0));
214 
215  // set the parametric functions control points
216  ParamFuncs* funcs = stateSimPtr->paramFuncs();
217  double initT = 0;
218  funcIdx = 0;
219  funcs->ctrlPtVal(funcIdx, 0, PfCpD::ARC) = 0 + initT;
220  funcs->ctrlPtVal(funcIdx, 1, PfCpD::ARC) = 1 + initT;
221  funcs->ctrlPtVal(funcIdx, 2, PfCpD::ARC) = 2 + initT;
222  funcs->ctrlPtVal(funcIdx, 3, PfCpD::ARC) = 3 + initT;
223  funcs->ctrlPtVal(funcIdx, 4, PfCpD::ARC) = 4 + initT;
224 
225  funcIdx = 0;
226  funcs->ctrlPtVal(funcIdx, 0, PfCpD::VAL) = 1.;
227  funcs->ctrlPtVal(funcIdx, 1, PfCpD::VAL) = 2.;
228  funcs->ctrlPtVal(funcIdx, 2, PfCpD::VAL) = 3.;
229  funcs->ctrlPtVal(funcIdx, 3, PfCpD::VAL) = 4.;
230  funcs->ctrlPtVal(funcIdx, 4, PfCpD::VAL) = 5.;
231 
232  funcIdx = 1;
233  funcs->ctrlPtVal(funcIdx, 0, PfCpD::VAL) = 3.5 * M_PI;
234  funcs->ctrlPtVal(funcIdx, 1, PfCpD::VAL) = 1.5 * M_PI;
235  funcs->ctrlPtVal(funcIdx, 2, PfCpD::VAL) = -4.5 * M_PI;
236  funcs->ctrlPtVal(funcIdx, 3, PfCpD::VAL) = -3.5 * M_PI;
237  funcs->ctrlPtVal(funcIdx, 4, PfCpD::VAL) = -2.0 * M_PI;
238  funcs->precompute();
239  }
240  virtual ~TrajOptTest()
241  {
242  }
243  // If the constructor and destructor are not enough for setting up
244  // and cleaning up each test, you can define the following methods:
245  virtual void SetUp()
246  {
247  Test::SetUp();
248  // Code here will be called immediately after the constructor (right
249  // before each test).
250  }
251  virtual void TearDown()
252  {
253  Test::TearDown();
254  // Code here will be called immediately after each test (right
255  // before the destructor).
256  }
257  StateSimPtr stateSimPtr;
258  TrajectoryOptimizerSPtr trajOpt;
259  shared_ptr<double> dummyMapData;
260 };
261 
263 
264 using TS = TrajectorySimulator;
265 using TSBSLT = TS::BaseSimLatticeType;
266 using TSLatVec = TS::LatticeVec;
267 
268 using MapData = double;
269 using namespace tuw::cost_functions;
270 
272 class TestCost_LinSumW_V : public CFLatMap1Weight<TSLatVec, MapData>
273 {
274 public:
275  TestCost_LinSumW_V()
276  {
277  stAcc = [this](const size_t& _i)
278  {
279  return latticePtr_->at(_i).statePtr->value(asInt(SNF::V));
280  };
281  funcPredef_FL1::lin(this);
282  funcPredef_FL2::sum(this);
283  funcPredef_FL3::weight(this);
284  weight_ = 1;
285  cost0_ = 0;
286  }
287 };
288 
290 class TestCost_LinIntWNorm_W : public CFLatMap1Weight<TSLatVec, MapData>
291 {
292 public:
293  TestCost_LinIntWNorm_W()
294  {
295  stAcc = [this](const size_t& _i)
296  {
297  return latticePtr_->at(_i).statePtr->value(asInt(SNF::W));
298  };
299  funcPredef_FL1::lin(this);
300  funcPredef_FL2::intTrap(this);
301  funcPredef_FL3::weightNorm(this);
302  weight_ = 1;
303  cost0_ = 0;
304  }
305 };
306 
308 class TestCost_Lin_TPos : public CFLatMap1Weight<TSLatVec, MapData>
309 {
310 public:
311  TestCost_Lin_TPos()
312  {
313  stAcc = [this](const size_t& _i)
314  {
315  return latticePtr_->at(_i).statePtr->value(asInt(SNF::X)) /*latticePtr_->at(_i).arc - latticePtr_->at(_i-1).arc*/;
316  };
317  funcPredef_FL1::lin(this);
318  funcPredef_FL2::sum(this);
319  funcPredef_FL3::weight(this);
320  weight_ = 1;
321  cost0_ = 0;
322  }
323 };
325 
326 class Test1CostArray_LinSumW_V : public CostsArrayLat<TSLatVec, MapData, TestCost_LinSumW_V>
327 {
328  size_t latFuncLayerIdx() override
329  {
330  return TS::lattTypeIdx(asInt(TSBSLT::LATTICE_ARC_EQ_DT));
331  }
332  size_t latKnotLayerIdx() override
333  {
334  return TS::lattTypeIdx(asInt(TSBSLT::ARC_BG_BK));
335  }
336 };
337 class Test1CostArray_LinSumW_W : public CostsArrayLat<TSLatVec, MapData, TestCost_LinIntWNorm_W>
338 {
339  size_t latFuncLayerIdx() override
340  {
341  return TS::lattTypeIdx(asInt(TSBSLT::LATTICE_ARC_EQ_DT));
342  }
343  size_t latKnotLayerIdx() override
344  {
345  return TS::lattTypeIdx(asInt(TSBSLT::ARC_BG_BK));
346  }
347 };
348 class Test1CostArray_Lin_TPos : public CostsArrayLat<TSLatVec, MapData, TestCost_Lin_TPos>
349 {
350  size_t latFuncLayerIdx() override
351  {
352  return TS::lattTypeIdx(0);
353  }
354  size_t latKnotLayerIdx() override
355  {
356  return TS::lattTypeIdx(0);
357  }
358 };
359 
360 class TestCostsEvaluatorT1 : public CostsEvaluator<TSLatVec, MapData>
361 {
362 public:
363  TestCostsEvaluatorT1(std::shared_ptr<MapData>& _mapDataPtr) : CostsEvaluator(_mapDataPtr)
364  {
365  }
366 
367 public:
368  void loadCostFunctions() override
369  {
370  partialCostsArray_[asInt(CostEvaluatorCostType::F)].resize(2);
371  partialCostsArray_[asInt(CostEvaluatorCostType::F)][0] = std::make_unique<Test1CostArray_LinSumW_V>();
372  partialCostsArray_[asInt(CostEvaluatorCostType::F)][1] = std::make_unique<Test1CostArray_LinSumW_W>();
373  partialCostsArray_[asInt(CostEvaluatorCostType::H)].resize(3);
374  partialCostsArray_[asInt(CostEvaluatorCostType::H)][0] = std::make_unique<Test1CostArray_Lin_TPos>();
375  partialCostsArray_[asInt(CostEvaluatorCostType::H)][1] = std::make_unique<Test1CostArray_Lin_TPos>();
376  partialCostsArray_[asInt(CostEvaluatorCostType::H)][2] = std::make_unique<Test1CostArray_LinSumW_V>();
377  }
378 };
379 
380 class OptimizationStateDiffDrive : public OptimizationState
381 {
382 public:
383  StateSPtr cloneState() const override
384  {
385  return std::shared_ptr<OptimizationStateDiffDrive>(new OptimizationStateDiffDrive(*this));
386  }
387 
388 public:
389  void toTrajState(TrajectorySimulator& _trajSim) override
390  {
391  auto* paramFuncs = _trajSim.stateSim()->paramFuncs();
392  size_t idxOptVec = 0;
393  for (size_t i = 0; i < paramFuncs->funcsSize(); ++i)
394  {
395  for (size_t j = 1; j < paramFuncs->funcCtrlPtSize(i); ++j)
396  {
397  paramFuncs->ctrlPtVal(i, j, ParamFuncs::CtrlPtDim::VAL) = vars[idxOptVec++];
398  }
399  }
400  for (size_t j = 1; j < paramFuncs->funcsArcSize(0); ++j)
401  {
402  paramFuncs->funcsArc(0, j) = vars[idxOptVec++];
403  }
404  }
405 
406 public:
407  void fromTrajState(const TrajectorySimulator& _trajSim) override
408  {
409  auto* paramFuncs = _trajSim.stateSim()->paramFuncs();
410  vars.resize(paramFuncs->funcsSize() * (paramFuncs->funcCtrlPtSize(0) - 1) + (paramFuncs->funcsArcSize(0) - 1));
411  size_t idxOptVec = 0;
412  for (size_t i = 0; i < paramFuncs->funcsSize(); ++i)
413  {
414  for (size_t j = 1; j < paramFuncs->funcCtrlPtSize(i); ++j)
415  {
416  vars[idxOptVec++] = paramFuncs->ctrlPtVal(i, j, ParamFuncs::CtrlPtDim::VAL);
417  }
418  }
419  for (size_t j = 1; j < paramFuncs->funcsArcSize(0); ++j)
420  {
421  vars[idxOptVec++] = paramFuncs->funcsArc(0, j);
422  }
423  }
424 };
425 
426 TEST_F(TrajOptTest, GenericTest)
427 {
428  trajOpt = shared_ptr<TrajectoryOptimizer>(new TrajectoryOptimizer(stateSimPtr, std::make_unique<TestCostsEvaluatorT1>(dummyMapData),
429  std::shared_ptr<OptimizationStateDiffDrive>(new OptimizationStateDiffDrive)));
430  stateSimPtr->setDiscrType(RungeKutta::DiscretizationType::HEUN);
431  vector<vector<double*> > funcKnotsLattice(1, vector<double*>(stateSimPtr->paramFuncs()->funcsArcSize(0), 0));
432  for (size_t i = 0; i < funcKnotsLattice[0].size(); ++i)
433  {
434  funcKnotsLattice[0][i] = &stateSimPtr->paramFuncs()->funcsArc(0, i);
435  }
436  trajOpt->trajSim()->setUserDefLattice(funcKnotsLattice);
437  trajOpt->setSimMode(TrajectorySimulator::SimMode::PRECALC);
438 
439  double dt = 0.01;
440  double ds = 0.1;
441 
442  trajOpt->trajSim()->dtBase() = dt;
443  trajOpt->trajSim()->dsBase() = ds;
444 
445  trajOpt->stepSize() = 1e-5;
446 
447  trajOpt->computeJacobian();
448 
449  auto& costsEvaluator = trajOpt->trajSim()->costsEvaluator_;
450  auto f = costsEvaluator->f;
451  auto h = costsEvaluator->h;
452  auto g = costsEvaluator->g;
453  auto gradF(costsEvaluator->gradF);
454  auto gradH(costsEvaluator->gradH);
455  auto gradG(costsEvaluator->gradG);
456 
457  cout << "gradH Precalc=" << endl
458  << gradH << endl
459  << endl;
460 }
461 
463 
464 } // namespace
465 
466 int main(int argc, char** argv)
467 {
468  ::testing::InitGoogleTest(&argc, argv);
469  return RUN_ALL_TESTS();
470 }
std::shared_ptr< State > StateSPtr
Definition: state.h:129
control point value
previous evaluation arc <= this evaluation arc
virtual double & value(const std::size_t &_i)=0
Access state variable based on index _i.
std::unique_ptr< StateSim > StateSimUPtr
Definition: state_sim.h:56
control point arc parameter
Helper function needed to upgrade c++ 2011.
Definition: utils.h:193
constexpr auto asInt(Enumeration const value) -> typename std::underlying_type< Enumeration >::type
Definition: utils.h:87
std::shared_ptr< TrajectoryOptimizer > TrajectoryOptimizerSPtr
function single integral
Templated partial implementation of StateSim.
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
Containts parametric function initialization data.
Definition: param_func.h:100
Generic tree-like recursive structure that allows sub-structure access as well as ordered (array-like...
Definition: state.h:135
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.
CtrlPtDim
Control point variable dimension.
Definition: param_func.h:73
Extends manipulation of parametric functions collection with closed-form arc length (distance) comput...
FuncEvalMode
Required type of computation relative to the parametric function.
Definition: param_func.h:62
std::shared_ptr< StateSim > StateSimPtr
StateSimPtr stateSim()
Reference of the state simulator object.
virtual void precompute()=0
Precomputes cached data.
agent base center linear velocity is parametric function
function double integral
virtual void setEvalArc(const double &_funcsArcEval, const EvalArcGuarantee &_evalArcGuarantee=EvalArcGuarantee::NONE)=0
Sets parametric function evaluation arc.
int main(int argc, char **argv)
Storage and manipulation of parametric functions collection.
Definition: param_func.h:57


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