DesignerTrajectoryManager.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2015-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package ArmarXGuiPlugins::RobotTrajectoryDesigner::Manager
19  * @author Luca Quaer
20  * @date 2018
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
26 
27 using namespace armarx;
28 
29 ////////////////////////////////////////////////////////////////////////////////////////////
30 /// Struct-functions
31 ////////////////////////////////////////////////////////////////////////////////////////////
32 
33 void
34 DesignerTrajectoryManager::ManipulationInterval::addFirstUserWaypoint(UserWaypointPtr uw)
35 {
36  userWaypointsList.push_back(uw);
37 }
38 
39 void
40 DesignerTrajectoryManager::ManipulationInterval::pushFront(UserWaypointPtr uw, TransitionPtr t)
41 {
42  userWaypointsList.push_front(uw);
43  transitionsList.push_front(t);
44  lowerIntervalLimit--;
45 }
46 
47 void
48 DesignerTrajectoryManager::ManipulationInterval::pushBack(UserWaypointPtr uw, TransitionPtr t)
49 {
50  userWaypointsList.push_back(uw);
51  transitionsList.push_back(t);
52  upperIntervalLimit++;
53 }
54 
55 void
56 DesignerTrajectoryManager::ManipulationInterval::addBreakpointIndex(int index)
57 {
58  breakpointIndicesSet.insert(index);
59 }
60 
61 void
62 DesignerTrajectoryManager::ManipulationInterval::finishSearch()
63 {
64  // copy userWaypointsList to userWaypoints vector
65  userWaypoints.reserve(userWaypointsList.size());
66  std::copy(
67  userWaypointsList.begin(), userWaypointsList.end(), std::back_inserter(userWaypoints));
68 
69  // copy transitionsList to transitions vector
70  transitions.reserve(transitionsList.size());
71  std::copy(transitionsList.begin(), transitionsList.end(), std::back_inserter(transitions));
72 
73  // copy breakpointInicesSet to breakpointIndices vector
74  breakpointIndices.reserve(breakpointIndicesSet.size());
75  std::copy(breakpointIndicesSet.begin(),
76  breakpointIndicesSet.end(),
77  std::back_inserter(breakpointIndices));
78 }
79 
81 DesignerTrajectoryManager::ManipulationInterval::getUserWaypointByRealIndex(unsigned int i) const
82 {
83  if (i - lowerIntervalLimit < userWaypoints.size())
84  {
85  return userWaypoints[i - lowerIntervalLimit];
86  }
87  else
88  {
89  // modify Exception?
90  throw OutOfRangeException();
91  }
92 }
93 
95 DesignerTrajectoryManager::ManipulationInterval::getUserWaypointByZeroBasedIndex(
96  unsigned int i) const
97 {
98  if (i < userWaypoints.size())
99  {
100  return userWaypoints[i];
101  }
102  else
103  {
104  // modify Exception?
105  throw OutOfRangeException();
106  }
107 }
108 
110 DesignerTrajectoryManager::ManipulationInterval::getTransitionByRealIndex(unsigned int i) const
111 {
112  if (i - lowerIntervalLimit < transitions.size())
113  {
114  return transitions[i - lowerIntervalLimit];
115  }
116  else
117  {
118  // modify Exception?
119  throw OutOfRangeException();
120  }
121 }
122 
124 DesignerTrajectoryManager::ManipulationInterval::getTransitionByZeroBasedIndex(unsigned int i) const
125 {
126  if (i < transitions.size())
127  {
128  return transitions[i];
129  }
130  else
131  {
132  // modify Exception?
133  throw OutOfRangeException();
134  }
135 }
136 
137 std::vector<std::vector<double>>
138 DesignerTrajectoryManager::ManipulationInterval::getUserWaypointsIKSolutions(
139  std::vector<std::vector<double>>& ikSolutions,
140  unsigned int intervalStart,
141  unsigned int intervalEnd)
142 {
143  std::vector<std::vector<double>> result;
144  for (unsigned int& newIndex : newIndexOfUserWaypoint)
145  {
146  if (newIndex < intervalStart)
147  {
148  continue;
149  }
150  if (newIndex > intervalEnd)
151  {
152  break;
153  }
154 
155  result.push_back(ikSolutions[newIndex]);
156  }
157  return result;
158 }
159 
160 void
161 DesignerTrajectoryManager::ManipulationInterval::applyJointAnglesOfUserWaypoints(
162  std::vector<std::vector<double>> ikSolution)
163 {
164  std::vector<std::vector<double>> jointAngles = getUserWaypointsIKSolutions(
165  ikSolution, newIndexOfUserWaypoint[0], newIndexOfUserWaypoint[userWaypoints.size() - 1]);
166 
167  int count = 0;
168  for (UserWaypointPtr w : userWaypoints)
169  {
170  w->setJointAngles(jointAngles[count++]);
171  }
172 }
173 
174 ////////////////////////////////////////////////////////////////////////////////////////////////////
175 /// Auxiliary functions
176 ////////////////////////////////////////////////////////////////////////////////////////////////////
177 
178 void
179 DesignerTrajectoryManager::saveState()
180 {
181  //cut off the last mementos behind the current memento
182  if (mementos.currentMemento < mementos.mementoList.size() - 1)
183  {
184  mementos.mementoList.resize(mementos.currentMemento + 1);
185  }
186 
187  if (designerTrajectory)
188  {
189  mementos.mementoList.push_back(
190  std::shared_ptr<DesignerTrajectory>(new DesignerTrajectory(*designerTrajectory)));
191  }
192  else
193  {
194  mementos.mementoList.push_back(nullptr);
195  }
196 
197  //if the size of the list is bigger than the MEMENTO_MAX, it just delete the first
198  //(oldest) memento
199  if (mementos.mementoList.size() > MEMENTO_MAX)
200  {
201  mementos.mementoList.pop_front();
202  }
203  else
204  {
205  mementos.currentMemento++;
206  }
207 }
208 
209 DesignerTrajectoryManager::ManipulationInterval
210 DesignerTrajectoryManager::calculateManipulationInterval(unsigned int manipulationIndex)
211 {
212  DesignerTrajectoryPtr& dt = designerTrajectory;
213  ManipulationInterval mi;
214 
215  // set start upper- and lowerIntervalLimit to manipulationIndex
216  mi.lowerIntervalLimit = manipulationIndex;
217  mi.upperIntervalLimit = manipulationIndex;
218 
219  // add UserWaypoint with index = manipulationIndex to ManipulationInterval
220  mi.addFirstUserWaypoint(dt->getUserWaypoint(manipulationIndex));
221 
222  // add index of first user waypoint if it is a breakepoint
223  if (dt->getUserWaypoint(manipulationIndex)->getIsTimeOptimalBreakpoint())
224  {
225  mi.addBreakpointIndex(manipulationIndex);
226  }
227 
228  // search upwards
229  for (unsigned int i = manipulationIndex + 1; i < dt->getNrOfUserWaypoints(); i++)
230  {
231  UserWaypointPtr tmpUwp = dt->getUserWaypoint(i);
232  TransitionPtr tmpTrans = dt->getTransition(i - 1);
233  mi.pushBack(tmpUwp, tmpTrans);
234 
235  if (tmpUwp->getIsTimeOptimalBreakpoint())
236  {
237  mi.addBreakpointIndex(i);
238 
239  /*
240  if (dt->getTransition(i - 1)->getInterpolationType()
241  != dt->getTransition(i)->getInterpolationType())
242  {
243  break;
244  }
245  */
246  }
247  }
248 
249  // search downwards
250  for (unsigned int i = manipulationIndex - 1; i != static_cast<unsigned>(-1); i--)
251  {
252  UserWaypointPtr tmpUwp = dt->getUserWaypoint(i);
253  TransitionPtr tmpTrans = dt->getTransition(i);
254  mi.pushFront(tmpUwp, tmpTrans);
255 
256  if (tmpUwp->getIsTimeOptimalBreakpoint())
257  {
258  mi.addBreakpointIndex(i);
259 
260  /*
261  if (dt->getTransition(i - 1)->getInterpolationType()
262  != dt->getTransition(i)->getInterpolationType())
263  {
264  break;
265  }
266  */
267  }
268  }
269 
270  // add first and last point to breakpointIndicesSet if they are not included already
271  mi.addBreakpointIndex(mi.lowerIntervalLimit);
272  mi.addBreakpointIndex(mi.upperIntervalLimit);
273  mi.finishSearch();
274 
275  return mi;
276 }
277 
278 std::vector<AbstractInterpolationPtr>
279 DesignerTrajectoryManager::getInterpolationObjects(ManipulationInterval& mi)
280 {
281  std::vector<PoseBasePtr> poses;
282  for (UserWaypointPtr& uwp : mi.userWaypoints)
283  {
284  poses.push_back(uwp->getPose());
285  }
286 
287  std::vector<InterpolationType> interpolationTypes;
288  for (TransitionPtr& tp : mi.transitions)
289  {
290  interpolationTypes.push_back(tp->getInterpolationType());
291  }
292 
293  return InterpolationSegmentFactory::produceInterpolationSegments(poses, interpolationTypes);
294 }
295 
296 void
297 DesignerTrajectoryManager::calculateInterpolatedPoints(
298  std::vector<AbstractInterpolationPtr> interpolationObjects,
299  unsigned int fps,
300  ManipulationInterval& mi)
301 {
302  // requirement: time in seconds !!!!
303 
304  // treat first point (with time 0.0) seperately
305  ////mi.interpolatedPoses.push_back(interpolationObjects[0]->getPoseAt(0.0));
306  ////mi.newIndexOfUserWaypoint.push_back(0);
307 
308  // calculate all timestamps and add the poses accordingly
309  for (unsigned int i = 0; i < mi.transitions.size(); i++)
310  {
311  std::vector<double> timestamps;
312 
313  // check if transition is linear interpolated (no need to calculate further points between)
314  // get the transition
315  TransitionPtr tmpTransition = mi.getTransitionByZeroBasedIndex(i);
316 
317  // calculate total frame count (how many frames to insert between 2 userwaypoints)
318  //unsigned int totalFrameCount = tmpTransition->getUserDuration() * fps;
319  unsigned int totalFrameCount = tmpTransition->getTimeOptimalDuration() * fps;
320 
321  if (totalFrameCount == 0)
322  {
323  totalFrameCount = DEFAULT_FRAME_COUNT;
324  }
325 
326  if (totalFrameCount > 1)
327  {
328  // calculate the increment value to get evenly distributed timestamps
329  double increment = 1.0 / (totalFrameCount - 1);
330 
331  // starting at k = 1 jumps the 0.0 timestamp in every transition
332  ////for (unsigned int k = 1; k < totalFrameCount; k++)
333  for (unsigned int k = 0; k < totalFrameCount; k++)
334  {
335  timestamps.push_back(k * increment);
336  }
337  }
338  else
339  {
340  timestamps.push_back(0.0);
341  timestamps.push_back(1.0);
342  }
343 
344 
345  std::vector<PoseBasePtr> tmpInterpolatedPositions;
346  for (double timestamp : timestamps)
347  {
348  ////mi.interpolatedPoses.push_back(interpolationObjects[i]->getPoseAt(timestamp));
349  tmpInterpolatedPositions.push_back(interpolationObjects[i]->getPoseAt(timestamp));
350  }
351 
352  mi.interpolatedTransitions.push_back(tmpInterpolatedPositions);
353  tmpInterpolatedPositions.clear();
354 
355  // add the index of the last pose, which originated from an userwaypoint, to the
356  // newIndexOfUserWaypoint vector
357  ////mi.newIndexOfUserWaypoint.push_back(mi.interpolatedPoses.size() - 1);
358  }
359 }
360 
361 bool
362 DesignerTrajectoryManager::checkTransitionReachability(ManipulationInterval& mi,
363  unsigned int transitionIndex)
364 {
365  for (PoseBasePtr pose : mi.interpolatedTransitions[transitionIndex])
366  {
367  continue;
368  //if (!kin->isReachable(rns, pose))
369 
370  //provisorisch
371  if (!kinSolver->isReachable(rns, pose, VirtualRobot::IKSolver::Position))
372  {
373  return false;
374  }
375  }
376 
377  return true;
378 }
379 
380 std::vector<std::vector<double>>
381 DesignerTrajectoryManager::calculateIKSolutions(ManipulationInterval& mi)
382 {
383  // IKSolutions
384  std::vector<std::vector<double>> ikSolutions;
385  ikSolutions.push_back(mi.userWaypoints[0]->getJointAngles());
386 
387  // the new index of userwaypoint 0 is 0
388  mi.newIndexOfUserWaypoint.push_back(0);
389 
390  // motion planning insertion indices
391  std::vector<InsertTransition> mpInserts;
392 
393  for (unsigned int transitionIndex = 0; transitionIndex < mi.interpolatedTransitions.size();
394  transitionIndex++)
395  {
396  if (!checkTransitionReachability(mi, transitionIndex))
397  {
398  // this transition is not reachable
399  InsertTransition mpInsert;
400  mpInsert.transitionIndex = transitionIndex;
401  mpInsert.insertionIndex = ikSolutions.size() - 1; //destinations.size() - 1;
402  mpInserts.push_back(mpInsert);
403 
404  //calculate IKSolution (jump to end point of this transition)
405  std::vector<double> start = {ikSolutions.back()};
406 
407  std::vector<PoseBasePtr> destinations = {
408  mi.interpolatedTransitions[transitionIndex].back()};
409 
410  std::vector<VirtualRobot::IKSolver::CartesianSelection> selections = {
411  mi.userWaypoints[transitionIndex + 1]->getIKSelection()};
412 
413  std::vector<std::vector<double>> tmpIkSolutions =
414  kinSolver->solveRecursiveIKRelative(rns, start, destinations, selections);
415 
416  // insert tmpIkSolutions into ikSolutions
417  ikSolutions.insert(ikSolutions.end(), tmpIkSolutions.begin(), tmpIkSolutions.end());
418 
419  // the new index of the userwaypoint transitionIndex+1 is set later
420  // when inserting motion planning results into ikSolutions
421  // reserve place in vector
422  mi.newIndexOfUserWaypoint.push_back(-1);
423 
424  continue;
425  }
426 
427  // this transition is reachable
428  // calculate IKSolution of this transition
429  // get start
430  std::vector<double> start = {ikSolutions.back()};
431 
432  // get destinations: all poses from interpolatedTransition except for the first
433  std::vector<PoseBasePtr> destinations(mi.interpolatedTransitions[transitionIndex].begin() +
434  1,
435  mi.interpolatedTransitions[transitionIndex].end());
436 
437  // get selection
438  std::vector<VirtualRobot::IKSolver::CartesianSelection> selections;
439 
440  // |destinations| - 1 times do:
441  for (unsigned int i = 1; i < destinations.size(); i++)
442  {
443  selections.push_back(mi.userWaypoints[transitionIndex + 1]->getIKSelection());
444  }
445 
446  // for last destination: get real IKSelection of UserWaypoint
447  selections.push_back(mi.userWaypoints[transitionIndex + 1]->getIKSelection());
448 
449  // call ikSolver
450  std::vector<std::vector<double>> tmpIkSolutions =
451  kinSolver->solveRecursiveIKRelative(rns, start, destinations, selections);
452  // END: calculate IKSolution of this transition
453 
454  // check for tmpIkSolutions for collision
455 
456  // this transition is reachable and has no collisions
457  // insert tmpIkSolutions into ikSolutions
458  ikSolutions.insert(ikSolutions.end(), tmpIkSolutions.begin(), tmpIkSolutions.end());
459  // save the new index of the userwaypoint with index transitionIndex + 1
460  mi.newIndexOfUserWaypoint.push_back(ikSolutions.size() - 1);
461  }
462  return ikSolutions;
463 }
464 
465 std::vector<TimedTrajectory>
466 DesignerTrajectoryManager::calculateTimeOptimalTrajectories(
467  std::vector<std::vector<double>> ikSolutions,
468  ManipulationInterval& mi)
469 {
470  std::vector<TimedTrajectory> result;
471 
472  for (unsigned int i = 0; i < mi.breakpointIndices.size() - 1; i++)
473  {
474  /*
475  * mi.breakpointIndices are the indices before the interpolated points were inserted.
476  */
477  int intervalStart = mi.breakpointIndices[i];
478  int intervalEnd = mi.breakpointIndices[i + 1];
479  std::vector<std::vector<double>> ikSolutionsInterval(
480  ikSolutions.begin() + mi.newIndexOfUserWaypoint[intervalStart],
481  ikSolutions.begin() + 1 + mi.newIndexOfUserWaypoint[intervalEnd]);
482 
483  /*
484  * Because intervalStart/intervalEnd are the breakpoint indices BEFORE interpolated
485  * points were inserted,
486  * their new index (retrieved with mi.newIndexOfUserWaypoint[...]) is needed as parameter
487  * for the function mi.getUserWaypointsIKSolutions(..., ..., ...)
488  */
489  std::vector<std::vector<double>> userWaypointsIKSolution =
490  mi.getUserWaypointsIKSolutions(ikSolutions,
491  mi.newIndexOfUserWaypoint[intervalStart],
492  mi.newIndexOfUserWaypoint[intervalEnd]);
493 
494  result.push_back(DesignerTrajectoryCalculator(environment)
495  .calculateTimeOptimalTrajectory(
496  ikSolutionsInterval, userWaypointsIKSolution, rns, MAX_DEVIATION));
497  }
498 
499  return result;
500 }
501 
502 bool
504 {
505  if (mementos.currentMemento != 0)
506  {
507  if (*(std::next(mementos.mementoList.begin(), mementos.currentMemento - 1)))
508  {
509  designerTrajectory = DesignerTrajectoryPtr(new DesignerTrajectory(
510  *(*(std::next(mementos.mementoList.begin(), mementos.currentMemento - 1)))));
511  isInitialized = true;
512  }
513  else
514  {
515  isInitialized = false;
516  }
517  mementos.currentMemento--;
518  return true;
519  }
520  else
521  {
522  return false;
523  }
524 }
525 
526 bool
528 {
529  if (mementos.currentMemento < mementos.mementoList.size() - 1)
530  {
531  if (*std::next(mementos.mementoList.begin(), mementos.currentMemento + 1))
532  {
533  designerTrajectory = DesignerTrajectoryPtr(new DesignerTrajectory(
534  *(*(std::next(mementos.mementoList.begin(), mementos.currentMemento + 1)))));
535  }
536  else
537  {
538  isInitialized = false;
539  }
540 
541  mementos.currentMemento++;
542  return true;
543  }
544  else
545  {
546  return false;
547  }
548 }
549 
550 bool
552 {
553  return isInitialized;
554 }
555 
556 void
557 DesignerTrajectoryManager::theUniversalMethod(unsigned int index)
558 {
559  if (designerTrajectory->getNrOfUserWaypoints() > 1)
560  {
561  //calculate ikSolution of mainpulation intervall//////////////////////////////////////
562  ManipulationInterval mi = calculateManipulationInterval(index);
563 
564  // poses
565  std::vector<PoseBasePtr> poses;
566  std::vector<PoseBasePtr> posesBackup;
567 
568  // selections
569  std::vector<VirtualRobot::IKSolver::CartesianSelection> selections;
570  std::vector<VirtualRobot::IKSolver::CartesianSelection> selectionsBackup;
571 
572  for (UserWaypointPtr uwp : mi.userWaypoints)
573  {
574  poses.push_back(uwp->getPose());
575  posesBackup.push_back(PoseBasePtr(
576  new Pose(Pose(uwp->getPose()->position, uwp->getPose()->orientation).toEigen())));
577  selections.push_back(uwp->getIKSelection());
578  selectionsBackup.push_back(uwp->getIKSelection());
579  }
580 
582  {
584  }
585 
586  std::vector<InterpolationType> interpolations;
587  for (TransitionPtr trans : mi.transitions)
588  {
589  interpolations.push_back(trans->getInterpolationType());
590  }
591  int count = 0;
592  for (UserWaypointPtr uwp : mi.userWaypoints)
593  {
594  uwp->setPose(poses[count]);
595  uwp->setIKSelection(selections[count]);
596  count++;
597  }
598 
599  calculateInterpolatedPoints(
601  DEFAULT_FRAME_COUNT,
602  mi);
603  //calculateInterpolatedPoints(getInterpolationObjects(mi), DEFAULT_FRAME_COUNT, mi);
604 
605  //bool motionPlanningCalled = false;
606 
607  std::vector<std::vector<double>> ikSolutions = calculateIKSolutions(mi);
608 
609  count = 0;
610  for (UserWaypointPtr uwp : mi.userWaypoints)
611  {
612  uwp->setIKSelection(selectionsBackup[count]);
613  uwp->setPose(posesBackup[count]);
614  count++;
615  }
616 
617  //Set the JointAngles of the UserWaypoints////////////////////////////////////////////
618  mi.applyJointAnglesOfUserWaypoints(ikSolutions);
619 
620  //set interBreakpointsTrajectories////////////////////////////////////////////////////
621  std::vector<TimedTrajectory> timedTrajectories =
622  calculateTimeOptimalTrajectories(ikSolutions, mi);
623  //search how many interBreakPointTrajectories are behind and before the new
624  //interBreakpointTrajectories
625  int countBefore = 0;
626  int countAfter = 0;
627  if (mi.lowerIntervalLimit != 0)
628  {
629  countBefore++;
630  for (unsigned int i = mi.lowerIntervalLimit - 1; i > 0; i--)
631  {
632  if (designerTrajectory->getUserWaypoint(i)->getIsTimeOptimalBreakpoint())
633  {
634  countBefore++;
635  }
636  }
637  }
638 
639  if (mi.upperIntervalLimit != designerTrajectory->getNrOfUserWaypoints() - 1)
640  {
641  countAfter++;
642  for (unsigned int i = mi.upperIntervalLimit + 1;
643  i < designerTrajectory->getNrOfUserWaypoints() - 1;
644  i++)
645  {
646  countAfter++;
647  }
648  }
649 
650  std::vector<TrajectoryPtr> InterBreakPointTrajectories =
651  designerTrajectory->getInterBreakpointTrajectories();
652  std::vector<TrajectoryPtr> newInterBreakPointTrajectories;
653  newInterBreakPointTrajectories.insert(newInterBreakPointTrajectories.end(),
654  InterBreakPointTrajectories.begin(),
655  InterBreakPointTrajectories.begin() + countBefore);
656 
657  // set new inter breakpoint trajectories
658  for (TimedTrajectory& t : timedTrajectories)
659  {
660  TrajectoryPtr traj = t.getTrajectory();
661  newInterBreakPointTrajectories.push_back(traj);
662  }
663 
664  newInterBreakPointTrajectories.insert(newInterBreakPointTrajectories.end(),
665  InterBreakPointTrajectories.end() - countAfter,
666  InterBreakPointTrajectories.end());
667  designerTrajectory->setInterBreakpointTrajectories(newInterBreakPointTrajectories);
668 
669  //set newTimeOptimalDuration of each Transition///////////////////////////////////////
670  //and timeOptimalTimestamp of each UserWaypoint///////////////////////////////////////
671  //and Trajectories of all changed Transitions ////////////////////////////////////////
672  TrajectoryPtr traj = designerTrajectory->getTimeOptimalTrajectory();
673  std::vector<double> timestamps = traj->getTimestamps();
674  unsigned int trajCount = 0;
675 
676  //search for the timestamp of first changed point of traj
677  while (trajCount < timestamps.size() &&
678  designerTrajectory->getUserWaypoint(mi.breakpointIndices[0])
679  ->getTimeOptimalTimestamp() > timestamps[trajCount])
680  {
681  trajCount++;
682  }
683 
684  for (unsigned int t = 0; t < timedTrajectories.size(); t++)
685  {
686  //all timestamps of the userWaypoint of the timedTrajectory
687  std::vector<double> timedUserWaypoints = timedTrajectories[t].getUserPoints();
688 
689  if (timedUserWaypoints.size() == 0)
690  {
691  throw InvalidArgumentException();
692  }
693 
694  unsigned int count = 0;
695 
696  //set timeOptimalDuration of all changed transitions
697  //set timeOptimalTimestamp of all changed userWaypoints
698  for (unsigned int i = mi.breakpointIndices[t]; i < mi.breakpointIndices[t + 1]; i++)
699  {
700  TransitionPtr trans = designerTrajectory->getTransition(i);
701  trans->setTimeOptimalDuration(timedUserWaypoints[count + 1] -
702  timedUserWaypoints[count]);
703  count++;
704  }
705 
706 
707  //set all Trajectories of changed Transitions
708  for (unsigned int i = mi.breakpointIndices[t]; i < mi.breakpointIndices[t + 1]; i++)
709  {
710  TransitionPtr trans = designerTrajectory->getTransition(i);
711  UserWaypointPtr end = trans->getEnd();
712  unsigned int trajCountEnd = trajCount + 1;
713  std::vector<double> newTimestamps = {0.0};
714  std::vector<std::vector<double>> newTrajData;
715  //add first jointAngles of first timestamp
716  for (unsigned int dim = 0; dim < traj->dim(); dim++)
717  {
718  newTrajData.push_back({traj->getState(timestamps[trajCount], dim)});
719  }
720 
721  //add all jointAngles for all timestamps at transition
722  while (trajCountEnd < timestamps.size() &&
723  timestamps[trajCountEnd] < end->getTimeOptimalTimestamp())
724  {
725  newTimestamps.push_back(timestamps[trajCountEnd] - timestamps[trajCount]);
726  for (unsigned int dim = 0; dim < traj->dim(); dim++)
727  {
728  //jointAngles of the dimension
729  newTrajData[dim].push_back(traj->getState(timestamps[trajCountEnd], dim));
730  }
731  trajCountEnd++;
732  }
733  trajCount = trajCountEnd;
734  TrajectoryPtr newTraj = TrajectoryPtr(
735  new Trajectory(newTrajData, newTimestamps, traj->getDimensionNames()));
736  trans->setTrajectory(newTraj);
737  }
738  }
739 
740  //shift all timeOptimaltimestamps of the userWaypoints behind last BreakpointIndices
741  //it goes through transitions (getNrOfUserWaypoints - 2 = NrOfTransitions - 1)
742  for (unsigned int i = mi.breakpointIndices.back();
743  i <= designerTrajectory->getNrOfUserWaypoints() - 2;
744  i++)
745  {
746  //the setter of transitions updates the timeOptimalTimestamps of end- and start-
747  //Userwaypoint
748  double time = designerTrajectory->getTransition(i)->getTimeOptimalDuration();
749  designerTrajectory->getTransition(i)->setTimeOptimalDuration(time);
750  }
751 
752 
753  //update UserTimestamps of all UserWaypoints
754  for (unsigned int i = 0; i < designerTrajectory->getNrOfUserWaypoints() - 2; i++)
755  {
756  double time = designerTrajectory->getTransition(i)->getStart()->getUserTimestamp() +
757  designerTrajectory->getTransition(i)->getUserDuration();
758  designerTrajectory->getTransition(i)->getEnd()->setUserTimestamp(time);
759  }
760  }
761  saveState();
762 }
763 
764 std::vector<double>
765 DesignerTrajectoryManager::getNewIkSolutionOfFirstPoint(PoseBasePtr oldStart,
766  PoseBasePtr newStart,
767  std::vector<double> jointAnglesOldStart)
768 {
769  //Resolve recursive IK from oldStart to NewStart
770  std::vector<AbstractInterpolationPtr> ip =
772  std::vector<PoseBasePtr> poses;
773  std::vector<VirtualRobot::IKSolver::CartesianSelection> selections;
774 
775  for (AbstractInterpolationPtr current : ip)
776  {
777  for (double i = 1; i < DEFAULT_FRAME_COUNT - 1; i = i + 1.0)
778  {
779  poses.push_back(current->getPoseAt(i / DEFAULT_FRAME_COUNT));
781  }
782  }
783  poses.push_back(newStart);
784  selections.push_back(VirtualRobot::IKSolver::CartesianSelection::All);
785  std::vector<std::vector<double>> ikSolutions =
786  kinSolver->solveRecursiveIKRelative(rns, jointAnglesOldStart, poses, selections);
787 
788  return ikSolutions.back();
789 }
790 
791 ////////////////////////////////////////////////////////////////////////////////////////////////////
792 /// Constructor(s)
793 ////////////////////////////////////////////////////////////////////////////////////////////////////
794 
796  EnvironmentPtr environment) :
797  kinSolver(KinematicSolver::getInstance(environment->getScene(), environment->getRobot())),
798  environment(environment)
799 {
800  rns = environment->getRobot()->getRobotNodeSet(rnsName);
801 }
802 
803 ////////////////////////////////////////////////////////////////////////////////////////////////////
804 /// Public Functions
805 ////////////////////////////////////////////////////////////////////////////////////////////////////
806 
807 void
809 {
810  PoseBasePtr pb = kinSolver->doForwardKinematic(rns, jointAngles);
811  Pose pose = Pose(pb->position, pb->orientation);
812  pb = PoseBasePtr(new Pose(rns->getKinematicRoot()->toLocalCoordinateSystem(pose.toEigen())));
813 
814  // create UserWaypoint with the given jointAngles
815  UserWaypointPtr tmpUwp(new UserWaypoint(pb));
816  tmpUwp->setJointAngles(jointAngles);
817 
818  designerTrajectory = DesignerTrajectoryPtr(new DesignerTrajectory(tmpUwp, rns));
819 
820  //mementos.currentMemento = 0;
821 
822  if (mementos.mementoList.size() != 0)
823  {
824  saveState();
825  }
826  else
827  {
828  mementos.mementoList.push_back(
829  DesignerTrajectoryPtr(new DesignerTrajectory(*designerTrajectory)));
830  }
831 
832  isInitialized = true;
833 }
834 
835 void
837 {
838  if (isInitialized)
839  {
840  //get a clean copy of the designerTrajectory
841  designerTrajectory = getDesignerTrajectory();
842 
843  UserWaypointPtr newPoint = UserWaypointPtr(new UserWaypoint(pb));
844  designerTrajectory->addLastUserWaypoint(newPoint);
845  theUniversalMethod(designerTrajectory->getNrOfUserWaypoints() - 1);
846  }
847  else
848  {
849  throw NotInitializedException("Manager is not intialized", "Manager");
850  }
851 }
852 
853 void
854 DesignerTrajectoryManager::insertWaypoint(unsigned int index, const PoseBasePtr pb)
855 {
856  if (isInitialized)
857  {
858  //get a clean copy of the designerTrajectory
859  designerTrajectory = getDesignerTrajectory();
860 
861  if (index != 0)
862  {
863  UserWaypointPtr newPoint = UserWaypointPtr(new UserWaypoint(pb));
864  designerTrajectory->insertUserWaypoint(newPoint, index);
865  theUniversalMethod(index);
866  }
867  else
868  {
869  PoseBasePtr oldStart = designerTrajectory->getUserWaypoint(0)->getPose();
870  std::vector<double> jointAngles = getNewIkSolutionOfFirstPoint(
871  oldStart, pb, designerTrajectory->getUserWaypoint(0)->getJointAngles());
872  if (jointAngles.size() == 0)
873  {
874  return;
875  }
876  UserWaypointPtr newPoint = UserWaypointPtr(new UserWaypoint(pb));
877  designerTrajectory->insertUserWaypoint(newPoint, index);
878  designerTrajectory->getUserWaypoint(0)->setJointAngles(jointAngles);
879 
880  theUniversalMethod(index);
881  }
882  }
883  else
884  {
885  throw NotInitializedException("Manager is not intialized", "Manager");
886  }
887 }
888 
889 void
890 DesignerTrajectoryManager::editWaypointPoseBase(unsigned int index, const PoseBasePtr pb)
891 {
892  if (isInitialized)
893  {
894  //get a clean copy of the designerTrajectory
895  designerTrajectory = getDesignerTrajectory();
896  if (index != 0)
897  {
898  designerTrajectory->getUserWaypoint(index)->setPose(pb);
899  }
900  else
901  {
902  std::vector<double> newJointAngles;
903  if (designerTrajectory->getNrOfUserWaypoints() > 1)
904  {
905  newJointAngles = getNewIkSolutionOfFirstPoint(
906  designerTrajectory->getUserWaypoint(1)->getPose(),
907  pb,
908  designerTrajectory->getUserWaypoint(1)->getJointAngles());
909  if (newJointAngles.size() == 0)
910  {
911  return;
912  }
913  designerTrajectory->getUserWaypoint(0)->setPose(pb);
914  designerTrajectory->getUserWaypoint(0)->setJointAngles(newJointAngles);
915  }
916  else
917  {
918  //newJointAngles = kinSolver->solveIK(rns, pb, designerTrajectory->getUserWaypoint(0)->getIKSelection(), 50);
919  newJointAngles = getNewIkSolutionOfFirstPoint(
920  designerTrajectory->getUserWaypoint(0)->getPose(),
921  pb,
922  designerTrajectory->getUserWaypoint(0)->getJointAngles());
923  if (newJointAngles.size() == 0)
924  {
925  return;
926  }
927  UserWaypointPtr uwpTmp(new UserWaypoint(pb));
928  uwpTmp->setJointAngles(newJointAngles);
929  uwpTmp->setIKSelection(designerTrajectory->getUserWaypoint(0)->getIKSelection());
930  uwpTmp->setIsTimeOptimalBreakpoint(
931  designerTrajectory->getUserWaypoint(0)->getIsTimeOptimalBreakpoint());
932  DesignerTrajectoryPtr dtTmp(new DesignerTrajectory(uwpTmp, rns));
933  designerTrajectory = dtTmp;
934  }
935  }
936  theUniversalMethod(index);
937  }
938  else
939  {
940  throw NotInitializedException("Manager is not intialized", "Manager");
941  }
942 }
943 
944 void
946  unsigned int index,
948 {
949  if (isInitialized)
950  {
951  //get a clean copy of the designerTrajectory
952  designerTrajectory = getDesignerTrajectory();
953 
954  designerTrajectory->getUserWaypoint(index)->setIKSelection(ikSelection);
955  theUniversalMethod(index);
956  }
957  else
958  {
959  throw NotInitializedException("Manager is not intialized", "Manager");
960  }
961 }
962 
963 void
965 {
966  if (isInitialized)
967  {
968  //get a clean copy of the designerTrajectory
969  designerTrajectory = getDesignerTrajectory();
970 
971  if (designerTrajectory->getNrOfUserWaypoints() == 1)
972  {
973  isInitialized = false;
974  designerTrajectory = nullptr;
975  saveState();
976  }
977  else
978  {
979  designerTrajectory->deleteUserWaypoint(index);
980 
981  //check if first userwaypoint was delted
982  if (index == 0)
983  {
984  designerTrajectory->getUserWaypoint(0)->setTimeOptimalTimestamp(0);
985  designerTrajectory->getUserWaypoint(0)->setUserTimestamp(0);
986  }
987 
988  // check if just one waypoint is left
989  if (designerTrajectory->getNrOfUserWaypoints() == 1)
990  {
991  saveState();
992  return;
993  }
994 
995  // check if last userwaypoint was deleted
996  if (index == designerTrajectory->getNrOfUserWaypoints())
997  {
998  theUniversalMethod(index - 1);
999  }
1000  else
1001  {
1002  theUniversalMethod(index);
1003  }
1004  }
1005  }
1006  else
1007  {
1008  throw NotInitializedException("Manager is not intialized", "Manager");
1009  }
1010 }
1011 
1012 void
1014 {
1015  if (isInitialized)
1016  {
1017  //get a clean copy of the designerTrajectory
1018  designerTrajectory = getDesignerTrajectory();
1019 
1020  designerTrajectory->getTransition(index)->setInterpolationType(it);
1021  theUniversalMethod(index);
1022  }
1023  else
1024  {
1025  throw NotInitializedException("Manager is not intialized", "Manager");
1026  }
1027 }
1028 
1029 void
1031 {
1032  if (isInitialized)
1033  {
1034  //get a clean copy of the designerTrajectory
1035  designerTrajectory = getDesignerTrajectory();
1036 
1037  designerTrajectory->getUserWaypoint(index)->setIsTimeOptimalBreakpoint(b);
1038  theUniversalMethod(index);
1039  }
1040  else
1041  {
1042  throw NotInitializedException("Manager is not intialized", "Manager");
1043  }
1044 }
1045 
1046 void
1048 {
1049  if (isInitialized)
1050  {
1051  //get a clean copy of the designerTrajectory
1052  designerTrajectory = getDesignerTrajectory();
1053 
1054  designerTrajectory->getTransition(index)->setUserDuration(duration);
1055  //shift all userTimestamps of the userwaypoints behind
1056  for (unsigned int i = index + 1; i < designerTrajectory->getNrOfUserWaypoints() - 1; i++)
1057  {
1058  TransitionPtr trans = designerTrajectory->getTransition(i);
1059  trans->setUserDuration(trans->getUserDuration());
1060  }
1061  //theUniversalMethod(index);
1062  saveState();
1063  }
1064  else
1065  {
1066  throw NotInitializedException("Manager is not intialized", "Manager");
1067  }
1068 }
1069 
1072 {
1073  if (isInitialized)
1074  {
1075  //return DesignerTrajectoryPtr(new DesignerTrajectory(*designerTrajectory));
1077  *(*std::next(mementos.mementoList.begin(), mementos.currentMemento))));
1078  }
1079  else
1080  {
1081  return nullptr;
1082  }
1083 }
1084 
1085 bool
1087 {
1088  if (newDesignerTrajectory->getNrOfUserWaypoints() > 1 &&
1089  newDesignerTrajectory->getRns()->getName() == rns->getName())
1090  {
1091  TrajectoryPtr trajectory = newDesignerTrajectory->getTimeOptimalTrajectory();
1092 
1093  //set Trajectories of transitions
1094  for (unsigned int i = 0; i < newDesignerTrajectory->getNrOfUserWaypoints() - 1; i++)
1095  {
1096  TransitionPtr trans = newDesignerTrajectory->getTransition(i);
1097  double transBeginTime = trans->getStart()->getTimeOptimalTimestamp();
1098  double transEndTime = trans->getEnd()->getTimeOptimalTimestamp();
1099  TrajectoryPtr traj = trajectory->getPart(transBeginTime, transEndTime, 2);
1100 
1101 
1102  //shift timestamps
1103  std::vector<std::vector<double>> nodeData;
1104  for (unsigned int dim = 0; dim < traj->dim(); dim++)
1105  {
1106  nodeData.push_back(traj->getDimensionData(dim));
1107  }
1108  std::vector<double> newTimestamps = {0.0};
1109  std::vector<double> oldTimestamps = traj->getTimestamps();
1110  for (unsigned int j = 1; j < oldTimestamps.size(); j++)
1111  {
1112  if (oldTimestamps[j] - transBeginTime >= 0)
1113  {
1114  newTimestamps.push_back(oldTimestamps[j] - transBeginTime);
1115  }
1116  else
1117  {
1118  newTimestamps.push_back(0);
1119  }
1120  }
1121 
1122  TrajectoryPtr shiftedTraj(
1123  new Trajectory(nodeData, newTimestamps, traj->getDimensionNames()));
1124  trans->setTrajectory(shiftedTraj);
1125  }
1126  designerTrajectory = newDesignerTrajectory;
1127 
1128  if (mementos.mementoList.size() != 0)
1129  {
1130  saveState();
1131  }
1132  else
1133  {
1134  mementos.mementoList.push_back(
1135  DesignerTrajectoryPtr(new DesignerTrajectory(*designerTrajectory)));
1136  }
1137  isInitialized = true;
1138  return true;
1139  }
1140  return false;
1141 }
1142 
1143 bool
1145 {
1146  return mementos.currentMemento > 0;
1147 }
1148 
1149 bool
1151 {
1152  if (mementos.mementoList.size() != 0 &&
1153  mementos.currentMemento < mementos.mementoList.size() - 1)
1154  {
1155  return true;
1156  }
1157  else
1158  {
1159  return false;
1160  }
1161 }
armarx::UserWaypointPtr
std::shared_ptr< UserWaypoint > UserWaypointPtr
Definition: UserWaypoint.h:142
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
index
uint8_t index
Definition: EtherCATFrame.h:59
armarx::DesignerTrajectoryManager::editWaypointIKSelection
void editWaypointIKSelection(unsigned int index, VirtualRobot::IKSolver::CartesianSelection ikSelection)
Edits the IKSelection of a UserWaypoint.
Definition: DesignerTrajectoryManager.cpp:945
armarx::KinematicSolver
Realizes the Singleton-Pattern, Provides Methods to solve Kinematic Problems (forward and inverse)
Definition: KinematicSolver.h:52
armarx::UserWaypoint
The UserWaypoint class represents a waypoint of the trajectory.
Definition: UserWaypoint.h:47
armarx::DesignerTrajectory
Definition: DesignerTrajectory.h:36
armarx::DesignerTrajectoryCalculator
Offers functionality to create TimedTrajectories from supplied Trajectories and points set by the use...
Definition: DesignerTrajectoryCalculator.h:19
armarx::InterpolationSegmentFactory::needsOptimizing
static bool needsOptimizing(std::vector< VirtualRobot::IKSolver::CartesianSelection > &selections)
needsOptimizing returns true if there is a CartesianSelection at i that dominates a CartesianSelectio...
Definition: InterpolationSegmentFactory.cpp:315
armarx::DesignerTrajectoryManager::undo
bool undo()
undo
Definition: DesignerTrajectoryManager.cpp:503
armarx::DesignerTrajectoryManager::undoPossible
bool undoPossible()
setCollisionModels Sets the collision models on the collision detection attribute
Definition: DesignerTrajectoryManager.cpp:1144
IceInternal::Handle< Trajectory >
armarx::EnvironmentPtr
std::shared_ptr< Environment > EnvironmentPtr
Definition: Environment.h:29
copy
Use of this software is granted under one of the following two to be chosen freely by the user Boost Software License Version Marcin Kalicinski Permission is hereby free of to any person or organization obtaining a copy of the software and accompanying documentation covered by this and transmit the and to prepare derivative works of the and to permit third parties to whom the Software is furnished to do all subject to the including the above license this restriction and the following must be included in all copies of the in whole or in and all derivative works of the unless such copies or derivative works are solely in the form of machine executable object code generated by a source language processor THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF FITNESS FOR A PARTICULAR TITLE AND NON INFRINGEMENT IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN TORT OR ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE The MIT Marcin Kalicinski Permission is hereby free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to copy
Definition: license.txt:39
armarx::DesignerTrajectoryManager::redo
bool redo()
redo
Definition: DesignerTrajectoryManager.cpp:527
armarx::AbstractInterpolationPtr
std::shared_ptr< AbstractInterpolation > AbstractInterpolationPtr
Definition: AbstractInterpolation.h:76
armarx::DesignerTrajectoryManager::setWaypointAsBreakpoint
void setWaypointAsBreakpoint(unsigned int index, bool b)
Sets a UserWaypoint as (not-) breakpoint.
Definition: DesignerTrajectoryManager.cpp:1030
armarx::InterpolationType
InterpolationType
The InterpolationType enum lists all available interpolation types eLinearInterpolation: represents l...
Definition: InterpolationType.h:32
armarx::NJointTaskSpaceDMPControllerMode::CartesianSelection
CartesianSelection
Definition: ControllerInterface.ice:34
armarx::Pose::toEigen
virtual Eigen::Matrix4f toEigen() const
Definition: Pose.cpp:334
armarx::DesignerTrajectoryManager::editWaypointPoseBase
void editWaypointPoseBase(unsigned int index, const PoseBasePtr pose)
Edits the pose of a UserWaypoint.
Definition: DesignerTrajectoryManager.cpp:890
armarx::DesignerTrajectoryManager::redoPossible
bool redoPossible()
Definition: DesignerTrajectoryManager.cpp:1150
armarx::DesignerTrajectoryManager::getIsInitialized
bool getIsInitialized()
True if the DesignerTrajectory is initialized.
Definition: DesignerTrajectoryManager.cpp:551
armarx::InterpolationSegmentFactory::produceLinearInterpolationSegments
static std::vector< AbstractInterpolationPtr > produceLinearInterpolationSegments(std::vector< PoseBasePtr > controlPoints)
produceInterpolationSegments constructs a vector of LinearInterpolations
Definition: InterpolationSegmentFactory.cpp:161
armarx::TransitionPtr
std::shared_ptr< Transition > TransitionPtr
Definition: Transition.h:143
armarx::TrajectoryPtr
IceInternal::Handle< Trajectory > TrajectoryPtr
Definition: Trajectory.h:52
armarx::VariantType::Trajectory
const VariantTypeId Trajectory
Definition: Trajectory.h:44
armarx::channels::KinematicUnitObserver::jointAngles
const KinematicUnitDatafieldCreator jointAngles("jointAngles")
armarx::Pose
The Pose class.
Definition: Pose.h:242
armarx::DesignerTrajectoryManager::getDesignerTrajectory
DesignerTrajectoryPtr getDesignerTrajectory() const
Returns a deep copy of this manager's DesignerTrajectory.
Definition: DesignerTrajectoryManager.cpp:1071
armarx::DesignerTrajectoryPtr
std::shared_ptr< DesignerTrajectory > DesignerTrajectoryPtr
Definition: DesignerTrajectory.h:163
armarx::TimedTrajectory
A container for a Trajectory and a set of timestamps, representing the arrival of the Trajectory at u...
Definition: TimedTrajectory.h:14
armarx::InterpolationSegmentFactory::optimizeControlPoints
static void optimizeControlPoints(std::vector< PoseBasePtr > &controlPoints, std::vector< VirtualRobot::IKSolver::CartesianSelection > &selections)
optimizeControlPoints changes the cartian selections and control points so that the IKSolving produce...
Definition: InterpolationSegmentFactory.cpp:216
armarx::InterpolationSegmentFactory::produceInterpolationSegments
static std::vector< AbstractInterpolationPtr > produceInterpolationSegments(std::vector< PoseBasePtr > controlPoints, std::vector< InterpolationType > interpolations)
produceInterpolationSegments constructs a vector of AbstractInterpolation the concrete Interpolationt...
Definition: InterpolationSegmentFactory.cpp:40
armarx::navigation::core::Position
Eigen::Vector3f Position
Definition: basic_types.h:36
armarx::DesignerTrajectoryManager::initializeDesignerTrajectory
void initializeDesignerTrajectory(std::vector< double > &jointAngles)
Public functions.
Definition: DesignerTrajectoryManager.cpp:808
armarx::DesignerTrajectoryManager::import
bool import(DesignerTrajectoryPtr newDesignerTrajectory)
Overrides the current DesignerTrajectory with the given DesignerTrajectory.
Definition: DesignerTrajectoryManager.cpp:1086
armarx::DesignerTrajectoryManager::setTransitionUserDuration
void setTransitionUserDuration(unsigned int index, double duration)
Sets the desired duration of a Transition.
Definition: DesignerTrajectoryManager.cpp:1047
armarx::DesignerTrajectoryManager::addWaypoint
void addWaypoint(const PoseBasePtr pose)
Adds a UserWaypoint to the end of this manager's DesignerTrajectory.
Definition: DesignerTrajectoryManager.cpp:836
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::DesignerTrajectoryManager::deleteWaypoint
void deleteWaypoint(unsigned int index)
Deletes a UserWaypoint from this manager's DesignerTrajectory.
Definition: DesignerTrajectoryManager.cpp:964
armarx::DesignerTrajectoryManager::insertWaypoint
void insertWaypoint(unsigned int index, const PoseBasePtr pose)
Inserts a UserWaypoint at the given position to this manager's DesignerTrajectory.
Definition: DesignerTrajectoryManager.cpp:854
dt
constexpr T dt
Definition: UnscentedKalmanFilterTest.cpp:45
DesignerTrajectoryManager.h
armarx::DesignerTrajectoryManager::DesignerTrajectoryManager
DesignerTrajectoryManager(std::string rnsName, EnvironmentPtr environment_)
Constructor(s)
Definition: DesignerTrajectoryManager.cpp:795
armarx::DesignerTrajectoryManager::setTransitionInterpolation
void setTransitionInterpolation(unsigned int index, InterpolationType it)
Sets the InterpolationType of a Transition from this manager's DesignerTrajectory.
Definition: DesignerTrajectoryManager.cpp:1013