MOOS 0.2375
|
00001 00002 // 00003 // MOOS - Mission Oriented Operating Suite 00004 // 00005 // A suit of Applications and Libraries for Mobile Robotics Research 00006 // Copyright (C) 2001-2005 Massachusetts Institute of Technology and 00007 // Oxford University. 00008 // 00009 // This software was written by Paul Newman at MIT 2001-2002 and Oxford 00010 // University 2003-2005. email: pnewman@robots.ox.ac.uk. 00011 // 00012 // This file is part of a MOOS Core Component. 00013 // 00014 // This program is free software; you can redistribute it and/or 00015 // modify it under the terms of the GNU General Public License as 00016 // published by the Free Software Foundation; either version 2 of the 00017 // License, or (at your option) any later version. 00018 // 00019 // This program is distributed in the hope that it will be useful, 00020 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00022 // General Public License for more details. 00023 // 00024 // You should have received a copy of the GNU General Public License 00025 // along with this program; if not, write to the Free Software 00026 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00027 // 02111-1307, USA. 00028 // 00030 #ifndef INTERP_BUFFER_H 00031 #define INTERP_BUFFER_H 00032 00033 #include <map> 00034 #include <iterator> 00035 #include <assert.h> 00036 #include <math.h> 00037 #include <algorithm> 00038 #include <MOOSGenLib/MOOSGenLibGlobalHelper.h> 00039 00041 template< class Key, class Data, class InterpFunc, class Compare=std::less<Key> > 00042 class TInterpBuffer : public std::map<Key,Data,Compare> 00043 { 00044 typedef std::map<Key,Data,Compare> BASE_TYPE; 00045 00046 InterpFunc m_interpFunc; 00047 public: 00048 void SetInterpFunc(const InterpFunc &interp) {m_interpFunc = interp;} 00049 InterpFunc &GetInterpFunc() {return m_interpFunc; } 00050 00051 // const version 00052 Data operator()(const Key &interp_time) const 00053 { 00054 assert(this->size() > 0 ); 00055 00056 if (this->size()==1) return this->begin()->second; 00057 00058 typename BASE_TYPE::const_iterator hi; 00059 00060 hi = BASE_TYPE::lower_bound(interp_time); 00061 if (hi != this->begin() && hi != this->end()) 00062 { 00063 typename BASE_TYPE::const_iterator low = hi; low--; 00064 return m_interpFunc(*low,*hi,interp_time); 00065 } 00066 else 00067 { 00068 if (hi == this->begin()) 00069 { 00070 typename BASE_TYPE::const_iterator hi2 = hi; hi2++; 00071 return m_interpFunc(*hi,*hi2,interp_time); 00072 } 00073 else if (hi == this->end()) 00074 { 00075 typename BASE_TYPE::const_iterator low = hi; low--; 00076 typename BASE_TYPE::const_iterator low2 = low; low2--; 00077 00078 return m_interpFunc(*low2,*low,interp_time); 00079 } 00080 } 00081 assert("should not get here"==0); 00082 return Data(); 00083 } 00084 00085 00086 void MakeSpanTime(double dfSpan) 00087 { 00088 if (this->size() > 0) 00089 { 00090 EraseOld(MaxKey()-dfSpan); 00091 } 00092 } 00093 00094 00095 void EraseOld(double dfTime) 00096 { 00097 if(this->size()>0) 00098 { 00099 typename BASE_TYPE::iterator oldest = this->lower_bound(dfTime); 00100 erase(this->begin(),oldest); 00101 } 00102 } 00103 00104 Key MaxKey() const 00105 { 00106 // Don't call this unless it's going to 00107 // give a valid output! 00108 assert(this->size() > 0); 00109 00110 Key maxkey = this->rbegin()->first; 00111 return maxkey; 00112 } 00113 00114 Key MinKey() const 00115 { 00116 // Don't call this unless it's going to 00117 // give a valid output! 00118 assert(this->size() > 0); 00119 00120 Key minkey = this->begin()->first; 00121 return minkey; 00122 }; 00123 00124 00125 bool MaxData(Data & D) const 00126 { 00127 if(this->size()) 00128 { 00129 D = this->rbegin()->second; 00130 return true; 00131 } 00132 return false; 00133 } 00134 00135 00136 bool MinData(Data & D) const 00137 { 00138 if(this->size()) 00139 { 00140 D = this->begin()->second; 00141 return true; 00142 } 00143 return false; 00144 } 00145 00146 }; 00147 00149 template <class T> 00150 class CTimeNumericInterpolator 00151 { 00152 public: 00153 //return object with time closest to requested time 00154 typedef std::pair<double,T> TIME_DOUBLE_NUM_PAIR; 00155 00156 T operator()(const TIME_DOUBLE_NUM_PAIR &loPair, const TIME_DOUBLE_NUM_PAIR &hiPair, double dfInterpTime) const 00157 { 00158 00159 double dfLoTime = loPair.first; 00160 double dfHiTime = hiPair.first; 00161 00162 double dfMidTime; 00163 00164 dfMidTime = dfInterpTime; 00165 00166 double dt = (dfHiTime - dfLoTime); 00167 00168 double alpha = 0.0; 00169 00170 if ( dt != 0.0 ) 00171 { 00172 alpha = (dfMidTime - dfLoTime) / dt; 00173 } 00174 00175 if(alpha>1.0 || alpha<0) 00176 { 00177 double dfExtrapTime = 0.0; 00178 if (alpha > 0) 00179 { 00180 dfExtrapTime = dfInterpTime - dfHiTime; 00181 } 00182 else 00183 { 00184 dfExtrapTime = dfLoTime - dfInterpTime; 00185 } 00186 00187 if(dfExtrapTime>0.5) 00188 { 00189 MOOSTrace("Warning more than 0.5 seconds data extrapolation (%f)\n",dfExtrapTime); 00190 } 00191 } 00192 00193 const T & Lo = loPair.second; 00194 const T & Hi = hiPair.second; 00195 00196 T MidVal = alpha*Hi + (1-alpha)*Lo; 00197 00198 00199 return MidVal; 00200 } 00201 00202 }; 00203 00205 template <class T> 00206 class CTimeGenericInterpolator 00207 { 00208 public: 00209 00210 typedef std::pair<double,T> TIME_DOUBLE_VAL_PAIR; 00211 00212 T operator()(const TIME_DOUBLE_VAL_PAIR &loPair, const TIME_DOUBLE_VAL_PAIR &hiPair, double dfInterpTime) const 00213 { 00214 00215 double dfLoTime = loPair.first; 00216 double dfHiTime = hiPair.first; 00217 00218 double dfMidTime; 00219 00220 dfMidTime = dfInterpTime; 00221 00222 double dt = (dfHiTime - dfLoTime); 00223 00224 double alpha = 0.0; 00225 00226 if ( dt != 0.0 ) 00227 { 00228 alpha = (dfMidTime - dfLoTime) / dt; 00229 } 00230 00231 if(alpha>1.0 || alpha<0) 00232 { 00233 double dfExtrapTime = 0.0; 00234 if (alpha > 0) 00235 { 00236 dfExtrapTime = dfInterpTime - dfHiTime; 00237 } 00238 else 00239 { 00240 dfExtrapTime = dfLoTime - dfInterpTime; 00241 } 00242 00243 if(dfExtrapTime>0.5) 00244 { 00245 MOOSTrace("Warning more than 0.5 seconds data extrapolation (%f)\n",dfExtrapTime); 00246 } 00247 } 00248 00249 const T & Lo = loPair.second; 00250 const T & Hi = hiPair.second; 00251 T Mid; 00252 00253 00254 double dfValLo,dfValHi; 00255 int i = 0; 00256 while(Lo.GetInterpValue(i,dfValLo) && Hi.GetInterpValue(i,dfValHi)) 00257 { 00258 double dfMidVal = alpha*dfValHi + (1-alpha)*dfValLo; 00259 Mid.SetInterpValue(i++,dfMidVal); 00260 } 00261 00262 00263 return Mid; 00264 } 00265 }; 00266 00268 00269 template <class T> 00270 class ClosestInterpFunc 00271 { 00272 typedef std::pair<double, T > val_type; 00273 public: 00274 //return object with time closest to requested time 00275 T operator()(const val_type &loPair, const val_type &hiPair, double interp_time) const 00276 { 00277 return fabs(interp_time-hiPair.first)>fabs(interp_time-loPair.first) ? loPair.second : hiPair.second; 00278 } 00279 }; 00280 00281 00282 00283 #endif