MinJerkTrajectory.cpp
Go to the documentation of this file.
00001 #include <robodyn_controllers/MinJerkTrajectory.h>
00002 
00003 #include "nasa_common_logging/Logger.h"
00004 #include <tf/tf.h>
00005 #include <tf_conversions/tf_kdl.h>
00006 #include <limits>
00007 
00008 void MinJerkUtility::TimeUtility::setTime(double timeIn)
00009 {
00010     if (timeIn < 0. || timeIn > 1.)
00011     {
00012         std::stringstream err;
00013         err << "MinJerkUtility::TimeUtility::setTime() - invalid time value (" << timeIn << ")";
00014         NasaCommonLogging::Logger::log("gov.nasa.controllers.MinJerkUtility", log4cpp::Priority::ERROR, err.str());
00015         throw std::runtime_error(err.str());
00016         return;
00017     }
00018 
00019     t  = timeIn;
00020     t2 = t * t;
00021     t3 = t2 * t;
00022     t4 = t3 * t;
00023     t5 = t4 * t;
00024 }
00025 
00026 void MinJerkUtility::setConstraints(double pinit, double pfinal, double vinit, double vfinal, double ainit, double afinal)
00027 {
00028     vinit = 0.;
00029     vfinal = 0.;
00030     ainit = 0.;
00031     afinal = 0.;
00032 
00033     // p1 - p0
00034     dist = pfinal - pinit;
00035     // a0   = p0
00036     a0   = pinit;
00037     // a1   = v0
00038     a1   = vinit;
00039     // a2   = vdot0/2
00040     a2   = ainit / 2.;
00041     // a3   = 10(p1-p0) - 6a1 - 3a2 - 4v1 + vdot1/2
00042     a3   = 10. * dist - 6. * a1 - 3. * a2 - 4. * vfinal + afinal / 2.;
00043     // a4   = 7v1 - vdot1 - 15(p1-p0) + 8a1 + 3a2
00044     a4   = 7. * vfinal - afinal - 15.*dist + 8. * a1 + 3. * a2;
00045     // a5   = vdot1/2 - 3v1 - a2 - 3a1 + 6(p1-p0)
00046     a5   = afinal / 2. - 3. * vfinal - a2 - 3. * a1 + 6. * dist;
00047 
00048     dist = fabs(dist);
00049 }
00050 
00051 double MinJerkUtility::duration(double vmax) const
00052 {
00053     static const double eps = std::numeric_limits<float>::epsilon();
00054 
00055     if (vmax <= eps)
00056     {
00057         if (dist > eps)
00058         {
00059             // movement needed but no movement allowed by velocity
00060             std::stringstream err;
00061             err << "MinJerkUtility::duration() - move requested but velocity limited to zero";
00062             NasaCommonLogging::Logger::log("gov.nasa.controllers.MinJerkUtility", log4cpp::Priority::ERROR, err.str());
00063             throw std::runtime_error(err.str());
00064             return 0.;
00065         }
00066         else
00067         {
00068             return 0.;
00069         }
00070     }
00071     else
00072     {
00073         return dist * 1.875 / vmax;
00074     }
00075 }
00076 
00077 double MinJerkUtility::p(const TimeUtility& t) const
00078 {
00079     return a0 + a1 * t.t + a2 * t.t2 + a3 * t.t3 + a4 * t.t4 + a5 * t.t5;
00080 }
00081 
00082 double MinJerkUtility::v(const TimeUtility& t) const
00083 {
00084     return a1 + 2.*a2 * t.t + 3.*a3 * t.t2 + 4.*a4 * t.t3 + 5.*a5 * t.t4;
00085 }
00086 
00087 double MinJerkUtility::a(const TimeUtility& t) const
00088 {
00089     return 2.*a2 + 6.*a3 * t.t + 12.*a4 * t.t2 + 20.*a5 * t.t3;
00090 }
00091 
00092 MinJerkJointTrajectory::MinJerkJointTrajectory(const JointVelocityLimiter& jvl, const KDL::JntArrayAcc& startPose,
00093         const KDL::JntArrayAcc& goalPose, double durationIn)
00094     : JointTrajectory(), JointVelocityLimiter(jvl)
00095 {
00096     if (startPose.q.rows() != goalPose.q.rows())
00097     {
00098         std::stringstream err;
00099         err << "MinJerkJointTrajectory::MinJerkJointTrajectory() - startPose and goalPose lengths don't match";
00100         NasaCommonLogging::Logger::log("gov.nasa.controllers.MinJerkJointTrajectory", log4cpp::Priority::ERROR, err.str());
00101         throw std::runtime_error(err.str());
00102         return;
00103     }
00104 
00105     utils.resize(startPose.q.rows());
00106 
00107     for (unsigned int i = 0; i < startPose.q.rows(); ++i)
00108     {
00109         utils[i].setConstraints(startPose.q(i), goalPose.q(i), startPose.qdot(i), goalPose.qdot(i), startPose.qdotdot(i), goalPose.qdotdot(i));
00110 
00111         double jointDur = utils[i].duration(getVelocityLimit(i));
00112 
00113         if (jointDur > durationIn)
00114         {
00115             durationIn = jointDur;
00116         }
00117     }
00118 
00119     setDuration(durationIn);
00120 }
00121 
00122 MinJerkJointTrajectory::~MinJerkJointTrajectory()
00123 {
00124 
00125 }
00126 
00127 void MinJerkJointTrajectory::getPose(double time, KDL::JntArrayAcc& pose)
00128 {
00129     MinJerkUtility::TimeUtility timeU;
00130     double dur = getDuration();
00131 
00132     if (dur == 0)
00133     {
00134         if (time > 0)
00135         {
00136             throw std::runtime_error("MinJerkJointTrajectory::getPose cannot get a pose for a zero duration trajectory with nonzero time");
00137             return;
00138         }
00139         else
00140         {
00141             timeU.setTime(0.);
00142         }
00143     }
00144     else
00145     {
00146         timeU.setTime(time / getDuration());
00147     }
00148 
00149     pose.resize(utils.size());
00150 
00151     for (unsigned int i = 0; i < utils.size(); ++i)
00152     {
00153         pose.q(i)       = utils[i].p(timeU);
00154         pose.qdot(i)    = utils[i].v(timeU) / dur;
00155         pose.qdotdot(i) = utils[i].a(timeU) / (dur * dur);
00156     }
00157 }
00158 
00159 MinJerkCartesianTrajectory::MinJerkCartesianTrajectory(const CartesianVelocityLimiter& cvl,
00160         const KDL::FrameAcc& startPose, const KDL::FrameAcc& goalPose, double durationIn)
00161     : CartesianTrajectory(), CartesianVelocityLimiter(cvl)
00162 {
00163     utils.resize(2);
00164 
00165     // linear
00166     startVec = startPose.p.p;
00167     moveVec  = goalPose.p.p - startVec;
00168 
00170     utils[0].setConstraints(0., 1., startPose.p.v.Norm(), goalPose.p.v.Norm(), startPose.p.dv.Norm(), startPose.p.dv.Norm());
00171     double linDuration = moveVec.Norm() * utils[0].duration(getLinearVelocityLimit());
00172 
00173     // angular
00174     double x, y, z, w;
00175 
00176     startPose.M.R.GetQuaternion(x, y, z, w);
00177     startQ.setValue(x, y, z, w);
00178     goalPose.M.R.GetQuaternion(x, y, z, w);
00179     goalQ.setValue(x, y, z, w);
00180 
00181     double angle = startQ.angleShortestPath(goalQ);
00182 
00184     utils[1].setConstraints(0., 1., startPose.M.w.Norm(), goalPose.M.w.Norm(), startPose.M.dw.Norm(), startPose.M.dw.Norm());
00185     double rotDuration = angle * utils[1].duration(getRotationalVelocityLimit());
00186 
00187     setDuration(std::max(std::max(linDuration, rotDuration), durationIn));
00188 }
00189 
00190 MinJerkCartesianTrajectory::~MinJerkCartesianTrajectory()
00191 {
00192 
00193 }
00194 
00195 void MinJerkCartesianTrajectory::getPose(double time, KDL::FrameAcc& pose)
00196 {
00197     MinJerkUtility::TimeUtility timeU;
00198     timeU.setTime(time / getDuration());
00199 
00200     double p = utils[0].p(timeU);
00201     pose.p   = startVec + moveVec * p;
00202     p = utils[1].p(timeU);
00203     tf::Quaternion stepQ = startQ.slerp(goalQ, p).normalize();
00204     pose.M               = KDL::Rotation::Quaternion(stepQ.x(), stepQ.y(), stepQ.z(), stepQ.w());
00205 }


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