Libbarrett  1.2.4
include/barrett/math/detail/spline-helper.h
00001 /*
00002         Copyright 2012 Barrett Technology <support@barrett.com>
00003 
00004         This file is part of libbarrett.
00005 
00006         This version of libbarrett is free software: you can redistribute it
00007         and/or modify it under the terms of the GNU General Public License as
00008         published by the Free Software Foundation, either version 3 of the
00009         License, or (at your option) any later version.
00010 
00011         This version of libbarrett is distributed in the hope that it will be
00012         useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00013         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014         GNU General Public License for more details.
00015 
00016         You should have received a copy of the GNU General Public License along
00017         with this version of libbarrett.  If not, see
00018         <http://www.gnu.org/licenses/>.
00019 
00020         Further, non-binding information about licensing is available at:
00021         <http://wiki.barrett.com/libbarrett/wiki/LicenseNotes>
00022 */
00023 
00024 /*
00025  * spline-helper.h
00026  *
00027  *  Created on: Jul 11, 2012
00028  *      Author: dc
00029  */
00030 
00031 
00032 #include <vector>
00033 #include <cassert>
00034 
00035 #include <boost/tuple/tuple.hpp>
00036 
00037 #include <barrett/math/utils.h>
00038 
00039 
00040 namespace barrett {
00041 namespace math {
00042 
00043 
00044 template<typename T> class Spline;
00045 
00046 
00047 // doxygen can't handle TupleSplineHolder's recursive inheritance.
00048 #ifndef BARRETT_PARSED_BY_DOXYGEN
00049 namespace detail {
00050 
00051 
00052 template<size_t N,
00053         typename T0, typename T1, typename T2, typename T3, typename T4,
00054         typename T5, typename T6, typename T7, typename T8, typename T9>
00055 struct TupleSplineHolder :
00056                 public TupleSplineHolder<N-1, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> {
00057 
00058         typedef TupleSplineHolder<N-1, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> inherited_type;
00059         typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> tuple_type;
00060         typedef Spline<tuple_type> parent_spline_type;
00061         typedef typename boost::tuples::element<N-1, tuple_type>::type current_data_type;
00062         typedef Spline<current_data_type> current_spline_type;
00063 
00064         template<template<typename, typename> class Container, typename Allocator>
00065         TupleSplineHolder(const Container<typename parent_spline_type::tuple_type, Allocator>& samples, bool saturateS) :
00066                 inherited_type(samples, saturateS), spline(NULL), rateAdjustment(1.0)
00067         {
00068                 std::vector<typename current_spline_type::tuple_type> currentSamples;
00069                 currentSamples.reserve(samples.size());
00070 
00071                 typename Container<typename parent_spline_type::tuple_type, Allocator>::const_iterator i;
00072                 for (i = samples.begin(); i != samples.end(); ++i) {
00073                         currentSamples.push_back(boost::make_tuple(boost::get<0>(*i), boost::get<N-1>(boost::get<1>(*i))));
00074                 }
00075 
00076                 spline = new current_spline_type(currentSamples, saturateS);
00077                 this->initialS = spline->initialS();
00078                 this->maxChangeInS = spline->changeInS();
00079         }
00080 
00081         template<template<typename, typename> class Container, typename Allocator>
00082         TupleSplineHolder(const Container<typename parent_spline_type::data_type, Allocator>& points, bool saturateS) :
00083                 inherited_type(points, saturateS), spline(NULL), rateAdjustment(0.0)
00084         {
00085                 std::vector<current_data_type> currentPoints;
00086                 currentPoints.reserve(points.size());
00087 
00088                 typename Container<typename parent_spline_type::data_type, Allocator>::const_iterator i;
00089                 for (i = points.begin(); i != points.end(); ++i) {
00090                         currentPoints.push_back(boost::get<N-1>(*i));
00091                 }
00092 
00093                 spline = new current_spline_type(currentPoints, saturateS);
00094                 this->initialS = spline->initialS();
00095                 updateRateAdjustments();
00096         }
00097 
00098         ~TupleSplineHolder() {
00099                 delete spline;
00100                 spline = NULL;
00101         }
00102 
00103         void updateRateAdjustments() {
00104                 double changeInS = spline->changeInS();
00105                 this->maxChangeInS = math::max(changeInS, this->maxChangeInS);
00106 
00107                 inherited_type::updateRateAdjustments();
00108 
00109                 rateAdjustment = changeInS / this->maxChangeInS;
00110                 assert(rateAdjustment <= 1.0);
00111         }
00112 
00113         void collectValues(double s) const {
00114                 inherited_type::collectValues(s);
00115 
00116                 // Scale s so that all of the component Splines have the same final value.
00117                 boost::get<N-1>(this->data) = spline->eval(s * rateAdjustment);
00118         }
00119 
00120         current_spline_type* spline;
00121         double rateAdjustment;
00122 };
00123 
00124 // Specialization for the inheritance base case:
00125 template<
00126         typename T0, typename T1, typename T2, typename T3, typename T4,
00127         typename T5, typename T6, typename T7, typename T8, typename T9>
00128 struct TupleSplineHolder<0, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> {
00129 
00130         typedef boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> tuple_type;
00131         typedef Spline<tuple_type> parent_spline_type;
00132 
00133         template<template<typename, typename> class Container, typename Allocator>
00134         TupleSplineHolder(const Container<typename parent_spline_type::tuple_type, Allocator>& samples, bool saturateS) :
00135                 initialS(0.0), maxChangeInS(0.0) {}
00136 
00137         template<template<typename, typename> class Container, typename Allocator>
00138         TupleSplineHolder(const Container<typename parent_spline_type::data_type, Allocator>& points, bool saturateS) :
00139                 initialS(0.0), maxChangeInS(0.0) {}
00140 
00141         void updateRateAdjustments() {}
00142         void collectValues(double s) const {}
00143 
00144         double initialS;
00145         double maxChangeInS;
00146         mutable tuple_type data;
00147 };
00148 
00149 
00150 }
00151 #endif // BARRETT_PARSED_BY_DOXYGEN
00152 }
00153 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Defines