Libbarrett
1.2.4
|
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 }