ocra-recipes
Doxygen documentation for the ocra-recipes repository
Trajectory.cpp
Go to the documentation of this file.
2 #include <math.h>
3 
4 #define MAX_VEL 0.05
5 
6 namespace ocra
7 {
8 
19 : maximumVelocity(MAX_VEL)
20 , nDoF(-1)
21 , usingDurationVector(false)
22 {
23 }
24 
26 {
27  // std::cout << "\nDestroying trajectory object..." << std::endl;
28 }
29 
30 void Trajectory::setWaypoints(const std::vector<double>& startingDoubleVec, const std::vector<double>& endingDoubleVec, const int waypointSelector, bool _endsWithQuaternion)
31 {
32  // Make sure that the vectors are the same size
33  if (startingDoubleVec.size() != endingDoubleVec.size())
34  throw std::runtime_error(std::string("[Trajectory::setWaypoints()]: Starting vector and ending vector are not the same size."));
35 
36 
37  int _nRows;
38  if (waypointSelector>0) {
39  _nRows = waypointSelector;
40  }
41  else {
42  _nRows = startingDoubleVec.size();
43  }
44  int _nCols = 2;
45 
46  Eigen::MatrixXd _waypoints(_nRows, _nCols);
47 
48  for(int i=0; i<_nRows; i++){
49  _waypoints(i,0)=startingDoubleVec[i];
50  _waypoints(i,1)=endingDoubleVec[i];
51  }
52 
53  setWaypoints(_waypoints, _endsWithQuaternion);
54 }
55 
56 
57 
58 void Trajectory::setWaypoints(const Eigen::VectorXd& _startingVector, const Eigen::VectorXd& _endingVector, bool _endsWithQuaternion)
59 {
60  // Make sure that the vectors are the same size
61  if (_startingVector.rows() != _endingVector.rows())
62  throw std::runtime_error(std::string("[Trajectory::setWaypoints()]: Starting vector and ending vector are not the same size."));
63 
64 
65  int _nRows = _startingVector.rows();
66  int _nCols = 2;
67 
68  Eigen::MatrixXd _waypoints(_nRows, _nCols);
69 
70  _waypoints << _startingVector, _endingVector;
71 
72 
73  setWaypoints(_waypoints, _endsWithQuaternion);
74 }
75 
76 void Trajectory::setWaypoints(Eigen::Displacementd& startingDisplacement, Eigen::Displacementd& endingDisplacement, bool _endsWithQuaternion)
77 {
78 
79  Eigen::VectorXd _startingVector = displacementToEigenVector(startingDisplacement);
80  Eigen::VectorXd _endingVector = displacementToEigenVector(endingDisplacement);
81 
82  int _nRows = _startingVector.rows();
83  int _nCols = 2;
84 
85  Eigen::MatrixXd _waypoints(_nRows, _nCols);
86  _waypoints << _startingVector, _endingVector;
87 
88  setWaypoints(_waypoints, _endsWithQuaternion);
89 
90 
91 }
92 
93 void Trajectory::setWaypoints(Eigen::Rotation3d& startingOrientation, Eigen::Rotation3d& endingOrientation, bool _endsWithQuaternion)
94 {
95 
96  Eigen::VectorXd _startingVector = quaternionToEigenVector(startingOrientation);
97  Eigen::VectorXd _endingVector = quaternionToEigenVector(endingOrientation);
98 
99  int _nRows = _startingVector.rows();
100  int _nCols = 2;
101 
102  Eigen::MatrixXd _waypoints(_nRows, _nCols);
103  _waypoints << _startingVector, _endingVector;
104 
105  setWaypoints(_waypoints, _endsWithQuaternion);
106  // tell class that there is a quaternion in the vector
107 
108 
109 }
110 
111 void Trajectory::setWaypoints(const std::list<Eigen::VectorXd>& _waypoints, bool _endsWithQuaternion)
112 {
116  endsWithQuaternion = _endsWithQuaternion;
117  waypointList = _waypoints;
118  nDoF = waypointList.begin()->rows();
119  nWaypoints = waypointList.size();
120  startTrigger = true;
121  trajectoryFinished = false;
122  //Determine number of non-quaternion DoF
124 
126 }
127 
128 
129 void Trajectory::setWaypoints(Eigen::MatrixXd& _waypoints, bool _endsWithQuaternion)
130 {
134  endsWithQuaternion = _endsWithQuaternion;
135  waypoints = _waypoints;
136  nDoF = waypoints.rows();
137  nWaypoints = waypoints.cols();
138  startTrigger = true;
140  trajectoryFinished = false;
141  //Determine number of non-quaternion DoF
143 
144  setDuration();
145 
147 
148 }
149 
150 void Trajectory::setMaxVelocity(double newMaxVel)
151 {
152  maximumVelocity = newMaxVel;
153  if (nDoF >= 0) {
154  maximumVelocityVector = Eigen::VectorXd::Constant(nDoF, newMaxVel);
155  }
156 }
157 
158 void Trajectory::setMaxVelocity(const Eigen::VectorXd& newMaxVel)
159 {
160  if (newMaxVel.size()==nDoF) {
161  maximumVelocityVector = newMaxVel;
162  } else {
163  OCRA_ERROR("The size of the newMaxVel vector ("<<newMaxVel.size()<<") doesn't match the nDoF (" << nDoF << ") of the trajectory. Ignoring.")
164  }
165 }
166 
168 {
169  return maximumVelocity;
170 }
171 
173 {
174  return maximumVelocityVector;
175 }
176 
177 void Trajectory::setMaxAcceleration(double newMaxAcc)
178 {
179  maximumAcceleration = newMaxAcc;
180  if (nDoF >= 0) {
181  maximumAccelerationVector = Eigen::VectorXd::Constant(nDoF, newMaxAcc);
182  }
183 }
184 
185 void Trajectory::setMaxAcceleration(const Eigen::VectorXd& newMaxAcc)
186 {
187  if (newMaxAcc.size()==nDoF) {
188  maximumAccelerationVector = newMaxAcc;
189  } else {
190  OCRA_ERROR("The size of the newMaxAcc vector ("<<newMaxAcc.size()<<") doesn't match the nDoF (" << nDoF << ") of the trajectory. Ignoring.")
191  }
192 }
193 
195 {
196  return maximumAcceleration;
197 }
198 
200 {
202 }
203 
204 void Trajectory::getDesiredValues(double _time, std::vector<double>& _desiredVector)
205 {
206  Eigen::MatrixXd desVals = getDesiredValues(_time);
207 
208  // eigenVectorToStdVector(desVals.col(POS_INDEX), _desiredVector);
209  eigenMatrixToStdVector(desVals, _desiredVector);
210 }
211 
212 
213 void Trajectory::getDesiredValues(double _time, Eigen::Displacementd& _desiredDisplacement)
214 {
215  Eigen::MatrixXd desVals = getDesiredValues(_time);
216 
217  eigenVectorToDisplacement(desVals.col(POS_INDEX), _desiredDisplacement);
218 }
219 
220 void Trajectory::getDesiredValues(double _time, Eigen::Rotation3d& _desiredOrientation)
221 {
222  Eigen::MatrixXd desVals = getDesiredValues(_time);
223 
224  eigenVectorToQuaternion(desVals.col(POS_INDEX), _desiredOrientation);
225 }
226 
227 void Trajectory::getDesiredValues(double _time, Eigen::Displacementd& _desiredDisplacement, Eigen::Twistd& _desiredVelocity, Eigen::Twistd& _desiredAcceleration)
228 {
229  Eigen::MatrixXd desVals = getDesiredValues(_time);
230  std::cout<< "\n\ndesVals: \n" << desVals << "\n\n";
231  eigenVectorToDisplacement(desVals.col(POS_INDEX), _desiredDisplacement);
232  eigenVectorToTwist(desVals.col(VEL_INDEX), _desiredVelocity);
233  eigenVectorToTwist(desVals.col(ACC_INDEX), _desiredAcceleration);
234 
235  Eigen::Displacementd::AdjointMatrix H_adj = Eigen::Displacementd(Eigen::Vector3d::Zero(), _desiredDisplacement.getRotation().inverse()).adjoint();
236  _desiredVelocity = H_adj * _desiredVelocity;
237  _desiredAcceleration = H_adj * _desiredAcceleration;
238 
239 }
240 
241 Eigen::Rotation3d Trajectory::quaternionSlerp(double _tau, Eigen::Rotation3d& _qStart, Eigen::Rotation3d& _qEnd)
242 {
248  Eigen::VectorXd startVec;
249  startVec = quaternionToEigenVector(_qStart);
250  Eigen::VectorXd endVec;
251  endVec = quaternionToEigenVector(_qEnd);
252  if ((startVec - endVec).norm() == 0.0){
253  return _qEnd;
254  }
255  else{
256 
257  Eigen::Rotation3d quaternionVector = _qEnd * _qStart.inverse();
258  double theta = 2.0 * acos(quaternionVector.w() );
259  Eigen::Vector3d new_XYZ;
260  new_XYZ << quaternionVector.x(), quaternionVector.y(), quaternionVector.z();
261  new_XYZ /= sin(theta/2.0);
262  new_XYZ *= sin((_tau*theta)/2.0);
263  double new_W = cos((_tau*theta)/2.0);
264 
265  Eigen::Rotation3d interpolatedQuaternion = Eigen::Rotation3d(new_W, new_XYZ);
266  interpolatedQuaternion *= _qStart;
267 
268  return interpolatedQuaternion;
269  }
270 }
271 
272 
273 
274 
275 /*
276 
277 void Trajectory::getDesiredValues()
278 {
279  throw std::runtime_error(std::string("[Trajectory::getDesiredValues()]: getDesiredValues has not been implemented or is not supported"));
280 }
281 
282 */
283 
285 {
286  // Approximate some duration between waypoints based an a velMax of 50cm/s
287 
288  // pointToPointDurationVector = Eigen::VectorXd::Constant(nWaypoints-1, 1.0);
290 
291  for (int i=0; i<nWaypoints-1; i++)
292  {
293  pointToPointDurationVector(i) = (waypoints.col(i+1) - waypoints.col(i)).norm() / maximumVelocity;
294  }
295 
296  // std::cout << "durationVector: " << pointToPointDurationVector.transpose() << std::endl;
298 }
299 
300 void Trajectory::setDuration(const Eigen::VectorXd& _pointToPointDurationVector)
301 {
302  if (_pointToPointDurationVector.size() == (nWaypoints-1)) {
303  pointToPointDurationVector = _pointToPointDurationVector;
306  usingDurationVector = true;
307  } else {
308  setDuration();
309  OCRA_WARNING("The point to point duration vector you passed is not the right size.")
310  }
311 }
312 
313 
314 void Trajectory::setDuration(double _duration)
315 {
316  pointToPointDuration = _duration;
318 }
319 
320 
321 
322 /********************************************************************************************************
323 *********************************************************************************************************
324 *********************************************************************************************************
325 ********************************************************************************************************/
326 
334 Eigen::VectorXd Trajectory::displacementToEigenVector(Eigen::Displacementd& _disp)
335 {
340  Eigen::VectorXd outputVector(7);
341  double x, y, z, qx, qy, qz, qw;
342  x = _disp.getTranslation().x();
343  y = _disp.getTranslation().y();
344  z = _disp.getTranslation().z();
345  qx = _disp.getRotation().x();
346  qy = _disp.getRotation().y();
347  qz = _disp.getRotation().z();
348  qw = _disp.getRotation().w();
349  outputVector << x, y, z, qw, qx, qy, qz;
350 
351  return outputVector;
352 };
353 
354 
355 Eigen::VectorXd Trajectory::quaternionToEigenVector(Eigen::Rotation3d& _quat)
356 {
361  Eigen::VectorXd outputVector(4);
362  double qx, qy, qz, qw;
363  qx = _quat.x();
364  qy = _quat.y();
365  qz = _quat.z();
366  qw = _quat.w();
367  outputVector << qw, qx, qy, qz;
368 
369  return outputVector;
370 };
371 
372 bool Trajectory::eigenVectorToStdVector(const Eigen::VectorXd& _dispVec, std::vector<double>& _doubleVec)
373 {
374  if (_doubleVec.size() == _dispVec.rows()){
375  for(int i=0; i<_dispVec.rows(); i++){
376  _doubleVec[i] = _dispVec[i];
377  }
378  return true;
379  }
380  else
381  return false;
382 }
383 
384 bool Trajectory::eigenMatrixToStdVector(const Eigen::MatrixXd& _dispMat, std::vector<double>& _doubleVec)
385 {
386  int nValues = _dispMat.size();
387  if (nValues == _doubleVec.size()) {
388  const double *eigPtr = _dispMat.data();
389  for(int i=0; i<nValues; i++){
390  _doubleVec[i] = *eigPtr;
391  eigPtr++;
392  }
393  return true;
394  }
395  else {
396  // std::cout << "[ERROR] (Trajectory::eigenMatrixToStdVector): Matrix size and vector size do not match." << std::endl;
397  return false;
398  }
399 }
400 
401 
402 bool Trajectory::eigenVectorToDisplacement(const Eigen::VectorXd& _dispVec, Eigen::Displacementd& _disp)
403 {
404  Eigen::Vector3d translation;
405  Eigen::Rotation3d rotation;
406 
407 
408  if (_dispVec.rows()==3)
409  {
410  translation = _dispVec;
411  rotation = Eigen::Rotation3d(1.0, 0.0, 0.0, 0.0); // no rotation
412  }
413 
414  else if((_dispVec.rows()==4) && (endsWithQuaternion))
415  {
416  translation << 0.0, 0.0, 0.0; // not necessarily the best solution... maybe error checking here
417  Trajectory::eigenVectorToQuaternion(_dispVec, rotation);
418  }
419 
420  else if(_dispVec.rows()==7)
421  {
422  translation = _dispVec.head(TRANSLATION_DIM);
423  Trajectory::eigenVectorToQuaternion(_dispVec.tail(QUATERNION_DIM), rotation);
424  }
425  else
426  {
427  _disp = Eigen::Displacementd(0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0);
428  return false;
429  }
430 
431  _disp = Eigen::Displacementd(translation, rotation);
432  return true;
433 };
434 
435 bool Trajectory::eigenVectorToQuaternion(const Eigen::VectorXd& _quatVec, Eigen::Rotation3d& _quat)
436 {
437  if ( (_quatVec.rows()==4) && ( endsWithQuaternion ) )
438  {
439  _quat = Eigen::Rotation3d(_quatVec(0), _quatVec(1), _quatVec(2), _quatVec(3));
440  return true;
441  }
442  else
443  {
444  _quat = Eigen::Rotation3d(1.0, 0.0, 0.0, 0.0);
445  return false;
446  }
447 
448 };
449 
450 
451 bool Trajectory::eigenVectorToTwist(const Eigen::VectorXd& _twistVec, Eigen::Twistd& _twist)
452 {
453  Eigen::Vector3d linearComponent, angularComponent;
454 
455 
456  if (_twistVec.rows()==3)
457  {
458  linearComponent = _twistVec;
459  angularComponent << 0.0, 0.0, 0.0; // no angularComponent
460  }
461 
462  else if((_twistVec.rows()==4) && (endsWithQuaternion))
463  {
464  linearComponent << 0.0, 0.0, 0.0; // not necessarily the best solution... maybe error checking here
465  angularComponent = _twistVec.head(TRANSLATION_DIM);
466  }
467 
468  else if(_twistVec.rows()==7)
469  {
470  linearComponent = _twistVec.head(TRANSLATION_DIM);
471  angularComponent = _twistVec.segment(TRANSLATION_DIM, TRANSLATION_DIM);
472  }
473  else
474  {
475  _twist = Eigen::Twistd::Zero();
476  return false;
477  }
478 
479  _twist = Eigen::Twistd(angularComponent, linearComponent);
480  return true;
481 };
482 
483 
484 Eigen::MatrixXd Trajectory::getFullTrajectory(double dt)
485 {
486  double t = 0.0;
487  int nCols = nDoF*3;
488  int rowCounter = 0;
489  int nRows = std::ceil(totalTrajectoryDuration / dt)*2;
490 
491  Eigen::MatrixXd posVelAcc(nRows, nCols);
492  while (t <= totalTrajectoryDuration) {
493  Eigen::MatrixXd vals = getDesiredValues(t);
494  posVelAcc.row(rowCounter) << vals.col(POS_INDEX).transpose(), vals.col(VEL_INDEX).transpose(), vals.col(ACC_INDEX).transpose();
495  t += dt;
496  ++rowCounter;
497  }
498 
499  return posVelAcc.topRows(rowCounter-1);
500 }
501 
502 // bool Trajectory::dumpToFile(const Eigen::MatrixXd& _desiredVals)
503 // {
504 // std::ofstream dataFile;
505 // dataFile.open("~/Desktop/trajectoryDataDump.txt", std::ios::app);
506 // if (dataFile.is_open())
507 // {
508 // dataFile << _desiredVals;
509 // dataFile << "\n";
510 // dataFile.close();
511 // return true;
512 // }
513 // else
514 // {
515 // std::cout << "Unable to open file"<< std::endl;
516 // return false;
517 // }
518 // };
519 
520 
521 } //namespace ocra
bool trajectoryFinished
Definition: Trajectory.h:130
#define MAX_VEL
Definition: Trajectory.cpp:4
int currentWaypointIndex
Definition: Trajectory.h:122
bool eigenVectorToStdVector(const Eigen::VectorXd &dispVec, std::vector< double > &doubleVec)
Definition: Trajectory.cpp:372
#define VEL_INDEX
Definition: Trajectory.h:21
void setMaxAcceleration(double newMaxAcc)
Definition: Trajectory.cpp:177
#define OCRA_ERROR(msg)
Definition: ErrorsHelper.h:32
bool usingDurationVector
Definition: Trajectory.h:129
Eigen::MatrixXd waypoints
Definition: Trajectory.h:117
Eigen::VectorXd getMaxAccelerationVector()
Definition: Trajectory.cpp:199
Eigen::VectorXd displacementToEigenVector(Eigen::Displacementd &disp)
Definition: Trajectory.cpp:334
double getMaxVelocity()
Definition: Trajectory.cpp:167
double maximumAcceleration
Definition: Trajectory.h:112
void setMaxVelocity(double newMaxVel)
Definition: Trajectory.cpp:150
#define QUATERNION_DIM
Definition: Trajectory.h:19
#define TRANSLATION_DIM
Definition: Trajectory.h:18
Eigen::VectorXd pointToPointDurationVector
Definition: Trajectory.h:126
Optimization-based Robot Controller namespace. a library of classes to write and solve optimization p...
bool eigenVectorToTwist(const Eigen::VectorXd &twistVec, Eigen::Twistd &twist)
Definition: Trajectory.cpp:451
std::list< Eigen::VectorXd > waypointList
Definition: Trajectory.h:116
Eigen::Rotation3d quaternionSlerp(double tau, Eigen::Rotation3d &qStart, Eigen::Rotation3d &qEnd)
Definition: Trajectory.cpp:241
double pointToPointDuration
Definition: Trajectory.h:127
virtual void initializeTrajectory()
Definition: Trajectory.h:108
#define ACC_INDEX
Definition: Trajectory.h:22
void setWaypoints(const std::vector< double > &startingDoubleVec, const std::vector< double > &endingDoubleVec, const int waypointSelector=0, bool endsWithQuaternion=false)
Definition: Trajectory.cpp:30
double totalTrajectoryDuration
Definition: Trajectory.h:128
Eigen::VectorXd maximumAccelerationVector
Definition: Trajectory.h:113
virtual ~Trajectory()
Definition: Trajectory.cpp:25
bool eigenMatrixToStdVector(const Eigen::MatrixXd &dispMat, std::vector< double > &doubleVec)
Definition: Trajectory.cpp:384
double maximumVelocity
Definition: Trajectory.h:108
#define POS_INDEX
Definition: Trajectory.h:20
bool endsWithQuaternion
Definition: Trajectory.h:120
double getMaxAcceleration()
Definition: Trajectory.cpp:194
Eigen::MatrixXd getFullTrajectory(double dt=0.01)
Definition: Trajectory.cpp:484
Eigen::VectorXd quaternionToEigenVector(Eigen::Rotation3d &quat)
Definition: Trajectory.cpp:355
bool eigenVectorToDisplacement(const Eigen::VectorXd &dispVec, Eigen::Displacementd &disp)
Definition: Trajectory.cpp:402
Eigen::VectorXd maximumVelocityVector
Definition: Trajectory.h:111
virtual Eigen::MatrixXd getDesiredValues(double time)
Definition: Trajectory.h:71
Eigen::VectorXd getMaxVelocityVector()
Definition: Trajectory.cpp:172
bool eigenVectorToQuaternion(const Eigen::VectorXd &quatVec, Eigen::Rotation3d &quat)
Definition: Trajectory.cpp:435