Trajectory.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-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 ArmarX
19 * @author Mirko Waechter( mirko.waechter at kit dot edu)
20 * @date 2016
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24#include "Trajectory.h"
25
26#include <cmath>
27#include <memory>
28
29#include <VirtualRobot/TimeOptimalTrajectory/TimeOptimalTrajectory.h>
30
33
35#include "VectorHelpers.h"
36#include "math/MathUtils.h"
37
38namespace armarx
39{
40
41 Trajectory::~Trajectory() = default;
42
43 void
45 {
46 dataVec.clear();
47 timestamps.clear();
48 dataVec.reserve(dim());
49 for (const auto& it : *this)
50 {
51 std::vector<DoubleSeqPtr>& data = it.data;
52 DoubleSeqSeq new2DVec;
53 new2DVec.reserve(data.size());
54 for (DoubleSeqPtr& subVec : data)
55 {
56 if (subVec)
57 {
58 new2DVec.emplace_back(*subVec);
59 }
60 else
61 {
62 new2DVec.emplace_back(Ice::DoubleSeq());
63 }
64 }
65 dataVec.emplace_back(new2DVec);
66 }
67 timestamps = getTimestamps();
68 }
69
70 void
72 {
73 int i = 0;
74 dataMap.clear();
75 for (DoubleSeqSeq& _2DVec : dataVec)
76 {
77
78 double t = timestamps.at(i);
79 int d = 0;
80 for (auto& vec : _2DVec)
81 {
82 setEntries(t, d++, vec);
83 }
84
85 i++;
86 }
87 }
88
89 void
90 Trajectory::serialize(const ObjectSerializerBasePtr& serializer, const Ice::Current&) const
91 {
92 AbstractObjectSerializerPtr obj = AbstractObjectSerializerPtr::dynamicCast(serializer);
93 Ice::StringSeq columnContent;
94 Eigen::MatrixXd m = toEigen();
95 auto cols = m.cols();
96 auto rows = m.rows();
97 for (int col = 0; col < cols; col++)
98 {
99 std::stringstream ss;
100
101 for (int row = 0; row < rows; row++)
102 {
103 ss << m(row, col) << (row < rows - 1 ? "," : "");
104 }
105
106 columnContent.push_back(ss.str());
107 }
108 obj->setDoubleArray("timestamps", getTimestamps());
109 obj->setStringArray("dimensionData", columnContent);
110 obj->setStringArray("dimensionNames", dimensionNames);
111 }
112
113 void
114 Trajectory::deserialize(const ObjectSerializerBasePtr& serializer, const Ice::Current&)
115 {
116 clear();
117 AbstractObjectSerializerPtr obj = AbstractObjectSerializerPtr::dynamicCast(serializer);
118 Ice::StringSeq rowContent;
119 obj->getStringArray("dimensionData", rowContent);
120
121 Ice::DoubleSeq timestamps;
122 obj->getDoubleArray("timestamps", timestamps);
123 for (const auto& row : rowContent)
124 {
125 Ice::StringSeq values = Split(row, ",");
126 Ice::DoubleSeq newRow;
127 newRow.reserve(values.size());
128 for (std::string v : values)
129 {
130 newRow.push_back(atof(v.c_str()));
131 }
132 addDimension(newRow, timestamps);
133 }
134 obj->getStringArray("dimensionNames", dimensionNames);
135 }
136
137 VariantDataClassPtr
138 Trajectory::clone(const Ice::Current&) const
139 {
140 return new Trajectory(*this);
141 }
142
145 {
146 TrajectoryPtr t = new Trajectory();
147 CopyMetaData(*this, *t);
148 return t;
149 }
150
151 std::string
152 Trajectory::output(const Ice::Current&) const
153 {
154
155 const ordered_view& ordv = dataMap.get<TagOrdered>();
156 typename ordered_view::const_iterator itMap = ordv.begin();
157 std::stringstream s;
158 s << "Dimensions names: \n";
159 for (size_t i = 0; i < dimensionNames.size(); i++)
160 {
161 s << dimensionNames.at(i)
162 << (i < limitless.size() && limitless.at(i).enabled ? " Limitless " : "") << "\n";
163 }
164
165 for (; itMap != ordv.end(); itMap++)
166 {
167 s << *itMap << std::endl;
168 }
169 return s.str();
170 }
171
172 Ice::Int
173 Trajectory::getType(const Ice::Current&) const
174 {
176 }
177
178 bool
179 Trajectory::validate(const Ice::Current&)
180 {
181 return true;
182 }
183
184 Ice::ObjectPtr
186 {
187 return clone();
188 }
189
191 IceUtil::Shared(source),
192 armarx::Serializable(source),
193 armarx::VariantDataClass(source),
194 TrajectoryBase(source)
195 {
196 CopyData(source, *this);
197 }
198
199 Trajectory::Trajectory(const std::map<double, Ice::DoubleSeq>& data)
200 {
201 if (data.size() == 0)
202 {
203 return;
204 }
205
206 typename std::map<double, Ice::DoubleSeq>::const_iterator it = data.begin();
207
208 for (; it != data.end(); it++)
209 {
210 TrajData dataEntry(this);
211 dataEntry.timestamp = it->first;
212 const Ice::DoubleSeq& dataVec = it->second;
213
214 for (double i : dataVec)
215 {
216 checkValue(i);
217 dataEntry.data.push_back(std::make_shared<Ice::DoubleSeq>(1, i));
218 }
219 dataMap.insert(std::move(dataEntry));
220 }
221 }
222
223 //
224 // Trajectory::Trajectory(const TrajMap &map)
225 // {
226 // copyMap(map, dataMap);
227 // }
228
231 {
232 CopyData(source, *this);
233 return *this;
234 }
235
236 double
237 Trajectory::getState(double t, size_t dim, size_t derivation)
238 {
239 if (dim >= this->dim())
240 {
241 throw LocalException() << "dimension is to big: " << dim << " max: " << this->dim();
242 }
243
244 typename timestamp_view::iterator it = dataMap.find(t);
245
246 if (it == dataMap.end() || dim >= it->data.size() || !it->data.at(dim) ||
247 it->data.at(dim)->size() <= derivation)
248 {
249 // ARMARX_INFO << "interpolating for " << VAROUT(t) << VAROUT(dim);
250 __fillBaseDataAtTimestamp(t); // interpolates and retrieves
251 it = dataMap.find(t);
252 }
253
254 if (it->data.size() <= dim)
255 {
256 // ARMARX_ERROR << "FAILED!";
257 // ARMARX_INFO << VAROUT(t) << VAROUT(dim) << VAROUT(it->data.size()) << this->output();
258 throw LocalException() << "std::vector ptr is not the correct size!? " << VAROUT(dim)
259 << VAROUT(it->data.size());
260 }
261
262 if (!it->data.at(dim))
263 // it->data.at(dim).reset(new Ice::DoubleSeq());
264 {
265 throw LocalException() << "std::vector ptr is NULL!?";
266 }
267
268
269 std::vector<DoubleSeqPtr>& vec = it->data;
270 ARMARX_CHECK_GREATER(vec.size(), dim);
271 if (derivation != 0 && vec.at(dim)->size() <= derivation)
272 {
273 //resize and calculate derivations
274 ARMARX_CHECK_GREATER(vec.size(), dim);
276
277 size_t curDeriv = vec.at(dim)->size();
278 // ARMARX_INFO << VAROUT(curDeriv) << VAROUT(dim);
279 vec.at(dim)->resize(derivation + 1);
280
281 while (curDeriv <= derivation)
282 {
283 double derivValue = getDiscretDifferentiationForDimAtT(t, dim, curDeriv);
284 checkValue(curDeriv);
285 vec.at(dim)->at(curDeriv) = derivValue;
286 curDeriv++;
287 }
288 }
289
290 ARMARX_CHECK_GREATER(vec.at(dim)->size(), derivation)
291 << VAROUT(t) << VAROUT(dim) << VAROUT(*this);
292 // std::cout << "dimensions: " <<it->data.size() << " derivations: " << it->data.at(dim)->size() << std::endl;
293 double result = vec.at(dim)->at(derivation);
294 // checkValue(result);
295 return result;
296 }
297
298 double
299 Trajectory::getState(double t, size_t dim, size_t derivation) const
300 {
301
302 if (dim >= this->dim())
303 {
304 throw LocalException() << "dimension is to big: " << dim << " max: " << this->dim();
305 }
306
307 typename timestamp_view::iterator it = dataMap.find(t);
308
309 if (!dataExists(t, dim, derivation))
310 {
311 if (derivation == 0)
312 {
313 return __interpolate(t, dim, derivation);
314 }
315 else
316 {
317 return getDiscretDifferentiationForDimAtT(t, dim, derivation);
318 }
319 }
320 else
321 {
322 // std::cout << "dimensions: " <<it->data.size() << " derivations: " << it->data.at(dim)->size() << std::endl;
323 double result = it->data.at(dim)->at(derivation);
324
325 checkValue(result);
326
327
328 return result;
329 }
330 }
331
332 std::vector<Ice::DoubleSeq>
333 Trajectory::getAllStates(double t, int maxDeriv)
334 {
335 std::vector<Ice::DoubleSeq> res;
336
337 for (size_t i = 0; i < dim(); i++)
338 {
339 Ice::DoubleSeq curdata;
340
341 for (int deri = 0; deri <= maxDeriv; deri++)
342 {
343 curdata.push_back(getState(t, i, deri));
344 }
345
346 res.push_back(curdata);
347 }
348
349 return res;
350 }
351
352 Ice::DoubleSeq
353 Trajectory::getDerivations(double t, size_t dimension, size_t derivations) const
354 {
355 if (dimension >= dim())
356 {
357 throw LocalException()
358 << "Dimension out of bounds: requested: " << dimension << " available: " << dim();
359 }
360
361 Ice::DoubleSeq result;
362
363 for (size_t i = 0; i <= derivations; i++)
364 {
365 result.push_back(getState(t, dimension, i));
366 }
367
368 return result;
369 }
370
371 std::string
373 {
374 return dimensionNames.at(dim);
375 }
376
377 const Ice::StringSeq&
379 {
380 return dimensionNames;
381 }
382
385 {
386 return dataMap;
387 }
388
389 Ice::DoubleSeq
390 Trajectory::getDimensionData(size_t dimension, size_t derivation) const
391 {
392 if (dimension >= dim())
393 {
394 throw LocalException("dimension is out of range: ")
395 << dimension << " actual dimensions: " << dim();
396 }
397
398 Ice::DoubleSeq result;
399
400 const ordered_view& ordv = dataMap.get<TagOrdered>();
401 typename ordered_view::const_iterator itMap = ordv.begin();
402
403 for (; itMap != ordv.end(); itMap++)
404 {
405 DoubleSeqPtr dataPtr = itMap->data[dimension];
406 result.push_back(itMap->getDeriv(dimension, derivation));
407 // if(dataPtr && dataPtr->size() > derivation)
408 // result.push_back(itMap->getDeriv(dimension, derivation));
409 // else result.push_back(getState(itMap->timestamp, dimension, derivation));
410 }
411
412 return result;
413 }
414
415 Eigen::VectorXd
416 Trajectory::getDimensionDataAsEigen(size_t dimension, size_t derivation) const
417 {
419 dimension, derivation, begin()->getTimestamp(), rbegin()->getTimestamp());
420 }
421
422 Eigen::VectorXd
424 size_t derivation,
425 double startTime,
426 double endTime) const
427 {
428 if (dimension >= dim())
429 {
430 throw LocalException("dimension is out of range: ")
431 << dimension << " actual dimensions: " << dim();
432 }
433
434 Ice::DoubleSeq result;
435
436 const ordered_view& ordv = dataMap.get<TagOrdered>();
437 ordered_view::iterator itO = ordv.lower_bound(startTime);
438 ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
439 // typename ordered_view::const_iterator itMap = ordv.begin();
440
441 size_t i = 0;
442 for (; itO != itOEnd && i < size(); itO++, i++)
443 {
444 DoubleSeqPtr dataPtr = itO->data[dimension];
445 result.push_back(itO->getDeriv(dimension, derivation));
446 // if(dataPtr && dataPtr->size() > derivation)
447 // result.push_back(itMap->getDeriv(dimension, derivation));
448 // else result.push_back(getState(itMap->timestamp, dimension, derivation));
449 }
450 Eigen::VectorXd resultVec(result.size());
451 for (size_t i = 0; i < result.size(); i++)
452 {
453 resultVec(i) = result[i];
454 }
455 return resultVec;
456 }
457
458 Eigen::MatrixXd
459 Trajectory::toEigen(size_t derivation, double startTime, double endTime) const
460 {
461 Eigen::MatrixXd result(size(), dim());
462
463 const ordered_view& ordv = dataMap.get<TagOrdered>();
464 ordered_view::iterator itO = ordv.lower_bound(startTime);
465 ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
466 // typename ordered_view::const_iterator itMap = ordv.begin();
467
468 size_t i = 0;
469 for (; itO != itOEnd; itO++, i++)
470 {
471 // DoubleSeqPtr dataPtr = itO->data[dimension];
472 for (size_t d = 0; d < itO->data.size(); d++)
473 {
474 result(i, d) = (itO->getDeriv(d, derivation));
475 }
476 }
477
478 return result;
479 }
480
481 Eigen::MatrixXd
482 Trajectory::toEigen(size_t derivation) const
483 {
484 if (size() == 0 || dim() == 0)
485 {
486 return Eigen::MatrixXd();
487 }
488 return toEigen(derivation, begin()->getTimestamp(), rbegin()->getTimestamp());
489 }
490
492 Trajectory::getPart(double startTime, double endTime, size_t numberOfDerivations) const
493 {
494 TrajectoryPtr result(new Trajectory());
495
496 const ordered_view& ordv = dataMap.get<TagOrdered>();
497 ordered_view::iterator itO = ordv.lower_bound(startTime);
498 ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
499 // typename ordered_view::const_iterator itMap = ordv.begin();
500
501 size_t i = 0;
502 for (; itO != itOEnd; itO++, i++)
503 {
504 // DoubleSeqPtr dataPtr = itO->data[dimension];
505 for (size_t d = 0; d < itO->data.size(); d++)
506 {
507 Ice::DoubleSeq derivs;
508 for (size_t i = 0; i < numberOfDerivations + 1; i++)
509 {
510 derivs.push_back(itO->getDeriv(d, i));
511 }
512
513 result->addDerivationsToDimension(d, itO->getTimestamp(), derivs);
514 }
515 // result.addPositionsToDimension(d, itO->getTimestamp(), itO->getDeriv(d, 0));
516 }
517 result->setDimensionNames(getDimensionNames());
518 return result;
519 }
520
521 size_t
523 {
524 if (dataMap.size() == 0)
525 {
526 return 0;
527 }
528 else
529 {
530 return dataMap.begin()->data.size();
531 }
532 }
533
534 size_t
536 {
537 return dataMap.size();
538 }
539
540 double
542 {
543 const ordered_view& ordView = dataMap.get<TagOrdered>();
544
545 if (ordView.begin() != ordView.end())
546 {
547 return ordView.rbegin()->timestamp - ordView.begin()->timestamp;
548 }
549 else
550 {
551 return 0;
552 }
553 }
554
555 double
556 Trajectory::getLength(size_t derivation) const
557 {
558 if (size() == 0)
559 {
560 return 0;
561 }
562 return getLength(derivation, begin()->getTimestamp(), rbegin()->getTimestamp());
563 }
564
565 double
566 Trajectory::getLength(size_t derivation, double startTime, double endTime) const
567 {
568 double length = 0.0;
569 const ordered_view& ordv = dataMap.get<TagOrdered>();
570 ordered_view::const_iterator itO = ordv.lower_bound(startTime);
571 ordered_view::const_iterator itOEnd = ordv.upper_bound(endTime);
572 if (itO == ordv.end())
573 {
574 return 0.0;
575 }
576 size_t dimensions = dim();
577 Ice::DoubleSeq prevValue(dimensions);
578 for (size_t d = 0; d < dimensions; ++d)
579 {
580 prevValue[d] = getState(startTime, d, derivation);
581 }
582
583 itO++;
584
585 double segmentLength = 0;
586 for (; itO != itOEnd && itO != ordv.end(); itO++)
587 {
588 if (itO->getTimestamp() >= endTime)
589 {
590 break;
591 }
592 segmentLength = 0;
593 double value;
594 for (size_t d = 0; d < dimensions; ++d)
595 {
596 value = itO->getDeriv(d, derivation);
597 double diff = value - prevValue[d];
598 segmentLength += diff * diff;
599 prevValue[d] = value;
600 }
601 length += sqrt(segmentLength);
602 }
603 segmentLength = 0;
604 // interpolate end values
605 for (size_t d = 0; d < dimensions; ++d)
606 {
607 double value = getState(endTime, d, derivation);
608 double diff = value - prevValue[d];
609 segmentLength += diff * diff;
610 prevValue[d] = value;
611 }
612 length += sqrt(segmentLength);
613 return length;
614 }
615
616 double
617 Trajectory::getLength(size_t dimension, size_t derivation) const
618 {
619 if (size() == 0)
620 {
621 return 0;
622 }
623 return getLength(dimension, derivation, begin()->getTimestamp(), rbegin()->getTimestamp());
624 }
625
626 double
627 Trajectory::getLength(size_t dimension,
628 size_t derivation,
629 double startTime,
630 double endTime) const
631 {
632 double length = 0.0;
633 const ordered_view& ordv = dataMap.get<TagOrdered>();
634 ordered_view::iterator itO = ordv.lower_bound(startTime);
635 ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
636 if (itO == ordv.end())
637 {
638 return 0.0;
639 }
640 double prevValue = getState(startTime, dimension, derivation);
641
642 for (; itO != itOEnd && itO != ordv.end(); itO++)
643 {
644 if (itO->getTimestamp() >= endTime)
645 {
646 break;
647 }
648 length += fabs(prevValue - itO->getDeriv(dimension, derivation));
649 prevValue = itO->getDeriv(dimension, derivation);
650 }
651 length += fabs(prevValue - getState(endTime, dimension, derivation));
652 return length;
653 }
654
655 double
656 Trajectory::getSquaredLength(size_t dimension, size_t derivation) const
657 {
658 return getSquaredLength(
659 dimension, derivation, begin()->getTimestamp(), rbegin()->getTimestamp());
660 }
661
662 double
664 size_t derivation,
665 double startTime,
666 double endTime) const
667 {
668 double length = 0.0;
669 const ordered_view& ordv = dataMap.get<TagOrdered>();
670 ordered_view::iterator itO = ordv.lower_bound(startTime);
671 ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
672 if (itO == ordv.end())
673 {
674 return 0.0;
675 }
676
677 double prevValue = itO->getDeriv(dimension, derivation);
678
679 for (; itO != itOEnd; itO++)
680 {
681 length += fabs(pow(prevValue, 2.0) - pow(itO->getDeriv(dimension, derivation), 2.0));
682 prevValue = itO->getDeriv(dimension, derivation);
683 }
684
685 return length;
686 }
687
688 double
689 Trajectory::getMax(size_t dimension, size_t derivation, double startTime, double endTime) const
690 {
691 return getWithFunc(&std::max<double>,
692 -std::numeric_limits<double>::max(),
693 dimension,
694 derivation,
695 startTime,
696 endTime);
697 }
698
699 double
700 Trajectory::getMin(size_t dimension, size_t derivation, double startTime, double endTime) const
701 {
702 return getWithFunc(&std::min<double>,
703 std::numeric_limits<double>::max(),
704 dimension,
705 derivation,
706 startTime,
707 endTime);
708 }
709
710 double
711 Trajectory::getWithFunc(const double& (*foo)(const double&, const double&),
712 double initValue,
713 size_t dimension,
714 size_t derivation,
715 double startTime,
716 double endTime) const
717 {
718 double bestValue = initValue;
719 const ordered_view& ordv = dataMap.get<TagOrdered>();
720 ordered_view::iterator itO = ordv.lower_bound(startTime);
721 ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
722
723 if (itO == ordv.end())
724 {
725 return bestValue;
726 }
727 for (; itO != itOEnd; itO++)
728 {
729 bestValue = foo(bestValue, itO->getDeriv(dimension, derivation));
730 }
731
732 return bestValue;
733 }
734
735 double
736 Trajectory::getAmplitude(size_t dimension,
737 size_t derivation,
738 double startTime,
739 double endTime) const
740 {
741 return getMax(dimension, derivation, startTime, endTime) -
742 getMin(dimension, derivation, startTime, endTime);
743 }
744
745 Ice::DoubleSeq
746 Trajectory::getMinima(size_t dimension,
747 size_t derivation,
748 double startTime,
749 double endTime) const
750 {
751 Ice::DoubleSeq result;
752 const ordered_view& ordv = dataMap.get<TagOrdered>();
753 ordered_view::iterator itO = ordv.lower_bound(startTime);
754 ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
755
756 if (itO == ordv.end())
757 {
758 return result;
759 }
760 double preValue = itO->getDeriv(dimension, derivation);
761 for (; itO != itOEnd;
762
763 )
764 {
765 // double t = itO->getTimestamp();
766 double cur = itO->getDeriv(dimension, derivation);
767 itO++;
768 if (itO == ordv.end())
769 {
770 break;
771 }
772 double next = itO->getDeriv(dimension, derivation);
773 if (cur <= preValue && cur <= next)
774 {
775 result.push_back(cur);
776 }
777 preValue = cur;
778 }
779
780 return result;
781 }
782
783 Ice::DoubleSeq
785 size_t derivation,
786 double startTime,
787 double endTime) const
788 {
789 Ice::DoubleSeq result;
790 const ordered_view& ordv = dataMap.get<TagOrdered>();
791 ordered_view::iterator itO = ordv.lower_bound(startTime);
792 ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
793
794 if (itO == ordv.end())
795 {
796 return result;
797 }
798 double preValue = itO->getDeriv(dimension, derivation);
799 for (; itO != itOEnd;
800
801 )
802 {
803 // double t = itO->getTimestamp();
804 double cur = itO->getDeriv(dimension, derivation);
805 itO++;
806 if (itO == ordv.end())
807 {
808 break;
809 }
810 double next = itO->getDeriv(dimension, derivation);
811 if (cur <= preValue && cur <= next)
812 {
813 result.push_back(itO->getTimestamp());
814 }
815 preValue = cur;
816 }
817
818 return result;
819 }
820
821 Ice::DoubleSeq
822 Trajectory::getMaxima(size_t dimension,
823 size_t derivation,
824 double startTime,
825 double endTime) const
826 {
827 Ice::DoubleSeq result;
828 const ordered_view& ordv = dataMap.get<TagOrdered>();
829 ordered_view::iterator itO = ordv.lower_bound(startTime);
830 ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
831
832 if (itO == ordv.end())
833 {
834 return result;
835 }
836 double preValue = itO->getDeriv(dimension, derivation);
837 for (; itO != itOEnd;
838
839 )
840 {
841 double cur = itO->getDeriv(dimension, derivation);
842 itO++;
843 if (itO == ordv.end())
844 {
845 break;
846 }
847 double next = itO->getDeriv(dimension, derivation);
848 if (cur >= preValue && cur >= next)
849 {
850 result.push_back(cur);
851 }
852 preValue = cur;
853 }
854
855 return result;
856 }
857
858 Ice::DoubleSeq
860 size_t derivation,
861 double startTime,
862 double endTime) const
863 {
864 Ice::DoubleSeq result;
865 const ordered_view& ordv = dataMap.get<TagOrdered>();
866 ordered_view::iterator itO = ordv.lower_bound(startTime);
867 ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
868
869 if (itO == ordv.end())
870 {
871 return result;
872 }
873 double preValue = itO->getDeriv(dimension, derivation);
874 for (; itO != itOEnd;
875
876 )
877 {
878 double cur = itO->getDeriv(dimension, derivation);
879 itO++;
880 if (itO == ordv.end())
881 {
882 break;
883 }
884 double next = itO->getDeriv(dimension, derivation);
885
886 if (cur >= preValue && cur >= next)
887 {
888 result.push_back(itO->getTimestamp());
889 }
890 preValue = cur;
891 }
892
893 return result;
894 }
895
896 std::vector<DoubleSeqPtr>
898 {
899 // ARMARX_INFO << "calcBaseDataAtTimestamp for " << t;
900 // typename timestamp_view::const_iterator it = dataMap.find(t);
901 // if(it != dataMap.end())
902 // return it->data;
903 std::vector<DoubleSeqPtr> result;
904
905 for (size_t dimension = 0; dimension < dim(); dimension++)
906 {
907 double newValue = __interpolate(t, dimension, 0);
908 checkValue(newValue);
909 result.push_back(std::make_shared<Ice::DoubleSeq>(1, newValue));
910 }
911
912 return result;
913 }
914
915 bool
916 Trajectory::dataExists(double t, size_t dimension, size_t derivation) const
917 {
918 typename timestamp_view::iterator it = dataMap.find(t);
919
920 if (it == dataMap.end() || !it->data.at(dimension) ||
921 it->data.at(dimension)->size() <= derivation)
922 {
923 return false;
924 }
925 else
926 {
927 return true;
928 }
929 }
930
931 Trajectory::timestamp_view::iterator
933 {
934 typename timestamp_view::const_iterator it = dataMap.find(t);
935
936 if (it != dataMap.end() && it->data.size() == dim())
937 {
938 bool foundEmpty = false;
939
940 for (auto& i : it->data)
941 {
942 if (!i || i->empty())
943 {
944 foundEmpty = true;
945 break;
946 }
947 }
948
949 if (!foundEmpty)
950 {
951 // ARMARX_INFO << "Was not empty for " << t;
952 return it;
953 }
954 }
955
956 TrajData entry(this);
957 entry.timestamp = t;
958 entry.data.resize(dim());
959 dataMap.insert(entry);
960 it = dataMap.find(t);
961
962 ARMARX_CHECK_EXPRESSION(it != dataMap.end());
963 // const ordered_view& ordv = dataMap.get<TagOrdered>();
964 // typename ordered_view::iterator itOrdered = ordv.iterator_to(*it);
965 it->data = __calcBaseDataAtTimestamp(t);
966
967 return it;
968 }
969
970 std::vector<DoubleSeqPtr>&
972 {
973 typename timestamp_view::const_iterator it = dataMap.find(t);
974
975 if (it == dataMap.end())
976 {
977 // interpolate and insert entry
979 }
980
981
982 return it->data;
983 }
984
985 std::vector<DoubleSeqPtr>
986 Trajectory::getStates(double t) const
987 {
988 typename timestamp_view::const_iterator it = dataMap.find(t);
989
990 if (it == dataMap.end())
991 {
992 // interpolate and return data
994 }
995
996
997 return it->data;
998 }
999
1000 Ice::DoubleSeq
1001 Trajectory::getStates(double t, size_t derivation) const
1002 {
1003 size_t dimensions = dim();
1004 Ice::DoubleSeq result;
1005 result.reserve(dimensions);
1006 for (size_t i = 0; i < dimensions; i++)
1007 {
1008 result.push_back(getState(t, i, derivation));
1009 }
1010
1011 return result;
1012 }
1013
1014 std::map<double, Ice::DoubleSeq>
1015 Trajectory::getStatesAround(double t, size_t derivation, size_t extend) const
1016 {
1017
1018 std::map<double, Ice::DoubleSeq> res;
1019 typename timestamp_view::iterator itMap = dataMap.find(t);
1020
1021 if (itMap != dataMap.end())
1022 {
1023 for (size_t i = 0; i < dim(); i++)
1024 {
1025 res.insert(std::pair<double, Ice::DoubleSeq>(t, {itMap->data[i]->at(derivation)}));
1026 }
1027
1028 return res;
1029 }
1030
1031 const ordered_view& ordv = dataMap.get<TagOrdered>();
1032
1033 typename ordered_view::iterator itNext = ordv.upper_bound(t);
1034
1035 typename ordered_view::iterator itPrev = itNext;
1036
1037 itPrev--;
1038
1039 if (itPrev == ordv.end())
1040 {
1041
1042 throw LocalException("Cannot find value at timestamp ") << t;
1043 }
1044
1045 for (size_t i = 0; i < extend; i++)
1046 {
1047 Ice::DoubleSeq preData = getStates(itPrev->timestamp, derivation);
1048 Ice::DoubleSeq nexData = getStates(itNext->timestamp, derivation);
1049
1050 res.insert(std::pair<double, Ice::DoubleSeq>(itPrev->timestamp, preData));
1051 res.insert(std::pair<double, Ice::DoubleSeq>(itNext->timestamp, nexData));
1052
1053 if (itPrev == ordv.begin() || itNext == ordv.end())
1054 {
1055 std::cout << "Warning: the timestamp is out of the range. "
1056 << "The current result will be returned" << std::endl;
1057 break;
1058 }
1059 itPrev--;
1060 itNext++;
1061 }
1062
1063 return res;
1064 }
1065
1066 Trajectory&
1068 {
1069 size_t dims = traj.dim();
1070 Ice::DoubleSeq timestamps = traj.getTimestamps();
1071
1072 for (size_t d = 0; d < dims; ++d)
1073 {
1074 addPositionsToDimension(d, timestamps, traj.getDimensionData(d));
1075 }
1076
1077 return *this;
1078 }
1079
1080 void
1082 {
1083 size_t newDim = dim() + 1;
1084
1085 typename timestamp_view::iterator itMap = dataMap.begin();
1086
1087 for (; itMap != dataMap.end(); itMap++)
1088 {
1089 itMap->data.resize(newDim);
1090 }
1091 }
1092
1093 void
1094 Trajectory::setEntries(const double t, const size_t dimIndex, const Ice::DoubleSeq& y)
1095 {
1096 typename timestamp_view::iterator itMap = dataMap.find(t);
1097
1098 if (itMap == dataMap.end() || dim() == 0)
1099 {
1100 // double dura = getTimeLength();
1101 TrajData newData(this);
1102 newData.timestamp = t;
1103 newData.data = std::vector<DoubleSeqPtr>(std::max((size_t)1, dim()));
1104 newData.data[dimIndex] = std::make_shared<Ice::DoubleSeq>(y);
1105 dataMap.insert(std::move(newData));
1106 }
1107 else
1108 {
1109 assert(dim() > 0);
1110
1111 while (dim() <= dimIndex)
1112 {
1114 }
1115
1116 itMap->data.resize(dim());
1117 ARMARX_CHECK_GREATER(itMap->data.size(), dimIndex);
1118 itMap->data.at(dimIndex) = std::make_shared<Ice::DoubleSeq>(y);
1119 }
1120 }
1121
1122 void
1123 Trajectory::setPositionEntry(const double t, const size_t dimIndex, const double& y)
1124 {
1125 typename timestamp_view::iterator itMap = dataMap.find(t);
1126
1127 if (itMap == dataMap.end() || dim() == 0)
1128 {
1129 TrajData newData(this);
1130 newData.timestamp = t;
1131 newData.data = std::vector<DoubleSeqPtr>(std::max((size_t)1, dim()));
1132 newData.data[dimIndex] = std::make_shared<Ice::DoubleSeq>(1, y);
1133 dataMap.insert(newData);
1134 }
1135 else
1136 {
1137 assert(dim() > 0);
1138
1139 while (dim() <= dimIndex)
1140 {
1142 }
1143
1144 itMap->data.resize(dim());
1145 itMap->data.at(dimIndex) = std::make_shared<Ice::DoubleSeq>(1, y);
1146 }
1147 }
1148
1149 void
1151 {
1152 const ordered_view& ordv = dataMap.get<TagOrdered>();
1153 typename ordered_view::const_iterator itMap = ordv.begin();
1154
1155 for (; itMap != ordv.end(); itMap++)
1156 {
1157 for (size_t dimension = 0; dimension < dim(); dimension++)
1158 {
1159 if (!itMap->data[dimension])
1160 {
1161 itMap->data[dimension] =
1162 std::make_shared<Ice::DoubleSeq>(__interpolate(itMap, dimension, 0));
1163 }
1164 }
1165 }
1166 }
1167
1168 Ice::DoubleSeq
1170 {
1171 Ice::DoubleSeq result;
1172 result.reserve(size());
1173 const ordered_view& ordv = dataMap.get<TagOrdered>();
1174 typename ordered_view::const_iterator itMap = ordv.begin();
1175
1176 for (; itMap != ordv.end(); itMap++)
1177 {
1178 result.push_back(itMap->timestamp);
1179 }
1180
1181 return result;
1182 }
1183
1184 Ice::FloatSeq
1186 {
1187 Ice::FloatSeq result;
1188 result.reserve(size());
1189 const ordered_view& ordv = dataMap.get<TagOrdered>();
1190 typename ordered_view::const_iterator itMap = ordv.begin();
1191
1192 for (; itMap != ordv.end(); itMap++)
1193 {
1194 result.push_back(itMap->timestamp);
1195 }
1196
1197 return result;
1198 }
1199
1200 Ice::DoubleSeq
1201 Trajectory::getDiscreteDifferentiationForDim(size_t trajDimension, size_t derivation) const
1202 {
1203 if (trajDimension >= dim())
1204 {
1205 throw LocalException("dimension is out of range: ")
1206 << trajDimension << " actual dimensions: " << dim();
1207 }
1208
1209
1210 const ordered_view& ordv = dataMap.get<TagOrdered>();
1211 typename ordered_view::const_iterator itPrev = ordv.begin();
1212
1213 typename ordered_view::const_iterator itCurrent = itPrev;
1214 // itCurrent++;
1215 typename ordered_view::const_iterator itNext = itCurrent;
1216 itNext++;
1217
1218 Ice::DoubleSeq result;
1219
1220 for (; itCurrent != ordv.end();)
1221 {
1222 if (itNext == ordv.end()) // last step-> differentiate between current and prev
1223 {
1224 itNext = itCurrent;
1225 }
1226
1227
1228 // get current data
1229 DoubleSeqPtr prevStatePtr = itPrev->data[trajDimension];
1230 DoubleSeqPtr nextStatePtr = itNext->data[trajDimension];
1231 // differentiateDiscretly now
1232 result.push_back((nextStatePtr->at(derivation) - prevStatePtr->at(derivation)) /
1233 (itNext->timestamp - itPrev->timestamp));
1234 checkValue(*result.rbegin());
1235
1236
1237 itCurrent++, itPrev++, itNext++;
1238
1239 if (itPrev == itCurrent)
1240 {
1241 // first step-> reestablish that current is > prev
1242 itPrev--;
1243 }
1244 }
1245
1246 return result;
1247 }
1248
1249 Ice::DoubleSeq
1250 Trajectory::DifferentiateDiscretly(const Ice::DoubleSeq& timestamps,
1251 const Ice::DoubleSeq& values,
1252 int derivationCount)
1253 {
1254 if (derivationCount < 0)
1255 {
1256 throw LocalException("Negative derivation value is not allowed!");
1257 }
1258
1259 if (derivationCount == 0)
1260 {
1261 return values;
1262 }
1263
1264 Ice::DoubleSeq result;
1265 int size = std::min(timestamps.size(), values.size());
1266
1267 if (size < 2)
1268 {
1269 return values;
1270 }
1271
1272 result.resize(size);
1273
1274 // boundaries
1275 result[0] = (values.at(1) - values.at(0)) / (timestamps.at(1) - timestamps.at(0));
1276 result[size - 1] = (values.at(size - 1) - values.at(size - 2)) /
1277 (timestamps.at(size - 1) - timestamps.at(size - 2));
1278
1279 //#pragma omp parallel for
1280 for (int i = 1; i < size - 1; ++i)
1281 {
1282 result[i] = (values.at(i + 1) - values.at(i - 1)) /
1283 (timestamps.at(i + 1) - timestamps.at(i - 1));
1284 checkValue(result[i]);
1285 }
1286
1287 if (derivationCount > 1) // recursivly differentiate
1288 {
1289 result = DifferentiateDiscretly(timestamps, result, derivationCount - 1);
1290 }
1291
1292 return result;
1293 }
1294
1295 double
1297 size_t trajDimension,
1298 size_t derivation) const
1299 {
1300 if (derivation == 0)
1301 {
1302 return getState(t, trajDimension, derivation);
1303 }
1304
1305 typename timestamp_view::iterator it = dataMap.find(t);
1306
1307 const ordered_view& ordV = dataMap.get<TagOrdered>();
1308 typename ordered_view::iterator itCurrent = ordV.end();
1309
1310 if (it != dataMap.end())
1311 {
1312 itCurrent = ordV.iterator_to(*it);
1313 }
1314
1315 typename ordered_view::iterator itNext = ordV.upper_bound(t); // first element after t
1316
1317 if (it != dataMap.end() && itNext == ordV.end())
1318 {
1319 itNext = itCurrent; // current item is last, set next to current
1320 }
1321 else if (itNext == ordV.end() && it == dataMap.end())
1322 {
1323 throw LocalException() << "Cannot interpolate for t " << t << " no data in trajectory";
1324 }
1325
1326 typename ordered_view::iterator itPrev = itNext;
1327 itPrev--; // now equal to current (if current exists) or before current
1328
1329 if (itCurrent != ordV.end()) // check if current item exists
1330 {
1331 itPrev--; //element in front of t
1332 }
1333
1334 if (itPrev == ordV.end())
1335 {
1336 //element in front of t does not exist
1337 if (itCurrent != ordV.end())
1338 {
1339 itPrev = itCurrent; // set prev element to current
1340 }
1341 else
1342 {
1343 throw LocalException() << "Cannot interpolate for t " << t;
1344 }
1345 }
1346
1347 if (itNext == ordV.end())
1348 {
1349 //element after t does not exist
1350 if (itCurrent != ordV.end())
1351 {
1352 itNext = itCurrent; // set next element to current
1353 }
1354 else
1355 {
1356 throw LocalException() << "Cannot interpolate for t " << t;
1357 }
1358 }
1359
1360 if (itNext == itPrev)
1361 {
1362 throw LocalException()
1363 << "Interpolation failed: the next data and the previous are missing.\nInfo:\n"
1364 << VAROUT(t) << VAROUT(trajDimension) << (getDimensionName(trajDimension)) << " "
1365 << VAROUT(size());
1366 }
1367
1368 // double diff = itNext->data[trajDimension]->at(derivation-1) - itPrev->data[trajDimension]->at(derivation-1);
1369 double tNext;
1370
1371 if (dataExists(itNext->timestamp, trajDimension, derivation - 1) || derivation > 1)
1372 {
1373 tNext = itNext->timestamp;
1374 }
1375 else
1376 {
1377 tNext = t;
1378 }
1379
1380 double next = getState(tNext, trajDimension, derivation - 1);
1381
1382 double tBefore;
1383
1384 if (dataExists(itPrev->timestamp, trajDimension, derivation - 1) || derivation > 1)
1385 {
1386 tBefore = itPrev->timestamp;
1387 }
1388 else
1389 {
1390 tBefore = t;
1391 }
1392
1393 double before = getState(tBefore, trajDimension, derivation - 1);
1394
1395 if (fabs(tNext - tBefore) < 1e-10)
1396 {
1397 throw LocalException()
1398 << "Interpolation failed: the next data and the previous are missing.\nInfo:\n"
1399 << VAROUT(tNext) << VAROUT(tBefore) << VAROUT(t) << VAROUT(trajDimension)
1400 << (getDimensionName(trajDimension)) << VAROUT(size()) << VAROUT(getTimestamps());
1401 }
1402
1403 double duration = tNext - tBefore;
1404
1405 double delta;
1406 if (trajDimension < limitless.size() && limitless.at(trajDimension).enabled)
1407 {
1408 double range =
1409 limitless.at(trajDimension).limitHi - limitless.at(trajDimension).limitLo;
1410
1411 double dist1 = next - before;
1412 double dist2 = next - (before + range);
1413 double dist3 = next - (before - range);
1414
1415 if (fabs(dist1) <= fabs(dist2) && fabs(dist1) <= fabs(dist3))
1416 {
1417 // no issue with bounds
1418 //ARMARX_IMPORTANT << "LIMITLESS deriv: checking dim " << trajDimension << ", prev:" << before << ", next:" << next << ", range:" << range << ", dist1:" << dist1 << ", dist2:" << dist2 << ", dist3:" << dist3;
1419 delta = dist1;
1420 }
1421 else if (fabs(dist2) <= fabs(dist3) && fabs(dist2) <= fabs(dist3))
1422 {
1423 // go over hi bound
1424 //ARMARX_IMPORTANT << "LIMITLESS deriv HIGH: checking dim " << trajDimension << ", prev:" << before << ", next:" << next << ", range:" << range << ", dist1:" << dist1 << ", dist2:" << dist2 << ", dist3:" << dist3;
1425 delta = dist2;
1426 }
1427 else
1428 {
1429 // go over lo bound
1430 //ARMARX_IMPORTANT << "LIMITLESS deriv LOW: checking dim " << trajDimension << ", prev:" << before << ", next:" << next << ", range:" << range << ", dist1:" << dist1 << ", dist2:" << dist2 << ", dist3:" << dist3;
1431 delta = dist3;
1432 }
1433
1434 //ARMARX_IMPORTANT << "LIMITLESS deriv: checking dim " << trajDimension << ": delta is " << delta;
1435 }
1436 else
1437 {
1438 // no limitless joint
1439 delta = next - before;
1440 }
1441
1442 delta = delta / duration;
1443 //ARMARX_IMPORTANT << "LIMITLESS deriv: checking dim " << trajDimension << ": delta/duration is " << delta;
1444 checkValue(delta);
1445 return delta;
1446 }
1447
1448 void
1450 {
1451
1452 for (size_t d = 0; d < dim(); d++)
1453 {
1454 differentiateDiscretlyForDim(d, derivation);
1455 }
1456 }
1457
1458 void
1459 Trajectory::differentiateDiscretlyForDim(size_t trajDimension, size_t derivation)
1460 {
1461 removeDerivation(trajDimension, derivation);
1462 typename ordered_view::iterator itOrd = begin();
1463
1464 for (; itOrd != end(); itOrd++)
1465 {
1466 getState(itOrd->timestamp, trajDimension, derivation);
1467 }
1468 }
1469
1470 void
1472 size_t trajDimension,
1473 size_t sourceDimOfSystemState,
1474 size_t targetDimOfSystemState)
1475 {
1476 const ordered_view& ordv = dataMap.get<TagOrdered>();
1477 typename ordered_view::iterator it = ordv.begin();
1478
1479 if (it == ordv.end())
1480 {
1481 return;
1482 }
1483
1484 it->data[trajDimension]->at(targetDimOfSystemState) = valueAtFirstTimestamp;
1485 double previousValue = valueAtFirstTimestamp;
1486 double previousTimestamp = it->timestamp;
1487
1488 // size_t derivation = double().size();
1489 for (it++; it != ordv.end(); it++)
1490 {
1491 double slope;
1492 if (it->data[trajDimension]->size() > sourceDimOfSystemState)
1493 {
1494 slope = it->data[trajDimension]->at(sourceDimOfSystemState);
1495 }
1496 else
1497 {
1498 slope = 0;
1499 }
1500
1501 double diff = it->timestamp - previousTimestamp;
1502 it->data[trajDimension]->at(targetDimOfSystemState) = previousValue + diff * slope;
1503 previousTimestamp = it->timestamp;
1504 previousValue = it->data[trajDimension]->at(targetDimOfSystemState);
1505 }
1506 }
1507
1508 void
1509 Trajectory::negateDim(size_t trajDimension)
1510 {
1511 if (trajDimension >= dim())
1512 {
1513 throw LocalException("dimension is out of range: ")
1514 << trajDimension << " actual dimensions: " << dim();
1515 }
1516
1517 const ordered_view& ordv = dataMap.get<TagOrdered>();
1518
1519 Trajectory filteredTraj;
1520
1521 for (const auto& it : ordv)
1522 {
1523 (*it.data.at(trajDimension)) *= -1;
1524 }
1525 }
1526
1527 double
1528 Trajectory::__interpolate(double t, size_t dimension, size_t derivation) const
1529 {
1530 typename timestamp_view::const_iterator it = dataMap.find(t);
1531
1532 if (it != dataMap.end() && it->data.size() > dimension && it->data.at(dimension) &&
1533 it->data.at(dimension)->size() > derivation)
1534 {
1535 return it->data.at(dimension)->at(derivation);
1536 }
1537
1538 const ordered_view& ordv = dataMap.get<TagOrdered>();
1539
1540 typename ordered_view::iterator itNext = ordv.upper_bound(t);
1541
1542 typename ordered_view::iterator itPrev = itNext;
1543
1544 itPrev--;
1545
1546 double result = __interpolate(t, itPrev, itNext, dimension, derivation);
1547
1548 checkValue(result);
1549
1550 return result;
1551 }
1552
1553 double
1554 Trajectory::__interpolate(typename ordered_view::const_iterator itMap,
1555 size_t dimension,
1556 size_t derivation) const
1557 {
1558 typename ordered_view::iterator itPrev = itMap;
1559 itPrev--;
1560 typename ordered_view::iterator itNext = itMap;
1561 itNext++;
1562 return __interpolate(itMap->timestamp, itPrev, itNext, dimension, derivation);
1563 }
1564
1565 double
1567 typename ordered_view::const_iterator itPrev,
1568 typename ordered_view::const_iterator itNext,
1569 size_t dimension,
1570 size_t derivation) const
1571 {
1572 const ordered_view& ordView = dataMap.get<TagOrdered>();
1573 double previous = 0;
1574 double next = 0;
1575
1576 // find previous SystemState that exists for that dimension
1577 while (itPrev != ordView.end() && (itPrev->data.at(dimension) == nullptr ||
1578 itPrev->data.at(dimension)->size() <= derivation))
1579 {
1580 itPrev--;
1581 }
1582
1583 if (itPrev != ordView.end())
1584 {
1585 // ARMARX_INFO << "Found prev state at " << itPrev->timestamp;
1586 ARMARX_CHECK_NOT_EQUAL(t, itPrev->timestamp)
1587 << VAROUT(t) << VAROUT(itPrev->timestamp) << VAROUT(*this);
1588 previous = getState(itPrev->timestamp, dimension, derivation);
1589 }
1590
1591 // find next SystemState that exists for that dimension
1592 while (itNext != ordView.end() &&
1593 (!itNext->data.at(dimension) || itNext->data.at(dimension)->size() <= derivation))
1594 {
1595 itNext++;
1596 }
1597
1598 if (itNext != ordView.end())
1599 {
1600 // ARMARX_INFO << "Found next state at " << itNext->timestamp;
1601 ARMARX_CHECK_NOT_EQUAL(t, itNext->timestamp) << VAROUT(t) << VAROUT(itNext->timestamp);
1602 next = getState(itNext->timestamp, dimension, derivation);
1603 }
1604
1605
1606 if (itNext == ordView.end() && itPrev == ordView.end())
1607 {
1608 throw LocalException()
1609 << "Cannot find next or prev values in dim " << dimension << " at timestamp " << t;
1610 }
1611
1612 if (itNext == ordView.end())
1613 {
1614 // ARMARX_INFO << "Extrapolating to the right from " << itPrev->timestamp;
1615 return getState(itPrev->timestamp, dimension, derivation) +
1616 getState(itPrev->timestamp, dimension, derivation + 1) * (t - itPrev->timestamp);
1617 }
1618 else if (itPrev == ordView.end())
1619 {
1620 // ARMARX_INFO << "Extrapolating to the left from " << itNext->timestamp;
1621 return getState(itNext->timestamp, dimension, derivation) -
1622 getState(itNext->timestamp, dimension, derivation + 1) * (itNext->timestamp - t);
1623 }
1624 else
1625 {
1626 // linear interpolation
1627
1628 float f = math::MathUtils::ILerp(itPrev->timestamp, itNext->timestamp, t);
1629
1630 if (dimension < limitless.size() && limitless.at(dimension).enabled)
1631 {
1632 return math::MathUtils::AngleLerp(previous, next, f);
1633 }
1634 else
1635 {
1636 return math::MathUtils::Lerp(previous, next, f);
1637 }
1638 }
1639 }
1640
1641 void
1642 Trajectory::gaussianFilter(double filterRadius)
1643 {
1644 const ordered_view& ordv = dataMap.get<TagOrdered>();
1645 Trajectory filteredTraj;
1646 filteredTraj.setDimensionNames(getDimensionNames());
1647 filteredTraj.setLimitless(getLimitless());
1648 Ice::DoubleSeq timestamps = getTimestamps();
1649
1650 for (size_t d = 0; d < dim(); d++)
1651 {
1652 Ice::DoubleSeq entries;
1653
1654 for (typename ordered_view::iterator it = ordv.begin(); it != ordv.end(); it++)
1655 {
1656 entries.push_back(__gaussianFilter(filterRadius, it, d, 0));
1657 }
1658
1659 filteredTraj.addDimension(entries, timestamps);
1660 }
1661
1662 CopyData(filteredTraj, *this);
1663 }
1664
1665 double
1666 Trajectory::__gaussianFilter(double filterRadiusInTime,
1667 typename ordered_view::iterator centerIt,
1668 size_t trajNum,
1669 size_t dim)
1670 {
1671 const ordered_view& ordView = dataMap.get<TagOrdered>();
1672 const double sigma = filterRadiusInTime / 2.5;
1673
1674 double weightedSum = 0;
1675 double sumOfWeight = 0;
1676 ordered_view::iterator start = centerIt;
1677
1678 const double sqrt2PI = sqrt(2 * M_PI);
1679
1680 for (int sign = -1; sign < 2; sign += 2)
1681 {
1682 for (ordered_view::iterator it = start;
1683 it != ordView.end() &&
1684 fabs(it->timestamp - centerIt->timestamp) <= fabs(filterRadiusInTime * 2);)
1685 {
1686 double value;
1687 value = it->getDeriv(trajNum, dim); //data[trajNum]->at(dim);
1688 double diff = (it->timestamp - centerIt->timestamp);
1689 double squared = diff * diff;
1690 const double gaussValue = exp(-squared / (2 * sigma * sigma)) / (sigma * sqrt2PI);
1691 sumOfWeight += gaussValue;
1692 weightedSum += gaussValue * value;
1693
1694 if (sign > 0)
1695 {
1696 it++;
1697 }
1698 else
1699 {
1700 it--;
1701 }
1702
1703 checkValue(weightedSum);
1704 }
1705
1706 start++; // skip center value in second loop iteration
1707 }
1708
1709 double result;
1710 result = weightedSum / sumOfWeight;
1711 checkValue(result);
1712 return result;
1713 }
1714
1715 void
1716 Trajectory::CopyData(const Trajectory& source, Trajectory& destination)
1717 {
1718 if (&source == &destination)
1719 {
1720 return;
1721 }
1722
1723 destination.clear();
1724
1725 Ice::DoubleSeq timestamps = source.getTimestamps();
1726
1727 for (size_t dim = 0; dim < source.dim(); dim++)
1728 {
1729 destination.addDimension(source.getDimensionData(dim), timestamps);
1730 }
1731 CopyMetaData(source, destination);
1732 }
1733
1734 void
1736 {
1737 destination.setDimensionNames(source.getDimensionNames());
1738
1739 destination.setLimitless(source.getLimitless());
1740 }
1741
1742 void
1743 Trajectory::clear(bool keepMetaData)
1744 {
1745 dataMap.erase(dataMap.begin(), dataMap.end());
1746 if (!keepMetaData)
1747 {
1748 dimensionNames.clear();
1749 limitless.clear();
1750 }
1751 }
1752
1753 Ice::DoubleSeq
1754 Trajectory::GenerateTimestamps(double startTime, double endTime, double stepSize)
1755 {
1756 if (startTime >= endTime)
1757 {
1758 throw LocalException("startTime must be smaller than endTime.");
1759 }
1760
1761 Ice::DoubleSeq result;
1762 size_t size = std::round((endTime - startTime) / stepSize) + 1;
1763 stepSize = (endTime - startTime) / (size - 1);
1764 result.reserve(size);
1765
1766 double currentTimestamp = startTime;
1767 size_t i = 0;
1768
1769 while (i < size)
1770 {
1771 result.push_back(currentTimestamp);
1772 currentTimestamp += stepSize;
1773 i++;
1774 }
1775 ARMARX_CHECK_EQUAL(result.size(), size)
1776 << VAROUT(startTime) << VAROUT(endTime) << VAROUT(stepSize);
1777 return result;
1778 }
1779
1780 Ice::DoubleSeq
1781 Trajectory::NormalizeTimestamps(const Ice::DoubleSeq& timestamps,
1782 const double startTime,
1783 const double endTime)
1784 {
1785 Ice::DoubleSeq normTimestamps;
1786 normTimestamps.resize(timestamps.size());
1787 const double minValue = *timestamps.begin();
1788 const double maxValue = *timestamps.rbegin();
1789 const double duration = maxValue - minValue;
1790
1791 for (size_t i = 0; i < timestamps.size(); i++)
1792 {
1793 normTimestamps[i] =
1794 startTime + (timestamps.at(i) - minValue) / duration * (endTime - startTime);
1795 }
1796
1797 return normTimestamps;
1798 }
1799
1802 const double startTime,
1803 const double endTime)
1804 {
1805
1806 if (traj.size() <= 1 ||
1807 (traj.begin()->timestamp == startTime && traj.rbegin()->timestamp == endTime))
1808 {
1809 return traj; // already normalized
1810 }
1811
1812
1813 Ice::DoubleSeq timestamps = traj.getTimestamps();
1814
1815
1816 Ice::DoubleSeq normTimestamps = NormalizeTimestamps(timestamps, startTime, endTime);
1817 Trajectory normExampleTraj;
1818
1819 for (size_t dim = 0; dim < traj.dim(); dim++)
1820 {
1821 Ice::DoubleSeq dimensionData = traj.getDimensionData(dim);
1822 normExampleTraj.addDimension(dimensionData, normTimestamps);
1823 }
1824 normExampleTraj.setDimensionNames(traj.getDimensionNames());
1825 normExampleTraj.setLimitless(traj.getLimitless());
1826 return normExampleTraj;
1827 }
1828
1830 Trajectory::normalize(const double startTime, const double endTime)
1831 {
1832 Trajectory normTraj = NormalizeTimestamps(*this, startTime, endTime);
1833 TrajectoryPtr newTraj = new Trajectory(normTraj);
1834 return newTraj;
1835 }
1836
1839 double maxAcceleration,
1840 double maxDeviation,
1841 const IceUtil::Time& timestep)
1842 {
1843 Eigen::VectorXd maxVelocities = Eigen::VectorXd::Constant(dim(), maxVelocity);
1844 Eigen::VectorXd maxAccelerations = Eigen::VectorXd::Constant(dim(), maxAcceleration);
1846 maxVelocities, maxAccelerations, maxDeviation, timestep);
1847 }
1848
1850 Trajectory::calculateTimeOptimalTrajectory(const Eigen::VectorXd& maxVelocities,
1851 const Eigen::VectorXd& maxAccelerations,
1852 double maxDeviation,
1853 IceUtil::Time const& timestep)
1854 {
1855
1856 bool hasLimitlessDimension = false;
1857 for (auto l : limitless)
1858 {
1859 hasLimitlessDimension |= l.enabled;
1860 }
1861
1862 TrajectoryPtr unfoldedTraj;
1863 if (hasLimitlessDimension)
1864 {
1865 unfoldedTraj = new Trajectory(*this);
1867 }
1868
1869
1870 auto timestepValue = timestep.toSecondsDouble();
1871 std::list<Eigen::VectorXd> waypointList;
1872 auto dimensions = dim();
1873 for (auto& waypoint : hasLimitlessDimension ? *unfoldedTraj : *this)
1874 {
1875 auto positions = waypoint.getPositions();
1876 waypointList.push_back(Eigen::Map<Eigen::VectorXd>(positions.data(), dimensions));
1877 }
1878
1879 VirtualRobot::TimeOptimalTrajectory timeOptimalTraj(
1880 VirtualRobot::Path(waypointList, maxDeviation),
1881 maxVelocities,
1882 maxAccelerations,
1883 timestepValue);
1884 ARMARX_CHECK_EXPRESSION(timeOptimalTraj.isValid());
1885
1886
1887 TrajectoryPtr newTraj = new Trajectory();
1888
1889 Ice::DoubleSeq newTimestamps;
1890 double duration = timeOptimalTraj.getDuration();
1891 newTimestamps.reserve(duration / timestepValue + 1);
1892 for (double t = 0.0; t < duration; t += timestepValue)
1893 {
1894 newTimestamps.push_back(t);
1895 }
1896 newTimestamps.push_back(duration);
1897
1898 for (size_t d = 0; d < dimensionNames.size(); d++)
1899 {
1900 Ice::DoubleSeq position;
1901 position.reserve(newTimestamps.size());
1902 for (double t = 0.0; t < duration; t += timestepValue)
1903 {
1904 position.push_back(timeOptimalTraj.getPosition(t)[d]);
1905 }
1906 position.push_back(timeOptimalTraj.getPosition(duration)[d]);
1907 newTraj->addDimension(position, newTimestamps, dimensionNames.at(d));
1908
1909 Ice::DoubleSeq derivs;
1910 derivs.reserve(newTimestamps.size());
1911
1912 for (double t = 0.0; t < duration; t += timestepValue)
1913 {
1914 derivs.clear();
1915 derivs.push_back(timeOptimalTraj.getPosition(t)[d]);
1916 derivs.push_back(timeOptimalTraj.getVelocity(t)[d]);
1917 newTraj->addDerivationsToDimension(d, t, derivs);
1918 }
1919 derivs.clear();
1920 derivs.push_back(timeOptimalTraj.getPosition(duration)[d]);
1921 derivs.push_back(timeOptimalTraj.getVelocity(duration)[d]);
1922 newTraj->addDerivationsToDimension(d, duration, derivs);
1923 }
1924 newTraj->setLimitless(limitless);
1925 if (hasLimitlessDimension)
1926 {
1928 }
1929 return newTraj;
1930 }
1931
1932 size_t
1933 Trajectory::addDimension(const Ice::DoubleSeq& values,
1934 const Ice::DoubleSeq& timestamps,
1935 const std::string name)
1936 {
1937
1938 const auto& tempTimestamps =
1939 timestamps.size() > 0 ? timestamps : GenerateTimestamps(values);
1940
1941 size_t newDimIndex = dim();
1942
1944
1945 addPositionsToDimension(newDimIndex, values, tempTimestamps);
1946 if (newDimIndex < dimensionNames.size())
1947 {
1948 dimensionNames.at(newDimIndex) = name;
1949 }
1950 else
1951 {
1952 dimensionNames.push_back(name);
1953 }
1954 return newDimIndex;
1955 }
1956
1957 void
1959 {
1960 typename timestamp_view::iterator itMap = dataMap.begin();
1961
1962 for (; itMap != dataMap.end(); itMap++)
1963 {
1964 std::vector<DoubleSeqPtr>& data = itMap->data;
1965
1966 if (dimension < data.size())
1967 {
1968 data.erase(data.begin() + dimension);
1969 }
1970 }
1971 if (dimension < dimensionNames.size())
1972 {
1973 dimensionNames.erase(dimensionNames.begin() + dimension);
1974 }
1975 }
1976
1977 void
1979 {
1980 typename timestamp_view::iterator itMap = dataMap.begin();
1981
1982 for (; itMap != dataMap.end(); itMap++)
1983 {
1984 std::vector<DoubleSeqPtr>& data = itMap->data;
1985
1986 for (auto& vec : data)
1987 {
1988 if (derivation + 1 < vec->size())
1989 {
1990 vec->resize(derivation);
1991 }
1992 }
1993 }
1994 }
1995
1996 void
1997 Trajectory::removeDerivation(size_t dimension, size_t derivation)
1998 {
1999 typename timestamp_view::iterator itMap = dataMap.begin();
2000
2001 for (; itMap != dataMap.end(); itMap++)
2002 {
2003 std::vector<DoubleSeqPtr>& data = itMap->data;
2004
2005 if (data.size() > dimension && derivation + 1 < data.at(dimension)->size())
2006 {
2007 data.at(dimension)->resize(derivation);
2008 }
2009 }
2010 }
2011
2012 Trajectory::ordered_view::const_iterator
2014 {
2015 return dataMap.get<TagOrdered>().begin();
2016 }
2017
2018 Trajectory::ordered_view::const_iterator
2020 {
2021 return dataMap.get<TagOrdered>().end();
2022 }
2023
2024 Trajectory::ordered_view::const_reverse_iterator
2026 {
2027 return dataMap.get<TagOrdered>().rbegin();
2028 }
2029
2030 Trajectory::ordered_view::const_reverse_iterator
2032 {
2033 return dataMap.get<TagOrdered>().rend();
2034 }
2035
2036 std::vector<DoubleSeqPtr>&
2038 {
2039 return getStates(timestamp);
2040 }
2041
2042 void
2044 const Ice::DoubleSeq& values,
2045 const Ice::DoubleSeq& timestamps)
2046 {
2047 if (dimension >= dim() && dim() > 0)
2048 {
2049 addDimension(values, timestamps);
2050 }
2051 else
2052 {
2053 ARMARX_CHECK_EXPRESSION(timestamps.size() == values.size())
2054 << timestamps.size() << ", " << values.size();
2055
2056 for (size_t i = 0; i < timestamps.size(); ++i)
2057 {
2058 checkValue(timestamps[i]);
2059 checkValue(values[i]);
2060 setPositionEntry(timestamps[i], dimension, values[i]);
2061 }
2062 }
2063 }
2064
2065 void
2067 const double t,
2068 const Ice::DoubleSeq& derivs)
2069 {
2070 setEntries(t, dimension, derivs);
2071 }
2072
2074 {
2075 trajectory = traj;
2076 }
2077
2080 {
2081 return data.at(dim);
2082 }
2083
2084 double
2086 {
2087 return timestamp;
2088 }
2089
2090 double
2092 {
2093 return getDeriv(dim, 0);
2094 }
2095
2096 Eigen::VectorXf
2098 {
2099 if (!trajectory)
2100 {
2101 throw LocalException("Ptr to trajectory is NULL");
2102 }
2103 size_t numDim = trajectory->dim();
2104 Eigen::VectorXf result(numDim);
2105 for (std::size_t i = 0; i < numDim; ++i)
2106 {
2107 result(i) = getPosition(i);
2108 }
2109 return result;
2110 }
2111
2112 Eigen::VectorXd
2114 {
2115 if (!trajectory)
2116 {
2117 throw LocalException("Ptr to trajectory is NULL");
2118 }
2119 size_t numDim = trajectory->dim();
2120 Eigen::VectorXd result(numDim);
2121 for (std::size_t i = 0; i < numDim; ++i)
2122 {
2123 result(i) = getPosition(i);
2124 }
2125 return result;
2126 }
2127
2128 double
2129 Trajectory::TrajData::getDeriv(size_t dim, size_t derivation) const
2130 {
2131 if (!trajectory)
2132 {
2133 throw LocalException("Ptr to trajectory is NULL");
2134 }
2135 return trajectory->getState(timestamp, dim, derivation);
2136 }
2137
2138 const std::vector<DoubleSeqPtr>&
2140 {
2141 return data;
2142 }
2143
2144 void
2146 {
2147 const ordered_view& ordv = dataMap.get<TagOrdered>();
2148 typename ordered_view::const_iterator itMap = ordv.begin();
2149 Trajectory shiftedTraj;
2150 CopyMetaData(*this, shiftedTraj);
2151 auto d = dim();
2152 for (; itMap != ordv.end(); itMap++)
2153 {
2154 for (size_t i = 0; i < d; ++i)
2155 {
2156 shiftedTraj.setEntries(itMap->timestamp + shift, i, *itMap->getData().at(i));
2157 }
2158 }
2159 // dataMap.swap(shiftedTraj.dataMap);
2160 *this = shiftedTraj;
2161 }
2162
2163 void
2164 Trajectory::shiftValue(const Ice::DoubleSeq& shift)
2165 {
2166 if (shift.size() > dim())
2167 {
2168 throw LocalException("dimension is out of range: ")
2169 << shift.size() << " actual dimensions: " << dim();
2170 }
2171
2172
2173 for (size_t dimension = 0; dimension < dim(); dimension++)
2174 {
2175 const ordered_view& ordv = dataMap.get<TagOrdered>();
2176 typename ordered_view::const_iterator itMap = ordv.begin();
2177
2178 for (; itMap != ordv.end(); itMap++)
2179 {
2180 itMap->data[dimension]->at(0) += shift[dimension];
2181 }
2182 }
2183 }
2184
2185 void
2186 Trajectory::scaleValue(const Ice::DoubleSeq& factor)
2187 {
2188 if (factor.size() > dim())
2189 {
2190 throw LocalException("dimension is out of range: ")
2191 << factor.size() << " actual dimensions: " << dim();
2192 }
2193
2194
2195 for (size_t dimension = 0; dimension < dim(); dimension++)
2196 {
2197 const ordered_view& ordv = dataMap.get<TagOrdered>();
2198 typename ordered_view::const_iterator itMap = ordv.begin();
2199
2200 for (; itMap != ordv.end(); itMap++)
2201 {
2202 itMap->data[dimension]->at(0) *= factor[dimension];
2203 }
2204 }
2205 }
2206
2207 void
2208 Trajectory::setLimitless(const LimitlessStateSeq& limitlessStates)
2209 {
2210 limitless = limitlessStates;
2211 }
2212
2213 LimitlessStateSeq
2215 {
2216 return limitless;
2217 }
2218
2219
2220} // namespace armarx
std::string timestamp()
#define M_PI
Definition MathTools.h:17
#define VAROUT(x)
static void UnfoldLimitlessJointPositions(TrajectoryPtr traj)
static void FoldLimitlessJointPositions(TrajectoryPtr traj)
The Trajectory class represents n-dimensional sampled trajectories.
Definition Trajectory.h:77
void shiftValue(const Ice::DoubleSeq &shift)
void negateDim(size_t trajDimension)
negateDim changes the sign of all values of the given dimension.
double getMax(size_t dimension, size_t derivation, double startTime, double endTime) const
double __interpolate(typename ordered_view::const_iterator itMap, size_t dimension, size_t derivation) const
static Ice::DoubleSeq DifferentiateDiscretly(const Ice::DoubleSeq &timestamps, const Ice::DoubleSeq &values, int derivationCount=1)
Trajectory & operator=(const Trajectory &source)
void ice_postUnmarshal() override
boost::multi_index::multi_index_container< TrajData, boost::multi_index::indexed_by< boost::multi_index::hashed_unique< boost::multi_index::tag< TagTimestamp >, boost::multi_index::member< TrajData, double, &TrajData::timestamp > >, boost::multi_index::ordered_unique< boost::multi_index::tag< TagOrdered >, boost::multi_index::member< TrajData, double, &TrajData::timestamp > > > > TrajDataContainer
Definition Trajectory.h:211
TrajDataContainer & data()
double getState(double t, size_t dim=0, size_t derivation=0)
void setEntries(const double t, const size_t dimIndex, const Ice::DoubleSeq &y)
size_t size() const
Returns number of data entries (i.e.
Ice::DoubleSeq getMinima(size_t dimension, size_t derivation, double startTime, double endTime) const
Calculate all minima.
std::string output(const Ice::Current &c=Ice::emptyCurrent) const override
void setPositionEntry(const double t, const size_t dimIndex, const double &y)
const Ice::StringSeq & getDimensionNames() const
double getMin(size_t dimension, size_t derivation, double startTime, double endTime) const
void removeDerivation(size_t derivation)
double getLength(size_t derivation=0) const
Returns the sum of a all subsequent distances of the entries in the trajectories over all dimensions.
VariantDataClassPtr clone(const Ice::Current &c=Ice::emptyCurrent) const override
void differentiateDiscretly(size_t derivation)
void serialize(const ObjectSerializerBasePtr &obj, const Ice::Current &=Ice::emptyCurrent) const override
ordered_view::const_iterator begin() const
Iterators that iterates in incremental order of the timestamps through the trajectory.
std::vector< DoubleSeqPtr > __calcBaseDataAtTimestamp(const double &t) const
timestamp_view::iterator __fillBaseDataAtTimestamp(const double &t)
std::vector< Ice::DoubleSeq > getAllStates(double t, int maxDeriv=1)
double getTimeLength() const
Difference between biggest and smallest timestamp.
void addPositionsToDimension(size_t dimension, const Ice::DoubleSeq &values, const Ice::DoubleSeq &timestamps)
void addDerivationsToDimension(size_t dimension, const double t, const Ice::DoubleSeq &derivs)
TrajDataContainer dataMap
Definition Trajectory.h:530
ordered_view::const_iterator end() const
Ice::DoubleSeq getDerivations(double t, size_t dimension, size_t derivations) const
bool validate(const Ice::Current &c=Ice::emptyCurrent) override
size_t addDimension(const Ice::DoubleSeq &values, const Ice::DoubleSeq &timestamps=Ice::DoubleSeq(), const std::string name="")
double getDiscretDifferentiationForDimAtT(double t, size_t trajDimension, size_t derivation) const
ordered_view::const_reverse_iterator rend() const
void differentiateDiscretlyForDim(size_t trajDimension, size_t derivation)
std::vector< DoubleSeqPtr > & getStates(double t)
~Trajectory() override
LimitlessStateSeq getLimitless() const
static Trajectory NormalizeTimestamps(const Trajectory &traj, const double startTime=0.0, const double endTime=1.0)
void scaleValue(const Ice::DoubleSeq &factor)
Eigen::VectorXd getDimensionDataAsEigen(size_t dimension, size_t derivation) const
void reconstructFromDerivativeForDim(double valueAtFirstTimestamp, size_t trajDimension, size_t sourceDimOfSystemState, size_t targetDimOfSystemState)
Eigen::MatrixXd toEigen(size_t derivation, double startTime, double endTime) const
Ice::DoubleSeq getMinimaTimestamps(size_t dimension, size_t derivation, double startTime, double endTime) const
void clear(bool keepMetaData=false)
size_t dim() const
dim returns the trajectory dimension count for this trajectory (e.g.
double getWithFunc(const double &(*foo)(const double &, const double &), double initValue, size_t dimension, size_t derivation, double startTime, double endTime) const
Ice::Int getType(const Ice::Current &c=Ice::emptyCurrent) const override
Ice::ObjectPtr ice_clone() const override
double getAmplitude(size_t dimension, size_t derivation, double startTime, double endTime) const
Ice::DoubleSeq getMaximaTimestamps(size_t dimension, size_t derivation, double startTime, double endTime) const
std::string getDimensionName(size_t dim) const
void setDimensionNames(const Ice::StringSeq dimNames)
Definition Trajectory.h:508
Ice::DoubleSeq getDimensionData(size_t dimension, size_t derivation=0) const
getDimensionData gets all entries for one dimensions with order of increasing timestamps
ordered_view::const_reverse_iterator rbegin() const
double __gaussianFilter(double filterRadius, typename ordered_view::iterator centerIt, size_t trajNum, size_t dim)
Ice::DoubleSeq getDiscreteDifferentiationForDim(size_t trajDimension, size_t derivation) const
Ice::FloatSeq getTimestampsFloat() const
void shiftTime(double shift)
Ice::DoubleSeq getTimestamps() const
void deserialize(const ObjectSerializerBasePtr &, const Ice::Current &=Ice::emptyCurrent) override
TrajectoryPtr calculateTimeOptimalTrajectory(double maxVelocity, double maxAcceleration, double maxDeviation, IceUtil::Time const &timestep)
typename boost::multi_index::index< TrajDataContainer, TagOrdered >::type ordered_view
Definition Trajectory.h:214
TrajectoryPtr normalize(const double startTime=0.0, const double endTime=1.0)
void setLimitless(const LimitlessStateSeq &limitlessStates)
void ice_preMarshal() override
static void CopyMetaData(const Trajectory &source, Trajectory &destination)
void removeDimension(size_t dimension)
TrajectoryPtr cloneMetaData() const
static Ice::DoubleSeq GenerateTimestamps(double startTime=0.0, double endTime=1.0, double stepSize=0.001)
TrajectoryPtr getPart(double startTime, double endTime, size_t numberOfDerivations=0) const
std::vector< DoubleSeqPtr > & operator[](double timestamp)
bool dataExists(double t, size_t dimension=0, size_t derivation=0) const
Trajectory & operator+=(const Trajectory traj)
static void CopyData(const Trajectory &source, Trajectory &destination)
double getSquaredLength(size_t dimension, size_t derivation) const
Ice::DoubleSeq getMaxima(size_t dimension, size_t derivation, double startTime, double endTime) const
std::map< double, Ice::DoubleSeq > getStatesAround(double t, size_t derivation, size_t extend) const
void gaussianFilter(double filterRadius)
gaussianFilter smoothes the trajectory
static float Lerp(float a, float b, float f)
Definition MathUtils.h:185
static float ILerp(float a, float b, float f)
Definition MathUtils.h:197
static float AngleLerp(float a, float b, float f)
Definition MathUtils.h:209
#define ARMARX_CHECK_GREATER(lhs, rhs)
This macro evaluates whether lhs is greater (>) than rhs and if it turns out to be false it will thro...
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
#define ARMARX_CHECK_NOT_EQUAL(lhs, rhs)
This macro evaluates whether lhs is inequal (!=) rhs and if it turns out to be false it will throw an...
#define ARMARX_CHECK_EQUAL(lhs, rhs)
This macro evaluates whether lhs is equal (==) rhs and if it turns out to be false it will throw an E...
const VariantTypeId Trajectory
Definition Trajectory.h:44
This file offers overloads of toIce() and fromIce() functions for STL container types.
std::shared_ptr< Ice::DoubleSeq > DoubleSeqPtr
Definition Trajectory.h:49
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
IceInternal::Handle< Trajectory > TrajectoryPtr
Definition Trajectory.h:52
void checkValue(const T &value)
IceInternal::Handle< AbstractObjectSerializer > AbstractObjectSerializerPtr
T sign(T t)
Definition algorithm.h:214
Eigen::VectorXd getPositionsAsVectorXd() const
std::vector< DoubleSeqPtr > data
Definition Trajectory.h:182
double getDeriv(size_t dim, size_t derivation) const
Eigen::VectorXf getPositionsAsVectorXf() const
double getPosition(size_t dim) const
const std::vector< DoubleSeqPtr > & getData() const
DoubleSeqPtr operator[](size_t dim) const