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

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

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