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

ArInterpolation.cpp

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

Generated on Wed Oct 19 12:56:35 2005 for Aria by  doxygen 1.4.0