00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "ArExport.h"
00027 #include "ariaOSDef.h"
00028 #include "ArRangeDevice.h"
00029 #include "ArRobot.h"
00030
00067 AREXPORT ArRangeDevice::ArRangeDevice(size_t currentBufferSize,
00068 size_t cumulativeBufferSize,
00069 const char *name,
00070 unsigned int maxRange,
00071 int maxSecondsToKeepCurrent,
00072 int maxSecondsToKeepCumulative,
00073 double maxDistToKeepCumulative,
00074 bool locationDependent) :
00075 myCurrentBuffer(currentBufferSize),
00076 myCumulativeBuffer(cumulativeBufferSize),
00077 myFilterCB(this, &ArRangeDevice::filterCallback)
00078 {
00079 myRobot = NULL;
00080 myName = name;
00081 myMaxRange = maxRange;
00082 myRawReadings = NULL;
00083 myAdjustedRawReadings = NULL;
00084 setMaxSecondsToKeepCurrent(maxSecondsToKeepCurrent);
00085 setMaxSecondsToKeepCumulative(maxSecondsToKeepCumulative);
00086 setMaxDistToKeepCumulative(maxDistToKeepCumulative);
00087 myCurrentDrawingData = NULL;
00088 myOwnCurrentDrawingData = false;
00089 myCumulativeDrawingData = NULL;
00090 myOwnCumulativeDrawingData = false;
00091 myIsLocationDependent = locationDependent;
00092 }
00093
00094 AREXPORT ArRangeDevice::~ArRangeDevice()
00095 {
00096 if (myRobot != NULL)
00097 myRobot->remSensorInterpTask(&myFilterCB);
00098 if (myCurrentDrawingData != NULL && myOwnCurrentDrawingData)
00099 {
00100 delete myCurrentDrawingData;
00101 myCurrentDrawingData = NULL;
00102 myOwnCurrentDrawingData = false;
00103 }
00104 if (myCumulativeDrawingData != NULL && myOwnCumulativeDrawingData)
00105 {
00106 delete myCumulativeDrawingData;
00107 myCumulativeDrawingData = NULL;
00108 myOwnCumulativeDrawingData = false;
00109 }
00110 }
00111
00112
00113 AREXPORT const char * ArRangeDevice::getName(void) const
00114 {
00115 return myName.c_str();
00116 }
00117
00118 AREXPORT void ArRangeDevice::setRobot(ArRobot *robot)
00119 {
00120 char buf[512];
00121 sprintf(buf, "filter %s", getName());
00122
00123 if (myRobot != NULL)
00124 myRobot->remSensorInterpTask(&myFilterCB);
00125
00126 myRobot = robot;
00127
00128 if (myRobot != NULL)
00129 myRobot->addSensorInterpTask(buf, 100, &myFilterCB);
00130 }
00131
00132 AREXPORT ArRobot *ArRangeDevice::getRobot(void)
00133 {
00134 return myRobot;
00135 }
00136
00137 AREXPORT void ArRangeDevice::filterCallback(void)
00138 {
00139 std::list<ArPoseWithTime *>::iterator it;
00140
00141 lockDevice();
00142
00143 if (myMaxSecondsToKeepCurrent > 0 &&
00144 myCurrentBuffer.getSize() > 0)
00145 {
00146
00147 myCurrentBuffer.beginInvalidationSweep();
00148 for (it = getCurrentBuffer()->begin();
00149 it != getCurrentBuffer()->end();
00150 ++it)
00151 {
00152 if ((*it)->getTime().secSince() >= myMaxSecondsToKeepCurrent)
00153 myCurrentBuffer.invalidateReading(it);
00154 }
00155 myCurrentBuffer.endInvalidationSweep();
00156 }
00157
00158
00159 bool doingDist = true;
00160 bool doingAge = true;
00161
00162 if (myCumulativeBuffer.getSize() == 0)
00163 {
00164 unlockDevice();
00165 return;
00166 }
00167
00168 double squaredFarDist = (myMaxDistToKeepCumulative *
00169 myMaxDistToKeepCumulative);
00170
00171 if (squaredFarDist < 1)
00172 doingDist = false;
00173 if (myMaxSecondsToKeepCumulative <= 0)
00174 doingAge = false;
00175
00176 if (!doingDist && !doingAge)
00177 {
00178 unlockDevice();
00179 return;
00180 }
00181
00182
00183 myCumulativeBuffer.beginInvalidationSweep();
00184 for (it = getCumulativeBuffer()->begin();
00185 it != getCumulativeBuffer()->end();
00186 ++it)
00187 {
00188
00189 if (doingDist &&
00190 myRobot->getPose().squaredFindDistanceTo(*(*it)) > squaredFarDist)
00191 myCumulativeBuffer.invalidateReading(it);
00192 else if (doingAge &&
00193 (*it)->getTime().secSince() >= myMaxSecondsToKeepCumulative)
00194 myCumulativeBuffer.invalidateReading(it);
00195 }
00196 myCumulativeBuffer.endInvalidationSweep();
00197 unlockDevice();
00198 }
00199
00208 AREXPORT void ArRangeDevice::setCurrentBufferSize(size_t size)
00209 {
00210 myCurrentBuffer.setSize(size);
00211 }
00212
00221 AREXPORT void ArRangeDevice::setCumulativeBufferSize(size_t size)
00222 {
00223 myCumulativeBuffer.setSize(size);
00224 }
00225
00226 AREXPORT void ArRangeDevice::addReading(double x, double y)
00227 {
00228 myCurrentBuffer.addReading(x, y);
00229 myCumulativeBuffer.addReading(x, y);
00230 }
00231
00255 AREXPORT double ArRangeDevice::currentReadingPolar(double startAngle,
00256 double endAngle,
00257 double *angle) const
00258 {
00259 ArPose pose;
00260 if (myRobot != NULL)
00261 pose = myRobot->getPose();
00262 else
00263 {
00264 ArLog::log(ArLog::Normal, "ArRangeDevice %s: NULL robot, won't get polar reading correctly", getName());
00265 pose.setPose(0, 0);
00266 }
00267 return myCurrentBuffer.getClosestPolar(startAngle, endAngle,
00268 pose,
00269 myMaxRange,
00270 angle);
00271 }
00272
00294 AREXPORT double ArRangeDevice::cumulativeReadingPolar(double startAngle,
00295 double endAngle,
00296 double *angle) const
00297 {
00298 ArPose pose;
00299 if (myRobot != NULL)
00300 pose = myRobot->getPose();
00301 else
00302 {
00303 ArLog::log(ArLog::Normal, "ArRangeDevice %s: NULL robot, won't get polar reading correctly", getName());
00304 pose.setPose(0, 0);
00305 }
00306 return myCumulativeBuffer.getClosestPolar(startAngle, endAngle,
00307 pose,
00308 myMaxRange,
00309 angle);
00310 }
00311
00324 AREXPORT double ArRangeDevice::currentReadingBox(double x1, double y1,
00325 double x2, double y2,
00326 ArPose *pose) const
00327 {
00328 ArPose robotPose;
00329 if (myRobot != NULL)
00330 robotPose = myRobot->getPose();
00331 else
00332 {
00333 ArLog::log(ArLog::Normal, "ArRangeDevice %s: NULL robot, won't get reading box correctly", getName());
00334 robotPose.setPose(0, 0);
00335 }
00336 return myCurrentBuffer.getClosestBox(x1, y1, x2, y2, robotPose,
00337 myMaxRange, pose);
00338 }
00339
00353 AREXPORT double ArRangeDevice::cumulativeReadingBox(double x1, double y1,
00354 double x2, double y2,
00355 ArPose *pose) const
00356 {
00357 ArPose robotPose;
00358 if (myRobot != NULL)
00359 robotPose = myRobot->getPose();
00360 else
00361 {
00362 ArLog::log(ArLog::Normal, "ArRangeDevice %s: NULL robot, won't get reading box correctly", getName());
00363 robotPose.setPose(0, 0);
00364 }
00365 return myCumulativeBuffer.getClosestBox(x1, y1, x2, y2,
00366 robotPose,
00367 myMaxRange, pose);
00368 }
00369
00377 AREXPORT void ArRangeDevice::applyTransform(ArTransform trans,
00378 bool doCumulative)
00379 {
00380 myCurrentBuffer.applyTransform(trans);
00381 if (doCumulative)
00382 myCumulativeBuffer.applyTransform(trans);
00383 }
00384
00389 AREXPORT std::vector<ArSensorReading> *ArRangeDevice::getRawReadingsAsVector(void)
00390 {
00391
00392 std::list<ArSensorReading *>::const_iterator it;
00393 myRawReadingsVector.clear();
00394
00395 if (myRawReadings == NULL)
00396 return &myRawReadingsVector;
00397 myRawReadingsVector.reserve(myRawReadings->size());
00398 for (it = myRawReadings->begin(); it != myRawReadings->end(); it++)
00399 myRawReadingsVector.insert(myRawReadingsVector.begin(), *(*it));
00400 return &myRawReadingsVector;
00401 }
00402
00407 AREXPORT std::vector<ArSensorReading> *ArRangeDevice::getAdjustedRawReadingsAsVector(void)
00408 {
00409
00410 std::list<ArSensorReading *>::const_iterator it;
00411 myAdjustedRawReadingsVector.clear();
00412
00413 if (myAdjustedRawReadings == NULL)
00414 return &myRawReadingsVector;
00415 myAdjustedRawReadingsVector.reserve(myRawReadings->size());
00416 for (it = myAdjustedRawReadings->begin();
00417 it != myAdjustedRawReadings->end();
00418 it++)
00419 myAdjustedRawReadingsVector.insert(myAdjustedRawReadingsVector.begin(),
00420 *(*it));
00421 return &myAdjustedRawReadingsVector;
00422 }
00423
00424
00425 AREXPORT void ArRangeDevice::setCurrentDrawingData(ArDrawingData *data,
00426 bool takeOwnershipOfData)
00427 {
00428 if (myCurrentDrawingData != NULL && myOwnCurrentDrawingData)
00429 {
00430 delete myCurrentDrawingData;
00431 myCurrentDrawingData = NULL;
00432 myOwnCurrentDrawingData = false;
00433 }
00434 myCurrentDrawingData = data;
00435 myOwnCurrentDrawingData = takeOwnershipOfData;
00436 }
00437
00438 AREXPORT void ArRangeDevice::setCumulativeDrawingData(ArDrawingData *data,
00439 bool takeOwnershipOfData)
00440 {
00441 if (myCumulativeDrawingData != NULL && myOwnCumulativeDrawingData)
00442 {
00443 delete myCumulativeDrawingData;
00444 myCumulativeDrawingData = NULL;
00445 myOwnCumulativeDrawingData = false;
00446 }
00447 myCumulativeDrawingData = data;
00448 myOwnCumulativeDrawingData = takeOwnershipOfData;
00449 }
00450
00451 AREXPORT void ArRangeDevice::adjustRawReadings(bool interlaced)
00452 {
00453 std::list<ArSensorReading *>::iterator rawIt;
00454
00455
00456
00457
00458
00459 if (myRawReadings == NULL || myRobot == NULL ||
00460 (myAdjustedRawReadings == NULL && myRobot->getOdometryDelay() == 0))
00461 return;
00462
00463
00464
00465 if (myAdjustedRawReadings == NULL)
00466 myAdjustedRawReadings = new std::list<ArSensorReading *>;
00467
00468
00469 if (myRawReadings->begin() != myRawReadings->end() &&
00470 myRawReadings->front()->getAdjusted())
00471 return;
00472
00473 std::list<ArSensorReading *>::iterator adjIt;
00474 ArSensorReading *adjReading;
00475 ArSensorReading *rawReading;
00476
00477 ArTransform trans;
00478 ArTransform encTrans;
00479 ArTransform interlacedTrans;
00480 ArTransform interlacedEncTrans;
00481
00482 bool first = true;
00483 bool second = true;
00484
00485 int onReading;
00486 for (rawIt = myRawReadings->begin(), adjIt = myAdjustedRawReadings->begin(),
00487 onReading = 0;
00488 rawIt != myRawReadings->end();
00489 rawIt++, onReading++)
00490 {
00491 rawReading = (*rawIt);
00492 if (adjIt != myAdjustedRawReadings->end())
00493 {
00494 adjReading = (*adjIt);
00495 adjIt++;
00496 }
00497 else
00498 {
00499 adjReading = new ArSensorReading;
00500 myAdjustedRawReadings->push_back(adjReading);
00501 }
00502 (*adjReading) = (*rawReading);
00503 if (first || (interlaced && second))
00504 {
00505 ArPose origPose;
00506 ArPose corPose;
00507 ArPose origEncPose;
00508 ArPose corEncPose;
00509 ArTime corTime;
00510
00511
00512 corTime = rawReading->getTimeTaken();
00513 corTime.addMSec(-myRobot->getOdometryDelay());
00514 if (myRobot->getPoseInterpPosition(corTime,
00515 &corPose) == 1 &&
00516 myRobot->getEncoderPoseInterpPosition(corTime,
00517 &corEncPose) == 1)
00518 {
00519 origPose = rawReading->getPoseTaken();
00520 origEncPose = rawReading->getEncoderPoseTaken();
00521
00522
00523
00524
00525
00526
00527
00528 if (first)
00529 {
00530 trans.setTransform(origPose, corPose);
00531 encTrans.setTransform(origEncPose, corEncPose);
00532 }
00533 else if (interlaced && second)
00534 {
00535 interlacedTrans.setTransform(origPose, corPose);
00536 interlacedEncTrans.setTransform(origEncPose, corEncPose);
00537 }
00538 }
00539 else
00540 {
00541
00542 }
00543
00544 if (first)
00545 first = false;
00546 else if (interlaced && second)
00547 second = false;
00548
00549 }
00550 if (!interlaced && (onReading % 2) == 0)
00551 {
00552 adjReading->applyTransform(trans);
00553 adjReading->applyEncoderTransform(encTrans);
00554 }
00555 else
00556 {
00557 adjReading->applyTransform(interlacedTrans);
00558 adjReading->applyEncoderTransform(interlacedEncTrans);
00559 }
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573 adjReading->setAdjusted(true);
00574 rawReading->setAdjusted(true);
00575 }
00576 }