math_spline.h
Go to the documentation of this file.
00001 // -*- mode: c++ -*-
00002 /*********************************************************************
00003  * Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2016, JSK Lab
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   * Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *   * Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions and the following
00016  *     disclaimer in the documentation and/o2r other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of the JSK Lab nor the names of its
00019  *     contributors may be used to endorse or promote products derived
00020  *     from this software without specific prior written permission.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  *  POSSIBILITY OF SUCH DAMAGE.
00034  *********************************************************************/
00035 
00036 /*
00037  * math_spline.h
00038  * Author: Yuki Furuta <furushchev@jsk.imi.i.u-tokyo.ac.jp>
00039  */
00040 
00041 #ifndef MATH_SPLINE_H__
00042 #define MATH_SPLINE_H__
00043 
00044 #include <iostream>
00045 #include <vector>
00046 #include <cfloat>
00047 #include <stdexcept>
00048 #include <boost/shared_ptr.hpp>
00049 
00050 namespace pr2_base_trajectory_action {
00051 
00052   static inline void pows(int n, double base, double* ret)
00053   {
00054     ret[0] = 1.0;
00055     for(int i = 1; i <= n; ++i)
00056     {
00057       ret[i] = ret[i-1] * base;
00058     }
00059   }
00060 
00061   struct Motion
00062   {
00063     double position, velocity, acceleration;
00064     Motion() : position(0.0), velocity(DBL_MAX), acceleration(DBL_MAX) {}
00065     Motion(double position) : position(position), velocity(DBL_MAX), acceleration(DBL_MAX) {}
00066     Motion(double position, double velocity)
00067       : position(position), velocity(velocity), acceleration(DBL_MAX) {}
00068     Motion(double position, double velocity, double acceleration)
00069       : position(position), velocity(velocity), acceleration(acceleration) {}
00070     friend std::ostream &operator << (std::ostream &os, const Motion &m)
00071     {
00072       return os << "<pos: " << m.position << ", vel: " << m.velocity << ", acc: " << m.acceleration << ">";
00073     }
00074   };
00075   struct BaseMotion
00076   {
00077     Motion x, y, yaw;
00078     const Motion &operator[] (size_t i) const {
00079       switch (i) {
00080       case 0: return x;
00081       case 1: return y;
00082       case 2: return yaw;
00083       default: throw std::out_of_range("range must be 0-2");
00084       }
00085     }
00086     Motion &operator[] (size_t i) {
00087       switch (i) {
00088       case 0: return x;
00089       case 1: return y;
00090       case 2: return yaw;
00091       default: throw std::out_of_range("range must be 0-2");
00092       }
00093     }
00094     friend std::ostream &operator << (std::ostream &os, const BaseMotion &m) {
00095       return os << "<x: " << m.x.position << " y: " << m.y.position << " yaw: " << m.yaw.position << ">";
00096     }
00097     bool hasVelocity() const {
00098       return x.velocity != DBL_MAX && y.velocity != DBL_MAX && yaw.velocity != DBL_MAX;
00099     }
00100     bool hasAcceleration() const {
00101       return x.acceleration != DBL_MAX && y.acceleration != DBL_MAX && yaw.acceleration != DBL_MAX;
00102     }
00103   };
00104 
00105   struct Spline
00106   {
00107     std::vector<double> coefficients;
00108     Spline() : coefficients(6, 0.0) {};
00109     virtual ~Spline(){ coefficients.clear(); };
00110     virtual void sample(const double &time, Motion &motion) const {
00111       double t[6];
00112       pows(5, time, t);
00113       motion.position =
00114         t[0] * coefficients[0] +
00115         t[1] * coefficients[1] +
00116         t[2] * coefficients[2] +
00117         t[3] * coefficients[3] +
00118         t[4] * coefficients[4] +
00119         t[5] * coefficients[5];
00120 
00121       motion.velocity =
00122         1.0 * t[0] * coefficients[1] +
00123         2.0 * t[1] * coefficients[2] +
00124         3.0 * t[2] * coefficients[3] +
00125         4.0 * t[3] * coefficients[4] +
00126         5.0 * t[4] * coefficients[5];
00127 
00128       motion.acceleration =
00129         2.0  * t[0] * coefficients[2] +
00130         6.0  * t[1] * coefficients[3] +
00131         12.0 * t[2] * coefficients[4] +
00132         20.0 * t[3] * coefficients[5];
00133     }
00134 
00135     virtual void sampleWithTimeBounds(const double &duration,
00136                                       const double &time, Motion &motion) const {
00137       if (time < 0.0) {
00138         sample(0.0, motion);
00139         motion.velocity = 0.0;
00140         motion.acceleration = 0.0;
00141       } else if (time > duration) {
00142         sample(duration, motion);
00143         motion.velocity = 0.0;
00144         motion.acceleration = 0.0;
00145       } else {
00146         sample(time, motion);
00147       }
00148     }
00149   };
00150 
00151   struct Line : public Spline {
00152     Line(const Motion &start, const Motion &end, const double &duration) {
00153       coefficients[0] = start.position;
00154       if (duration == 0.0) coefficients[1] = 0.0;
00155       else coefficients[1] = (end.position - start.position) / duration;
00156     }
00157   };
00158 
00159   struct CubicSpline : public Spline {
00160     CubicSpline(const Motion &start, const Motion &end, const double &duration) {
00161       if (duration == 0.0) {
00162         coefficients[0] = end.position;
00163         coefficients[1] = end.velocity;
00164       } else {
00165         double t[4];
00166         pows(3, duration, t);
00167         coefficients[0] = start.position;
00168         coefficients[1] = start.velocity;
00169         coefficients[2] = (-3.0 * start.position +
00170                            3.0 * end.position -
00171                            2.0 * start.velocity * t[1] -
00172                            end.velocity * t[1]) / t[2];
00173         coefficients[3] = (2.0 * start.position -
00174                            2.0 * end.position +
00175                            start.velocity * t[1] +
00176                            end.velocity * t[1]) / t[3];
00177       }
00178     }
00179   };
00180 
00181   struct QuinticSpline : public Spline {
00182     QuinticSpline(const Motion &start, const Motion &end, const double &duration) {
00183       if (duration == 0.0) {
00184         coefficients[0] = end.position;
00185         coefficients[1] = end.velocity;
00186         coefficients[2] = 0.5 * end.acceleration;
00187       } else {
00188         double t[6];
00189         pows(5, duration, t);
00190 
00191         coefficients[0] = start.position;
00192         coefficients[1] = start.velocity;
00193         coefficients[2] = 0.5 * start.acceleration;
00194         coefficients[3] = (-20.0 * start.position +
00195                            20.0 * end.position -
00196                            3.0  * start.acceleration * t[2] +
00197                            end.acceleration * t[2] -
00198                            12.0 * start.velocity * t[1] -
00199                            8.0  * end.velocity * t[1]) / (2.0 * t[3]);
00200         coefficients[4] = ( 30.0 * start.position -
00201                             30.0 * end.position +
00202                             3.0  * start.acceleration * t[2] -
00203                             2.0  * end.acceleration * t[2] +
00204                             16.0 * start.velocity * t[1] +
00205                             14.0 * end.velocity * t[1]) / (2.0 * t[4]);
00206         coefficients[5] = (-12.0 * start.position +
00207                            12.0 * end.position -
00208                            start.acceleration * t[2] +
00209                            end.acceleration * t[2] -
00210                            6.0  * start.velocity * t[1] -
00211                            6.0  * end.velocity * t[1]) / (2.0*t[5]);
00212       }
00213     }
00214   };
00215 } // namespace
00216 
00217 #endif // MATH_SPLINE_H__


pr2_base_trajectory_action
Author(s): saito, Yuki Furuta
autogenerated on Sat Jul 1 2017 02:43:02