InterpolationSegmentFactory.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @package ArmarXGuiPlugins::RobotTrajectoryDesigner::Interpolation
17  * @author Timo Birr
18  * @date 2018
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
23 
25 
27 
28 #include "LinearInterpolation.h"
29 #include "SplineInterpolation.h"
30 
31 ///EXCEPTIONS
32 #include "../exceptions/ControlPointsInterpolationMatchException.h"
33 #include "../exceptions/InterpolationNotDefinedException.h"
34 #include "../exceptions/NoInterpolationPossibleException.h"
35 
36 using namespace armarx;
37 using namespace VirtualRobot;
38 
39 std::vector<AbstractInterpolationPtr>
41  std::vector<PoseBasePtr> controlPoints,
42  std::vector<InterpolationType> interpolations)
43 {
44  if (controlPoints.size() != interpolations.size() + 1)
45  {
47  controlPoints.size(), interpolations.size());
48  }
49 
50  std::vector<AbstractInterpolationPtr> producedInterpolations =
51  std::vector<AbstractInterpolationPtr>();
52 
53  std::vector<int> interPolationChangePoints = std::vector<int>();
54  interPolationChangePoints.push_back(0);
55 
56  if (interpolations.size() == 1 && interpolations.at(0) == eSplineInterpolation)
57  {
58  interpolations.assign(0, eLinearInterpolation);
59  }
60 
61  //mark parts of the Interpolaion where it changes
62  int splineCounter = 0;
63  InterpolationType current = interpolations.at(0);
64  if (eSplineInterpolation == interpolations.at(0))
65  {
66  splineCounter++;
67  }
68  for (unsigned int i = 1; i < interpolations.size(); i++)
69  {
70  if (eSplineInterpolation == interpolations.at(i))
71  {
72  splineCounter++;
73  }
74  if (current != interpolations.at(i))
75  {
76  if (current == eSplineInterpolation && interpolations.at(i) != eSplineInterpolation)
77  {
78  if (splineCounter < 2)
79  {
80  interpolations[i - 1] = eLinearInterpolation;
81  }
82  else
83  {
84  interPolationChangePoints.push_back(i);
85  }
86  splineCounter = 0;
87  }
88  else
89  {
90  interPolationChangePoints.push_back(i);
91  }
92  current = interpolations[i];
93  }
94  }
95  if (interpolations.size() >= 2 &&
96  interpolations.at(interpolations.size() - 1) == eSplineInterpolation &&
97  interpolations.at(interpolations.size() - 2) != eSplineInterpolation)
98  {
99  interpolations.pop_back();
100  interpolations.push_back(eLinearInterpolation);
101  }
102  //mark parts of the Interpolaion where it changes
103  /*InterpolationType current = interpolations.at(0);
104  for (unsigned int i = 1; i < interpolations.size(); i++)
105  {
106  if (current != interpolations.at(i))
107  {
108  int prev = interPolationChangePoints.back();
109  //A splineInterpolation needs 3 Points or more to be a valid spline Interpolation
110  if (i - prev < 2 && interpolations.at(prev + 1) == InterpolationType::eSplineInterpolation && interpolations.at(i) == InterpolationType::eSplineInterpolation)
111  {
112  throw new exceptions::local::NoInterpolationPossibleException(3, 2);
113  }
114  interPolationChangePoints.push_back(i);
115  current = interpolations[i];
116  }
117  }*/
118  //Produce the InterpolationSegments and add them to producedInterpolationsVector
119  for (unsigned int j = 1; j < interPolationChangePoints.size(); j++)
120  {
121  std::vector<PoseBasePtr> currentCP = std::vector<PoseBasePtr>();
122  for (int i = interPolationChangePoints.at(j - 1); i <= interPolationChangePoints.at(j); i++)
123  {
124  currentCP.push_back(controlPoints.at(i));
125  }
126  std::vector<AbstractInterpolationPtr> temp;
127  switch (interpolations.at(interPolationChangePoints.at(j - 1)))
128  {
130  temp = produceLinearInterpolationSegments(currentCP);
131  break;
133  temp = produceSplineInterpolationSegments(currentCP);
134  break;
135  }
136  producedInterpolations.insert(producedInterpolations.end(), temp.begin(), temp.end());
137  }
138 
139  std::vector<PoseBasePtr> currentCP = std::vector<PoseBasePtr>();
140  for (unsigned int i = interPolationChangePoints.at(interPolationChangePoints.size() - 1);
141  i < controlPoints.size();
142  i++)
143  {
144  currentCP.push_back(controlPoints.at(i));
145  }
146  std::vector<AbstractInterpolationPtr> temp;
147  switch (interpolations.at(interpolations.size() - 1))
148  {
150  temp = produceLinearInterpolationSegments(currentCP);
151  break;
153  temp = produceSplineInterpolationSegments(currentCP);
154  break;
155  }
156  producedInterpolations.insert(producedInterpolations.end(), temp.begin(), temp.end());
157  return producedInterpolations;
158 }
159 
160 std::vector<AbstractInterpolationPtr>
162  std::vector<PoseBasePtr> controlPoints)
163 {
164  std::vector<AbstractInterpolationPtr> producedInterpolations =
165  std::vector<AbstractInterpolationPtr>();
166  for (unsigned int i = 0; i < controlPoints.size() - 1; i++)
167  {
168  std::vector<PoseBasePtr> currentCP = std::vector<PoseBasePtr>();
169  currentCP.push_back(controlPoints.at(i));
170  currentCP.push_back(controlPoints.at(i + 1));
171  AbstractInterpolationPtr interpolation =
172  std::shared_ptr<AbstractInterpolation>(new LinearInterpolation(currentCP));
173  producedInterpolations.push_back(interpolation);
174  }
175  return producedInterpolations;
176 }
177 
178 std::vector<AbstractInterpolationPtr>
180  std::vector<PoseBasePtr> controlPoints)
181 {
182  std::vector<AbstractInterpolationPtr> producedInterpolations =
183  std::vector<AbstractInterpolationPtr>();
184  SplineInterpolationPtr parent = *new std::shared_ptr<SplineInterpolation>(
185  new SplineInterpolation(controlPoints)); //das hier muss genauso aussehen
186 
187  for (unsigned int i = 0; i < controlPoints.size() - 1; i++)
188  {
189  AbstractInterpolationPtr interpolation =
190  std::shared_ptr<AbstractInterpolation>(parent->getInterPolationSegment(i));
191  producedInterpolations.push_back(interpolation);
192  }
193  return producedInterpolations;
194 }
195 
198  std::vector<PoseBasePtr> controlPoints,
199  PoseBasePtr segmentStart)
200 {
201  SplineInterpolationPtr parent = *new std::shared_ptr<SplineInterpolation>(
202  new SplineInterpolation(controlPoints)); //das hier muss genauso aussehen
203 
204  AbstractInterpolationPtr interpolation =
205  std::shared_ptr<AbstractInterpolation>(parent->getInterPolationSegment(segmentStart));
206 
207  return interpolation;
208 }
209 
210 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
211 /// \brief InterpolationSegmentFactory::optimizeControlPoints
212 /// \param controlPoints
213 /// \param selections
214 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
215 void
217  std::vector<PoseBasePtr>& controlPoints,
218  std::vector<IKSolver::CartesianSelection>& selections)
219 {
220  /*for(PoseBasePtr pose: controlPoints) {
221  ARMARX_WARNING << Pose(pose->position, pose->orientation).toEigen();
222  }
223  for(IKSolver::CartesianSelection sel: selections) {
224  ARMARX_WARNING << std::to_string(sel);
225  }*/
226 
227  for (unsigned int i = 0; i < selections.size() - 1; i++)
228  {
229  //ARMARX_INFO << "OPTIMIZE";
230  if (InterpolationSegmentFactory::isDominantOver(selections[i + 1], selections[i]))
231  {
232  std::vector<IKSolver::CartesianSelection> followingDominations =
233  std::vector<IKSolver::CartesianSelection>();
234  followingDominations.push_back(selections[i + 1]);
235  int followingDominationsStart = i;
236  bool isBreaking;
237  do
238  {
239  //look left until an equal or fully dominating cartesian selection appears
240  for (int j = i; j >= 0; j--)
241  {
243  selections[i + 1]) &&
245  selections[j])) ||
246  selections[i + 1] == selections[j])
247  {
248 
249  //ARMARX_INFO << std::to_string(selections[j]) + " is dominant over " + std::to_string(selections[i + 1]);
250  followingDominationsStart = j + 1;
251 
252  int dominanceIntervalSize = i + 1 - j;
253  PoseBasePtr dominanceIntervalStart = controlPoints[j];
254  PoseBasePtr dominanceIntervalEnd = controlPoints[i + 1];
255  std::vector<AbstractInterpolationPtr> li =
256  produceLinearInterpolationSegments(
257  {dominanceIntervalStart, dominanceIntervalEnd});
258  int counter = 1;
259  for (unsigned int k = j + 1; k < i + 1; k++)
260  {
261  controlPoints[k] = optimizePose(
262  controlPoints[k],
263  li[0]->getPoseAt(double(1.0 / dominanceIntervalSize) * counter),
264  selections[k],
265  selections[i + 1]);
266  counter++;
267  //ARMARX_INFO << std::to_string(double(1.0 / dominanceIntervalSize) * k) + " SET POINT AT------" + std::to_string(k) + " with " + std::to_string(selections[i + 1]);
268  }
269  break;
270  }
271  followingDominations.push_back(selections[j]);
272  }
273 
274  if (i + 2 < selections.size() &&
275  isDominantOver(selections[i + 2], selections[i + 1]))
276  {
277  isBreaking = false;
278  i++;
279  followingDominations.push_back(selections[i + 1]);
280  }
281  else
282  {
283  isBreaking = true;
284  }
285 
286  } while (!isBreaking);
287  /*ARMARX_WARNING << "FOLLOWING DOMINATIONS START ";
288  for(IKSolver::CartesianSelection sel: followingDominations) {
289  ARMARX_WARNING << std::to_string(sel);
290  }
291  ARMARX_WARNING << "FOLLOWING DOMINATIONS END ";*/
292  IKSolver::CartesianSelection dominatingSelection =
293  getSmallestDominating(followingDominations);
294  for (unsigned int m = followingDominationsStart; m <= i + 1; m++)
295  {
296  //ARMARX_WARNING << "SET SELECTION " + std::to_string(m) + " with " + std::to_string(dominatingSelection);
297  selections[m] = dominatingSelection;
298  //selections[m] = IKSolver::CartesianSelection::All;
299  }
300  }
301  //ARMARX_INFO << "Optimizing done";
302  }
303  ARMARX_INFO << "Optimizing done";
304 
305  /*ARMARX_WARNING << "RESULT XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
306  for(PoseBasePtr pose: controlPoints) {
307  ARMARX_WARNING << Pose(pose->position, pose->orientation).toEigen();
308  }
309  for(IKSolver::CartesianSelection sel: selections) {
310  ARMARX_WARNING << std::to_string(sel);
311  }*/
312 }
313 
314 bool
315 InterpolationSegmentFactory::needsOptimizing(std::vector<IKSolver::CartesianSelection>& selections)
316 {
317  for (unsigned int i = 0; i < selections.size() - 1; i++)
318  {
319  //ARMARX_INFO << "NEEDS OPTIMIZING";
320  if (InterpolationSegmentFactory::isDominantOver(selections[i + 1], selections[i]))
321  {
322  return true;
323  }
324  }
325  return false;
326 }
327 
328 bool
331 {
332  if (other == IKSolver::CartesianSelection::X || other == IKSolver::CartesianSelection::Y ||
333  other == IKSolver::CartesianSelection::Z ||
335  {
336  return current != other;
337  }
338  else if (other == IKSolver::CartesianSelection::Position)
339  {
340  return (current == IKSolver::CartesianSelection::Orientation ||
341  current == IKSolver::CartesianSelection::All);
342  }
343  return false;
344 }
345 
348  std::vector<VirtualRobot::IKSolver::CartesianSelection> selections)
349 {
350  bool isInhomogenous = false;
351  ARMARX_INFO << "Vector start";
352  int max = 0;
353  for (IKSolver::CartesianSelection current : selections)
354  {
355  if (current > max)
356  {
357  ARMARX_INFO << "In Vector" + std::to_string(current);
358  max = current;
359  }
360  if (max != 0 && current != max)
361  {
362  isInhomogenous = true;
363  }
364  }
365  if (max <= 4 && isInhomogenous)
366  {
367  ARMARX_INFO << "SMALLEST DOMINATING" +
370  }
372  {
373  for (IKSolver::CartesianSelection currentSelection : selections)
374  {
375  if (currentSelection != IKSolver::CartesianSelection::Orientation)
376  {
377  ARMARX_INFO << "SMALLEST DOMINATING" +
378  std::to_string(IKSolver::CartesianSelection::All);
379  return IKSolver::CartesianSelection::All;
380  }
381  }
382  ARMARX_INFO << "SMALLEST DOMINATING" +
385  }
386  else
387  {
388  ARMARX_INFO << "SMALLEST DOMINATING" + std::to_string(max);
389  return static_cast<IKSolver::CartesianSelection>(max);
390  }
391 }
392 
393 PoseBasePtr
395  PoseBasePtr corrected,
396  IKSolver::CartesianSelection selectionOriginal,
397  IKSolver::CartesianSelection selectionCorrecting)
398 {
399  //ARMARX_WARNING << Pose(original->position, original->orientation).toEigen();
400  //ARMARX_WARNING << Pose(corrected->position, corrected->orientation).toEigen();
401  PoseBasePtr firstStep;
402  switch (selectionCorrecting)
403  {
404  case (IKSolver::CartesianSelection::X):
405  firstStep = PoseBasePtr(
406  new Pose(Vector3BasePtr(new Vector3(
407  corrected->position->x, original->position->y, original->position->z)),
408  original->orientation));
409  case (IKSolver::CartesianSelection::Y):
410  firstStep = PoseBasePtr(
411  new Pose(Vector3BasePtr(new Vector3(
412  original->position->x, corrected->position->y, original->position->z)),
413  original->orientation));
414  case (IKSolver::CartesianSelection::Z):
415  firstStep = PoseBasePtr(
416  new Pose(Vector3BasePtr(new Vector3(
417  original->position->x, original->position->y, corrected->position->z)),
418  original->orientation));
420  firstStep = PoseBasePtr(new Pose(corrected->position, original->orientation));
422  firstStep = PoseBasePtr(new Pose(original->position, corrected->orientation));
423  case (IKSolver::CartesianSelection::All):
424  //ARMARX_WARNING << "CORRECTED ALL";
425  firstStep = corrected;
426  }
427  switch (selectionOriginal)
428  {
429  case (IKSolver::CartesianSelection::X):
430  return PoseBasePtr(new Pose(Vector3BasePtr(new Vector3(original->position->x,
431  firstStep->position->y,
432  firstStep->position->z)),
433  firstStep->orientation));
434  case (IKSolver::CartesianSelection::Y):
435  return PoseBasePtr(new Pose(Vector3BasePtr(new Vector3(firstStep->position->x,
436  original->position->y,
437  firstStep->position->z)),
438  firstStep->orientation));
439  case (IKSolver::CartesianSelection::Z):
440  return PoseBasePtr(new Pose(Vector3BasePtr(new Vector3(firstStep->position->x,
441  firstStep->position->y,
442  original->position->z)),
443  firstStep->orientation));
445  return PoseBasePtr(new Pose(original->position, firstStep->orientation));
447  return PoseBasePtr(new Pose(firstStep->position, original->orientation));
448  case (IKSolver::CartesianSelection::All):
449  return original;
450  default:
451  return corrected;
452  }
453 }
GfxTL::Orientation
ScalarT Orientation(const VectorXD< 2, ScalarT > &p1, const VectorXD< 2, ScalarT > &p2, const VectorXD< 2, ScalarT > &c)
Definition: Orientation.h:10
armarx::navigation::core::Pose
Eigen::Isometry3f Pose
Definition: basic_types.h:31
VirtualRobot
Definition: FramedPose.h:42
armarx::InterpolationSegmentFactory::optimizePose
static PoseBasePtr optimizePose(armarx::PoseBasePtr original, armarx::PoseBasePtr corrected, VirtualRobot::IKSolver::CartesianSelection selectionOriginal, VirtualRobot::IKSolver::CartesianSelection selectionCorrected)
optimizePose changes the original pose so that the interpolation is smove when it changes from select...
Definition: InterpolationSegmentFactory.cpp:394
armarx::max
std::vector< T > max(const std::vector< T > &v1, const std::vector< T > &v2)
Definition: VectorHelpers.h:297
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::eSplineInterpolation
@ eSplineInterpolation
Definition: InterpolationType.h:35
armarx::SplineInterpolationPtr
std::shared_ptr< SplineInterpolation > SplineInterpolationPtr
Definition: SplineInterpolation.h:72
FramedPose.h
armarx::InterpolationSegmentFactory::isDominantOver
static bool isDominantOver(VirtualRobot::IKSolver::CartesianSelection current, VirtualRobot::IKSolver::CartesianSelection other)
isDominantOver returns true when current selection dominates other selection Definition: A CartesianS...
Definition: InterpolationSegmentFactory.cpp:329
armarx::AbstractInterpolationPtr
std::shared_ptr< AbstractInterpolation > AbstractInterpolationPtr
Definition: AbstractInterpolation.h:76
armarx::InterpolationType
InterpolationType
The InterpolationType enum lists all available interpolation types eLinearInterpolation: represents l...
Definition: InterpolationType.h:32
SplineInterpolation.h
armarx::NJointTaskSpaceDMPControllerMode::CartesianSelection
CartesianSelection
Definition: ControllerInterface.ice:34
InterpolationSegmentFactory.h
armarx::InterpolationSegmentFactory::produceLinearInterpolationSegments
static std::vector< AbstractInterpolationPtr > produceLinearInterpolationSegments(std::vector< PoseBasePtr > controlPoints)
produceInterpolationSegments constructs a vector of LinearInterpolations
Definition: InterpolationSegmentFactory.cpp:161
armarx::InterpolationSegmentFactory::produceSplineInterpolationSegment
static AbstractInterpolationPtr produceSplineInterpolationSegment(std::vector< PoseBasePtr > controlPoints, PoseBasePtr segmentStart)
produceSplineInterpolationSegment constructs the splineInterpolationSegment of a splineInterpolation ...
Definition: InterpolationSegmentFactory.cpp:197
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:41
armarx::LinearInterpolation
The LinearInterpolation class represents a linear Interpolation between a series of control points Li...
Definition: LinearInterpolation.h:35
LinearInterpolation.h
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:181
memoryx::KBM::Vector3
Eigen::Vector3d Vector3
Definition: kbm.h:43
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
Logging.h
armarx::navigation::core::Position
Eigen::Vector3f Position
Definition: basic_types.h:36
armarx::eLinearInterpolation
@ eLinearInterpolation
Definition: InterpolationType.h:34
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::exceptions::local::ControlPointsInterpolationMatchException
Definition: ControlPointsInterpolationMatchException.h:40
armarx::InterpolationSegmentFactory::getSmallestDominating
static VirtualRobot::IKSolver::CartesianSelection getSmallestDominating(std::vector< VirtualRobot::IKSolver::CartesianSelection > selections)
getSmallestDominating returns the cartesian selection that dominates all other cartesian selections i...
Definition: InterpolationSegmentFactory.cpp:347
armarx::InterpolationSegmentFactory::produceSplineInterpolationSegments
static std::vector< AbstractInterpolationPtr > produceSplineInterpolationSegments(std::vector< PoseBasePtr > controlPoints)
produceInterpolationSegments constructs a vector of SplineInterpolations
Definition: InterpolationSegmentFactory.cpp:179
armarx::SplineInterpolation
The SplineInterpolation class represents a linear Interpolation between a series of control points Sp...
Definition: SplineInterpolation.h:34