Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages | Examples

ArInterpolation.cpp

00001 /*
00002 MobileRobots Advanced Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004, 2005 ActivMedia Robotics LLC
00004 Copyright (C) 2006, 2007 MobileRobots Inc.
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      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
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 MobileRobots for information about a commercial version of ARIA at 
00022 robots@mobilerobots.com or 
00023 MobileRobots Inc, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 */
00025 
00026 #include "ArExport.h"
00027 #include "ariaOSDef.h"
00028 #include "ArInterpolation.h"
00029 
00030 AREXPORT ArInterpolation::ArInterpolation(size_t numberOfReadings)
00031 {
00032   mySize = numberOfReadings;
00033 
00034 }
00035 
00036 AREXPORT ArInterpolation::~ArInterpolation()
00037 {
00038 
00039 }
00040 
00041 AREXPORT bool ArInterpolation::addReading(ArTime timeOfReading, 
00042                       ArPose position)
00043 {
00044   if (myTimes.size() >= mySize)
00045   {
00046     myTimes.pop_back();
00047     myPoses.pop_back();
00048   }
00049   myTimes.push_front(timeOfReading);
00050   myPoses.push_front(position);
00051   return true;
00052 }
00053 
00062 AREXPORT int ArInterpolation::getPose(ArTime timeStamp,
00063                       ArPose *position)
00064 {
00065   std::list<ArTime>::iterator tit;
00066   std::list<ArPose>::iterator pit;
00067   
00068   ArPose thisPose;
00069   ArTime thisTime;
00070   ArPose lastPose;
00071   ArTime lastTime;
00072 
00073   ArTime nowTime;
00074   long total;
00075   long toStamp;
00076   double percentage;
00077   ArPose retPose;
00078   
00079   // find the time we want
00080   for (tit = myTimes.begin(), pit = myPoses.begin();
00081        tit != myTimes.end() && pit != myPoses.end(); 
00082        ++tit, ++pit)
00083   {
00084     lastTime = thisTime;
00085     lastPose = thisPose;
00086 
00087     thisTime = (*tit);
00088     thisPose = (*pit);
00089 
00090     //printf("## %d %d %d b %d at %d after %d\n", timeStamp.getMSec(), thisTime.getMSec(), timeStamp.mSecSince(thisTime), timeStamp.isBefore(thisTime), timeStamp.isAt(thisTime), timeStamp.isAfter(thisTime));
00091     //if (timeStamp.isBefore(thisTime) || timeStamp.isAt(thisTime))
00092     if (!timeStamp.isAfter(thisTime))
00093     {
00094       //printf("Found one!\n");
00095       break;
00096     } 
00097 
00098   }
00099   // if we're at the end then it was too long ago
00100   if (tit == myTimes.end() || pit == myPoses.end())
00101   {
00102     //printf("Too old\n");
00103     return -2;
00104   }
00105   
00106   // this is for forecasting (for the brave)
00107   if ((tit == myTimes.begin() || pit == myPoses.begin()) && 
00108       !timeStamp.isAt((*tit)))
00109   {
00110     //printf("Too new %d %d\n", tit == myTimes.begin(), pit == myPoses.begin());
00111   
00112     thisTime = (*tit);
00113     thisPose = (*pit);
00114     tit++;
00115     pit++;  
00116     if (tit == myTimes.end() || pit == myPoses.end())
00117     {
00118       //printf("Not enough data\n");
00119       return -3;
00120     }
00121     lastTime = (*tit);
00122     lastPose = (*pit);
00123     nowTime.setToNow();
00124     total = thisTime.mSecSince(lastTime);
00125     if (total == 0)
00126       total = 100;
00127     toStamp = nowTime.mSecSince(thisTime);
00128     percentage = (double)toStamp/(double)total;
00129     //printf("Total time %d, to stamp %d, percentage %.2f\n", total, toStamp, percentage);
00130     if (percentage > 3)
00131       return -1;
00132 
00133     retPose.setX(thisPose.getX() + 
00134          (thisPose.getX() - lastPose.getX()) * percentage);
00135     retPose.setY(thisPose.getY() + 
00136          (thisPose.getY() - lastPose.getY()) * percentage);
00137     retPose.setTh(ArMath::addAngle(thisPose.getTh(),
00138                    ArMath::subAngle(thisPose.getTh(),
00139                             lastPose.getTh())
00140                    * percentage));
00141     *position = retPose;
00142     return 0;
00143   }
00144 
00145   // this is the actual interpolation
00146 
00147   //printf("Woo hoo!\n");
00148 
00149   total = thisTime.mSecSince(lastTime);
00150   toStamp = thisTime.mSecSince(timeStamp);
00151   percentage = (double)toStamp/(double)total;
00152   //printf("Total time %d, to stamp %d, percentage %.2f\n",      total, toStamp, percentage);
00153   retPose.setX(thisPose.getX() + 
00154           (lastPose.getX() - thisPose.getX()) * percentage); 
00155   retPose.setY(thisPose.getY() + 
00156           (lastPose.getY() - thisPose.getY()) * percentage); 
00157   retPose.setTh(ArMath::addAngle(thisPose.getTh(),
00158                 ArMath::subAngle(lastPose.getTh(), 
00159                          thisPose.getTh())
00160                 * percentage));
00161 /*
00162   printf("original:");
00163   thisPose.log();
00164   printf("After:");
00165   lastPose.log();
00166   printf("ret:");
00167   retPose.log();
00168 */
00169   *position = retPose;
00170   return 1;
00171   
00172 }
00173 
00174 AREXPORT size_t ArInterpolation::getNumberOfReadings(void) const
00175 {
00176   return mySize;
00177 }
00178 
00179 AREXPORT void ArInterpolation::setNumberOfReadings(size_t numberOfReadings)
00180 {
00181   while (myTimes.size() > numberOfReadings)
00182   {
00183     myTimes.pop_back();
00184     myPoses.pop_back();
00185   }
00186   mySize = numberOfReadings;  
00187 }
00188 
00189 AREXPORT void ArInterpolation::reset(void)
00190 {
00191   while (myTimes.size() > 0)
00192     myTimes.pop_back();
00193   while (myPoses.size() > 0)
00194     myPoses.pop_back();
00195 }
00196 
00197 

Generated on Tue Feb 20 10:51:40 2007 for Aria by  doxygen 1.4.0