MOOS 0.2375
/home/toby/moos-ivp/MOOS-2375-Oct0611/Essentials/MOOSUtilityLib/InterpBuffer.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines