MinJerkTrajectory_Test.cpp
Go to the documentation of this file.
00001 /*
00002  * TrajectoryGenerator_Test.cpp
00003  *
00004  *  Created on: Aug 16, 2012
00005  *      Author: Ross Taylor
00006  */
00007 
00008 #include <iostream>
00009 #include <gtest/gtest.h>
00010 #include "robodyn_controllers/MinJerkTrajectoryFactory.h"
00011 #include <tf/tf.h>
00012 
00013 class TrajectoryGeneratorTest : public ::testing::Test
00014 {
00015 protected:
00016     virtual void SetUp()
00017     {
00018         ctg = new MinJerkCartesianTrajectoryFactory();
00019         jtg = new MinJerkJointTrajectoryFactory();
00020     }
00021 
00022     virtual void TearDown()
00023     {
00024         // delete stuff, etc.
00025         delete ctg;
00026         delete jtg;
00027     }
00028 
00029     MinJerkCartesianTrajectoryFactory*     ctg; // pointer for easy destruction between tests
00030     MinJerkJointTrajectoryFactory*         jtg; // pointer for easy destruction between tests
00031     boost::shared_ptr<CartesianTrajectory> ctptr;
00032     boost::shared_ptr<JointTrajectory>     jtptr;
00033 };
00034 
00035 // TEST_F uses SetUp/TearDown in Test above
00036 // second argument describes the test (make descriptive)
00037 TEST_F(TrajectoryGeneratorTest, minJerkCartGetSetTest)
00038 {
00039     // EXPECT_EQ (test equality)
00040     // EXPECT_FLOAT_EQ (test equality, with roundoff allowed)
00041     // EXPECT_TRUE
00042     // EXPECT_FALSE
00043     // EXPECT_THROW
00044     // google google test for more
00045 
00046     const double linVel = 0.05;
00047     const double rotVel = 0.3;
00048 
00049     // check set/get methods
00050     EXPECT_THROW(ctg->setVelocityLimits(-linVel, rotVel), std::invalid_argument);
00051     EXPECT_THROW(ctg->setVelocityLimits(linVel, -rotVel), std::invalid_argument);
00052 
00053     ctg->setVelocityLimits(linVel, rotVel);
00054     EXPECT_EQ(linVel, ctg->getLinearVelocityLimit());
00055     EXPECT_EQ(rotVel, ctg->getRotationalVelocityLimit());
00056 }
00057 
00058 TEST_F(TrajectoryGeneratorTest, minJerkCartTrajTest)
00059 {
00060     const double linVel = 0.05;
00061     const double rotVel = 0.3;
00062 
00063     ctg->setVelocityLimits(linVel, rotVel);
00064 
00065     // check trajectory
00066     KDL::FrameAcc currPose, desPose, startTest, endTest, testPose, testPose2;
00067     currPose.p.p.x(0.);
00068     currPose.p.p.y(0.);
00069     currPose.p.p.z(0.);
00070     currPose.M.R = KDL::Rotation::Quaternion(0, 0, 0, 1);
00071     desPose.p.p.x(1.);
00072     desPose.p.p.y(2.);
00073     desPose.p.p.z(3.);
00074     desPose.M.R = currPose.M.R;
00075     desPose.M.R.DoRotX(.3);
00076     desPose.M.R.DoRotY(.2);
00077     desPose.M.R.DoRotZ(.1);
00078     std::vector<KDL::FrameAcc> traj;
00079 
00080     ctptr = ctg->getTrajectory(currPose, desPose);
00081     ctptr->getPose(ctptr->getDuration(), endTest);
00082     EXPECT_EQ(desPose.GetFrame(), endTest.GetFrame());
00083     ctptr->getPose(0., startTest);
00084     EXPECT_EQ(currPose.GetFrame(), startTest.GetFrame());
00085 
00086     double         x, y, z, w;
00087     double         prevLinDist = 0.;
00088     double         totLinDist  = (endTest.p.p - startTest.p.p).Norm();
00089     startTest.M.R.GetQuaternion(x, y, z, w);
00090     tf::Quaternion startQuat(x, y, z, w);
00091     endTest.M.R.GetQuaternion(x, y, z, w);
00092     tf::Quaternion endQuat(x, y, z, w);
00093     double         totRotDist  = std::fabs(endQuat.angleShortestPath(startQuat));
00094     double         prevRotDist = 0.;
00095 
00096     double timeStep = 0.01;
00097     ctptr->getPose(0., testPose);
00098 
00099     for (double time = timeStep; time < ctptr->getDuration(); time += timeStep)
00100     {
00101         // check lin velocity
00102         testPose2 = testPose;
00103         ctptr->getPose(time, testPose);
00104         EXPECT_LE((testPose.p.p - testPose2.p.p).Norm() / timeStep, linVel);
00105         EXPECT_LE(testPose.p.v.Norm(), linVel);
00106 
00107         // check rot velocity
00108         testPose2.M.R.GetQuaternion(x, y, z, w);
00109         tf::Quaternion quat1(x, y, z, w);
00110         testPose.M.R.GetQuaternion(x, y, z, w);
00111         tf::Quaternion quat2(x, y, z, w);
00112         EXPECT_LE(std::fabs(quat2.angleShortestPath(quat1) / timeStep), rotVel);
00113         EXPECT_LE(testPose.M.w.Norm(), rotVel);
00114 
00115         // check distance along path
00116         double linDist = (testPose.p.p - startTest.p.p).Norm();
00117         EXPECT_GE(linDist, prevLinDist);
00118 
00119         if (totLinDist > 0)
00120         {
00121             EXPECT_GE(linDist / totLinDist, 0);
00122             EXPECT_LE(linDist / totLinDist, 1);
00123         }
00124 
00125         double linDistToEnd = (endTest.p.p - testPose.p.p).Norm();
00126         EXPECT_LE(totLinDist - linDistToEnd - linDist, 0.0001);
00127         prevLinDist = linDist;
00128 
00129         // check angle along path
00130         double rotDist = std::fabs(quat2.angleShortestPath(startQuat));
00131         EXPECT_GE(rotDist, prevRotDist);
00132 
00133         if (totRotDist > 0)
00134         {
00135             EXPECT_GE(rotDist / totRotDist, 0);
00136             EXPECT_LE(rotDist / totRotDist, 1);
00137         }
00138 
00139         double rotDistToEnd = std::fabs(quat2.angleShortestPath(endQuat));
00140         EXPECT_LE(totRotDist - rotDistToEnd - rotDist, 0.0001);
00141         prevRotDist = rotDist;
00142     }
00143 
00144     // give a longer time and make sure it takes longer
00145     double timeToFinish = ctptr->getDuration() * 2.;
00146     ctptr = ctg->getTrajectory(currPose, desPose, timeToFinish);
00147     EXPECT_EQ(timeToFinish, ctptr->getDuration());
00148 }
00149 
00150 TEST_F(TrajectoryGeneratorTest, minJerkCartZeroVelTrajTest)
00151 {
00152     const double linVel = 0.05;
00153     const double rotVel = 0.3;
00154 
00155     ctg->setVelocityLimits(0., rotVel);
00156 
00157     // check trajectory
00158     KDL::FrameAcc currPose, desPose;
00159     currPose.p.p.x(0.);
00160     currPose.p.p.y(0.);
00161     currPose.p.p.z(0.);
00162     currPose.M.R = KDL::Rotation::Quaternion(0, 0, 0, 1);
00163     desPose.p.p.x(1.);
00164     desPose.p.p.y(2.);
00165     desPose.p.p.z(3.);
00166     desPose.M.R = currPose.M.R;
00167     desPose.M.R.DoRotX(.3);
00168     desPose.M.R.DoRotY(.2);
00169     desPose.M.R.DoRotZ(.1);
00170     std::vector<KDL::FrameAcc> traj;
00171 
00172     EXPECT_THROW(ctg->getTrajectory(currPose, desPose), std::runtime_error);
00173 
00174     ctg->setVelocityLimits(linVel, 0.);
00175 
00176     EXPECT_THROW(ctg->getTrajectory(currPose, desPose), std::runtime_error);
00177 }
00178 
00179 TEST_F(TrajectoryGeneratorTest, minJerkJointGetSetTest)
00180 {
00181     std::vector<double> jntLimits(3);
00182     jntLimits.at(0) = .1;
00183     jntLimits.at(1) = .2;
00184     jntLimits.at(2) = .3;
00185 
00186     // check set/get methods
00187     jtg->setLimits(jntLimits, std::vector<double>(3));
00188     EXPECT_EQ(jntLimits, jtg->getVelocityLimits());
00189 
00190     for (unsigned int i = 0; i < jntLimits.size(); ++i)
00191     {
00192         EXPECT_EQ(jntLimits.at(i), jtg->getVelocityLimit(i));
00193     }
00194 
00195     EXPECT_ANY_THROW(jtg->getVelocityLimit(jntLimits.size())); // one past the end
00196 }
00197 
00198 TEST_F(TrajectoryGeneratorTest, minJerkJointTrajTest)
00199 {
00200     std::vector<double> jntLimits(5);
00201     jntLimits.at(0) = .1;
00202     jntLimits.at(1) = .2;
00203     jntLimits.at(2) = .3;
00204     jntLimits.at(3) = .15;
00205     jntLimits.at(4) = .25;
00206 
00207     KDL::JntArrayAcc jntStart(5);
00208     jntStart.q(0) = 0;
00209     jntStart.q(1) = 0;
00210     jntStart.q(2) = 0;
00211     jntStart.q(3) = 0;
00212     jntStart.q(4) = 0;
00213 
00214     KDL::JntArrayAcc jntEnd(5);
00215     jntEnd.q(0) = 15.*3.14 / 180;
00216     jntEnd.q(1) = 20.*3.14 / 180;
00217     jntEnd.q(2) = 30.*3.14 / 180;
00218     jntEnd.q(3) = 25.*3.14 / 180;
00219     jntEnd.q(4) = 10.*3.14 / 180;
00220 
00221     jtg->setLimits(jntLimits, std::vector<double>(5));
00222 
00223     // check trajectory
00224     KDL::JntArrayAcc startTest, endTest, testPose, testPose2;
00225     jtptr = jtg->getTrajectory(jntStart, jntEnd);
00226     jtptr->getPose(0., startTest);
00227     jtptr->getPose(jtptr->getDuration(), endTest);
00228     EXPECT_EQ(jntEnd.q, endTest.q);
00229     EXPECT_EQ(jntStart.q, startTest.q);
00230 
00231     KDL::JntArray prevDist(5);
00232     KDL::JntArray totDist(jntStart.q.rows());
00233 
00234     for (unsigned int i = 0; i < totDist.rows(); ++i)
00235     {
00236         totDist(i) = std::fabs(endTest.q(i) - startTest.q(i));
00237     }
00238 
00239     double timeStep = 0.01;
00240     jtptr->getPose(0., testPose);
00241 
00242     for (double time = timeStep; time < jtptr->getDuration(); time += timeStep)
00243     {
00244         testPose2 = testPose;
00245         jtptr->getPose(time, testPose);
00246 
00247 //        std::cout << testPose.q(0) << ", " << testPose.qdot(0) << ", " << testPose.qdotdot(0) << "; " << (testPose.q(0) - testPose2.q(0))/timeStep << ", " << (testPose.qdot(0) - testPose2.qdot(0))/timeStep << std::endl;
00248         for (unsigned int j = 0; j < jntStart.q.rows(); ++j)
00249         {
00250             // check velocity
00251             EXPECT_LE((testPose.q(j) - testPose2.q(j)) / timeStep, jntLimits.at(j));
00252 
00253             // check distance along path
00254             double dist = std::fabs(testPose.q(j) - jntStart.q(j));
00255             EXPECT_GE(dist, prevDist(j));
00256 
00257             if (totDist(j) > 0)
00258             {
00259                 EXPECT_GE(dist / totDist(j), 0);
00260                 EXPECT_LE(dist / totDist(j), 1);
00261             }
00262 
00263             double distToEnd = std::fabs(endTest.q(j) - testPose.q(j));
00264             EXPECT_FLOAT_EQ(dist, totDist(j) - distToEnd);
00265             prevDist(j) = dist;
00266         }
00267     }
00268 }
00269 
00270 TEST_F(TrajectoryGeneratorTest, minJerkJointZeroVelTrajTest)
00271 {
00272     std::vector<double> jntLimits(5);
00273     jntLimits.at(0) = .1;
00274     jntLimits.at(1) = .2;
00275     jntLimits.at(2) = .3;
00276     jntLimits.at(3) = .15;
00277     jntLimits.at(4) = .25;
00278 
00279     KDL::JntArrayAcc jntStart(5);
00280     jntStart.q(0) = 0;
00281     jntStart.q(1) = 0;
00282     jntStart.q(2) = 0;
00283     jntStart.q(3) = 0;
00284     jntStart.q(4) = 0;
00285 
00286     KDL::JntArrayAcc jntEnd(4);
00287     jntEnd.q(0) = 15.*3.14 / 180;
00288     jntEnd.q(1) = 20.*3.14 / 180;
00289     jntEnd.q(2) = 30.*3.14 / 180;
00290     jntEnd.q(3) = 25.*3.14 / 180;
00291 
00292     jtg->setLimits(jntLimits, std::vector<double>(5));
00293 
00294     // mismatched lengths
00295     EXPECT_THROW(jtg->getTrajectory(jntStart, jntEnd), std::runtime_error);
00296 
00297     // zero vel
00298     jntEnd.resize(5);
00299     jntEnd.q(0)     = 15.*3.14 / 180;
00300     jntEnd.q(1)     = 20.*3.14 / 180;
00301     jntEnd.q(2)     = 30.*3.14 / 180;
00302     jntEnd.q(3)     = 25.*3.14 / 180;
00303     jntEnd.q(4)     = 10.*3.14 / 180;
00304     jntLimits.at(3) = 0.;
00305     jtg->setLimits(jntLimits, std::vector<double>(5));
00306     EXPECT_THROW(jtg->getTrajectory(jntStart, jntEnd), std::runtime_error);
00307 }
00308 
00309 int main(int argc, char** argv)
00310 {
00311     testing::InitGoogleTest(&argc, argv);
00312     return RUN_ALL_TESTS();
00313 }


robodyn_controllers
Author(s):
autogenerated on Sat Jun 8 2019 20:20:53