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

ArRangeBuffer.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 "ArRangeBuffer.h"
00029 #include "ArLog.h"
00030 
00032 AREXPORT ArRangeBuffer::ArRangeBuffer(int size)
00033 {
00034   mySize = size;
00035   myVector.reserve(mySize);
00036 }
00037 
00038 AREXPORT ArRangeBuffer::~ArRangeBuffer()
00039 {
00040   ArUtil::deleteSet(myBuffer.begin(), myBuffer.end());
00041   ArUtil::deleteSet(myInvalidBuffer.begin(), myInvalidBuffer.end());
00042 }
00043 
00044 AREXPORT size_t ArRangeBuffer::getSize(void) const
00045 {
00046   return mySize;
00047 }
00048 
00049 AREXPORT ArPose ArRangeBuffer::getPoseTaken() const
00050 {
00051   return myBufferPose;
00052 }
00053 
00054 AREXPORT void ArRangeBuffer::setPoseTaken(ArPose p)
00055 {
00056   myBufferPose = p;
00057 }
00058 
00059 AREXPORT ArPose ArRangeBuffer::getEncoderPoseTaken() const
00060 {
00061   return myEncoderBufferPose;
00062 }
00063 
00064 AREXPORT void ArRangeBuffer::setEncoderPoseTaken(ArPose p)
00065 {
00066   myEncoderBufferPose = p;
00067 }
00068 
00075 AREXPORT void ArRangeBuffer::setSize(size_t size) 
00076 {
00077   mySize = size;
00078   myVector.reserve(mySize);
00079   // if its smaller then chop the lists down to size
00080   while (myInvalidBuffer.size() + myBuffer.size() > mySize)
00081   {
00082     if ((myRevIterator = myInvalidBuffer.rbegin()) != myInvalidBuffer.rend())
00083     {
00084       myReading = (*myRevIterator);
00085       myInvalidBuffer.pop_back();
00086       delete myReading;
00087     }
00088     else if ((myRevIterator = myBuffer.rbegin()) != myBuffer.rend())
00089     {
00090       myReading = (*myRevIterator);
00091       myBuffer.pop_back();
00092       delete myReading;
00093     }
00094   }
00095 }
00096 
00106 AREXPORT const std::list<ArPoseWithTime *> *ArRangeBuffer::getBuffer(void) const
00107 { 
00108   return &myBuffer; 
00109 }
00110 
00120 AREXPORT std::list<ArPoseWithTime *> *ArRangeBuffer::getBuffer(void)
00121 { 
00122   return &myBuffer; 
00123 }
00124 
00125 
00148 AREXPORT double ArRangeBuffer::getClosestPolar(double startAngle, 
00149                            double endAngle, 
00150                            ArPose startPos, 
00151                            unsigned int maxRange,
00152                            double *angle) const
00153 {
00154   return getClosestPolarInList(startAngle, endAngle, 
00155                    startPos, maxRange, angle, &myBuffer);
00156 }
00157 
00158 AREXPORT double ArRangeBuffer::getClosestPolarInList(
00159     double startAngle, double endAngle, ArPose startPos, 
00160     unsigned int maxRange, double *angle, 
00161     const std::list<ArPoseWithTime *> *buffer)
00162 {
00163   double closest;
00164   bool foundOne = false;
00165   std::list<ArPoseWithTime *>::const_iterator it;
00166   ArPoseWithTime *reading;
00167   double th;
00168   double closeTh;
00169   double dist;
00170   double angle1, angle2;
00171 
00172   startAngle = ArMath::fixAngle(startAngle);
00173   endAngle = ArMath::fixAngle(endAngle);
00174 
00175   for (it = buffer->begin(); it != buffer->end(); ++it)
00176   {
00177     reading = (*it);
00178 
00179     angle1=startPos.findAngleTo(*reading);
00180     angle2=startPos.getTh();
00181     th = ArMath::subAngle(angle1, angle2);
00182     if (ArMath::angleBetween(th, startAngle, endAngle))
00183     {
00184       if (!foundOne || (dist = reading->findDistanceTo(startPos)) < closest)
00185       {
00186     closeTh = th;   
00187     if (!foundOne)
00188       closest = reading->findDistanceTo(startPos);
00189     else
00190       closest = dist;
00191     foundOne = true;
00192       }
00193     }
00194   }
00195   if (!foundOne)
00196     return maxRange;
00197   if (angle != NULL)
00198     *angle = closeTh;
00199   if (closest > maxRange)
00200     return maxRange;
00201   else
00202     return closest;  
00203 }
00204 
00224 AREXPORT double ArRangeBuffer::getClosestBox(double x1, double y1, double x2,
00225                          double y2, ArPose startPos,
00226                          unsigned int maxRange, 
00227                          ArPose *readingPos,
00228                          ArPose targetPose) const
00229 {
00230   return getClosestBoxInList(x1, y1, x2, y2, startPos, maxRange, readingPos, 
00231                  targetPose, &myBuffer);
00232 }
00233 
00257 AREXPORT double ArRangeBuffer::getClosestBoxInList(
00258     double x1, double y1, double x2, double y2, ArPose startPos,
00259     unsigned int maxRange, ArPose *readingPos, ArPose targetPose,
00260     const std::list<ArPoseWithTime *> *buffer)
00261 
00262 {
00263   double closest;
00264   double dist;
00265   ArPose closestPos;
00266   std::list<ArPoseWithTime *>::const_iterator it;
00267   ArTransform trans;
00268   ArPoseWithTime pose;
00269   ArPose zeroPos;
00270   
00271   double temp;
00272 
00273   closest = maxRange;
00274   zeroPos.setPose(0, 0, 0);
00275   trans.setTransform(startPos, zeroPos);
00276 
00277   if (x1 >= x2)
00278   {
00279     temp = x1, 
00280     x1 = x2;
00281     x2 = temp;
00282   }
00283   if (y1 >= y2)
00284   {
00285     temp = y1, 
00286     y1 = y2;
00287     y2 = temp;
00288   }
00289   
00290   for (it = buffer->begin(); it != buffer->end(); ++it)
00291   {
00292     pose = trans.doTransform(*(*it));
00293 
00294     // see if its in the box
00295     if (pose.getX() >= x1 && pose.getX() <= x2 &&
00296     pose.getY() >= y1 && pose.getY() <= y2)
00297     {
00298       dist = pose.findDistanceTo(targetPose);
00299       //pose.log();
00300       if (dist < closest)
00301       {
00302     closest = dist;
00303     closestPos = pose;
00304       }
00305     }
00306   }
00307   if (readingPos != NULL)
00308     *readingPos = closestPos;
00309   if (closest > maxRange)
00310     return maxRange;
00311   else
00312     return closest;
00313 }
00314 
00320 AREXPORT void ArRangeBuffer::applyTransform(ArTransform trans)
00321 {
00322   trans.doTransform(&myBuffer);
00323 }
00324 
00325 AREXPORT void ArRangeBuffer::clear(void)
00326 {
00327   beginRedoBuffer();
00328   endRedoBuffer();
00329 }
00330 
00331 AREXPORT void ArRangeBuffer::reset(void)
00332 {
00333   clear();
00334 }
00335 
00336 AREXPORT void ArRangeBuffer::clearOlderThan(int milliSeconds)
00337 {
00338   std::list<ArPoseWithTime *>::iterator it;
00339 
00340   beginInvalidationSweep();
00341   for (it = myBuffer.begin(); it != myBuffer.end(); ++it)
00342   {
00343     if ((*it)->getTime().mSecSince() > milliSeconds)
00344       invalidateReading(it);
00345   }
00346   endInvalidationSweep();
00347 }
00348 
00349 AREXPORT void ArRangeBuffer::clearOlderThanSeconds(int seconds)
00350 {
00351   clearOlderThan(seconds*1000);
00352 }
00353 
00364 AREXPORT void ArRangeBuffer::beginRedoBuffer(void)
00365 {
00366   myRedoIt = myBuffer.begin();
00367   myHitEnd = false;
00368   myNumRedone = 0;
00369 }
00370 
00376 AREXPORT void ArRangeBuffer::redoReading(double x, double y)
00377 {
00378   if (myRedoIt != myBuffer.end() && !myHitEnd)
00379   {
00380     (*myRedoIt)->setPose(x, y);
00381     myRedoIt++;
00382   }
00383   // if we don't, add more (its just moving from buffers here, 
00384   //but let the class for this do the work
00385   else
00386   {
00387     addReading(x,y);
00388     myHitEnd = true;
00389   }
00390   myNumRedone++;
00391 }
00392 
00396 AREXPORT void ArRangeBuffer::endRedoBuffer(void)
00397 {
00398   if (!myHitEnd)
00399   {
00400     // now we get rid of the extra readings on the end
00401     beginInvalidationSweep();
00402     while (myRedoIt != myBuffer.end())
00403     {
00404       invalidateReading(myRedoIt);
00405       myRedoIt++;
00406     }
00407     endInvalidationSweep();
00408   } 
00409 }
00410 
00415 AREXPORT void ArRangeBuffer::addReading(double x, double y) 
00416 {
00417   if (myBuffer.size() < mySize)
00418   {
00419     if ((myIterator = myInvalidBuffer.begin()) != myInvalidBuffer.end())
00420     {
00421       myReading = (*myIterator);
00422       myReading->setPose(x, y);
00423       myReading->setTimeToNow();
00424       myBuffer.push_front(myReading);
00425       myInvalidBuffer.pop_front();
00426     }
00427     else
00428       myBuffer.push_front(new ArPoseWithTime(x, y));
00429   }
00430   else if ((myRevIterator = myBuffer.rbegin()) != myBuffer.rend())
00431   {
00432     myReading = (*myRevIterator);
00433     myReading->setPose(x, y);
00434     myReading->setTimeToNow();
00435     myBuffer.pop_back();
00436     myBuffer.push_front(myReading);
00437   }
00438 }
00439 
00451 void ArRangeBuffer::beginInvalidationSweep(void)
00452 {
00453   myInvalidSweepList.clear();
00454 }
00455 
00463 AREXPORT void ArRangeBuffer::invalidateReading(
00464     std::list<ArPoseWithTime*>::iterator readingIt)
00465 {
00466   myInvalidSweepList.push_front(readingIt);
00467 }
00468 
00475 void ArRangeBuffer::endInvalidationSweep(void)
00476 {
00477   while ((myInvalidIt = myInvalidSweepList.begin()) != 
00478      myInvalidSweepList.end())
00479   {
00480     //printf("nuked one before %d %d\n", myBuffer.size(), myInvalidBuffer.size());
00481     myReading = (*(*myInvalidIt));
00482     myInvalidBuffer.push_front(myReading);
00483     myBuffer.erase((*myInvalidIt));
00484     myInvalidSweepList.pop_front();
00485     //printf("after %d %d\n", myBuffer.size(), myInvalidBuffer.size());
00486   }
00487 }
00488 
00496 AREXPORT std::vector<ArPoseWithTime> *ArRangeBuffer::getBufferAsVector(void)
00497 {
00498   std::list<ArPoseWithTime *>::iterator it;
00499 
00500   myVector.clear();
00501   // start filling the array with the buffer until we run out of
00502   // readings or its full
00503   for (it = myBuffer.begin(); it != myBuffer.end(); it++)
00504   {
00505     myVector.insert(myVector.begin(), *(*it));
00506   }
00507   return &myVector;
00508 }
00509 
00510 

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