7 #ifndef VAR_LENGTH_FACTOR 8 #define VAR_LENGTH_FACTOR 0.1 11 #ifndef MEAN_LENGTH_FACTOR 12 #define MEAN_LENGTH_FACTOR 10.0//20.0 20 meanGP =
new smlt::gaussianProcess();
21 varianceGP =
new smlt::gaussianProcess();
31 numberOfOptimizationWaypoints = 1;
32 boptVariablesSet =
false;
34 timeline = Eigen::VectorXd::Zero(
waypoints.cols());
40 std::vector<Eigen::VectorXi> tmpDofToOptVec;
47 calculateGaussianProcessParameters();
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;
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;
90 if (bMeanVec.empty()) {
93 isMeanWaypoint[i] =
true;
96 else if (bMeanVec.size()==
waypoints.cols()) {
97 isMeanWaypoint = bMeanVec;
102 std::cout <<
"[ERROR] (): The number of vector entries must match the number of waypoints ("<<
waypoints.cols() <<
")." << std::endl;
106 if (gpParametersAreSet()) {
107 calculateGaussianProcessParameters();
116 if (bVarVec.empty()) {
119 isVarWaypoint[i] =
true;
123 else if (bVarVec.size()==
waypoints.cols()) {
124 isVarWaypoint = bVarVec;
129 std::cout <<
"[ERROR] (): The number of vector entries must match the number of waypoints ("<<
waypoints.cols() <<
")." << std::endl;
133 if (gpParametersAreSet()) {
134 calculateGaussianProcessParameters();
143 if (bOptVec.empty()) {
146 isOptWaypoint[i] =
false;
149 else if (bOptVec.size()==
waypoints.cols()) {
150 isOptWaypoint = bOptVec;
155 std::cout <<
"[ERROR] (): The number of vector entries must match the number of waypoints ("<<
waypoints.cols() <<
")." << std::endl;
165 if (dofToOptVec.empty()) {
168 Eigen::VectorXi tmpVec = Eigen::VectorXi::LinSpaced(
nDoF+1, 0,
nDoF);
169 dofToOptimize[i] = tmpVec;
172 else if (dofToOptVec.size()==
waypoints.cols()) {
173 dofToOptimize = dofToOptVec;
178 std::cout <<
"[ERROR] (): The number of vector entries must match the number of waypoints ("<<
waypoints.cols() <<
")." << std::endl;
184 bool GaussianProcessTrajectory::gpParametersAreSet()
187 retVal = retVal && isMeanWaypoint.size() ==
waypoints.cols();
188 retVal = retVal && isVarWaypoint.size() ==
waypoints.cols();
193 void GaussianProcessTrajectory::calculateGaussianProcessParameters()
200 if (isMeanWaypoint[i]){
203 if (isVarWaypoint[i]){
208 meanKernelCenters.resize(meanCounter);
209 meanKernelTrainingData.resize(
nDoF, meanCounter);
210 varKernelCenters.resize(varCounter);
211 varKernelTrainingData.resize(
nDoF, varCounter);
213 int meanTDColCounter = 0;
214 int varTDColCounter = 0;
218 if (isMeanWaypoint[i])
220 meanKernelCenters(meanTDColCounter) = timeline(i);
221 meanKernelTrainingData.col(meanTDColCounter) <<
waypoints.col(i);
226 if (isVarWaypoint[i])
228 varKernelCenters(varTDColCounter) = timeline(i);
229 varKernelTrainingData.col(varTDColCounter) <<
waypoints.col(i);
236 double minMeanTime = meanKernelCenters.minCoeff(&minIdx);
240 double maxMeanTime = meanKernelCenters.maxCoeff(&maxIdx);
242 minMeanTime += extraWpDt;
243 maxMeanTime += extraWpDt;
247 Eigen::VectorXd extraWptTimes(2); extraWptTimes << minMeanTime, maxMeanTime;
249 Eigen::MatrixXd extraWpts(
nDoF, 2); extraWpts << meanKernelTrainingData.col(minIdx), meanKernelTrainingData.col(maxIdx);
251 meanKernelCenters = vStack(meanKernelCenters, extraWptTimes);
253 meanKernelTrainingData = hStack(meanKernelTrainingData, extraWpts);
256 if (isVarWaypoint[minIdx]){
257 Eigen::VectorXd extraWptT(1); extraWptT << minMeanTime;
258 varKernelCenters = vStack(varKernelCenters, extraWptT);
259 varKernelTrainingData = hStack(varKernelTrainingData, meanKernelTrainingData.col(minIdx) );
263 if (isVarWaypoint[maxIdx]){
264 Eigen::VectorXd extraWptT(1); extraWptT << maxMeanTime;
265 varKernelCenters = vStack(varKernelCenters, extraWptT);
266 varKernelTrainingData = hStack(varKernelTrainingData, meanKernelTrainingData.col(maxIdx) );
278 Eigen::MatrixXd meanCovMat(1,1);
279 meanCovMat << meanLengthParameter;
280 Eigen::MatrixXd varCovMat(1,1);
281 varCovMat << varLengthParameter;
283 meanGP->setKernelCenters(Eigen::MatrixXd(meanKernelCenters.transpose()));
284 meanGP->setKernelTrainingData(meanKernelTrainingData);
285 meanGP->setCovarianceMatrix(meanCovMat);
286 meanGP->setMaxCovariance(maxCovariance);
287 meanGP->calculateParameters();
289 varianceGP->setKernelCenters(Eigen::MatrixXd(varKernelCenters.transpose()));
290 varianceGP->setKernelTrainingData(varKernelTrainingData);
291 varianceGP->setCovarianceMatrix(varCovMat);
292 varianceGP->setMaxCovariance(maxCovariance);
293 varianceGP->calculateParameters();
295 varianceStartTrigger =
true;
307 Eigen::MatrixXd desiredValue = Eigen::MatrixXd::Zero(
nDoF,
TRAJ_DIM);
313 int minTimeIndex; timeline.minCoeff(&minTimeIndex);
330 double t = _time - t0;
332 if (t<=meanKernelCenters.maxCoeff())
334 Eigen::VectorXd tVec = Eigen::VectorXd::Constant(1, t);
335 Eigen::VectorXd posMean;
336 meanGP->calculateMean(tVec, posMean);
341 int maxTimeIndex; meanKernelCenters.maxCoeff(&maxTimeIndex);
343 desiredValue.col(
POS_INDEX) = meanKernelTrainingData.col(maxTimeIndex);
347 double delta_t = t-t_old;
360 if (varianceStartTrigger) {
362 varianceStartTrigger =
false;
366 double t = _time - t0_variance;
369 Eigen::VectorXd variance;
371 if (t<=meanKernelCenters.maxCoeff())
373 Eigen::VectorXd tVec = Eigen::VectorXd::Constant(1, t);
374 varianceGP->calculateVariance(tVec, variance);
377 variance = Eigen::VectorXd::Zero(maxCovariance.rows());
394 Eigen::MatrixXd dataMat = Eigen::MatrixXd::Zero(
waypoints.cols(),
nDoF+1);
396 dataMat.col(0) = timeline;
404 Eigen::MatrixXd dataMat = Eigen::MatrixXd::Zero(meanKernelCenters.rows(),
nDoF+1);
406 dataMat.col(0) = meanKernelCenters;
407 dataMat.rightCols(
nDoF) = meanKernelTrainingData.transpose();
414 Eigen::MatrixXd dataMat = Eigen::MatrixXd::Zero(varKernelCenters.rows(),
nDoF+1);
416 dataMat.col(0) = varKernelCenters;
417 dataMat.rightCols(
nDoF) = varKernelTrainingData.transpose();
427 void GaussianProcessTrajectory::addWaypoint(
const Eigen::VectorXd newWaypoint,
const double waypointTime,
const Eigen::VectorXi& _dofToOpt,
const bool useForMean,
const bool useForVar,
const bool useForOpt)
429 Eigen::VectorXi dofToOpt = _dofToOpt;
430 if ( (newWaypoint.rows() ==
nDoF) && (waypointTime>=0.0) )
433 Eigen::VectorXd wyptime(1); wyptime<< waypointTime;
434 timeline = vStack(timeline, wyptime);
436 isMeanWaypoint.push_back(useForMean);
437 isVarWaypoint.push_back(useForVar);
438 isOptWaypoint.push_back(useForOpt);
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();
446 dofToOptimize.push_back(dofToOpt);
448 calculateGaussianProcessParameters();
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;
456 if (waypointTime<=0.0){
457 std::cout <<
"[ERROR] (GaussianProcessTrajectory::addWaypoint): New waypoint time should be greater than 0.0 seconds." << std::endl;
467 if ( (index>=0) && (index<
waypoints.cols()) )
471 removeRows(meanKernelCenters, index, 1);
473 isMeanWaypoint.erase(isMeanWaypoint.begin()+index);
474 isVarWaypoint.erase(isVarWaypoint.begin()+index);
475 isOptWaypoint.erase(isOptWaypoint.begin()+index);
476 dofToOptimize.erase(dofToOptimize.begin()+index);
479 calculateGaussianProcessParameters();
483 std::cout <<
"[ERROR] (GaussianProcessTrajectory::addWaypoint): New waypoint time is out of index bounds. Should have fall between 0 and " <<
nWaypoints-1 <<
"." << std::endl;
492 int optVectorSize = 0;
495 if (isOptWaypoint[i]){optVectorSize+=dofToOptimize[i].size();}
498 Eigen::MatrixXd covarianceMatrix = Eigen::MatrixXd::Identity(optVectorSize,optVectorSize);
501 if (boptVariablesSet) {
502 int indexCounter = 0;
505 if (isOptWaypoint[i])
507 for(
int j=0; j<dofToOptimize[i].size(); j++)
510 if (dofToOptimize[i](j)==0)
512 covarianceMatrix(indexCounter,indexCounter) = meanLengthParameter;
514 else if (dofToOptimize[i](j)>0 && dofToOptimize[i](j)<=
nDoF)
516 covarianceMatrix(indexCounter,indexCounter) = maxVarVec(j-1)*1.0;
520 std::cout <<
"[ERROR] (GaussianProcessTrajectory::getBoptCovarianceMatrix): You are trying to optimize an index which doesn't exist! Ignoring." << std::endl;
529 std::cout <<
"[ERROR] (GaussianProcessTrajectory::getBoptCovarianceMatrix): Bayesian optimization variables have not yet been set. Please call GaussianProcessTrajectory::getBoptVariables(const int extraPointsToAdd) first." << std::endl;
531 return covarianceMatrix;
536 int optVectorSize = 0;
539 if (isOptWaypoint[i]){optVectorSize+=dofToOptimize[i].size();}
542 Eigen::VectorXd minBound(optVectorSize);
544 if (boptVariablesSet)
546 double timeMin = timeline.minCoeff() + (extraWpDt*10.0);
547 Eigen::VectorXd minDofCoord(
waypoints.rows());
548 minDofCoord <<
waypoints.rowwise().minCoeff();
550 int indexCounter = 0;
553 if (isOptWaypoint[i])
555 for(
int j=0; j<dofToOptimize[i].size(); j++)
558 if (dofToOptimize[i](j)==0)
560 minBound(indexCounter) = timeMin;
562 else if (dofToOptimize[i](j)>0 && dofToOptimize[i](j)<=
nDoF)
564 minBound(indexCounter) = minDofCoord(dofToOptimize[i](j)-1);
568 std::cout <<
"[ERROR] (GaussianProcessTrajectory::getBoptSearchSpaceMinBound): You are trying to optimize an index which doesn't exist! Ignoring." << std::endl;
576 std::cout <<
"[ERROR] (GaussianProcessTrajectory::getBoptSearchSpaceMinBound): Bayesian optimization variables have not yet been set. Please call GaussianProcessTrajectory::getBoptVariables(const int extraPointsToAdd) first." << std::endl;
584 int optVectorSize = 0;
587 if (isOptWaypoint[i]){optVectorSize+=dofToOptimize[i].size();}
590 Eigen::VectorXd maxBound(optVectorSize);
592 if (boptVariablesSet)
594 double timeMin = timeline.maxCoeff() - (extraWpDt*4.0);
595 Eigen::VectorXd maxDofCoord(
waypoints.rows());
596 maxDofCoord <<
waypoints.rowwise().maxCoeff();
598 int indexCounter = 0;
601 if (isOptWaypoint[i])
603 for(
int j=0; j<dofToOptimize[i].size(); j++)
606 if (dofToOptimize[i](j)==0)
608 maxBound(indexCounter) = timeMin;
610 else if (dofToOptimize[i](j)>0 && dofToOptimize[i](j)<=
nDoF)
612 maxBound(indexCounter) = maxDofCoord(dofToOptimize[i](j)-1);
616 std::cout <<
"[ERROR] (GaussianProcessTrajectory::getBoptSearchSpaceMaxBound): You are trying to optimize an index which doesn't exist! Ignoring." << std::endl;
624 std::cout <<
"[ERROR] (GaussianProcessTrajectory::getBoptSearchSpaceMaxBound): Bayesian optimization variables have not yet been set. Please call GaussianProcessTrajectory::getBoptVariables(const int extraPointsToAdd) first." << std::endl;
635 int nW = originalWaypoints.cols();
637 bool optimizeExistingWaypoints =
false;
639 optimizeExistingWaypoints = optimizeExistingWaypoints || isOptWaypoint[i];
642 if (extraPointsToAdd<=0 && !optimizeExistingWaypoints) {
645 }
else{nP = extraPointsToAdd;}
650 numberOfOptimizationWaypoints = nP;
654 Eigen::VectorXd timeVec = Eigen::VectorXd::LinSpaced(nP+2, 0.0, timeline.maxCoeff()).segment(1,nP);
656 for (
int i=0; i<nP; i++)
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()) {
672 int optVectorSize = 0;
675 if (isOptWaypoint[i]){optVectorSize+=dofToOptimize[i].size();}
678 Eigen::VectorXd optVector = Eigen::VectorXd::Zero(optVectorSize);
679 int indexCounter = 0;
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);
690 std::cout <<
"[ERROR] (GaussianProcessTrajectory::getBoptVariables): You are trying to optimize an index which doesn't exist! Ignoring and setting to zero." << std::endl;
698 boptVariablesSet =
true;
705 int optVectorSize = 0;
708 if (isOptWaypoint[i]){optVectorSize+=dofToOptimize[i].size();}
712 if (newOptVariables.rows() == optVectorSize)
714 int indexCounter = 0;
717 if (isOptWaypoint[i])
719 for(
int j=0; j<dofToOptimize[i].size(); j++)
722 if (dofToOptimize[i](j)==0)
724 timeline(i) = newOptVariables(indexCounter);
726 else if (dofToOptimize[i](j)>0 && dofToOptimize[i](j)<=
nDoF)
728 waypoints(dofToOptimize[i](j)-1, i) = newOptVariables(indexCounter);
732 std::cout <<
"[ERROR] (GaussianProcessTrajectory::getBoptVariables): You are trying to change an index which doesn't exist! Ignoring." << std::endl;
738 calculateGaussianProcessParameters();
743 std::cout <<
"[ERROR] (): The new optimization variable vector size (" << newOptVariables.rows() <<
") doesn't match what I was expecting ("<< optVectorSize <<
")." << std::endl;
772 void GaussianProcessTrajectory::precalculateTrajectory(Eigen::MatrixXd& _traj, Eigen::MatrixXd& _variance, Eigen::VectorXd& _timeline,
const double DT)
774 double currentTime = 0.0;
778 Eigen::MatrixXd traj(numberOfDataPoints,
nDoF*3);
779 Eigen::MatrixXd variance(numberOfDataPoints,
nDoF);
780 Eigen::VectorXd timeline(numberOfDataPoints);
789 Eigen::MatrixXd desValsMat;
790 Eigen::VectorXd desVarianceVec;
794 traj.row(index) << desValsMat.col(
POS_INDEX).transpose(),
798 variance.row(index) << desVarianceVec.transpose();
800 timeline(index) = currentTime;
808 _traj = traj.topRows(index);
809 _variance = variance.topRows(index);
810 _timeline = timeline.head(index);
817 smlt::checkAndCreateDirectory(dirPath);
818 std::string filePath = dirPath +
"/trajectory.txt";
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++)
829 trajFile << timeVec(i) <<
" " << trajMat.row(i) <<
" " << varianceMat.row(i) << std::endl;
835 std::cout <<
"[ERROR](line: "<< __LINE__ <<
") -> Could not write the trajectory to file, " << filePath << std::endl;
843 smlt::checkAndCreateDirectory(dirPath);
844 std::string filePath = dirPath +
"/waypoints.txt";
846 std::ofstream waypointFile;
847 waypointFile.open(filePath.c_str());
848 if (waypointFile.is_open()) {
850 waypointFile.close();
854 std::cout <<
"[ERROR](line: "<< __LINE__ <<
") -> Could not write the trajectory to file, " << filePath << std::endl;
Eigen::VectorXd getMaxCovarianceVector()
bool setVarianceWaypoints(boolVector &bVarVec)
Eigen::VectorXd getBoptVariables(const int extraPointsToAdd=0, std::vector< Eigen::VectorXi > dofToOptVec=std::vector< Eigen::VectorXi >())
Eigen::MatrixXd waypoints
Eigen::MatrixXd getDesiredValues(double time)
Eigen::VectorXd getBoptSearchSpaceMinBound()
virtual void initializeTrajectory()
bool setOptimizationWaypoints(boolVector &bOptVec)
void addWaypoint(const Eigen::VectorXd newWaypoint, const double waypointTime)
Eigen::VectorXd pointToPointDurationVector
Optimization-based Robot Controller namespace. a library of classes to write and solve optimization p...
Eigen::VectorXd getVariance(double time)
bool setMeanWaypoints(boolVector &bMeanVec)
void saveTrajectoryToFile(const std::string dirPath="./")
void saveWaypointDataToFile(const std::string dirPath="./")
#define MEAN_LENGTH_FACTOR
std::vector< bool > boolVector
Eigen::VectorXd getBoptSearchSpaceMaxBound()
bool setDofToOptimize(std::vector< Eigen::VectorXi > &dofToOptVec)
Eigen::MatrixXd getWaypointData()
Eigen::MatrixXd getMeanGPData()
Eigen::MatrixXd getBoptCovarianceMatrix()
Eigen::MatrixXd getVarGPData()
bool setBoptVariables(const Eigen::VectorXd &newOptVariables)
void removeWaypoint(int index)
#define VAR_LENGTH_FACTOR