diff --git a/source/RobotAPI/interface/CMakeLists.txt b/source/RobotAPI/interface/CMakeLists.txt
index 1bd39e90ff1fa82748c5057ca0842cc84a44361a..044aadda547e4b93c3b1672a85af91a208fec47f 100644
--- a/source/RobotAPI/interface/CMakeLists.txt
+++ b/source/RobotAPI/interface/CMakeLists.txt
@@ -17,6 +17,7 @@ set(SLICE_FILES
     core/FramedPoseBase.ice
     core/RobotState.ice
     core/RobotStateObserverInterface.ice
+    core/Trajectory.ice
 
     selflocalisation/SelfLocalisationProcess.ice
 
diff --git a/source/RobotAPI/interface/core/Trajectory.ice b/source/RobotAPI/interface/core/Trajectory.ice
new file mode 100644
index 0000000000000000000000000000000000000000..daeb1ce6fca713dab8cc238f90a495aa9380d92d
--- /dev/null
+++ b/source/RobotAPI/interface/core/Trajectory.ice
@@ -0,0 +1,55 @@
+/*
+* This file is part of ArmarX.
+*
+* ArmarX is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* ArmarX is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* @package    ArmarX::RobotAPI
+* @author     Mirko Waechter
+* @copyright  2016 Humanoids Group, HIS, KIT
+* @license    http://www.gnu.org/licenses/gpl-2.0.txt
+*             GNU General Public License
+*/
+
+#ifndef _ARMARX_ROBOTAPI_TRAJECTORY_SLICE_
+#define _ARMARX_ROBOTAPI_TRAJECTORY_SLICE_
+
+#include <ArmarXCore/interface/observers/VariantBase.ice>
+#include <ArmarXCore/interface/core/BasicTypes.ice>
+
+module armarx
+{
+    sequence<DoubleSeqSeq> DoubleSeqSeqSeq;
+
+        /**
+        * [TrajectoryBase] defines a n-dimension trajectory with n deriviations.
+        *
+        */
+    ["cpp:virtual"]
+    class TrajectoryBase extends VariantDataClass
+    {
+        ["protected"]
+        Ice::StringSeq dimensionNames;
+        /**
+         * first vector dimension is the frame of the trajectory
+         * second vector dimension is dimension of trajectory (e.g. which joint).
+         * third vector dimension is the derivation of the trajectory (position, velocity, acceleration)
+         * data might be incomplete (not all dimension 3 vector might have values)
+        */
+        ["protected"] DoubleSeqSeqSeq dataVec;
+        ["protected"] Ice::DoubleSeq timestamps;
+    };
+
+
+};
+
+#endif
diff --git a/source/RobotAPI/libraries/core/CMakeLists.txt b/source/RobotAPI/libraries/core/CMakeLists.txt
index 05a4af6d9f1f88c93349ee33c25da9464368053a..9b50618c86521727b69bb49fa1ea9231cfe42208 100644
--- a/source/RobotAPI/libraries/core/CMakeLists.txt
+++ b/source/RobotAPI/libraries/core/CMakeLists.txt
@@ -22,6 +22,7 @@ set(LIBS RobotAPIInterfaces ArmarXCoreObservers ArmarXCoreStatechart ArmarXCoreE
 
 set(LIB_FILES
     PIDController.cpp
+    Trajectory.cpp
     Pose.cpp
     FramedPose.cpp
     LinkedPose.cpp
@@ -39,6 +40,8 @@ set(LIB_FILES
 set(LIB_HEADERS
     EigenStl.h
     PIDController.h
+    Trajectory.h
+    VectorHelpers.h
     Pose.h
     FramedPose.h
     LinkedPose.h
@@ -63,5 +66,6 @@ set(LIB_HEADERS
     math/MatrixHelpers.h
 )
 
+add_subdirectory(test)
 
 armarx_add_library("${LIB_NAME}"  "${LIB_FILES}" "${LIB_HEADERS}" "${LIBS}")
diff --git a/source/RobotAPI/libraries/core/RobotAPIObjectFactories.h b/source/RobotAPI/libraries/core/RobotAPIObjectFactories.h
index 81ff0980712a4ffe79d12c7b2a4d0a91cdcd7a17..6298a152bf44c0f0b3f9b1f2c2a027e16379ab79 100644
--- a/source/RobotAPI/libraries/core/RobotAPIObjectFactories.h
+++ b/source/RobotAPI/libraries/core/RobotAPIObjectFactories.h
@@ -23,6 +23,8 @@
 #ifndef _ARMARX_ROBOTAPI_OBJECT_FACTORIES_H
 #define _ARMARX_ROBOTAPI_OBJECT_FACTORIES_H
 
+#include "Trajectory.h"
+
 #include <ArmarXCore/core/system/FactoryCollectionBase.h>
 #include <RobotAPI/interface/core/PoseBase.h>
 #include <RobotAPI/interface/core/RobotState.h>
@@ -183,7 +185,7 @@ namespace armarx
                 add<armarx::MatrixPercentileFilterBase, armarx::filters::MatrixPercentileFilter>(map);
                 add<armarx::MatrixPercentilesFilterBase, armarx::filters::MatrixPercentilesFilter>(map);
                 add<armarx::MatrixCumulativeFrequencyFilterBase, armarx::filters::MatrixCumulativeFrequencyFilter>(map);
-
+                add<armarx::TrajectoryBase, armarx::Trajectory>(map);
                 return map;
             }
             static const FactoryCollectionBaseCleanUp RobotAPIObjectFactoriesVar;
diff --git a/source/RobotAPI/libraries/core/Trajectory.cpp b/source/RobotAPI/libraries/core/Trajectory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..544072b37ef1ea55601c2a6e89c9444a47a73987
--- /dev/null
+++ b/source/RobotAPI/libraries/core/Trajectory.cpp
@@ -0,0 +1,1745 @@
+/*
+ * This file is part of ArmarX.
+ *
+ * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @package    ArmarX
+ * @author     Mirko Waechter( mirko.waechter at kit dot edu)
+ * @date       2016
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+#include "Trajectory.h"
+#include <ArmarXCore/core/logging/Logging.h>
+#include "VectorHelpers.h"
+
+#include <ArmarXCore/observers/AbstractObjectSerializer.h>
+
+namespace armarx
+{
+
+    void Trajectory::ice_preMarshal()
+    {
+        dataVec.clear();
+        timestamps.clear();
+        dataVec.reserve(dim());
+        for (auto it = begin(); it != end(); it++)
+        {
+            std::vector< DoubleSeqPtr >& data = it->data;
+            DoubleSeqSeq new2DVec;
+            new2DVec.reserve(data.size());
+            for (DoubleSeqPtr & subVec : data)
+            {
+                new2DVec.emplace_back(*subVec);
+            }
+            dataVec.emplace_back(new2DVec);
+        }
+        timestamps = getTimestamps();
+    }
+
+    void Trajectory::ice_postUnmarshal()
+    {
+        int i = 0;
+        for (DoubleSeqSeq & _2DVec : dataVec)
+        {
+
+            double t = timestamps.at(i);
+            int d = 0;
+            for (auto & vec : _2DVec)
+            {
+                setEntries(t, d++, vec);
+            }
+
+            i++;
+        }
+    }
+
+    void Trajectory::serialize(const ObjectSerializerBasePtr& serializer, const Ice::Current&) const
+    {
+        AbstractObjectSerializerPtr obj = AbstractObjectSerializerPtr::dynamicCast(serializer);
+        Ice::StringSeq columnContent;
+        Eigen::MatrixXd m = toEigen();
+        auto cols = m.cols();
+        auto rows = m.rows();
+        for (int col = 0; col < cols; col++)
+        {
+            std::stringstream ss;
+
+            for (int row = 0; row < rows; row++)
+            {
+                ss << m(row, col) << (row < rows - 1 ? "," : "");
+            }
+
+            columnContent.push_back(ss.str());
+        }
+        obj->setDoubleArray("timestamps", getTimestamps());
+        obj->setStringArray("dimensionData", columnContent);
+        obj->setStringArray("dimensionNames", dimensionNames);
+    }
+
+    void Trajectory::deserialize(const ObjectSerializerBasePtr& serializer, const Ice::Current&)
+    {
+        clear();
+        AbstractObjectSerializerPtr obj = AbstractObjectSerializerPtr::dynamicCast(serializer);
+        Ice::StringSeq rowContent;
+        obj->getStringArray("dimensionData", rowContent);
+
+        Ice::DoubleSeq timestamps;
+        obj->getDoubleArray("timestamps", timestamps);
+        for (size_t row = 0; row < rowContent.size(); row++)
+        {
+            Ice::StringSeq values;
+            boost::split(values, rowContent[row], boost::is_any_of(","));
+            Ice::DoubleSeq newRow;
+            newRow.reserve(values.size());
+            for (std::string v : values)
+            {
+                newRow.push_back(atof(v.c_str()));
+            }
+            addDimension(timestamps, newRow);
+        }
+        obj->getStringArray("dimensionNames", dimensionNames);
+    }
+
+    VariantDataClassPtr Trajectory::clone(const Ice::Current&) const
+    {
+        return new Trajectory(*this);
+    }
+
+    std::string Trajectory::output(const Ice::Current&) const
+    {
+        return "Trajectory with " + std::to_string(dim()) + " dimensions";
+    }
+
+    Ice::Int Trajectory::getType(const Ice::Current&) const
+    {
+        return VariantType::Trajectory;
+    }
+
+    bool Trajectory::validate(const Ice::Current&)
+    {
+        return true;
+    }
+
+    Ice::ObjectPtr Trajectory::ice_clone() const
+    {
+        return clone();
+    }
+
+    Trajectory::Trajectory(const Trajectory& source) :
+        IceUtil::Shared(source),
+        TrajectoryBase(source)
+    {
+        CopyData(source, *this);
+    }
+
+
+
+    Trajectory::Trajectory(const Ice::DoubleSeq& x, const Ice::DoubleSeq& y, const std::string& dimensionName)
+    {
+        addDimension(x, y, dimensionName);
+    }
+
+
+    Trajectory::Trajectory(const std::map<double, Ice::DoubleSeq >& data)
+    {
+        if (data.size() == 0)
+        {
+            return;
+        }
+
+        typename  std::map<double, Ice::DoubleSeq >::const_iterator it = data.begin();
+
+        for (; it != data.end(); it++)
+        {
+            TrajData dataEntry(*this);
+            dataEntry.timestamp = it->first;
+            const Ice::DoubleSeq& dataVec = it->second;
+
+            for (size_t i = 0; i < dataVec.size(); i++)
+            {
+                checkValue(dataVec[i]);
+                dataEntry.data.push_back(DoubleSeqPtr(new Ice::DoubleSeq(1, dataVec[i])));
+            }
+
+            dataMap.insert(dataEntry);
+        }
+    }
+
+    //
+    //    Trajectory::Trajectory(const TrajMap &map)
+    //    {
+    //        copyMap(map, dataMap);
+    //    }
+
+    Trajectory& Trajectory::operator=(const Trajectory& source)
+    {
+        CopyData(source, *this);
+        return *this;
+    }
+
+
+    double Trajectory::getState(double t, size_t dim, size_t deriv)
+    {
+        if (dim >= this->dim())
+        {
+            throw LocalException() << "dimension is to big: " << dim << " max: " << this->dim();
+        }
+
+        typename timestamp_view::iterator it = dataMap.find(t);
+
+        if (it == dataMap.end() || !it->data.at(dim))
+        {
+            __fillBaseDataAtTimestamp(t);// interpolates and retrieves
+            it = dataMap.find(t);
+        }
+
+        if (!it->data.at(dim))
+            //        it->data.at(dim).reset(new Ice::DoubleSeq());
+        {
+            throw LocalException() << "std::vector ptr is NULL!?";
+        }
+
+        std::vector<DoubleSeqPtr>& vec = it->data;
+
+        if (deriv != 0 && vec.at(dim)->size() <= deriv)
+        {
+            //resize and calculate derivations
+            size_t curDeriv = it->data.at(dim)->size();
+            it->data.at(dim)->resize(deriv + 1);
+
+            while (curDeriv <= deriv)
+            {
+                double derivValue = getDiscretDifferentiationForDimAtT(t, dim, curDeriv);
+                checkValue(curDeriv);
+                it->data.at(dim)->at(curDeriv) = derivValue;
+                curDeriv++;
+            }
+
+        }
+
+        //    std::cout << "dimensions: " <<it->data.size() << " derivations: " <<  it->data.at(dim)->size() << std::endl;
+        double result = it->data.at(dim)->at(deriv);
+        //    checkValue(result);
+        return result;
+    }
+
+    double Trajectory::getState(double t, size_t dim, size_t deriv) const
+    {
+
+        if (dim >= this->dim())
+        {
+            throw LocalException() << "dimension is to big: " << dim << " max: " << this->dim();
+        }
+
+        typename timestamp_view::iterator it = dataMap.find(t);
+
+        if (!dataExists(t, dim, deriv))
+        {
+            if (deriv == 0)
+            {
+                return __calcBaseDataAtTimestamp(t).at(dim)->at(deriv);    // interpolates and retrieves
+            }
+            else
+            {
+                return getDiscretDifferentiationForDimAtT(t, dim, deriv);
+            }
+        }
+        else
+        {
+            //                std::cout << "dimensions: " <<it->data.size() << " derivations: " <<  it->data.at(dim)->size() << std::endl;
+            double result = it->data.at(dim)->at(deriv);
+
+            checkValue(result);
+
+
+            return result;
+        }
+    }
+
+    Ice::DoubleSeq Trajectory::getDerivations(double t, size_t dimension, size_t derivations) const
+    {
+        if (dimension >= dim())
+        {
+            throw LocalException() << "Dimension out of bounds: requested: " << dimension << " available: " << dim();
+        }
+
+        Ice::DoubleSeq result;
+
+        for (size_t i = 0; i <= derivations; i++)
+        {
+            result.push_back(getState(t, dimension, i));
+        }
+
+        return result;
+    }
+
+    std::string Trajectory::getDimensionName(size_t dim) const
+    {
+        return dimensionNames.at(dim);
+    }
+
+    Ice::StringSeq Trajectory::getDimensionNames() const
+    {
+        return dimensionNames;
+    }
+
+    Trajectory::TrajDataContainer& Trajectory::data()
+    {
+        return dataMap;
+    }
+
+    Ice::DoubleSeq
+    Trajectory::getDimensionData(size_t dimension, size_t deriv) const
+    {
+        if (dimension >= dim())
+        {
+            throw LocalException("dimension is out of range: ") << dimension << " actual dimensions: " << dim();
+        }
+
+        Ice::DoubleSeq result;
+
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        typename ordered_view::const_iterator itMap = ordv.begin();
+
+        for (; itMap != ordv.end(); itMap++)
+        {
+            DoubleSeqPtr dataPtr = itMap->data[dimension];
+            result.push_back(itMap->getDeriv(dimension, deriv));
+            //        if(dataPtr && dataPtr->size() > deriv)
+            //            result.push_back(itMap->getDeriv(dimension, deriv));
+            //        else result.push_back(getState(itMap->timestamp, dimension, deriv));
+        }
+
+        return result;
+
+    }
+
+    Eigen::VectorXd Trajectory::getDimensionDataAsEigen(size_t dimension, size_t derivation) const
+    {
+        return getDimensionDataAsEigen(dimension, derivation, begin()->getTimestamp(), rbegin()->getTimestamp());
+    }
+
+    Eigen::VectorXd Trajectory::getDimensionDataAsEigen(size_t dimension, size_t derivation, double startTime, double endTime) const
+    {
+        if (dimension >= dim())
+        {
+            throw LocalException("dimension is out of range: ") << dimension << " actual dimensions: " << dim();
+        }
+
+        Ice::DoubleSeq result;
+
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        ordered_view::iterator itO = ordv.lower_bound(startTime);
+        ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
+        //    typename ordered_view::const_iterator itMap = ordv.begin();
+
+        size_t i = 0;
+        for (; itO != itOEnd && i < size(); itO++, i++)
+        {
+            DoubleSeqPtr dataPtr = itO->data[dimension];
+            result.push_back(itO->getDeriv(dimension, derivation));
+            //        if(dataPtr && dataPtr->size() > deriv)
+            //            result.push_back(itMap->getDeriv(dimension, deriv));
+            //        else result.push_back(getState(itMap->timestamp, dimension, deriv));
+        }
+        Eigen::VectorXd resultVec(result.size());
+        for (size_t i = 0; i < result.size(); i++)
+        {
+            resultVec(i) = result[i];
+        }
+        return resultVec;
+    }
+
+    Eigen::MatrixXd Trajectory::toEigen(size_t derivation, double startTime, double endTime) const
+    {
+        Eigen::MatrixXd result(size(), dim());
+
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        ordered_view::iterator itO = ordv.lower_bound(startTime);
+        ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
+        //    typename ordered_view::const_iterator itMap = ordv.begin();
+
+        size_t i = 0;
+        for (; itO != itOEnd; itO++, i++)
+        {
+            //        DoubleSeqPtr dataPtr = itO->data[dimension];
+            for (size_t d = 0; d < itO->data.size(); d++)
+            {
+                result(i, d) = (itO->getDeriv(d, derivation));
+            }
+        }
+
+        return result;
+    }
+
+    Eigen::MatrixXd Trajectory::toEigen(size_t derivation) const
+    {
+        if (size() == 0 || dim() == 0)
+        {
+            return Eigen::MatrixXd();
+        }
+        return toEigen(derivation, begin()->getTimestamp(), rbegin()->getTimestamp());
+    }
+
+    Trajectory Trajectory::getPart(double startTime, double endTime, size_t numberOfDerivations) const
+    {
+        Trajectory result;
+
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        ordered_view::iterator itO = ordv.lower_bound(startTime);
+        ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
+        //    typename ordered_view::const_iterator itMap = ordv.begin();
+
+        size_t i = 0;
+        for (; itO != itOEnd; itO++, i++)
+        {
+            //        DoubleSeqPtr dataPtr = itO->data[dimension];
+            for (size_t d = 0; d < itO->data.size(); d++)
+            {
+                Ice::DoubleSeq derivs;
+                for (size_t i = 0; i < numberOfDerivations + 1; i++)
+                {
+                    derivs.push_back(itO->getDeriv(d, i));
+                }
+
+                result.addDerivationsToDimension(d, itO->getTimestamp(), derivs);
+            }
+            //            result.addPositionsToDimension(d, itO->getTimestamp(), itO->getDeriv(d, 0));
+        }
+
+        return result;
+    }
+
+    size_t Trajectory::dim() const
+    {
+        if (dataMap.size() == 0)
+        {
+            return 0;
+        }
+        else
+        {
+            return dataMap.begin()->data.size();
+        }
+    }
+
+    size_t Trajectory::size() const
+    {
+        return dataMap.size();
+    }
+
+
+    //    Ice::DoubleSeq
+    //    Trajectory::getDimensionData(size_t dimension, size_t deriv) const
+    //    {
+    //        if(dimension >= dim()){
+    //            throw LocalException("dimension is out of range: ") << dimension << " actual dimensions: " << dim();
+    //        }
+
+    //        Ice::DoubleSeq result;
+    //        Ice::DoubleSeq tempResult = getDimensionData(dimension);
+    //        typename Ice::DoubleSeq::iterator it = tempResult.begin();
+    //        for(; it != tempResult.end(); it++)
+    //            result.push_back(it->at(deriv));
+
+    //        return result;
+    //    }
+
+
+    double Trajectory::getTimeLength() const
+    {
+        const ordered_view& ordView = dataMap.get<TagOrdered>();
+
+        if (ordView.begin() != ordView.end())
+        {
+            return ordView.rbegin()->timestamp - ordView.begin()->timestamp;
+        }
+        else
+        {
+            return 0;
+        }
+    }
+
+    double Trajectory::getSpaceLength(size_t dimension, size_t stateDim) const
+    {
+        return getSquaredSpaceLength(dimension, stateDim, begin()->getTimestamp(), rbegin()->getTimestamp());
+    }
+
+    double Trajectory::getSpaceLength(size_t dimension, size_t stateDim, double startTime, double endTime) const
+    {
+        double length = 0.0;
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        //    timestamp_view::iterator it = dataMap.find(startTime);
+        //    Ice::DoubleSeq data = getDimensionData(0);
+        //    timestamp_view::iterator itEnd= dataMap.find(endTime);
+        ordered_view::iterator itO = ordv.lower_bound(startTime);
+        ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
+        if (itO == ordv.end())
+        {
+            return 0.0;
+        }
+        double prevValue = itO->getDeriv(dimension, stateDim);
+
+        for (;
+             itO != itOEnd;
+             itO++
+            )
+        {
+            length += fabs(prevValue - itO->getDeriv(dimension, stateDim));
+            prevValue = itO->getDeriv(dimension, stateDim);
+        }
+
+        return length;
+    }
+
+    double Trajectory::getSquaredSpaceLength(size_t dimension, size_t stateDim) const
+    {
+        return getSquaredSpaceLength(dimension, stateDim, begin()->getTimestamp(), rbegin()->getTimestamp());
+    }
+
+    double Trajectory::getSquaredSpaceLength(size_t dimension, size_t stateDim, double startTime, double endTime) const
+    {
+        double length = 0.0;
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        //    timestamp_view::iterator it = dataMap.find(startTime);
+        //    Ice::DoubleSeq data = getDimensionData(0);
+        //    timestamp_view::iterator itEnd= dataMap.find(endTime);
+        ordered_view::iterator itO = ordv.lower_bound(startTime);
+        ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
+        if (itO == ordv.end())
+        {
+            return 0.0;
+        }
+        //    double prevValue = itO->data[dimension]->at(stateDim);
+        double prevValue = itO->getDeriv(dimension, stateDim);
+
+        for (;
+             itO != itOEnd;
+             itO++
+            )
+        {
+            length += fabs(pow(prevValue, 2.0) - pow(itO->getDeriv(dimension, stateDim), 2.0));
+            prevValue = itO->getDeriv(dimension, stateDim);
+        }
+
+        return length;
+    }
+
+    double Trajectory::getMax(size_t dimension, size_t stateDim, double startTime, double endTime) const
+    {
+        return getWithFunc(&std::max<double>, -std::numeric_limits<double>::max(), dimension, stateDim, startTime, endTime);
+    }
+
+    double Trajectory::getMin(size_t dimension, size_t stateDim, double startTime, double endTime) const
+    {
+        return getWithFunc(&std::min<double>, std::numeric_limits<double>::max(), dimension, stateDim, startTime, endTime);
+    }
+
+    double Trajectory::getWithFunc(const double & (*foo)(const double&, const double&), double initValue, size_t dimension, size_t stateDim, double startTime, double endTime) const
+    {
+        double bestValue = initValue;
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        ordered_view::iterator itO = ordv.lower_bound(startTime);
+        ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
+
+        if (itO == ordv.end())
+        {
+            return bestValue;
+        }
+        for (;
+             itO != itOEnd;
+             itO++
+            )
+        {
+            bestValue = foo(bestValue, itO->getDeriv(dimension, stateDim));
+        }
+
+        return bestValue;
+    }
+
+    double Trajectory::getTrajectorySpace(size_t dimension, size_t stateDim, double startTime, double endTime) const
+    {
+        return getMax(dimension, stateDim, startTime, endTime) - getMin(dimension, stateDim, startTime, endTime);
+    }
+
+    Ice::DoubleSeq Trajectory::getMinima(size_t dimension, size_t stateDim, double startTime, double endTime) const
+    {
+        Ice::DoubleSeq result;
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        ordered_view::iterator itO = ordv.lower_bound(startTime);
+        ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
+
+        if (itO == ordv.end())
+        {
+            return result;
+        }
+        double preValue = itO->getDeriv(dimension, stateDim);
+        for (;
+             itO != itOEnd;
+
+            )
+        {
+            //            double t = itO->getTimestamp();
+            double cur = itO->getDeriv(dimension, stateDim);
+            itO++;
+            if (itO == ordv.end())
+            {
+                break;
+            }
+            double next = itO->getDeriv(dimension, stateDim);
+            if (cur <= preValue && cur <= next)
+            {
+                result.push_back(cur);
+            }
+            preValue = cur;
+        }
+
+        return result;
+    }
+
+    Ice::DoubleSeq Trajectory::getMinimaPositions(size_t dimension, size_t stateDim, double startTime, double endTime) const
+    {
+        Ice::DoubleSeq result;
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        ordered_view::iterator itO = ordv.lower_bound(startTime);
+        ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
+
+        if (itO == ordv.end())
+        {
+            return result;
+        }
+        double preValue = itO->getDeriv(dimension, stateDim);
+        for (;
+             itO != itOEnd;
+
+            )
+        {
+            //            double t = itO->getTimestamp();
+            double cur = itO->getDeriv(dimension, stateDim);
+            itO++;
+            if (itO == ordv.end())
+            {
+                break;
+            }
+            double next = itO->getDeriv(dimension, stateDim);
+            if (cur <= preValue && cur <= next)
+            {
+                result.push_back(itO->getTimestamp());
+            }
+            preValue = cur;
+        }
+
+        return result;
+    }
+
+    Ice::DoubleSeq Trajectory::getMaxima(size_t dimension, size_t stateDim, double startTime, double endTime) const
+    {
+        Ice::DoubleSeq result;
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        ordered_view::iterator itO = ordv.lower_bound(startTime);
+        ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
+
+        if (itO == ordv.end())
+        {
+            return result;
+        }
+        double preValue = itO->getDeriv(dimension, stateDim);
+        for (;
+             itO != itOEnd;
+
+            )
+        {
+            double cur = itO->getDeriv(dimension, stateDim);
+            itO++;
+            if (itO == ordv.end())
+            {
+                break;
+            }
+            double next = itO->getDeriv(dimension, stateDim);
+            if (cur >= preValue && cur >= next)
+            {
+                result.push_back(cur);
+            }
+            preValue = cur;
+        }
+
+        return result;
+    }
+
+    Ice::DoubleSeq Trajectory::getMaximaPositions(size_t dimension, size_t stateDim, double startTime, double endTime) const
+    {
+        Ice::DoubleSeq result;
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        ordered_view::iterator itO = ordv.lower_bound(startTime);
+        ordered_view::iterator itOEnd = ordv.upper_bound(endTime);
+
+        if (itO == ordv.end())
+        {
+            return result;
+        }
+        double preValue = itO->getDeriv(dimension, stateDim);
+        for (;
+             itO != itOEnd;
+
+            )
+        {
+            double cur = itO->getDeriv(dimension, stateDim);
+            itO++;
+            if (itO == ordv.end())
+            {
+                break;
+            }
+            double next = itO->getDeriv(dimension, stateDim);
+
+            if (cur >= preValue && cur >= next)
+            {
+                result.push_back(itO->getTimestamp());
+            }
+            preValue = cur;
+        }
+
+        return result;
+    }
+
+
+    std::vector<DoubleSeqPtr> Trajectory::__calcBaseDataAtTimestamp(const double& t) const
+    {
+        //    typename timestamp_view::const_iterator it = dataMap.find(t);
+        //    if(it != dataMap.end())
+        //        return it->data;
+        std::vector<DoubleSeqPtr> result;
+
+        for (size_t dimension = 0; dimension < dim(); dimension++)
+        {
+            double newValue = __interpolate(t, dimension, 0);
+            checkValue(newValue);
+            result.push_back(DoubleSeqPtr(new Ice::DoubleSeq(1, newValue)));
+
+        }
+
+        return result;
+
+    }
+
+    bool Trajectory::dataExists(double t, size_t dimension, size_t deriv) const
+    {
+        typename timestamp_view::iterator it = dataMap.find(t);
+
+        if (it == dataMap.end() || !it->data.at(dimension) || it->data.at(dimension)->size() <= deriv)
+        {
+            return false;
+        }
+        else
+        {
+            return true;
+        }
+    }
+
+
+    Trajectory::timestamp_view::iterator Trajectory::__fillBaseDataAtTimestamp(const double& t)
+    {
+        typename timestamp_view::const_iterator it = dataMap.find(t);
+
+        if (it != dataMap.end())
+        {
+            bool foundEmpty = false;
+
+            for (size_t i = 0; i < it->data.size(); i++)
+            {
+                if (!it->data.at(i))
+                {
+                    foundEmpty = true;
+                }
+            }
+
+            if (!foundEmpty)
+            {
+                return it;
+            }
+        }
+
+        TrajData entry(*this);
+        entry.timestamp = t;
+        entry.data.resize(dim());
+        dataMap.insert(entry);
+        it = dataMap.find(t);
+
+        assert(it != dataMap.end());
+        //        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        //        typename ordered_view::iterator itOrdered = ordv.iterator_to(*it);
+        it->data = __calcBaseDataAtTimestamp(t);
+
+        return it;
+    }
+
+    std::vector<DoubleSeqPtr>& Trajectory::getStates(double t)
+    {
+        typename timestamp_view::const_iterator it = dataMap.find(t);
+
+        if (it == dataMap.end())
+        {
+            // interpolate and insert entry
+            it = __fillBaseDataAtTimestamp(t);
+        }
+
+
+        return it->data;
+    }
+
+    std::vector<DoubleSeqPtr> Trajectory::getStates(double t) const
+    {
+        typename timestamp_view::const_iterator it = dataMap.find(t);
+
+        if (it == dataMap.end())
+        {
+            // interpolate and return data
+            return __calcBaseDataAtTimestamp(t);
+        }
+
+
+        return it->data;
+    }
+
+
+
+    Ice::DoubleSeq Trajectory::getStates(double t, size_t derivation) const
+    {
+        Ice::DoubleSeq result;
+        size_t dimensions = dim();
+
+        for (size_t i = 0; i < dimensions; i++)
+        {
+            result.push_back(getState(t, i, derivation));
+        }
+
+        return result;
+    }
+
+    std::map<double, Ice::DoubleSeq> Trajectory::getStatesAround(double t, size_t derivation, size_t extend) const
+    {
+
+        std::map<double, Ice::DoubleSeq> res;
+        typename timestamp_view::iterator itMap = dataMap.find(t);
+
+        if (itMap != dataMap.end())
+        {
+            for (size_t i = 0; i < dim(); i++)
+            {
+                res.insert(std::pair<double, Ice::DoubleSeq>(t, {itMap->data[i]->at(derivation)}));
+            }
+
+            return res;
+        }
+
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+
+        typename ordered_view::iterator itNext = ordv.upper_bound(t);
+
+        typename ordered_view::iterator itPrev = itNext;
+
+        itPrev--;
+
+        if (itPrev == ordv.end())
+        {
+
+            throw LocalException("Cannot find value at timestamp ") << t;
+        }
+
+        for (size_t i = 0; i < extend; i++)
+        {
+            Ice::DoubleSeq preData = getStates(itPrev->timestamp, derivation);
+            Ice::DoubleSeq nexData = getStates(itNext->timestamp, derivation);
+
+            res.insert(std::pair<double, Ice::DoubleSeq>(itPrev->timestamp, preData));
+            res.insert(std::pair<double, Ice::DoubleSeq>(itNext->timestamp, nexData));
+
+            if (itPrev == ordv.begin() || itNext == ordv.end())
+            {
+                std::cout << "Warning: the timestamp is out of the range. " <<
+                          "The current result will be returned" << std::endl;
+                break;
+            }
+            itPrev--;
+            itNext++;
+        }
+
+        return res;
+
+    }
+
+
+
+
+
+
+
+
+
+
+    Trajectory& Trajectory::operator +=(const Trajectory traj)
+    {
+        int dims = traj.dim();
+        Ice::DoubleSeq timestamps = traj.getTimestamps();
+
+        for (int d = 0; d < dims; ++d)
+        {
+            addPositionsToDimension(d, timestamps, traj.getDimensionData(d));
+        }
+
+        return *this;
+    }
+
+
+    void Trajectory::__addDimension()
+    {
+        size_t newDim = dim() + 1;
+
+        typename timestamp_view::iterator itMap = dataMap.begin();
+
+        for (; itMap != dataMap.end(); itMap++)
+        {
+            itMap->data.resize(newDim);
+        }
+    }
+
+    void Trajectory::setEntries(const double t, const size_t dimIndex, const Ice::DoubleSeq& y)
+    {
+        typename timestamp_view::iterator itMap = dataMap.find(t);
+
+        if (itMap == dataMap.end() || dim() == 0)
+        {
+            //            double dura = getTimeLength();
+            TrajData newData(*this);
+            newData.timestamp = t;
+            newData.data =  std::vector<DoubleSeqPtr>(std::max((size_t)1, dim()));
+            newData.data[dimIndex] = DoubleSeqPtr(new Ice::DoubleSeq(y));
+            dataMap.insert(newData);
+        }
+        else
+        {
+            assert(dim() > 0);
+
+            while (dim() <= dimIndex)
+            {
+                __addDimension();
+            }
+
+            itMap->data.resize(dim());
+            itMap->data.at(dimIndex) = DoubleSeqPtr(new Ice::DoubleSeq(y));
+        }
+
+    }
+
+
+    void Trajectory::setPositionEntry(const double t, const size_t dimIndex, const double& y)
+    {
+        typename timestamp_view::iterator itMap = dataMap.find(t);
+
+        if (itMap == dataMap.end() || dim() == 0)
+        {
+            TrajData newData(*this);
+            newData.timestamp = t;
+            newData.data =  std::vector<DoubleSeqPtr>(std::max((size_t)1, dim()));
+            newData.data[dimIndex] = DoubleSeqPtr(new Ice::DoubleSeq(1, y));
+            dataMap.insert(newData);
+        }
+        else
+        {
+            assert(dim() > 0);
+            itMap->data.resize(dim());
+            itMap->data.at(dimIndex) = DoubleSeqPtr(new Ice::DoubleSeq(1, y));
+        }
+
+    }
+
+
+    void Trajectory::__fillAllEmptyFields()
+    {
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        typename ordered_view::const_iterator itMap = ordv.begin();
+
+        for (; itMap != ordv.end(); itMap++)
+        {
+            for (size_t dimension = 0; dimension < dim(); dimension++)
+            {
+                if (!itMap->data[dimension])
+                {
+                    itMap->data[dimension] = DoubleSeqPtr(new Ice::DoubleSeq(__interpolate(itMap, dimension, 0)));
+                }
+            }
+        }
+    }
+
+
+
+
+    Ice::DoubleSeq Trajectory::getTimestamps() const
+    {
+        Ice::DoubleSeq result;
+        result.reserve(size());
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        typename ordered_view::const_iterator itMap = ordv.begin();
+
+        for (; itMap != ordv.end(); itMap++)
+        {
+            result.push_back(itMap->timestamp);
+        }
+
+        return result;
+    }
+
+
+
+    Ice::DoubleSeq
+    Trajectory::getDiscreteDifferentiationForDim(size_t trajDimension, size_t derivation) const
+    {
+        if (trajDimension >= dim())
+        {
+            throw LocalException("dimension is out of range: ") << trajDimension << " actual dimensions: " << dim();
+        }
+
+        //        if(sourceDimOfSystemState >= double().size()){
+        //            throw LocalException("sourceDimOfSystemState is out of range: ") << sourceDimOfSystemState << " actual dimensions: " << double().size();
+        //        }
+        //        if(targetDimOfSystemState >= double().size()){
+        //            throw LocalException("sourceDimOfSystemState is out of range: ") << targetDimOfSystemState << " actual dimensions: " << double().size();
+        //        }
+
+
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        typename ordered_view::const_iterator itPrev = ordv.begin();
+
+        typename ordered_view::const_iterator itCurrent = itPrev;
+        //        itCurrent++;
+        typename ordered_view::const_iterator itNext = itCurrent;
+        itNext++;
+
+        Ice::DoubleSeq result;
+
+        for (; itCurrent != ordv.end();)
+        {
+            if (itNext == ordv.end()) // last step-> differentiate between current and prev
+            {
+                itNext = itCurrent;
+            }
+
+
+            // get current data
+            DoubleSeqPtr prevStatePtr = itPrev->data[trajDimension];
+            DoubleSeqPtr nextStatePtr = itNext->data[trajDimension];
+            //            double nextValue = nextStatePtr->getValues()[sourceDimOfSystemState];
+            //            double prevValue = prevStatePtr->getValues()[sourceDimOfSystemState];
+            //            double nextTime = itNext->timestamp;
+            //            double prevTime = itPrev->timestamp;
+            // differentiateDiscretly now
+            result.push_back((nextStatePtr->at(derivation) - prevStatePtr->at(derivation)) /
+                             (itNext->timestamp - itPrev->timestamp));
+            checkValue(*result.rbegin());
+
+
+            itCurrent++, itPrev++, itNext++;
+
+            if (itPrev == itCurrent)
+            {
+                // first step-> reestablish that current is > prev
+                itPrev--;
+            }
+
+        }
+
+        return result;
+    }
+
+
+    Ice::DoubleSeq Trajectory::DifferentiateDiscretly(const Ice::DoubleSeq& timestamps, const Ice::DoubleSeq& values, int derivationCount)
+    {
+        if (derivationCount < 0)
+        {
+            throw LocalException("Negative derivation value is not allowed!");
+        }
+
+        if (derivationCount == 0)
+        {
+            return values;
+        }
+
+        Ice::DoubleSeq result;
+        int size = std::min(timestamps.size(), values.size());
+
+        if (size < 2)
+        {
+            return values;
+        }
+
+        result.resize(size);
+
+        // boundaries
+        result[0] = (values.at(1) - values.at(0)) / (timestamps.at(1) - timestamps.at(0)) ;
+        result[size - 1] = (values.at(size - 1) - values.at(size - 2)) / (timestamps.at(size - 1) - timestamps.at(size - 2)) ;
+
+        //#pragma omp parallel for
+        for (int i = 1; i < size - 1; ++i)
+        {
+            result[i] = (values.at(i + 1) - values.at(i - 1)) / (timestamps.at(i + 1) - timestamps.at(i - 1)) ;
+            checkValue(result[i]);
+        }
+
+        if (derivationCount > 1) // recursivly differentiate
+        {
+            result = DifferentiateDiscretly(timestamps, result, derivationCount - 1);
+        }
+
+        return result;
+
+    }
+
+
+    double Trajectory::getDiscretDifferentiationForDimAtT(double t, size_t trajDimension, size_t deriv) const
+    {
+        if (deriv == 0)
+        {
+            getState(t, trajDimension, deriv);
+        }
+
+        typename timestamp_view::iterator it = dataMap.find(t);
+        //        if(it == dataMap.end())
+        //        {
+        //            getStates(t); // interpolate and insert entry
+        //            it = dataMap.find(t);
+        //        }
+
+        const ordered_view& ordV = dataMap.get<TagOrdered>();
+        typename ordered_view::iterator itCurrent = ordV.end();
+
+        if (it != dataMap.end())
+        {
+            itCurrent = ordV.iterator_to(*it);
+        }
+
+        typename ordered_view::iterator itNext = ordV.upper_bound(t); // first element after t
+
+        if (it != dataMap.end() && itNext == ordV.end())
+        {
+            itNext = itCurrent;    // current item is last, set next to current
+        }
+        else if (itNext == ordV.end() && it == dataMap.end())
+        {
+            throw LocalException() << "Cannot interpolate for t " << t << " no data in trajectory";
+        }
+
+        typename ordered_view::iterator itPrev = itNext;
+        itPrev--; // now equal to current (if current exists) or before current
+
+        if (itCurrent != ordV.end()) // check if current item exists
+        {
+            itPrev--;    //element in front of t
+        }
+
+        if (itPrev == ordV.end())
+        {
+            //element in front of t does not exist
+            if (itCurrent != ordV.end())
+            {
+                itPrev = itCurrent;    // set prev element to current
+            }
+            else
+            {
+                throw LocalException() << "Cannot interpolate for t " << t;
+            }
+        }
+
+        if (itNext == ordV.end())
+        {
+            //element after t does not exist
+            if (itCurrent != ordV.end())
+            {
+                itNext = itCurrent;    // set next element to current
+            }
+            else
+            {
+                throw LocalException() << "Cannot interpolate for t " << t;
+            }
+        }
+
+        if (itNext == itPrev)
+        {
+            throw LocalException() << "Interpolation failed: the next data and the previous are missing";
+        }
+
+        //        double diff = itNext->data[trajDimension]->at(deriv-1) - itPrev->data[trajDimension]->at(deriv-1);
+        double tNext;
+
+        if (dataExists(itNext->timestamp, trajDimension, deriv - 1) || deriv > 1)
+        {
+            tNext = itNext->timestamp;
+        }
+        else
+        {
+            tNext = t;
+        }
+
+        double next = getState(tNext, trajDimension, deriv - 1);
+
+        double tBefore;
+
+        if (dataExists(itPrev->timestamp, trajDimension, deriv - 1) || deriv > 1)
+        {
+            tBefore = itPrev->timestamp;
+        }
+        else
+        {
+            tBefore = t;
+        }
+
+        double before = getState(tBefore, trajDimension, deriv - 1);
+
+        if (fabs(tNext - tBefore) < 1e-10)
+        {
+            throw LocalException() << "Interpolation failed: the next data and the previous are missing";
+        }
+
+        double duration = tNext - tBefore;
+        double delta = next - before;
+        delta = delta / duration;
+        checkValue(delta);
+        return delta;
+    }
+
+    void Trajectory::differentiateDiscretly(size_t derivation)
+    {
+
+        for (size_t d = 0; d < dim(); d++)
+        {
+            differentiateDiscretlyForDim(d, derivation);
+        }
+    }
+
+    void Trajectory::differentiateDiscretlyForDim(size_t trajDimension, size_t derivation)
+    {
+        removeDerivation(trajDimension, derivation);
+        typename ordered_view::iterator itOrd = begin();
+
+        for (; itOrd != end(); itOrd++)
+        {
+            getState(itOrd->timestamp, trajDimension, derivation);
+        }
+    }
+
+
+
+
+    void Trajectory::reconstructFromDerivativeForDim(double valueAtFirstTimestamp, size_t trajDimension, size_t sourceDimOfSystemState, size_t targetDimOfSystemState)
+    {
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        typename ordered_view::iterator it = ordv.begin();
+
+        if (it == ordv.end())
+        {
+            return;
+        }
+
+        it->data[trajDimension]->at(targetDimOfSystemState) = valueAtFirstTimestamp;
+        double previousValue = valueAtFirstTimestamp;
+        double previousTimestamp = it->timestamp;
+
+        //        size_t stateDim = double().size();
+        for (it++; it != ordv.end(); it++)
+        {
+            double slope;
+            if (it->data[trajDimension]->size() > sourceDimOfSystemState)
+            {
+                slope = it->data[trajDimension]->at(sourceDimOfSystemState);
+            }
+            else
+            {
+                slope = 0;
+            }
+
+            double diff = it->timestamp - previousTimestamp;
+            it->data[trajDimension]->at(targetDimOfSystemState) = previousValue + diff * slope;
+            previousTimestamp = it->timestamp;
+            previousValue = it->data[trajDimension]->at(targetDimOfSystemState);
+        }
+
+    }
+
+
+    void Trajectory::negateDim(size_t trajDimension)
+    {
+        if (trajDimension >= dim())
+        {
+            throw LocalException("dimension is out of range: ") << trajDimension << " actual dimensions: " << dim();
+        }
+
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+
+        Trajectory filteredTraj;
+
+        for (typename ordered_view::iterator it = ordv.begin(); it != ordv.end(); it++)
+        {
+            (*it->data.at(trajDimension)) *= -1;
+        }
+    }
+
+
+
+
+
+    double
+    Trajectory::__interpolate(double t, size_t dimension, size_t deriv) const
+    {
+        typename timestamp_view::const_iterator it = dataMap.find(t);
+
+        if (it != dataMap.end() && it->data.size() > dimension && it->data.at(dimension) && it->data.at(dimension)->size() > deriv)
+        {
+            return it->data.at(dimension)->at(deriv);
+        }
+
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+
+        typename ordered_view::iterator itNext = ordv.upper_bound(t);
+
+        typename ordered_view::iterator itPrev = itNext;
+
+        itPrev--;
+
+        double result = __interpolate(t, itPrev, itNext, dimension, deriv);
+
+        checkValue(result);
+
+        return result;
+    }
+
+    double
+    Trajectory::__interpolate(typename ordered_view::const_iterator itMap, size_t dimension, size_t deriv) const
+    {
+        typename ordered_view::iterator itPrev = itMap;
+        itPrev--;
+        typename ordered_view::iterator itNext = itMap;
+        itNext++;
+        return __interpolate(itMap->timestamp, itPrev, itNext, dimension, deriv);
+    }
+
+    double
+    Trajectory::__interpolate(double t, typename ordered_view::const_iterator itPrev, typename ordered_view::const_iterator itNext, size_t dimension, size_t deriv) const
+    {
+        //    typename ordered_view::const_iterator itCur = itPrev;
+        //    itCur++;
+
+        const ordered_view& ordView = dataMap.get<TagOrdered>();
+        double previous;
+        double next;
+
+        // find previous SystemState that exists for that dimension
+        while (itPrev != ordView.end() && (itPrev->data.at(dimension) == NULL /*|| itPrev->data[dimension]->size() <= deriv*/))
+        {
+            itPrev--;
+        }
+
+        if (itPrev != ordView.end())
+        {
+            previous = getState(itPrev->timestamp, dimension, deriv);
+        }
+
+        // find next SystemState that exists for that dimension
+        while (itNext != ordView.end() && (itNext->data.at(dimension) == NULL /*|| itNext->data[dimension]->size() <= deriv*/))
+        {
+            itNext++;
+        }
+
+        if (itNext != ordView.end())
+        {
+            next = getState(itNext->timestamp, dimension, deriv);
+        }
+
+
+
+        if (itNext == ordView.end() && itPrev == ordView.end())
+        {
+            throw LocalException() << "Cannot find next or prev values in dim " << dimension << " at timestamp " << t;
+        }
+
+        if (itNext == ordView.end())
+        {
+            return getState(itPrev->timestamp, dimension, deriv) + getState(itPrev->timestamp, dimension, deriv + 1) * (t - itPrev->timestamp);
+        }
+        else if (itPrev == ordView.end())
+        {
+            return getState(itNext->timestamp, dimension, deriv) - getState(itNext->timestamp, dimension, deriv + 1) * (itNext->timestamp - t);
+        }
+        else
+        {
+            // linear interpolation
+
+            double distance = fabs(itNext->timestamp - itPrev->timestamp);
+            double weightPrev = fabs(t - itNext->timestamp) / distance;
+            double weightNext = fabs(itPrev->timestamp - t) / distance;
+
+            return weightNext * next + weightPrev * previous;
+
+        }
+    }
+    void Trajectory::gaussianFilter(double filterRadius)
+    {
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        Trajectory filteredTraj;
+        Ice::DoubleSeq timestamps = getTimestamps();
+
+        for (size_t d = 0; d < dim(); d++)
+        {
+            Ice::DoubleSeq entries;
+
+            for (typename ordered_view::iterator it = ordv.begin(); it != ordv.end(); it++)
+            {
+                entries.push_back(__gaussianFilter(filterRadius, it, d, 0));
+            }
+
+            filteredTraj.addDimension(timestamps, entries);
+        }
+
+        CopyData(filteredTraj, *this);
+    }
+
+
+
+    // gauss macro
+#define g(x)  exp(-double((x)*(x))/(2*sigma*sigma)) / ( sigma * sqrt(2*3.14159265))
+#define round(x) int(0.5+x)
+
+
+    double
+    Trajectory::__gaussianFilter(double filterRadiusInTime, typename ordered_view::iterator centerIt, size_t trajNum, size_t dim)
+    {
+        const ordered_view& ordView = dataMap.get<TagOrdered>();
+        //        typename ordered_view::iterator start = centerIt;
+        //        while(start != ordView.end() && start->timestamp > centerIt->timestamp - filterRadiusInTime)
+        //            start--;
+        //        if(start == ordView.end())
+        //            start = ordView.begin();
+
+        //        typename ordered_view::iterator end;
+        //        while(end != ordView.end() && end->timestamp < centerIt->timestamp + filterRadiusInTime)
+        //            end++;
+
+        const double sigma = filterRadiusInTime / 2.5;
+        //-log(0.05) / pow(itemsToCheck+1+centerIndex,2) * ( sqrt(1.0/h) * sqrt(2*3.14159265));
+
+        double weightedSum = 0;
+        double sumOfWeight = 0;
+        ordered_view::iterator start = centerIt;
+
+        const double sqrt2PI = sqrt(2 * M_PI);
+
+        for (int sign = -1; sign < 2; sign += 2)
+        {
+            for (ordered_view::iterator it = start;
+                 it != ordView.end()
+                 && fabs(it->timestamp - centerIt->timestamp) <= fabs(filterRadiusInTime * 2);
+                )
+            {
+                double value;
+                value = it->getDeriv(trajNum, dim);//data[trajNum]->at(dim);
+                double diff = (it->timestamp - centerIt->timestamp);
+                double squared = diff * diff;
+                const double gaussValue = exp(-squared / (2 * sigma * sigma)) / (sigma * sqrt2PI);
+                sumOfWeight += gaussValue;
+                weightedSum += gaussValue * value;
+
+                if (sign > 0)
+                {
+                    it++;
+                }
+                else
+                {
+                    it--;
+                }
+
+                checkValue(weightedSum);
+            }
+
+            start++;// skip center value in second loop iteration
+        }
+
+        double result;
+        result = weightedSum / sumOfWeight;
+        checkValue(result);
+        //        centerIt->data[trajNum]->at(dim) = result;
+        return result;
+
+    }
+
+
+    void Trajectory::CopyData(const Trajectory& source, Trajectory& destination)
+    {
+        if (&source == &destination)
+        {
+            return;
+        }
+
+        destination.clear();
+        Ice::DoubleSeq timestamps = source.getTimestamps();
+
+        for (size_t dim = 0; dim < source.dim(); dim++)
+        {
+            destination.addDimension(timestamps, source.getDimensionData(dim));
+        }
+
+    }
+
+    void Trajectory::clear()
+    {
+        dataMap.erase(dataMap.begin(), dataMap.end());
+        dimensionNames.clear();
+    }
+
+
+
+    Ice::DoubleSeq Trajectory::GenerateTimestamps(double startTime, double endTime, double stepSize)
+    {
+        if (startTime >= endTime)
+        {
+            throw LocalException("startTime must be smaller than endTime.");
+        }
+
+        Ice::DoubleSeq result;
+        int size = int((endTime - startTime) / stepSize) + 1;
+        stepSize = (endTime - startTime) / (size - 1);
+        result.reserve(size);
+
+        double currentTimestamp = startTime;
+        int i = 0;
+
+        while (i < size)
+        {
+            result.push_back(currentTimestamp);
+            currentTimestamp += stepSize;
+            i++;
+        }
+
+        //        if(*result.rbegin() != endTime)
+        //            result.push_back(endTime);
+        return result;
+    }
+
+
+
+
+    Ice::DoubleSeq Trajectory::normalizeTimestamps(const Ice::DoubleSeq& timestamps, const double startTime, const double endTime)
+    {
+        Ice::DoubleSeq normTimestamps;
+        normTimestamps.resize(timestamps.size());
+        const double minValue = *timestamps.begin();
+        const double maxValue = *timestamps.rbegin();
+        const double duration = maxValue - minValue;
+
+        for (size_t i = 0; i < timestamps.size(); i++)
+        {
+            normTimestamps[i] = startTime + (timestamps.at(i) - minValue) / duration * (endTime - startTime);
+        }
+
+        return normTimestamps;
+    }
+
+
+    Trajectory Trajectory::normalizeTimestamps(const Trajectory& traj, const double startTime, const double endTime)
+    {
+
+        if (traj.size() <= 1 || (traj.begin()->timestamp == startTime && traj.rbegin()->timestamp == endTime))
+        {
+            return traj;    // already normalized
+        }
+
+
+        Ice::DoubleSeq timestamps = traj.getTimestamps();
+
+
+        Ice::DoubleSeq normTimestamps = normalizeTimestamps(timestamps, startTime, endTime);
+        Trajectory normExampleTraj;
+
+        for (size_t dim = 0; dim < traj.dim(); dim++)
+        {
+            Ice::DoubleSeq dimensionData  =  traj.getDimensionData(dim);
+            normExampleTraj.addDimension(normTimestamps, dimensionData);
+        }
+
+        return normExampleTraj;
+
+
+    }
+
+
+
+
+
+
+
+    size_t Trajectory::addDimension(const Ice::DoubleSeq& x, const Ice::DoubleSeq& y, const std::string name)
+    {
+
+        size_t newDim = dim() + 1;
+
+        __addDimension();
+
+        addPositionsToDimension(newDim - 1, x, y);
+        dimensionNames.push_back(name);
+        return newDim - 1;
+    }
+
+    void Trajectory::removeDimension(size_t dimension)
+    {
+        typename timestamp_view::iterator itMap = dataMap.begin();
+
+        for (; itMap != dataMap.end(); itMap++)
+        {
+            std::vector< DoubleSeqPtr >& data = itMap->data;
+
+            if (dimension < data.size())
+            {
+                data.erase(data.begin() + dimension);
+            }
+        }
+        if (dimension < dimensionNames.size())
+        {
+            dimensionNames.erase(dimensionNames.begin() + dimension);
+        }
+    }
+
+    void Trajectory::removeDerivation(size_t deriv)
+    {
+        typename timestamp_view::iterator itMap = dataMap.begin();
+
+        for (; itMap != dataMap.end(); itMap++)
+        {
+            std::vector< DoubleSeqPtr >& data = itMap->data;
+
+            for (size_t i = 0; i < data.size(); i++)
+            {
+                DoubleSeqPtr& vec = data.at(i);
+
+                if (deriv + 1 <  vec->size())
+                {
+                    vec->resize(deriv);
+                }
+            }
+        }
+    }
+
+    void Trajectory::removeDerivation(size_t dimension, size_t deriv)
+    {
+        typename timestamp_view::iterator itMap = dataMap.begin();
+
+        for (; itMap != dataMap.end(); itMap++)
+        {
+            std::vector< DoubleSeqPtr >& data = itMap->data;
+
+            if (data.size() > dimension && deriv + 1 < data.at(dimension)->size())
+            {
+                data.at(dimension)->resize(deriv);
+            }
+        }
+    }
+
+    Trajectory::ordered_view::const_iterator Trajectory::begin() const
+    {
+        return dataMap.get<TagOrdered>().begin();
+    }
+
+    Trajectory::ordered_view::const_iterator Trajectory::end() const
+    {
+        return dataMap.get<TagOrdered>().end();
+    }
+
+    Trajectory::ordered_view::const_reverse_iterator Trajectory::rbegin() const
+    {
+        return dataMap.get<TagOrdered>().rbegin();
+    }
+
+    Trajectory::ordered_view::const_reverse_iterator Trajectory::rend() const
+    {
+        return dataMap.get<TagOrdered>().rend();
+    }
+
+    std::vector<DoubleSeqPtr>& Trajectory::operator[](double timestamp)
+    {
+        return getStates(timestamp);
+    }
+
+
+
+    void Trajectory::addPositionsToDimension(size_t dimension, const Ice::DoubleSeq& x, const Ice::DoubleSeq& y)
+    {
+        if (dimension >= dim() && dim() > 0)
+        {
+            addDimension(x, y);
+        }
+        else
+        {
+            BOOST_ASSERT(x.size() == y.size());
+
+            for (size_t i = 0; i < x.size(); ++i)
+            {
+                checkValue(x[i]);
+                checkValue(y[i]);
+                setPositionEntry(x[i], dimension, y[i]);
+            }
+        }
+    }
+
+
+    void Trajectory::addDerivationsToDimension(size_t dimension, const double t, const Ice::DoubleSeq& derivs)
+    {
+        setEntries(t, dimension, derivs);
+    }
+
+    Trajectory::TrajData::TrajData(Trajectory& traj) :
+        trajectory(traj)
+    {
+
+    }
+
+    void Trajectory::shiftTime(double shift)
+    {
+        const ordered_view& ordv = dataMap.get<TagOrdered>();
+        typename ordered_view::const_iterator itMap = ordv.begin();
+
+        for (; itMap != ordv.end(); itMap++)
+        {
+            //itMap->timestamp -= shift;
+        }
+    }
+
+    void Trajectory::shiftValue(const Ice::DoubleSeq& shift)
+    {
+        if (shift.size() > dim())
+        {
+            throw LocalException("dimension is out of range: ") << shift.size() << " actual dimensions: " << dim();
+        }
+
+
+        for (size_t dimension = 0; dimension < dim(); dimension++)
+        {
+            const ordered_view& ordv = dataMap.get<TagOrdered>();
+            typename ordered_view::const_iterator itMap = ordv.begin();
+
+            for (; itMap != ordv.end(); itMap++)
+            {
+                itMap->data[dimension]->at(0) += shift[dimension];
+            }
+        }
+
+    }
+
+
+} // namespace armarx
diff --git a/source/RobotAPI/libraries/core/Trajectory.h b/source/RobotAPI/libraries/core/Trajectory.h
new file mode 100644
index 0000000000000000000000000000000000000000..3573e5dd8c6006fcbf9ef834fd318df62c49e1fa
--- /dev/null
+++ b/source/RobotAPI/libraries/core/Trajectory.h
@@ -0,0 +1,327 @@
+/*
+ * This file is part of ArmarX.
+ *
+ * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @package    ArmarX
+ * @author     Mirko Waechter( mirko.waechter at kit dot edu)
+ * @date       2016
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+#ifndef ARMARX_ROBOTAPI_TRAJECTORY_H
+#define ARMARX_ROBOTAPI_TRAJECTORY_H
+
+
+#include <boost/tokenizer.hpp>
+#include <boost/unordered_map.hpp>
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/hashed_index.hpp>
+#include <boost/multi_index/random_access_index.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/member.hpp>
+#include <boost/typeof/typeof.hpp>
+#include <boost/shared_ptr.hpp>
+#include <ArmarXCore/core/exceptions/Exception.h>
+#include <ArmarXCore/core/exceptions/local/ExpressionException.h>
+#include <ArmarXCore/observers/variant/Variant.h>
+
+
+#include <Eigen/Core>
+
+
+#include <RobotAPI/interface/core/Trajectory.h>
+namespace armarx
+{
+
+    namespace VariantType
+    {
+        // Variant types
+        const VariantTypeId Trajectory = Variant::addTypeName("::armarx::TrajectoryBase");
+    }
+
+    typedef boost::shared_ptr<Ice::DoubleSeq> DoubleSeqPtr;
+
+    class Trajectory;
+    typedef IceInternal::Handle<Trajectory> TrajectoryPtr;
+
+    /**
+     * @class The Trajectory class represents n-dimensional sampled trajectories.
+     * @ingroup VariantsGrp
+     *
+     * The class interpolates all missing values with linear interpolation and calculates derivations.
+     * This means dimensions with different timestamps can easily be used.
+     * Access complexity for a  query with a timestamp is like from an unordered_map
+     *
+     * Basic usage:
+     * \verbatim
+     * Ice::DoubleSeq myPositionValues // fill with your values;
+     * Ice::DoubleSeq timestamps = Trajectory::GenerateTimestamps(0, 1); // if you dont have timestamps
+     * Trajectory trajectory;
+     * trajectory.addDimension(timestamps, myPositionValues, "Shoulder 1 L");
+     *
+     * double timestamp = 0.1;
+     * double dimension = 0;
+     * double derivation = 0;
+     * double pos = trajectory.getState(timestamp, dimension, derivation);
+     * // or
+     * Ice::DoubleSeq positions = getDimensionData(dimension, derivation);
+     * \endverbatim
+     */
+    class Trajectory : public TrajectoryBase
+    {
+    public:
+        // Object interface
+        void ice_preMarshal();
+        void ice_postUnmarshal();
+
+        // Serializable interface
+        void serialize(const ObjectSerializerBasePtr& obj, const Ice::Current& = Ice::Current()) const;
+        void deserialize(const ObjectSerializerBasePtr&, const Ice::Current& = Ice::Current());
+
+        // VariantDataClass interface
+        VariantDataClassPtr clone(const Ice::Current& c = Ice::Current()) const;
+        std::string output(const Ice::Current& c = Ice::Current()) const;
+        Ice::Int getType(const Ice::Current& c = Ice::Current()) const;
+        bool validate(const Ice::Current& c = Ice::Current());
+
+        Ice::ObjectPtr ice_clone() const;
+
+
+        typedef std::map<double, std::vector< DoubleSeqPtr > > TrajMap;
+
+
+        struct TrajData
+        {
+            TrajData(Trajectory& traj);
+            DoubleSeqPtr operator[](size_t dim)
+            {
+                return data.at(dim);
+            }
+            inline double getTimestamp() const
+            {
+                return timestamp;
+            }
+            inline double getPosition(int dim) const
+            {
+                return getDeriv(dim, 0);
+            }
+            inline double getDeriv(size_t dim, size_t derivation) const
+            {
+                return trajectory.getState(timestamp, dim, derivation);
+            }
+            inline const std::vector< DoubleSeqPtr >& getData() const
+            {
+                return data;
+            }
+
+            double timestamp;
+            mutable std::vector< DoubleSeqPtr > data; // mutable so that it can be changed
+            Trajectory& trajectory;
+            friend class Trajectory;
+
+        };
+
+        // structs for indices
+        struct TagTimestamp {};
+        struct TagOrdered {};
+
+
+        // Trajectory data container
+        typedef 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> > // this index represents timestamp incremental order
+        >
+        > TrajDataContainer;
+        typedef typename boost::multi_index::index<TrajDataContainer, TagTimestamp>::type timestamp_view;
+        typedef typename boost::multi_index::index<TrajDataContainer, TagOrdered>::type ordered_view;
+
+
+
+        Trajectory() {}
+        Trajectory(const Trajectory& source);
+        Trajectory(const Ice::DoubleSeq& timestamps, const Ice::DoubleSeq& values, const std::string& dimensionName = "");
+
+        /**
+         * Constructor to add n-dimensions with m-values.
+         * @param data data vector with positions. Dimension 1 is the joint dimension and Dimension is the position of that joint.
+         * @param timestamps timestamps of the trajectory. If not empty, need to be of same size as the inner values of data.
+         * If empty, timestamps from 0..1 are generated with a stepsize aligned with the size of the inner vector of data.
+         *
+         */
+        template <typename T>
+        Trajectory(const std::vector<std::vector<T>>& data, const Ice::DoubleSeq timestamps = Ice::DoubleSeq(), const Ice::StringSeq& dimensionNames = "")
+        {
+            if (data.size() == 0)
+            {
+                return;
+            }
+            Ice::DoubleSeq generatedTimestamps;
+            ARMARX_CHECK_EXPRESSION(timestamps.size() ==  0 || data.at(0).size() == timestamps.size());
+            ARMARX_CHECK_EXPRESSION(data.size() == dimensionNames.size());
+            if (timestamps.size() == 0)
+            {
+                generatedTimestamps = GenerateTimestamps(0, 1, 1.0 / (data.at(0).size() - 1));
+            }
+            const auto& tempTimestamps = timestamps.size() > 0 ? timestamps : generatedTimestamps;
+            size_t i = 0;
+            for (const auto & subvec : data)
+            {
+                Ice::DoubleSeq dvec(subvec.begin(), subvec.end());
+                addDimension(tempTimestamps, dvec, dimensionNames.at(i++));
+            }
+        }
+
+        Trajectory(const std::map<double, Ice::DoubleSeq>& data);
+
+
+        Trajectory& operator=(const Trajectory& source);
+
+
+        size_t addDimension(const Ice::DoubleSeq& timestamps, const Ice::DoubleSeq& values, const std::string name = "");
+        void addPositionsToDimension(size_t dimension, const Ice::DoubleSeq& x, const Ice::DoubleSeq& y);
+        void addDerivationsToDimension(size_t dimension, const double t, const Ice::DoubleSeq& derivs);
+        Trajectory& operator+=(const Trajectory traj);
+        void removeDimension(size_t dimension);
+        void removeDerivation(size_t deriv);
+        void removeDerivation(size_t dimension, size_t deriv);
+
+        // iterators
+        typename ordered_view::const_iterator begin() const;
+        typename ordered_view::const_iterator end() const;
+        typename ordered_view::const_reverse_iterator rbegin() const;
+        typename ordered_view::const_reverse_iterator rend() const;
+
+        ///// getters
+        std::vector<DoubleSeqPtr>& operator[](double timestamp);
+        Ice::DoubleSeq getTimestamps() const;
+        std::vector<DoubleSeqPtr>& getStates(double t);
+        std::vector<DoubleSeqPtr> getStates(double t) const;
+        Ice::DoubleSeq getStates(double t, size_t derivation) const;
+        template<typename T>
+        std::map<std::string, T> getStatesMap(double t, size_t derivation = 0) const
+        {
+            std::map<std::string, T> result;
+            size_t dimensions = dim();
+
+            for (size_t dim = 0; dim < dimensions; dim++)
+            {
+                result[getDimensionName(dim)] = getState(t, dim, derivation);
+            }
+
+            return result;
+        }
+
+        double getState(double t, size_t dim = 0, size_t deriv = 0);
+        double getState(double t, size_t dim = 0, size_t deriv = 0) const;
+        Ice::DoubleSeq getDerivations(double t, size_t dimension, size_t derivations)  const;
+        std::string getDimensionName(size_t dim) const;
+        Ice::StringSeq getDimensionNames() const;
+
+        TrajDataContainer& data();
+
+        /**
+         * @brief getDimensionData gets all entries for one dimensions with order of increasing timestamps
+         * @param dimension
+         * @return
+         */
+        //        Ice::DoubleSeq getDimensionData(size_t dimension = 0) const;
+        Ice::DoubleSeq getDimensionData(size_t dimension, size_t deriv = 0) const;
+        Eigen::VectorXd getDimensionDataAsEigen(size_t dimension, size_t derivation) const;
+        Eigen::VectorXd getDimensionDataAsEigen(size_t dimension, size_t derivation, double startTime, double endTime) const;
+        Eigen::MatrixXd toEigen(size_t derivation, double startTime, double endTime) const;
+        Eigen::MatrixXd toEigen(size_t derivation = 0) const;
+        Trajectory getPart(double startTime, double endTime, size_t numberOfDerivations = 0) const;
+        /**
+         * @brief dim returns the trajectory dimension count for this trajectory (e.g. taskspace w/o orientation would be 3)
+         * @return
+         */
+        size_t dim() const;
+        size_t size() const;
+        double getTimeLength() const;
+        double getSpaceLength(size_t dimension, size_t stateDim) const;
+        double getSpaceLength(size_t dimension, size_t stateDim, double startTime, double endTime) const;
+        double getSquaredSpaceLength(size_t dimension, size_t stateDim) const;
+        double getSquaredSpaceLength(size_t dimension, size_t stateDim, double startTime, double endTime) const;
+        double getMax(size_t dimension, size_t stateDim, double startTime, double endTime) const;
+        double getMin(size_t dimension, size_t stateDim, double startTime, double endTime) const;
+        double getWithFunc(const double & (*foo)(const double&, const double&), double initValue, size_t dimension, size_t stateDim, double startTime, double endTime) const;
+        double getTrajectorySpace(size_t dimension, size_t stateDim, double startTime, double endTime) const;
+        Ice::DoubleSeq getMinima(size_t dimension, size_t stateDim, double startTime, double endTime) const;
+        Ice::DoubleSeq getMaxima(size_t dimension, size_t stateDim, double startTime, double endTime) const;
+        Ice::DoubleSeq getMinimaPositions(size_t dimension, size_t stateDim, double startTime, double endTime) const;
+        Ice::DoubleSeq getMaximaPositions(size_t dimension, size_t stateDim, double startTime, double endTime) const;
+
+        // calculations
+
+        Ice::DoubleSeq getDiscreteDifferentiationForDim(size_t trajDimension, size_t derivation) const;
+        static Ice::DoubleSeq DifferentiateDiscretly(const Ice::DoubleSeq& timestamps, const Ice::DoubleSeq& values, int derivationCount = 1);
+        double getDiscretDifferentiationForDimAtT(double t, size_t trajDimension, size_t deriv) const;
+
+        void differentiateDiscretlyForDim(size_t trajDimension, size_t derivation);
+        void differentiateDiscretly(size_t derivation);
+        //        void differentiateDiscretly( size_t sourceDimOfSystemState, size_t targetDimOfSystemState);
+
+        void reconstructFromDerivativeForDim(double valueAtFirstTimestamp, size_t trajDimension, size_t sourceDimOfSystemState, size_t targetDimOfSystemState);
+
+        /**
+         * @brief negateDim changes the sign of all values of the given dimension.
+         */
+        void negateDim(size_t trajDimension);
+        /**
+         * @brief gaussianFilter smoothes the trajectory
+         * @param filterRadius, in easy words: time range to left and right from center that
+         * influences the resulting center value
+         */
+        void gaussianFilter(double filterRadius);
+
+        static Trajectory normalizeTimestamps(const Trajectory& traj, const double startTime = 0.0,  const double endTime = 1.0);
+        static Ice::DoubleSeq normalizeTimestamps(const Ice::DoubleSeq& timestamps, const double startTime = 0.0,  const double endTime = 1.0);
+        static Ice::DoubleSeq GenerateTimestamps(double startTime = 0.0, double endTime = 1.0, double stepSize = 0.001);
+        void shiftTime(double shift);
+        void shiftValue(const Ice::DoubleSeq& shift);
+
+
+        static void CopyData(const Trajectory& source, Trajectory& destination);
+        void clear();
+        void setPositionEntry(const double t, const size_t dimIndex, const double& y);
+        void setEntries(const double t, const size_t dimIndex, const Ice::DoubleSeq& y);
+        bool dataExists(double t, size_t dimension = 0, size_t deriv = 0) const;
+
+
+        std::map<double, Ice::DoubleSeq> getStatesAround(double t, size_t derivation, size_t extend) const;
+
+    protected:
+        void __addDimension();
+        void __fillAllEmptyFields();
+        double __interpolate(typename ordered_view::const_iterator itMap, size_t dimension, size_t deriv) const;
+        double __gaussianFilter(double filterRadius , typename ordered_view::iterator centerIt , size_t trajNum, size_t dim);
+        timestamp_view::iterator __fillBaseDataAtTimestamp(const double& t);
+        std::vector<DoubleSeqPtr> __calcBaseDataAtTimestamp(const double& t) const;
+
+
+        TrajDataContainer dataMap;
+
+        virtual double __interpolate(double t, ordered_view::const_iterator itPrev, ordered_view::const_iterator itNext, size_t dimension, size_t deriv) const;
+        double __interpolate(double t, size_t dimension, size_t deriv) const;
+
+
+    };
+
+}
+
+#endif
diff --git a/source/RobotAPI/libraries/core/VectorHelpers.h b/source/RobotAPI/libraries/core/VectorHelpers.h
new file mode 100644
index 0000000000000000000000000000000000000000..04fbfd27e9473ca1f6affeca99b638b4541440f0
--- /dev/null
+++ b/source/RobotAPI/libraries/core/VectorHelpers.h
@@ -0,0 +1,322 @@
+/*
+ * This file is part of ArmarX.
+ *
+ * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
+ *
+ * ArmarX is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ArmarX is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @package    ArmarX
+ * @author     Mirko Waechter( mirko.waechter at kit dot edu)
+ * @date       2016
+ * @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+ *             GNU General Public License
+ */
+#ifndef VECTORHELPERS_H
+#define VECTORHELPERS_H
+
+#include <ArmarXCore/core/exceptions/Exception.h>
+
+#include <eigen3/Eigen/Geometry>
+#include <cmath>
+#include <map>
+#include <vector>
+#include <limits>
+
+namespace armarx
+{
+    template<class T>
+    inline void checkValue(const T& value)
+    {
+        if (std::numeric_limits<T>::infinity() == value)
+        {
+            throw LocalException("result value is inf");
+        }
+
+        if (value != value)
+        {
+            throw LocalException("result value is nan");
+        }
+    }
+
+    template<class T>
+    inline void checkValues(const std::vector<T >& values)
+    {
+        for (size_t i = 0; i < values.size(); ++i)
+        {
+            checkValue(values[i]);
+        }
+    }
+
+
+
+    template <class T> std::vector<T> operator -(const std::vector<T>& v1, const std::vector<T>& v2)
+    {
+        std::vector<T> res(std::min(v1.size(), v2.size()), T());
+        int j = 0;
+
+        for (typename std::vector<T>::iterator i = res.begin(); i != res.end(); ++i)
+        {
+            *i = v1[j] - v2[j];
+            ++j;
+        }
+
+        return res;
+    }
+
+    template <class T> std::vector<T> operator +(const std::vector<T>& v1, const std::vector<T>& v2)
+    {
+        std::vector<T> res(std::min(v1.size(), v2.size()), T());
+        int j = 0;
+
+        for (typename std::vector<T>::iterator i = res.begin(); i != res.end(); ++i)
+        {
+            *i = v1[j] + v2[j];
+            ++j;
+        }
+
+        return res;
+    }
+
+    template <class T> std::vector<T>& operator +=(std::vector<T>& v1, const std::vector<T>& v2)
+    {
+        int j = 0;
+
+        for (typename std::vector<T>::iterator i = v1.begin(); i != v1.end(); ++i)
+        {
+            *i += v2[j];
+            ++j;
+        }
+
+        return v1;
+    }
+
+
+    template <class T> std::vector<T>& operator -=(std::vector<T>& v1, const std::vector<T>& v2)
+    {
+        int j = 0;
+
+        for (typename std::vector<T>::iterator i = v1.begin(); i != v1.end(); ++i)
+        {
+            *i -= v2[j];
+            ++j;
+        }
+
+        return v1;
+    }
+
+    template <class T> std::vector<T>& operator *=(std::vector<T>& v1, double c)
+    {
+        int j = 0;
+
+        for (typename std::vector<T>::iterator i = v1.begin(); i != v1.end(); ++i)
+        {
+            *i *= c;
+            ++j;
+        }
+
+        return v1;
+    }
+
+
+
+    template <class T> std::vector<T>& operator /=(std::vector<T>& v1, double c)
+    {
+        int j = 0;
+
+        for (typename std::vector<T>::iterator i = v1.begin(); i != v1.end(); ++i)
+        {
+            *i /= c;
+            ++j;
+        }
+
+        return v1;
+    }
+
+    template <class T> std::vector<T> operator *(double c, const std::vector<T>& v)
+    {
+        std::vector<T> res(v.size(), T());
+        int j = 0;
+
+        for (typename std::vector<T>::iterator i = res.begin(); i != res.end(); ++i)
+        {
+            *i = c * v[j];
+            ++j;
+        }
+
+        return res;
+    }
+
+    template <class T> double operator *(const std::vector<T>& v, const std::vector<T>& v2)
+    {
+        double res = 0;
+
+        if (v.size() != v2.size())
+        {
+            throw LocalException("vectors do not match in size: ") << v.size() << " vs. " << v2.size();
+        }
+
+        int j = 0;
+
+        for (typename std::vector<T>::const_iterator i = v.begin(); i != v.end(); ++i)
+        {
+            res += *i * v2[j];
+            ++j;
+        }
+
+        return res;
+    }
+
+
+    template <class T> std::vector<T> operator +(const std::vector<T>& v, double s)
+    {
+        std::vector<T> res(v.size(), T());
+        int j = 0;
+
+        for (typename std::vector<T>::iterator i = res.begin(); i != res.end(); ++i)
+        {
+            *i = v[j] + s;
+            ++j;
+        }
+
+        return res;
+    }
+
+    template <class T> std::vector<T> operator -(const std::vector<T>& v, double s)
+    {
+        std::vector<T> res(v.size(), T());
+        int j = 0;
+
+        for (typename std::vector<T>::iterator i = res.begin(); i != res.end(); ++i)
+        {
+            *i = v[j] - s;
+            ++j;
+        }
+
+        return res;
+    }
+
+    template <class T> double vecLength(const std::vector<T>& v)
+    {
+        double result = 0.0;
+
+        for (typename std::vector<T>::const_iterator it = v.begin(); it != v.end(); it++)
+        {
+            result += *it** it;
+        }
+
+        return sqrt(result);
+    }
+
+    template <class T> double vecSum(const std::vector<T>& v)
+    {
+        double result = 0.0;
+
+        for (typename std::vector<T>::const_iterator it = v.begin(); it != v.end(); it++)
+        {
+            result += *it;
+        }
+
+        return result;
+    }
+
+    template <class T> std::vector<T> normalizedVec(const std::vector<T>& v)
+    {
+        double length = vecLength(v);
+        std::vector<T> result = v;
+        result /= length;
+        return result;
+    }
+
+    template <class T> std::vector<T> operator /(const std::vector<T>& v, double c)
+    {
+        std::vector<T> res(v.size(),  T());
+        int j = 0;
+
+        for (typename std::vector<T>::iterator i = res.begin(); i != res.end(); ++i)
+        {
+            *i = v[j] / c;
+            ++j;
+        }
+
+        return res;
+    }
+
+    template <class T> std::vector<T> abs(const std::vector<T>& v)
+    {
+        std::vector<T> res(v.size(), T());
+        int j = 0;
+
+        for (typename std::vector<T>::iterator i = res.begin(); i != res.end(); ++i)
+        {
+            *i = fabs(v[j]);
+            ++j;
+        }
+
+        return res;
+    }
+
+    template <class T> std::vector<T> max(const std::vector<T>& v1, const std::vector<T>& v2)
+    {
+        std::vector<T> res(std::min(v1.size(), v2.size()), T());
+        int j = 0;
+
+        for (typename std::vector<T>::iterator i = res.begin(); i != res.end(); ++i)
+        {
+            *i = std::max(v1[j], v2[j]);
+            ++j;
+        }
+
+        return res;
+    }
+
+    template <class T> T max(const std::vector<T>& v1)
+    {
+        T maxValue = std::numeric_limits<T>::min();
+
+        for (typename std::vector<T>::const_iterator i = v1.begin(); i != v1.end(); ++i)
+        {
+            maxValue = std::max(maxValue, *i);
+
+        }
+
+        return maxValue;
+    }
+
+    template <class T> std::vector<T> min(const std::vector<T>& v1, const std::vector<T>& v2)
+    {
+        std::vector<T> res(std::min(v1.size(), v2.size()));
+        int j = 0;
+
+        for (typename std::vector<T>::iterator i = res.begin(); i != res.end(); ++i)
+        {
+            *i = std::min(v1[j], v2[j]);
+            ++j;
+        }
+
+        return res;
+    }
+
+    template <class T> T min(const std::vector<T>& v1)
+    {
+        T minValue = std::numeric_limits<T>::max();
+
+        for (typename std::vector<T>::const_iterator i = v1.begin(); i != v1.end(); ++i)
+        {
+            minValue = std::min(minValue, *i);
+
+        }
+
+        return minValue;
+    }
+}
+#endif //
diff --git a/source/RobotAPI/libraries/core/test/CMakeLists.txt b/source/RobotAPI/libraries/core/test/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..35d29e49c514f5f7e957e937b8d33eeb034cab0a
--- /dev/null
+++ b/source/RobotAPI/libraries/core/test/CMakeLists.txt
@@ -0,0 +1,4 @@
+set(LIBS ${LIBS} RobotAPICore )
+
+armarx_add_test(TrajectoryTest TrajectoryTest.cpp "${LIBS}")
+
diff --git a/source/RobotAPI/libraries/core/test/TrajectoryTest.cpp b/source/RobotAPI/libraries/core/test/TrajectoryTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..65289894b8f0065fb63d782e6852f651985f2703
--- /dev/null
+++ b/source/RobotAPI/libraries/core/test/TrajectoryTest.cpp
@@ -0,0 +1,222 @@
+/*
+* This file is part of ArmarX.
+*
+* ArmarX is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License version 2 as
+* published by the Free Software Foundation.
+*
+* ArmarX is distributed in the hope that it will be useful, but
+* WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+* @package    ArmarX::RobotAPI::Test
+* @author     Nils Adermann (naderman at naderman dot de)
+* @date       2010
+* @copyright  http://www.gnu.org/licenses/gpl-2.0.txt
+*             GNU General Public License
+*/
+
+#define BOOST_TEST_MODULE RobotAPI::Trajectory::Test
+#define ARMARX_BOOST_TEST
+#include <RobotAPI/Test.h>
+#include <ArmarXCore/core/test/IceTestHelper.h>
+#include <ArmarXCore/util/json/JSONObject.h>
+#include "../Trajectory.h"
+using namespace armarx;
+
+
+//BOOST_AUTO_TEST_CASE(testTrajectoryLoading)
+//{
+//    // Load the trajectory
+//    Trajectory traj;
+//    //    traj.readFromCSVFile("pouring_x_short.csv");
+//    //    traj.readFromCSVFile("sampletraj_withvel_shortened.csv.txt");
+//    traj.readFromCSVFile(std::string(DATA_DIR) + "/ExampleTrajectories/pouring_x_short.csv");
+//    BOOST_CHECK(traj.begin()->getPosition(0) == 445.35);
+//    traj = Trajectory::normalizeTimestamps(traj, 0, 1);
+//    Ice::DoubleSeq timestamps = traj.getTimestamps();
+//    traj.differentiateDiscretly(2);
+//    Ice::DoubleSeq d0 = traj.getDimensionData(0, 0);
+//    Ice::DoubleSeq d1 = traj.getDimensionData(0, 1);
+//    BOOST_CHECK(traj.begin()->getDeriv(0, 1) == d1.at(0));
+//    std::cout << "end" << std::endl;
+//}
+
+//#define SIGN_FACTOR(x) ((x>=0)?1:-1)
+
+//BOOST_AUTO_TEST_CASE(testExtrapolation)
+//{
+//    // Load the trajectory
+//    Trajectory traj;
+//    //    traj.readFromCSVFile("pouring_x_short.csv");
+//    //    traj.readFromCSVFile("sampletraj_withvel_shortened.csv.txt");
+//    traj.readFromCSVFile(std::string(DATA_DIR) + "/ExampleTrajectories/pouring_x_short.csv");
+
+//    //    traj = Trajectory::normalizeTimestamps(traj,0,1);
+//    Ice::DoubleSeq timestamps = traj.getTimestamps();
+//    traj.differentiateDiscretly(2);
+//    double first = traj.begin()->getPosition(0);
+//    double derivFirst = traj.begin()->getDeriv(0, 1);
+//    double before = traj.getState(timestamps.at(0) - 5, 0, 0);
+//    BOOST_CHECK(before < SIGN_FACTOR(derivFirst) * first);
+//    std::cout << "end" << std::endl;
+//}
+
+//BOOST_AUTO_TEST_CASE(testInplaceInterpolation)
+//{
+//    // Load the trajectory
+//    Trajectory traj;
+//    //    traj.readFromCSVFile("pouring_x_short.csv");
+//    //    traj.readFromCSVFile("sampletraj_withvel_shortened.csv.txt");
+//    traj.readFromCSVFile(std::string(DATA_DIR) + "/ExampleTrajectories/pouring_x_short.csv");
+//    Ice::DoubleSeq timestamps = traj.getTimestamps();
+//    double middle = (timestamps.at(1) + timestamps.at(0)) * 0.5;
+//    double before = traj.getState(timestamps.at(0));
+//    double after = traj.getState(timestamps.at(1));
+//    double interpolation = traj.getState(middle);
+//    BOOST_CHECK(before < interpolation && after > interpolation);
+//    std::cout << "end" << std::endl;
+//}
+
+//BOOST_AUTO_TEST_CASE(testDerivation)
+//{
+//    // Load the trajectory
+//    Trajectory traj;
+//    //    traj.readFromCSVFile("pouring_x_short.csv");
+//    //    traj.readFromCSVFile("sampletraj_withvel_shortened.csv.txt");
+//    traj.readFromCSVFile(std::string(DATA_DIR) + "/ExampleTrajectories/pouring_x_short.csv");
+//    traj.differentiateDiscretly(1);
+//    traj.differentiateDiscretly(2);
+//    Trajectory traj2;
+//    traj2.readFromCSVFile(std::string(DATA_DIR) + "/ExampleTrajectories/pouring_x_short.csv");
+//    traj2.differentiateDiscretly(2);
+
+//    BOOST_CHECK_EQUAL(traj.begin()->getDeriv(0, 2), traj2.begin()->getDeriv(0, 2));
+//    BOOST_CHECK_EQUAL(traj.rbegin()->getDeriv(0, 2), traj2.rbegin()->getDeriv(0, 2));
+//    BOOST_CHECK_EQUAL(traj.rbegin()->getDeriv(0, 1), traj2.rbegin()->getDeriv(0, 1));
+//    double middleTimestamp = traj.getTimestamps().at(0) + traj.getTimeLength() / 2;
+//    BOOST_CHECK_EQUAL(traj.getState(middleTimestamp, 0, 2), traj2.getState(middleTimestamp, 0, 2));
+//    BOOST_CHECK_EQUAL(traj.getState(middleTimestamp, 0, 1), traj2.getState(middleTimestamp, 0, 1));
+//    std::cout << "end" << std::endl;
+//}
+
+
+
+//BOOST_AUTO_TEST_CASE(testInplaceDerivation)
+//{
+//    // Load the trajectory
+//    Trajectory traj;
+//    //    traj.readFromCSVFile("pouring_x_short.csv");
+//    //    traj.readFromCSVFile("sampletraj_withvel_shortened.csv.txt");
+//    traj.readFromCSVFile(std::string(DATA_DIR) + "/ExampleTrajectories/pouring_x_short.csv");
+//    double d2 = traj.begin()->getDeriv(0, 2);
+//    BOOST_CHECK(d2 != 0);
+//    std::cout << "end" << std::endl;
+//}
+
+BOOST_AUTO_TEST_CASE(testInplaceDerivation2)
+{
+    // Load the trajectory
+    Ice::DoubleSeq timestamps { 0, 1, 2 };
+    Ice::DoubleSeq positions { 1, 2, 5 };
+
+    Trajectory traj(timestamps, positions);
+    Trajectory traj2(timestamps, positions);
+    traj.differentiateDiscretly(1);
+    BOOST_CHECK_EQUAL(traj.getState(-1, 0, 1), traj2.getState(-1, 0, 1));
+}
+
+BOOST_AUTO_TEST_CASE(testInplaceDerivation3)
+{
+    // Load the trajectory
+    Ice::DoubleSeq timestamps { 0, 1, 2 };
+    Ice::DoubleSeq positions { 1, 2, 5 };
+
+    Trajectory traj(timestamps, positions);
+    Trajectory traj2(timestamps, positions);
+    traj.differentiateDiscretly(2);
+    BOOST_CHECK_EQUAL(traj.getState(-1, 0, 2), traj2.getState(-1, 0, 2));
+}
+
+BOOST_AUTO_TEST_CASE(testDerivationRemoval)
+{
+    // Load the trajectory
+    Ice::DoubleSeq timestamps { 0, 1, 2 };
+    Ice::DoubleSeq positions { 1, 2, 5 };
+
+    Trajectory traj(timestamps, positions);
+    //    Trajectory traj2(timestamps, positions);
+    traj.differentiateDiscretly(2);
+    BOOST_CHECK_EQUAL(traj.begin()->getData().at(0)->size(), 3);
+    traj.removeDerivation(1);
+    BOOST_CHECK_EQUAL(traj.begin()->getData().at(0)->size(), 1);
+}
+
+
+
+BOOST_AUTO_TEST_CASE(TrajectoryMarshalTest)
+{
+    // Load the trajectory
+    Ice::DoubleSeq timestamps { 0, 1, 2 };
+    Ice::DoubleSeq positions { 1, 2, 5 };
+
+    Trajectory traj(timestamps, positions);
+    traj.ice_preMarshal();
+    TrajectoryPtr traj2 = TrajectoryPtr::dynamicCast(traj.clone());
+    traj2->clear();
+    traj2->ice_postUnmarshal();
+    BOOST_CHECK_EQUAL(traj.getState(0), traj2->getState(0));
+}
+
+BOOST_AUTO_TEST_CASE(TrajectoryPerformanceTest)
+{
+    // Load the trajectory
+    Ice::DoubleSeq timestamps;
+    int count = 1000;
+    for (int i = 0; i < count; ++i) {
+        timestamps.push_back(rand());
+    }
+    Trajectory traj;
+    for (int var = 0; var < 8; ++var) {
+        Ice::DoubleSeq p;
+        p.reserve(count);
+        for (int i = 0; i < count; ++i) {
+            p.push_back(rand());
+        }
+        traj.addDimension(timestamps, p);
+    }
+    ARMARX_INFO_S << "Starting";
+    traj.ice_preMarshal();
+    ARMARX_INFO_S << "Marshalled";
+    TrajectoryPtr traj2 = TrajectoryPtr::dynamicCast(traj.clone());
+    ARMARX_INFO_S << "Cloned";
+
+    traj2->clear();
+    ARMARX_INFO_S << "Cleared";
+    traj2->ice_postUnmarshal();
+    ARMARX_INFO_S << "Unmarshalled";
+
+    BOOST_CHECK_EQUAL(traj.getState(0), traj2->getState(0));
+}
+
+
+BOOST_AUTO_TEST_CASE(TrajectorySerializationTest)
+{
+    // Load the trajectory
+    FloatSeqSeq positions {{ 1, 2, 5 }, { 10, 2332, 53425 }};
+    JSONObjectPtr json = new JSONObject();
+    Trajectory traj(positions, {}, {"joint1", "joint2"});
+    traj.serialize(json);
+    ARMARX_INFO_S << json->asString(true);
+    Trajectory traj2;
+    traj2.deserialize(json);
+    BOOST_CHECK_CLOSE(traj.getState(0), traj2.getState(0), 0.01);
+    BOOST_CHECK_CLOSE(traj.getState(0.4,1), traj2.getState(0.4,1), 0.01);
+    BOOST_CHECK_EQUAL(traj.getDimensionName(0), traj2.getDimensionName(0));
+}
+
+