ocra-recipes
Doxygen documentation for the ocra-recipes repository
GaussianProcessTrajectory.cpp
Go to the documentation of this file.
2 
3 #ifndef ALPHA_L
4 #define ALPHA_L 1.0
5 #endif
6 
7 #ifndef VAR_LENGTH_FACTOR
8 #define VAR_LENGTH_FACTOR 0.1
9 #endif
10 
11 #ifndef MEAN_LENGTH_FACTOR
12 #define MEAN_LENGTH_FACTOR 10.0//20.0
13 #endif
14 
15 namespace ocra
16 {
17 
19 {
20  meanGP = new smlt::gaussianProcess();
21  varianceGP = new smlt::gaussianProcess();
22 
23 
24  // Store the original user defined waypoints
25  originalWaypoints = waypoints;
26 
27  extraWaypoints = 1;
28  extraWpDt = 0.01 * pointToPointDurationVector.mean(); // meanLengthParameter;
29 
30 
31  numberOfOptimizationWaypoints = 1; // by default only one waypoint is used in optimization.
32  boptVariablesSet = false; // must set all starting bopt values to get the other optimization parameters
33 
34  timeline = Eigen::VectorXd::Zero(waypoints.cols());
35  for(int i=0; i<waypoints.cols()-1; i++){
36  timeline(i+1) = timeline(i) + pointToPointDurationVector(i);
37  }
38 
39  boolVector tmp;
40  std::vector<Eigen::VectorXi> tmpDofToOptVec;
41  setMeanWaypoints(tmp);
44  setDofToOptimize(tmpDofToOptVec);
45 
46 
47  calculateGaussianProcessParameters();
48 }
49 
50 
52 {
53  int w1 = 12;
54  int w2 = 5;
55  int w3 = 8;
56  int w4 = 13;
57  int w5 = 12;
58  int w6 = 12;
59  int w7 = 9;
60 
61 
62  std::cout << std::setw(1) << "|" << std::setw(w1) << "waypoint #";
63  std::cout << std::setw(2) << "|" << std::setw(w2) << " time";
64  std::cout << std::setw(2) << "|" << std::setw(w3) << " coordinates";
65  std::cout << std::setw(2) << "|" << std::setw(w4) << " meanWaypoint";
66  std::cout << std::setw(2) << "|" << std::setw(w5) << " varWaypoint";
67  std::cout << std::setw(2) << "|" << std::setw(w6) << " optWaypoint";
68  std::cout << std::setw(2) << "|" << std::setw(w7) << " optIndexes";
69  std::cout << std::setw(2) << "|";
70  std::cout << std::endl;
71 
72  for(int i=0; i<waypoints.cols(); i++)
73  {
74  std::cout << std::setw(1) << "|" << std::setw(w1) << i;
75  std::cout << std::setw(2) << "|" << std::setw(w2) << timeline(i);
76  std::cout << std::setw(2) << "|" << std::setw(w3) << waypoints.col(i).transpose();
77  std::cout << std::setw(2) << "|" << std::setw(w4) << isMeanWaypoint[i];
78  std::cout << std::setw(2) << "|" << std::setw(w5) << isVarWaypoint[i];
79  std::cout << std::setw(2) << "|" << std::setw(w6) << isOptWaypoint[i];
80  std::cout << std::setw(2) << "|" << std::setw(w7) << dofToOptimize[i].transpose();
81  std::cout << std::setw(2) << "|";
82  std::cout << std::endl;
83  }
84 }
85 
86 
88 {
89  bool retval;
90  if (bMeanVec.empty()) {
91  isMeanWaypoint.resize(waypoints.cols());
92  for (int i=0; i<waypoints.cols(); i++){
93  isMeanWaypoint[i] = true;
94  }
95  }
96  else if (bMeanVec.size()==waypoints.cols()) {
97  isMeanWaypoint = bMeanVec;
98  retval = true;
99  }
100  else {
101  retval = false;
102  std::cout << "[ERROR] (): The number of vector entries must match the number of waypoints ("<< waypoints.cols() <<")." << std::endl;
103  }
104 
105 
106  if (gpParametersAreSet()) {
107  calculateGaussianProcessParameters();
108  }
109 
110  return retval;
111 }
112 
114 {
115  bool retval;
116  if (bVarVec.empty()) {
117  isVarWaypoint.resize(waypoints.cols());
118  for (int i=0; i<waypoints.cols(); i++){
119  isVarWaypoint[i] = true;
120  }
121  }
122 
123  else if (bVarVec.size()==waypoints.cols()) {
124  isVarWaypoint = bVarVec;
125  retval = true;
126  }
127  else {
128  retval = false;
129  std::cout << "[ERROR] (): The number of vector entries must match the number of waypoints ("<< waypoints.cols() <<")." << std::endl;
130  }
131 
132 
133  if (gpParametersAreSet()) {
134  calculateGaussianProcessParameters();
135  }
136 
137  return retval;
138 }
139 
141 {
142  bool retval;
143  if (bOptVec.empty()) {
144  isOptWaypoint.resize(waypoints.cols());
145  for (int i=0; i<waypoints.cols(); i++){
146  isOptWaypoint[i] = false;
147  }
148  }
149  else if (bOptVec.size()==waypoints.cols()) {
150  isOptWaypoint = bOptVec;
151  retval = true;
152  }
153  else {
154  retval = false;
155  std::cout << "[ERROR] (): The number of vector entries must match the number of waypoints ("<< waypoints.cols() <<")." << std::endl;
156  }
157 
158  return retval;
159 }
160 
161 bool GaussianProcessTrajectory::setDofToOptimize(std::vector<Eigen::VectorXi>& dofToOptVec)
162 {
163  bool retval;
164 
165  if (dofToOptVec.empty()) {
166  dofToOptimize.resize(waypoints.cols());
167  for (int i=0; i<waypoints.cols(); i++){
168  Eigen::VectorXi tmpVec = Eigen::VectorXi::LinSpaced(nDoF+1, 0, nDoF); // all DOF
169  dofToOptimize[i] = tmpVec;
170  }
171  }
172  else if (dofToOptVec.size()==waypoints.cols()) {
173  dofToOptimize = dofToOptVec;
174  retval = true;
175  }
176  else {
177  retval = false;
178  std::cout << "[ERROR] (): The number of vector entries must match the number of waypoints ("<< waypoints.cols() <<")." << std::endl;
179  }
180 
181  return retval;
182 }
183 
184 bool GaussianProcessTrajectory::gpParametersAreSet()
185 {
186  bool retVal = true;
187  retVal = retVal && isMeanWaypoint.size() == waypoints.cols();
188  retVal = retVal && isVarWaypoint.size() == waypoints.cols();
189  return retVal;
190 }
191 
192 
193 void GaussianProcessTrajectory::calculateGaussianProcessParameters()
194 {
195 
196  // Add a waypoint(s) to the ends of the movement.
197  int meanCounter = 0;
198  int varCounter = 0;
199  for(int i=0; i<waypoints.cols(); i++){
200  if (isMeanWaypoint[i]){
201  meanCounter++;
202  }
203  if (isVarWaypoint[i]){
204  varCounter++;
205  }
206  }
207 
208  meanKernelCenters.resize(meanCounter);
209  meanKernelTrainingData.resize(nDoF, meanCounter);
210  varKernelCenters.resize(varCounter);
211  varKernelTrainingData.resize(nDoF, varCounter);
212 
213  int meanTDColCounter = 0;
214  int varTDColCounter = 0;
215 
216  for(int i=0; i<waypoints.cols(); i++)
217  {
218  if (isMeanWaypoint[i])
219  {
220  meanKernelCenters(meanTDColCounter) = timeline(i);
221  meanKernelTrainingData.col(meanTDColCounter) << waypoints.col(i);
222  meanTDColCounter++;
223  }
224 
225 
226  if (isVarWaypoint[i])
227  {
228  varKernelCenters(varTDColCounter) = timeline(i);
229  varKernelTrainingData.col(varTDColCounter) << waypoints.col(i);
230  varTDColCounter++;
231  }
232  }
233 
234 
235  int minIdx;
236  double minMeanTime = meanKernelCenters.minCoeff(&minIdx);
237 
238 
239  int maxIdx;
240  double maxMeanTime = meanKernelCenters.maxCoeff(&maxIdx);
241 
242  minMeanTime += extraWpDt;
243  maxMeanTime += extraWpDt;
244 
245 
246 
247  Eigen::VectorXd extraWptTimes(2); extraWptTimes << minMeanTime, maxMeanTime;
248 
249  Eigen::MatrixXd extraWpts(nDoF, 2); extraWpts << meanKernelTrainingData.col(minIdx), meanKernelTrainingData.col(maxIdx);
250 
251  meanKernelCenters = vStack(meanKernelCenters, extraWptTimes);
252 
253  meanKernelTrainingData = hStack(meanKernelTrainingData, extraWpts);
254 
255 
256  if (isVarWaypoint[minIdx]){
257  Eigen::VectorXd extraWptT(1); extraWptT << minMeanTime;
258  varKernelCenters = vStack(varKernelCenters, extraWptT);
259  varKernelTrainingData = hStack(varKernelTrainingData, meanKernelTrainingData.col(minIdx) );
260  }
261 
262 
263  if (isVarWaypoint[maxIdx]){
264  Eigen::VectorXd extraWptT(1); extraWptT << maxMeanTime;
265  varKernelCenters = vStack(varKernelCenters, extraWptT);
266  varKernelTrainingData = hStack(varKernelTrainingData, meanKernelTrainingData.col(maxIdx) );
267  }
268 
269  // Calculate the max covariance vector for the movement.
270  maxCovariance = ( waypoints - waypoints.rowwise().mean().replicate(1, waypoints.cols()) ).array().square().rowwise().sum() / (waypoints.cols() - 1) ;
271 
272  // Get the length param to be used on the movement.
273  varLengthParameter = pointToPointDurationVector.mean() * VAR_LENGTH_FACTOR;
274 
275  // Get the length param to be used for the calculation of covariance
276  meanLengthParameter = pointToPointDurationVector.mean() * MEAN_LENGTH_FACTOR;
277 
278  Eigen::MatrixXd meanCovMat(1,1);
279  meanCovMat << meanLengthParameter;
280  Eigen::MatrixXd varCovMat(1,1);
281  varCovMat << varLengthParameter;
282 
283  meanGP->setKernelCenters(Eigen::MatrixXd(meanKernelCenters.transpose()));
284  meanGP->setKernelTrainingData(meanKernelTrainingData);
285  meanGP->setCovarianceMatrix(meanCovMat);
286  meanGP->setMaxCovariance(maxCovariance);
287  meanGP->calculateParameters();
288 
289  varianceGP->setKernelCenters(Eigen::MatrixXd(varKernelCenters.transpose()));
290  varianceGP->setKernelTrainingData(varKernelTrainingData);
291  varianceGP->setCovarianceMatrix(varCovMat);
292  varianceGP->setMaxCovariance(maxCovariance);
293  varianceGP->calculateParameters();
294  startTrigger = true;
295  varianceStartTrigger = true;
296 
297 }
298 
299 
300 Eigen::MatrixXd GaussianProcessTrajectory::getDesiredValues(double _time)
301 {
307  Eigen::MatrixXd desiredValue = Eigen::MatrixXd::Zero(nDoF, TRAJ_DIM);
308 
309  if (startTrigger)
310  {
311  startTrigger = false;
312  t0 = _time;
313  int minTimeIndex; timeline.minCoeff(&minTimeIndex);
314  desiredValue.col(POS_INDEX) = waypoints.col(minTimeIndex);
315  desiredValue.col(VEL_INDEX) = Eigen::VectorXd::Zero(nDoF);
316  desiredValue.col(ACC_INDEX) = Eigen::VectorXd::Zero(nDoF);
317 
318  posOld = desiredValue.col(POS_INDEX);
319  velOld = desiredValue.col(VEL_INDEX);
320 
321  // posOld = waypoints.col(0);
322  // velOld =Eigen::VectorXd::Zero(nDoF);
323  t_old = t0;
324 
325  // return desiredValue;
326  }
327 
328  else
329  {
330  double t = _time - t0;
331 
332  if (t<=meanKernelCenters.maxCoeff())
333  {
334  Eigen::VectorXd tVec = Eigen::VectorXd::Constant(1, t);
335  Eigen::VectorXd posMean;
336  meanGP->calculateMean(tVec, posMean);
337  desiredValue.col(POS_INDEX) = posMean;
338  }
339  else
340  {
341  int maxTimeIndex; meanKernelCenters.maxCoeff(&maxTimeIndex);
342 
343  desiredValue.col(POS_INDEX) = meanKernelTrainingData.col(maxTimeIndex);
344  trajectoryFinished = true;
345  }
346 
347  double delta_t = t-t_old;
348  desiredValue.col(VEL_INDEX) = (desiredValue.col(POS_INDEX) - posOld) / delta_t;
349  desiredValue.col(ACC_INDEX) = (desiredValue.col(VEL_INDEX) - velOld) / delta_t;
350 
351  posOld = desiredValue.col(POS_INDEX);
352  velOld = desiredValue.col(VEL_INDEX);
353  t_old = t;
354  }
355  return desiredValue;
356 }
357 
358 Eigen::VectorXd GaussianProcessTrajectory::getVariance(double _time)
359 {
360  if (varianceStartTrigger) {
361  t0_variance = _time;
362  varianceStartTrigger = false;
363  }
364 
365 
366  double t = _time - t0_variance;
367 
368 
369  Eigen::VectorXd variance;
370 
371  if (t<=meanKernelCenters.maxCoeff())
372  {
373  Eigen::VectorXd tVec = Eigen::VectorXd::Constant(1, t);
374  varianceGP->calculateVariance(tVec, variance);
375  }
376  else{
377  variance = Eigen::VectorXd::Zero(maxCovariance.rows());
378  trajectoryFinished = true;
379 
380  }
381 
382  return variance;
383 }
384 
385 void GaussianProcessTrajectory::getDesiredValues(double _time, Eigen::MatrixXd& desiredValues, Eigen::VectorXd& variance)
386 {
387  desiredValues = getDesiredValues(_time);
388  variance = getVariance(_time);
389 }
390 
391 
393 {
394  Eigen::MatrixXd dataMat = Eigen::MatrixXd::Zero(waypoints.cols(), nDoF+1);
395 
396  dataMat.col(0) = timeline;
397  dataMat.rightCols(nDoF) = waypoints.transpose();
398 
399  return dataMat;
400 }
401 
403 {
404  Eigen::MatrixXd dataMat = Eigen::MatrixXd::Zero(meanKernelCenters.rows(), nDoF+1);
405 
406  dataMat.col(0) = meanKernelCenters;
407  dataMat.rightCols(nDoF) = meanKernelTrainingData.transpose();
408 
409  return dataMat;
410 }
411 
413 {
414  Eigen::MatrixXd dataMat = Eigen::MatrixXd::Zero(varKernelCenters.rows(), nDoF+1);
415 
416  dataMat.col(0) = varKernelCenters;
417  dataMat.rightCols(nDoF) = varKernelTrainingData.transpose();
418 
419  return dataMat;
420 }
421 
422 void GaussianProcessTrajectory::addWaypoint(const Eigen::VectorXd newWaypoint, const double waypointTime)
423 {
424  addWaypoint(newWaypoint, waypointTime, Eigen::VectorXi::LinSpaced(nDoF+1, 0, nDoF));
425 }
426 
427 void GaussianProcessTrajectory::addWaypoint(const Eigen::VectorXd newWaypoint, const double waypointTime, const Eigen::VectorXi& _dofToOpt, const bool useForMean, const bool useForVar, const bool useForOpt)
428 {
429  Eigen::VectorXi dofToOpt = _dofToOpt;
430  if ( (newWaypoint.rows() == nDoF) && (waypointTime>=0.0) )
431  {
432  waypoints = hStack(waypoints, newWaypoint);
433  Eigen::VectorXd wyptime(1); wyptime<< waypointTime;
434  timeline = vStack(timeline, wyptime);
435 
436  isMeanWaypoint.push_back(useForMean);
437  isVarWaypoint.push_back(useForVar);
438  isOptWaypoint.push_back(useForOpt);
439 
440  if (dofToOpt.rows()==0) {
441  dofToOpt.resize(nDoF+1);
442  dofToOpt << Eigen::VectorXi::LinSpaced(nDoF+1, 0, nDoF);
443  }else if (dofToOpt.rows()>nDoF+1) {
444  dofToOpt = dofToOpt.head(nDoF).eval();
445  }
446  dofToOptimize.push_back(dofToOpt);
447 
448  calculateGaussianProcessParameters();
449 
450 
451  }
452  else{
453  if (newWaypoint.rows() != nDoF){
454  std::cout << "[ERROR] (GaussianProcessTrajectory::addWaypoint): New waypoint is not the right size. Should have dim = " <<nDoF << "x1." << std::endl;
455  }
456  if (waypointTime<=0.0){
457  std::cout << "[ERROR] (GaussianProcessTrajectory::addWaypoint): New waypoint time should be greater than 0.0 seconds." << std::endl;
458  }
459  }
460 
461 
462 }
463 
465 {
466  // std::cout << "Removing waypoint index: " << index << "..." << std::endl;
467  if ( (index>=0) && (index<waypoints.cols()) )
468  {
469 
470  removeCols(waypoints, index, 1);
471  removeRows(meanKernelCenters, index, 1);
472 
473  isMeanWaypoint.erase(isMeanWaypoint.begin()+index);
474  isVarWaypoint.erase(isVarWaypoint.begin()+index);
475  isOptWaypoint.erase(isOptWaypoint.begin()+index);
476  dofToOptimize.erase(dofToOptimize.begin()+index);
477 
478 
479  calculateGaussianProcessParameters();
480  }
481  else
482  {
483  std::cout << "[ERROR] (GaussianProcessTrajectory::addWaypoint): New waypoint time is out of index bounds. Should have fall between 0 and " << nWaypoints-1 << "." << std::endl;
484  }
485 
486 }
487 
488 
490 {
491 
492  int optVectorSize = 0;
493  for (int i =0; i<waypoints.cols(); i++)
494  {
495  if (isOptWaypoint[i]){optVectorSize+=dofToOptimize[i].size();}
496  }
497 
498  Eigen::MatrixXd covarianceMatrix = Eigen::MatrixXd::Identity(optVectorSize,optVectorSize);
499  Eigen::VectorXd maxVarVec = getMaxCovarianceVector();
500 
501  if (boptVariablesSet) {
502  int indexCounter = 0;
503  for (int i =0; i<waypoints.cols(); i++)
504  {
505  if (isOptWaypoint[i])
506  {
507  for(int j=0; j<dofToOptimize[i].size(); j++)
508  {
509 
510  if (dofToOptimize[i](j)==0)
511  {
512  covarianceMatrix(indexCounter,indexCounter) = meanLengthParameter;//getVarianceLengthParameter()*1.0;
513  }
514  else if (dofToOptimize[i](j)>0 && dofToOptimize[i](j)<=nDoF)
515  {
516  covarianceMatrix(indexCounter,indexCounter) = maxVarVec(j-1)*1.0;
517  }
518  else
519  {
520  std::cout << "[ERROR] (GaussianProcessTrajectory::getBoptCovarianceMatrix): You are trying to optimize an index which doesn't exist! Ignoring." << std::endl;
521  }
522  indexCounter++;
523  }
524  }
525  }
526 
527  }
528  else {
529  std::cout << "[ERROR] (GaussianProcessTrajectory::getBoptCovarianceMatrix): Bayesian optimization variables have not yet been set. Please call GaussianProcessTrajectory::getBoptVariables(const int extraPointsToAdd) first." << std::endl;
530  }
531  return covarianceMatrix;
532 }
533 
535 {
536  int optVectorSize = 0;
537  for (int i =0; i<waypoints.cols(); i++)
538  {
539  if (isOptWaypoint[i]){optVectorSize+=dofToOptimize[i].size();}
540  }
541 
542  Eigen::VectorXd minBound(optVectorSize);
543 
544  if (boptVariablesSet)
545  {
546  double timeMin = timeline.minCoeff() + (extraWpDt*10.0);
547  Eigen::VectorXd minDofCoord(waypoints.rows());
548  minDofCoord << waypoints.rowwise().minCoeff();
549 
550  int indexCounter = 0;
551  for (int i =0; i<waypoints.cols(); i++)
552  {
553  if (isOptWaypoint[i])
554  {
555  for(int j=0; j<dofToOptimize[i].size(); j++)
556  {
557 
558  if (dofToOptimize[i](j)==0)
559  {
560  minBound(indexCounter) = timeMin;
561  }
562  else if (dofToOptimize[i](j)>0 && dofToOptimize[i](j)<=nDoF)
563  {
564  minBound(indexCounter) = minDofCoord(dofToOptimize[i](j)-1);
565  }
566  else
567  {
568  std::cout << "[ERROR] (GaussianProcessTrajectory::getBoptSearchSpaceMinBound): You are trying to optimize an index which doesn't exist! Ignoring." << std::endl;
569  }
570  indexCounter++;
571  }
572  }
573  }
574  }
575  else {
576  std::cout << "[ERROR] (GaussianProcessTrajectory::getBoptSearchSpaceMinBound): Bayesian optimization variables have not yet been set. Please call GaussianProcessTrajectory::getBoptVariables(const int extraPointsToAdd) first." << std::endl;
577  }
578 
579  return minBound;
580 }
581 
583 {
584  int optVectorSize = 0;
585  for (int i =0; i<waypoints.cols(); i++)
586  {
587  if (isOptWaypoint[i]){optVectorSize+=dofToOptimize[i].size();}
588  }
589 
590  Eigen::VectorXd maxBound(optVectorSize);
591 
592  if (boptVariablesSet)
593  {
594  double timeMin = timeline.maxCoeff() - (extraWpDt*4.0);
595  Eigen::VectorXd maxDofCoord(waypoints.rows());
596  maxDofCoord << waypoints.rowwise().maxCoeff();
597 
598  int indexCounter = 0;
599  for (int i =0; i<waypoints.cols(); i++)
600  {
601  if (isOptWaypoint[i])
602  {
603  for(int j=0; j<dofToOptimize[i].size(); j++)
604  {
605 
606  if (dofToOptimize[i](j)==0)
607  {
608  maxBound(indexCounter) = timeMin;
609  }
610  else if (dofToOptimize[i](j)>0 && dofToOptimize[i](j)<=nDoF)
611  {
612  maxBound(indexCounter) = maxDofCoord(dofToOptimize[i](j)-1);
613  }
614  else
615  {
616  std::cout << "[ERROR] (GaussianProcessTrajectory::getBoptSearchSpaceMaxBound): You are trying to optimize an index which doesn't exist! Ignoring." << std::endl;
617  }
618  indexCounter++;
619  }
620  }
621  }
622  }
623  else {
624  std::cout << "[ERROR] (GaussianProcessTrajectory::getBoptSearchSpaceMaxBound): Bayesian optimization variables have not yet been set. Please call GaussianProcessTrajectory::getBoptVariables(const int extraPointsToAdd) first." << std::endl;
625  }
626 
627  return maxBound;
628 
629 }
630 
631 
632 Eigen::VectorXd GaussianProcessTrajectory::getBoptVariables(const int extraPointsToAdd, std::vector<Eigen::VectorXi> dofToOptVec)
633 {
634  int nP;
635  int nW = originalWaypoints.cols();
636 
637  bool optimizeExistingWaypoints = false;
638  for (int i=0; i<waypoints.cols(); i++){
639  optimizeExistingWaypoints = optimizeExistingWaypoints || isOptWaypoint[i];
640  }
641 
642  if (extraPointsToAdd<=0 && !optimizeExistingWaypoints) {
643  if (nW<3) {nP = 1;}
644  else{nP = 2;}
645  }else{nP = extraPointsToAdd;}
646 
647  if (nP>0) {
648 
649 
650  numberOfOptimizationWaypoints = nP;
651  // int optDim = (nDoF+1)*nP; // +1 for the time dimension
652  // Eigen::MatrixXd variables = Eigen::MatrixXd::Zero(optDim, 1);
653 
654  Eigen::VectorXd timeVec = Eigen::VectorXd::LinSpaced(nP+2, 0.0, timeline.maxCoeff()).segment(1,nP);
655 
656  for (int i=0; i<nP; i++)
657  {
658  double tmpTime = timeVec(i);
659  Eigen::VectorXd tVec = Eigen::VectorXd::Constant(1, tmpTime);
660  Eigen::VectorXd tmpWaypt;
661  meanGP->calculateMean(tVec, tmpWaypt);
662  if (nP==dofToOptVec.size()) {
663  addWaypoint(tmpWaypt, tmpTime, dofToOptVec[i]);
664  }
665  else {
666  addWaypoint(tmpWaypt, tmpTime);
667  }
668 
669  }
670  }
671 
672  int optVectorSize = 0;
673  for (int i =0; i<waypoints.cols(); i++)
674  {
675  if (isOptWaypoint[i]){optVectorSize+=dofToOptimize[i].size();}
676  }
677 
678  Eigen::VectorXd optVector = Eigen::VectorXd::Zero(optVectorSize);
679  int indexCounter = 0;
680  for (int i =0; i<waypoints.cols(); i++)
681  {
682  if (isOptWaypoint[i]) {
683  for(int j=0;j<dofToOptimize[i].size();j++){
684  if (dofToOptimize[i](j)==0) {
685  optVector(indexCounter) = timeline(i);
686  }else if (dofToOptimize[i](j)>0 && dofToOptimize[i](j)<=nDoF) {
687  optVector(indexCounter) = waypoints(dofToOptimize[i](j)-1, i);
688  }
689  else{
690  std::cout << "[ERROR] (GaussianProcessTrajectory::getBoptVariables): You are trying to optimize an index which doesn't exist! Ignoring and setting to zero." << std::endl;
691  }
692  indexCounter++;
693 
694  }
695  }
696  }
697 
698  boptVariablesSet = true;
699  return optVector;
700 
701 }
702 
703 bool GaussianProcessTrajectory::setBoptVariables(const Eigen::VectorXd& newOptVariables)
704 {
705  int optVectorSize = 0;
706  for (int i =0; i<waypoints.cols(); i++)
707  {
708  if (isOptWaypoint[i]){optVectorSize+=dofToOptimize[i].size();}
709  }
710  bool retval = false;
711 
712  if (newOptVariables.rows() == optVectorSize)
713  {
714  int indexCounter = 0;
715  for (int i =0; i<waypoints.cols(); i++)
716  {
717  if (isOptWaypoint[i])
718  {
719  for(int j=0; j<dofToOptimize[i].size(); j++)
720  {
721 
722  if (dofToOptimize[i](j)==0)
723  {
724  timeline(i) = newOptVariables(indexCounter);
725  }
726  else if (dofToOptimize[i](j)>0 && dofToOptimize[i](j)<=nDoF)
727  {
728  waypoints(dofToOptimize[i](j)-1, i) = newOptVariables(indexCounter);
729  }
730  else
731  {
732  std::cout << "[ERROR] (GaussianProcessTrajectory::getBoptVariables): You are trying to change an index which doesn't exist! Ignoring." << std::endl;
733  }
734  indexCounter++;
735  }
736  }
737  }
738  calculateGaussianProcessParameters();
739  retval = true;
740  }
741  else
742  {
743  std::cout << "[ERROR] (): The new optimization variable vector size (" << newOptVariables.rows() << ") doesn't match what I was expecting ("<< optVectorSize <<")." << std::endl;
744  retval = false;
745  }
746 
747  return retval;
748 
749 }
750 
751 
752 // smlt::bopt_Parameters GaussianProcessTrajectory::getBoptParameters()
753 // {
754 // smlt::bopt_Parameters bopt_params = smlt::bopt_Parameters();
755 //
756 // bopt_params.dataLogDir = "./tmp/";
757 // bopt_params.maxIter = 20;
758 // bopt_params.gridSpacing = Eigen::VectorXd::Constant(2, 1.0);
759 // bopt_params.costMaxCovariance = Eigen::VectorXd::Ones(1);
760 //
761 //
762 // bopt_params.searchSpaceMinBound = getBoptSearchSpaceMinBound();
763 //
764 // bopt_params.searchSpaceMaxBound = getBoptSearchSpaceMaxBound();
765 //
766 // bopt_params.costCovariance = getBoptCovarianceMatrix();
767 //
768 // return bopt_params;
769 // }
770 
771 
772 void GaussianProcessTrajectory::precalculateTrajectory(Eigen::MatrixXd& _traj, Eigen::MatrixXd& _variance, Eigen::VectorXd& _timeline, const double DT)
773 {
774  double currentTime = 0.0;
775 
776  int numberOfDataPoints = ceil((pointToPointDurationVector.sum() / DT)*2);
777 
778  Eigen::MatrixXd traj(numberOfDataPoints, nDoF*3);
779  Eigen::MatrixXd variance(numberOfDataPoints, nDoF);
780  Eigen::VectorXd timeline(numberOfDataPoints);
781 
782 
783  int index = 0;
784  startTrigger = true;
785  trajectoryFinished = false;
786 
787  while (!trajectoryFinished)
788  {
789  Eigen::MatrixXd desValsMat;
790  Eigen::VectorXd desVarianceVec;
791 
792  getDesiredValues(currentTime, desValsMat, desVarianceVec);
793 
794  traj.row(index) << desValsMat.col(POS_INDEX).transpose(),
795  desValsMat.col(VEL_INDEX).transpose(),
796  desValsMat.col(ACC_INDEX).transpose();
797 
798  variance.row(index) << desVarianceVec.transpose();
799 
800  timeline(index) = currentTime;
801  currentTime += DT;
802  index++;
803  }
804  // reset values to their original state
805  startTrigger = true;
806  trajectoryFinished = false;
807 
808  _traj = traj.topRows(index);
809  _variance = variance.topRows(index);
810  _timeline = timeline.head(index);
811 
812 
813 }
814 
815 void GaussianProcessTrajectory::saveTrajectoryToFile(const std::string dirPath)
816 {
817  smlt::checkAndCreateDirectory(dirPath);
818  std::string filePath = dirPath + "/trajectory.txt";
819 
820  std::ofstream trajFile;
821  trajFile.open(filePath.c_str());
822  if (trajFile.is_open()) {
823  Eigen::VectorXd timeVec;
824  Eigen::MatrixXd trajMat;
825  Eigen::MatrixXd varianceMat;
826  precalculateTrajectory(trajMat, varianceMat, timeVec);
827  for(int i=0; i<trajMat.rows(); i++)
828  {
829  trajFile << timeVec(i) << " " << trajMat.row(i) << " " << varianceMat.row(i) << std::endl;
830  }
831  trajFile.close();
832  }
833  else
834  {
835  std::cout << "[ERROR](line: "<< __LINE__ <<") -> Could not write the trajectory to file, " << filePath << std::endl;
836  }
837 
838 }
839 
840 
842 {
843  smlt::checkAndCreateDirectory(dirPath);
844  std::string filePath = dirPath + "/waypoints.txt";
845 
846  std::ofstream waypointFile;
847  waypointFile.open(filePath.c_str());
848  if (waypointFile.is_open()) {
849  waypointFile << getWaypointData();
850  waypointFile.close();
851  }
852  else
853  {
854  std::cout << "[ERROR](line: "<< __LINE__ <<") -> Could not write the trajectory to file, " << filePath << std::endl;
855  }
856 }
857 
858 
859 } //namespace ocra
bool trajectoryFinished
Definition: Trajectory.h:130
bool setVarianceWaypoints(boolVector &bVarVec)
#define VEL_INDEX
Definition: Trajectory.h:21
#define TRAJ_DIM
Definition: Trajectory.h:24
Eigen::VectorXd getBoptVariables(const int extraPointsToAdd=0, std::vector< Eigen::VectorXi > dofToOptVec=std::vector< Eigen::VectorXi >())
Eigen::MatrixXd waypoints
Definition: Trajectory.h:117
Eigen::MatrixXd getDesiredValues(double time)
bool setOptimizationWaypoints(boolVector &bOptVec)
void addWaypoint(const Eigen::VectorXd newWaypoint, const double waypointTime)
Eigen::VectorXd pointToPointDurationVector
Definition: Trajectory.h:126
Optimization-based Robot Controller namespace. a library of classes to write and solve optimization p...
Eigen::VectorXd getVariance(double time)
bool setMeanWaypoints(boolVector &bMeanVec)
#define ACC_INDEX
Definition: Trajectory.h:22
void saveTrajectoryToFile(const std::string dirPath="./")
void saveWaypointDataToFile(const std::string dirPath="./")
#define POS_INDEX
Definition: Trajectory.h:20
#define MEAN_LENGTH_FACTOR
std::vector< bool > boolVector
bool setDofToOptimize(std::vector< Eigen::VectorXi > &dofToOptVec)
bool setBoptVariables(const Eigen::VectorXd &newOptVariables)
#define VAR_LENGTH_FACTOR