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
00027 #include "ArExport.h"
00028 #include "ariaOSDef.h"
00029 #include "ArSick.h"
00030 #include "ArRobot.h"
00031 #include "ArSerialConnection.h"
00032 #include "ariaInternal.h"
00033 #include <time.h>
00034
00035 ArSick::ArSick(size_t currentBufferSize, size_t cumulativeBufferSize,
00036 const char *name, bool addAriaExitCB) :
00037 ArRangeDeviceThreaded(currentBufferSize, cumulativeBufferSize, name, 32500),
00038 myRobotConnectCB(this, &ArSick::robotConnectCallback),
00039 mySimPacketHandler(this, &ArSick::simPacketHandler),
00040 mySensorInterpCB(this, &ArSick::sensorInterpCallback),
00041 mySickPacketReceiver(0, true),
00042 myAriaExitCB(this, &ArSick::disconnect, true)
00043 {
00044 myAriaExitCB.setName("ArSickExit");
00045 if (addAriaExitCB)
00046 Aria::addExitCallback(&myAriaExitCB, 10);
00047 configure();
00048 setSensorPosition(0, 0, 0);
00049 myAssembleReadings = new std::list<ArSensorReading *>;
00050 myCurrentReadings = new std::list<ArSensorReading *>;
00051 myRawReadings = myCurrentReadings;
00052 myIter = myAssembleReadings->begin();
00053 myConn = NULL;
00054 myRobot = NULL;
00055 myStartConnect = false;
00056 myRunningOnRobot = false;
00057 switchState(STATE_NONE);
00058 myProcessImmediately = false;
00059 myInterpolation = true;
00060 myTimeoutTime = 8;
00061 myRealConfigured = false;
00062
00063
00064 setMinRange(125);
00065 setFilterNearDist(50);
00066 setFilterCumulativeMaxDist(6000);
00067 setFilterCumulativeInsertMaxDist(3000);
00068 setFilterCumulativeNearDist(200);
00069 setFilterCumulativeCleanDist(75);
00070 setFilterCumulativeMaxAge(30);
00071 setFilterCleanCumulativeInterval(1000);
00072
00073 myLastCleanedCumulative.setToNow();
00074
00075 setCurrentDrawingData(new ArDrawingData("polyDots",
00076 ArColor(0, 0, 255),
00077 80,
00078 75),
00079 true);
00080
00081 setCumulativeDrawingData(new ArDrawingData("polyDots",
00082 ArColor(125, 125, 125),
00083 100,
00084 60),
00085 true);
00086 }
00087
00088 ArSick::~ArSick()
00089 {
00090 if (myRobot != NULL)
00091 {
00092 myRobot->remRangeDevice(this);
00093 myRobot->remPacketHandler(&mySimPacketHandler);
00094 myRobot->remSensorInterpTask(&mySensorInterpCB);
00095 myRobot->addConnectCB(&myRobotConnectCB, ArListPos::FIRST);
00096 }
00097 lockDevice();
00098 if (isConnected())
00099 {
00100 disconnect();
00101 }
00102 unlockDevice();
00103 }
00104
00105 void ArSick::robotConnectCallback(void)
00106 {
00107 const ArRobotParams *params;
00108 if (myRealConfigured || !myRobot->isConnected())
00109 return;
00110 params = myRobot->getRobotParams();
00111 myLaserFlipped = params->getLaserFlipped();
00112 myPowerControl = params->getLaserPowerControlled();
00113
00114 if (myDegrees == DEGREES180)
00115 myOffsetAmount = 90;
00116 else if (myDegrees == DEGREES100)
00117 myOffsetAmount = 50;
00118 else
00119 {
00120 myOffsetAmount = 0;
00121 ArLog::log(ArLog::Terse,"ArSick::robotConnectCallback: bad degrees configured.\n");
00122 }
00123
00124
00125 if (myLaserFlipped)
00126 myOffsetAmount *= -1;
00127
00128 if (myIncrement == INCREMENT_ONE)
00129 myIncrementAmount = 1.0;
00130 else if (myIncrement == INCREMENT_HALF)
00131 myIncrementAmount = 0.5;
00132 else
00133 {
00134 myIncrementAmount = 0;
00135 ArLog::log(ArLog::Terse,"ArSick::robotConnectCallback: bad increment configured.\n");
00136 }
00137 if (myLaserFlipped)
00138 myIncrementAmount *= -1;
00139
00140 clearIgnoreReadings();
00141 ArArgumentBuilder builder;
00142 builder.add(myRobot->getRobotParams()->getLaserIgnore());
00143 size_t i;
00144 for (i = 0; i < builder.getArgc(); i++)
00145 {
00146 if (!builder.isArgDouble(i))
00147 {
00148 ArLog::log(ArLog::Normal, "ArRobotConfig::setIgnoreReadings: argument is not a double");
00149 }
00150 addIgnoreReading(builder.getArgDouble(i));
00151 }
00152
00153 setSensorPosition(params->getLaserX(), params->getLaserY(), params->getLaserTh());
00154 }
00155
00156 bool ArSick::isUsingSim(void)
00157 {
00158 return myUseSim;
00159 }
00160
00161 bool ArSick::isControllingPower(void)
00162 {
00163 return myPowerControl;
00164 }
00165
00166 bool ArSick::isLaserFlipped(void)
00167 {
00168 return myLaserFlipped;
00169 }
00170
00171 ArSick::Degrees ArSick::getDegrees(void)
00172 {
00173 return myDegrees;
00174 }
00175
00176 ArSick::Increment ArSick::getIncrement(void)
00177 {
00178 return myIncrement;
00179 }
00180
00181
00182 void ArSick::setIsUsingSim(bool usingSim)
00183 {
00184 myUseSim = usingSim;
00185 }
00186
00187 void ArSick::setIsControllingPower(bool controlPower)
00188 {
00189 myPowerControl = controlPower;
00190 }
00191
00192 void ArSick::setIsLaserFlipped(bool laserFlipped)
00193 {
00194 myLaserFlipped = laserFlipped;
00195 }
00196
00197
00198 void ArSick::setSensorPosition(double x, double y, double th)
00199 {
00200 mySensorPose.setPose(x, y, th);
00201 }
00202
00203 void ArSick::setSensorPosition(ArPose pose)
00204 {
00205 mySensorPose = pose;
00206 }
00207
00208 ArPose ArSick::getSensorPosition(void)
00209 {
00210 return mySensorPose;
00211 }
00212
00213 double ArSick::getSensorPositionX(void)
00214 {
00215 return mySensorPose.getX();
00216 }
00217
00218 double ArSick::getSensorPositionY(void)
00219 {
00220 return mySensorPose.getY();
00221 }
00222
00223 double ArSick::getSensorPositionTh(void)
00224 {
00225 return mySensorPose.getTh();
00226 }
00227
00228
00229 void ArSick::setDeviceConnection(ArDeviceConnection *conn)
00230 {
00231 myConnLock.lock();
00232 myConn = conn;
00233 mySickPacketReceiver.setDeviceConnection(conn);
00234 myConnLock.unlock();
00235 }
00236
00237 ArDeviceConnection *ArSick::getDeviceConnection(void)
00238 {
00239 return myConn;
00240 }
00241
00251 void ArSick::setConnectionTimeoutTime(int mSecs)
00252 {
00253 if (mSecs > 0)
00254 myTimeoutTime = mSecs;
00255 else
00256 myTimeoutTime = 0;
00257 }
00258
00264 int ArSick::getConnectionTimeoutTime(void)
00265 {
00266 return myTimeoutTime;
00267 }
00268
00269 ArTime ArSick::getLastReadingTime(void)
00270 {
00271 return myLastReading;
00272 }
00273
00274 void ArSick::setRobot(ArRobot *robot)
00275 {
00276 myRobot = robot;
00277 if (myRobot != NULL)
00278 {
00279 myRobot->addPacketHandler(&mySimPacketHandler, ArListPos::LAST);
00280 myRobot->addSensorInterpTask("sick", 90, &mySensorInterpCB);
00281 myRobot->addConnectCB(&myRobotConnectCB, ArListPos::FIRST);
00282 if (myRobot->isConnected())
00283 robotConnectCallback();
00284 }
00285 ArRangeDevice::setRobot(robot);
00286 }
00287
00292 void ArSick::configure(bool useSim, bool powerControl,
00293 bool laserFlipped, BaudRate baud,
00294 Degrees deg, Increment incr)
00295 {
00296
00297 myUseSim = useSim;
00298 myPowerControl = powerControl;
00299 myLaserFlipped = laserFlipped;
00300 myBaud = baud;
00301 myDegrees = deg;
00302 myIncrement = incr;
00303
00304 if (myDegrees == DEGREES180)
00305 myOffsetAmount = 90;
00306 else if (myDegrees == DEGREES100)
00307 myOffsetAmount = 50;
00308 else
00309 {
00310 myOffsetAmount = 0;
00311 ArLog::log(ArLog::Terse,"ArSick::configure: bad degrees configured.\n");
00312 }
00313
00314 if (myLaserFlipped)
00315 myOffsetAmount *= -1;
00316
00317 if (myIncrement == INCREMENT_ONE)
00318 myIncrementAmount = 1.0;
00319 else if (myIncrement == INCREMENT_HALF)
00320 myIncrementAmount = 0.5;
00321 else
00322 {
00323 myIncrementAmount = 0;
00324 ArLog::log(ArLog::Terse,"ArSick::configure: bad increment configured.\n");
00325 }
00326
00327 if (myLaserFlipped)
00328 myIncrementAmount *= -1;
00329
00330 myRealConfigured = true;
00331 }
00332
00337 void ArSick::configureShort(bool useSim, BaudRate baud,
00338 Degrees deg, Increment incr)
00339 {
00340
00341 myUseSim = useSim;
00342 myPowerControl = true;
00343 myLaserFlipped = false;
00344 myBaud = baud;
00345 myDegrees = deg;
00346 myIncrement = incr;
00347
00348 if (myDegrees == DEGREES180)
00349 myOffsetAmount = 90;
00350 else if (myDegrees == DEGREES100)
00351 myOffsetAmount = 50;
00352 else
00353 {
00354 myOffsetAmount = 0;
00355 ArLog::log(ArLog::Terse,"ArSick::configureShort: bad degrees configured.\n");
00356 }
00357
00358 if (myLaserFlipped)
00359 myOffsetAmount *= -1;
00360
00361 if (myIncrement == INCREMENT_ONE)
00362 myIncrementAmount = 1.0;
00363 else if (myIncrement == INCREMENT_HALF)
00364 myIncrementAmount = 0.5;
00365 else
00366 {
00367 myIncrementAmount = 0;
00368 ArLog::log(ArLog::Terse,"ArSick::configureShort: bad increment configured.\n");
00369 }
00370 if (myLaserFlipped)
00371 myIncrementAmount *= -1;
00372
00373 myRealConfigured = false;
00374
00375 if (myRobot != NULL && myRobot->isConnected())
00376 robotConnectCallback();
00377 }
00378
00379 bool ArSick::simPacketHandler(ArRobotPacket *packet)
00380 {
00381 std::list<ArFunctor *>::iterator it;
00382
00383 unsigned int totalNumReadings;
00384 unsigned int readingNumber;
00385 double atDeg;
00386 unsigned int i;
00387 ArSensorReading *reading;
00388 std::list<ArSensorReading *>::iterator tempIt;
00389 unsigned int newReadings;
00390 int range;
00391 ArPose encoderPose;
00392 std::list<double>::iterator ignoreIt;
00393 bool ignore;
00394
00395 if (packet->getID() != 0x60)
00396 return false;
00397
00398
00399
00400
00401 lockDevice();
00402
00403 if (!myUseSim)
00404 {
00405 ArLog::log(ArLog::Terse, "ArSick: Got a packet from the simulator with laser information, but the laser is not being simulated, major trouble.");
00406 unlockDevice();
00407 return true;
00408 }
00409
00410 packet->bufToByte2();
00411 packet->bufToByte2();
00412 packet->bufToByte2();
00413 totalNumReadings = packet->bufToByte2();
00414 readingNumber = packet->bufToByte2();
00415 newReadings = packet->bufToUByte();
00416 if (readingNumber == 0)
00417 {
00418 mySimPacketStart = myRobot->getPose();
00419 mySimPacketTrans = myRobot->getToGlobalTransform();
00420 mySimPacketEncoderTrans = myRobot->getEncoderTransform();
00421 mySimPacketCounter = myRobot->getCounter();
00422 }
00423
00424
00425 while (myAssembleReadings->size() > totalNumReadings)
00426 {
00427 ArLog::log(ArLog::Verbose, "ArSick::simPacketHandler, too many readings, popping one.\n");
00428 tempIt = myAssembleReadings->begin();
00429 if (tempIt != myAssembleReadings->end())
00430 delete (*tempIt);
00431 myAssembleReadings->pop_front();
00432 }
00433
00434
00435 if (myAssembleReadings->size() == 0)
00436 for (i = 0; i < totalNumReadings; i++)
00437 myAssembleReadings->push_back(new ArSensorReading);
00438
00439
00440
00441
00442 if ((readingNumber != myWhichReading + 1) ||
00443 totalNumReadings != myTotalNumReadings)
00444 {
00445
00446 myWhichReading = readingNumber;
00447 myTotalNumReadings = totalNumReadings;
00448 for (i = 0, myIter = myAssembleReadings->begin(); i < readingNumber; i++)
00449 {
00450 tempIt = myIter;
00451 tempIt++;
00452 if (tempIt == myAssembleReadings->end() && (i + 1 != myTotalNumReadings))
00453 myAssembleReadings->push_back(new ArSensorReading);
00454 myIter++;
00455 }
00456 }
00457 else
00458 {
00459
00460 myWhichReading = readingNumber;
00461 }
00462
00463 atDeg = (mySensorPose.getTh() - myOffsetAmount +
00464 readingNumber * myIncrementAmount);
00465
00466 encoderPose = mySimPacketEncoderTrans.doInvTransform(mySimPacketStart);
00467
00468 for (i = 0;
00469
00470
00471 i < newReadings;
00472 i++, myWhichReading++, atDeg += myIncrementAmount)
00473 {
00474 reading = (*myIter);
00475 range = packet->bufToUByte2();
00476 ignore = false;
00477 for (ignoreIt = myIgnoreReadings.begin();
00478 ignoreIt != myIgnoreReadings.end();
00479 ignoreIt++)
00480 {
00481
00482
00483 if (ArMath::fabs(ArMath::subAngle(atDeg, *(ignoreIt))) < 1.0)
00484 {
00485
00486 ignore = true;
00487 break;
00488 }
00489 }
00490 if (myMaxRange != 0 && range < (int)myMinRange)
00491 ignore = true;
00492 if (myMaxRange != 0 && range > (int)myMaxRange)
00493 ignore = true;
00494
00495 reading->resetSensorPosition(ArMath::roundInt(mySensorPose.getX()),
00496 ArMath::roundInt(mySensorPose.getY()),
00497 atDeg);
00498
00499 reading->newData(range, mySimPacketStart,
00500 encoderPose,
00501 mySimPacketTrans,
00502 mySimPacketCounter, packet->getTimeReceived(), ignore);
00503
00504 tempIt = myIter;
00505 tempIt++;
00506 if (tempIt == myAssembleReadings->end() &&
00507 myWhichReading + 1 != myTotalNumReadings)
00508 {
00509 myAssembleReadings->push_back(new ArSensorReading);
00510 }
00511 myIter++;
00512 }
00513
00514
00515
00516 if (newReadings + readingNumber >= totalNumReadings)
00517 {
00518
00519 myRawReadings = myAssembleReadings;
00520
00521 myAssembleReadings = myCurrentReadings;
00522 myCurrentReadings = myRawReadings;
00523
00524 filterReadings();
00525
00526 if (myTimeLastSickPacket != time(NULL))
00527 {
00528 myTimeLastSickPacket = time(NULL);
00529 mySickPacCount = mySickPacCurrentCount;
00530 mySickPacCurrentCount = 0;
00531 }
00532 mySickPacCurrentCount++;
00533 myLastReading.setToNow();
00534
00535 for (it = myDataCBList.begin(); it != myDataCBList.end(); it++)
00536 (*it)->invoke();
00537 }
00538
00539 unlockDevice();
00540 return true;
00541 }
00542
00555 void ArSick::filterReadings()
00556 {
00557 std::list<ArSensorReading *>::iterator sensIt;
00558 ArSensorReading *sReading;
00559 double x, y;
00560 double squaredDist;
00561 double lastX = 0.0, lastY = 0.0;
00562 unsigned int i;
00563 double squaredNearDist = myFilterNearDist * myFilterNearDist;
00564 ArTime len;
00565 len.setToNow();
00566
00567 bool clean;
00568 if (myFilterCleanCumulativeInterval == 0 ||
00569 myLastCleanedCumulative.mSecSince() > myFilterCleanCumulativeInterval)
00570 {
00571 myLastCleanedCumulative.setToNow();
00572 clean = true;
00573 }
00574 else
00575 {
00576 clean = false;
00577 }
00578
00579 sensIt = myRawReadings->begin();
00580 sReading = (*sensIt);
00581 myCurrentBuffer.setPoseTaken(sReading->getPoseTaken());
00582 myCurrentBuffer.setEncoderPoseTaken(sReading->getEncoderPoseTaken());
00583
00584
00585
00586 if (myCurrentBuffer.getBuffer()->size() == 0)
00587 for (i = 0; i < myRawReadings->size(); i++)
00588 myCurrentBuffer.getBuffer()->push_back(new ArPoseWithTime);
00589
00590 i = 0;
00591
00592 for (myCurrentBuffer.beginRedoBuffer();
00593 sensIt != myRawReadings->end();
00594 ++sensIt)
00595 {
00596 sReading = (*sensIt);
00597
00598
00599
00600
00601
00602 if (!sReading->getIgnoreThisReading())
00603 {
00604
00605 x = sReading->getX();
00606 y = sReading->getY();
00607
00608
00609
00610
00611
00612 if (squaredNearDist > 0.0000001)
00613 {
00614
00615 squaredDist = (x-lastX)*(x-lastX) + (y-lastY)*(y-lastY);
00616
00617 if (squaredDist > squaredNearDist)
00618 {
00619 lastX = x;
00620 lastY = y;
00621
00622
00623 filterAddAndCleanCumulative(x, y, clean);
00624
00625
00626
00627
00628
00629
00630 }
00631
00632 else
00633 {
00634 continue;
00635 }
00636 }
00637
00638
00639 else
00640 {
00641 filterAddAndCleanCumulative(x, y, clean);
00642 }
00643
00644 myCurrentBuffer.redoReading(x, y);
00645 i++;
00646 }
00647 }
00648 myCurrentBuffer.endRedoBuffer();
00649
00650
00651
00652
00653
00654 }
00655
00656 void ArSick::filterAddAndCleanCumulative(double x, double y, bool clean)
00657 {
00658 if (myCumulativeBuffer.getSize() == 0)
00659 return;
00660
00661
00662 std::list<ArPoseWithTime *>::iterator cit;
00663 bool addReading = true;
00664 double squaredDist;
00665
00666 ArLineSegment line;
00667 double xTaken = myCurrentBuffer.getPoseTaken().getX();
00668 double yTaken = myCurrentBuffer.getPoseTaken().getY();
00669 ArPose intersection;
00670 ArPoseWithTime reading(x, y);
00671
00672
00673 if (clean && myFilterSquaredCumulativeCleanDist < 1)
00674 clean = false;
00675
00676 squaredDist = ArMath::squaredDistanceBetween(x, y, xTaken, yTaken);
00677
00678
00679 if (!clean &&
00680 myFilterSquaredCumulativeInsertMaxDist > 1 &&
00681 squaredDist > myFilterSquaredCumulativeInsertMaxDist)
00682 return;
00683
00684
00685 if (clean)
00686 myCumulativeBuffer.beginInvalidationSweep();
00687
00688 for (cit = getCumulativeBuffer()->begin();
00689 cit != getCumulativeBuffer()->end();
00690 ++cit)
00691 {
00692
00693 if (myFilterSquaredCumulativeNearDist < .0000001 ||
00694 (ArMath::squaredDistanceBetween(x, y, (*cit)->getX(), (*cit)->getY()) <
00695 myFilterSquaredCumulativeNearDist))
00696 {
00697
00698
00699 if (!clean)
00700 return;
00701 addReading = false;
00702 }
00703
00704 if (clean)
00705 {
00706
00707 line.newEndPoints(x, y, xTaken, yTaken);
00708
00709
00710 if (line.getPerpPoint((*cit), &intersection) &&
00711 (intersection.squaredFindDistanceTo(*(*cit)) <
00712 myFilterSquaredCumulativeCleanDist) &&
00713 (intersection.squaredFindDistanceTo(reading) > 50 * 50))
00714 {
00715
00716 myCumulativeBuffer.invalidateReading(cit);
00717 }
00718 }
00719 }
00720
00721 if (clean)
00722 myCumulativeBuffer.endInvalidationSweep();
00723
00724 if (addReading)
00725 myCumulativeBuffer.addReading(x, y);
00726
00727 }
00728
00729 void ArSick::switchState(State state)
00730 {
00731 myStateMutex.lock();
00732 myState = state;
00733 myStateStart.setToNow();
00734 myStateMutex.unlock();
00735 }
00736
00740 int ArSick::internalConnectHandler(void)
00741 {
00742 ArSickPacket *packet;
00743 ArSerialConnection *conn;
00744 int value;
00745
00746 switch (myState)
00747 {
00748 case STATE_INIT:
00749 if (myConn->getStatus() != ArDeviceConnection::STATUS_OPEN)
00750 {
00751 if ((conn = dynamic_cast<ArSerialConnection *>(myConn)) != NULL)
00752 {
00753 conn->setBaud(9600);
00754 }
00755 if (!myConn->openSimple())
00756 {
00757 ArLog::log(ArLog::Terse,
00758 "ArSick: Failed to connect to laser, could not open port.");
00759 switchState(STATE_NONE);
00760 failedConnect();
00761 return 2;
00762 }
00763 }
00764 if (!myPowerControl)
00765 {
00766
00767
00768
00769
00770
00771
00772
00773 switchState(STATE_CHANGE_BAUD);
00774 return internalConnectHandler();
00775 }
00776 ArLog::log(ArLog::Terse, "ArSick: waiting for laser to power on.");
00777 myPacket.empty();
00778 myPacket.uByteToBuf(0x10);
00779 myPacket.finalizePacket();
00780 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
00781 {
00782 switchState(STATE_WAIT_FOR_POWER_ON);
00783 return 0;
00784 }
00785 else
00786 {
00787 ArLog::log(ArLog::Terse,
00788 "ArSick: Failed to connect to laser, could not send init.");
00789 switchState(STATE_NONE);
00790 failedConnect();
00791 return 2;
00792 }
00793 break;
00794 case STATE_WAIT_FOR_POWER_ON:
00795 while ((packet = mySickPacketReceiver.receivePacket()) != NULL)
00796 {
00797 if (packet->getID() == 0x90)
00798 {
00799 switchState(STATE_CHANGE_BAUD);
00800 return 0;
00801 }
00802 }
00803 if (myStateStart.secSince() > 65)
00804 {
00805 ArLog::log(ArLog::Terse,
00806 "ArSick: Failed to connect to laser, no poweron received.");
00807 switchState(STATE_NONE);
00808 failedConnect();
00809 return 2;
00810 }
00811 break;
00812 case STATE_CHANGE_BAUD:
00813 myPacket.empty();
00814 myPacket.byteToBuf(0x20);
00815 if (myBaud == BAUD9600)
00816 myPacket.byteToBuf(0x42);
00817 else if (myBaud == BAUD19200)
00818 myPacket.byteToBuf(0x41);
00819 else if (myBaud == BAUD38400)
00820 myPacket.byteToBuf(0x40);
00821 myPacket.finalizePacket();
00822 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
00823 {
00824 ArUtil::sleep(20);
00825 if ((conn = dynamic_cast<ArSerialConnection *>(myConn)))
00826 {
00827 if (myBaud == BAUD9600)
00828 conn->setBaud(9600);
00829 else if (myBaud == BAUD19200)
00830 conn->setBaud(19200);
00831 else if (myBaud == BAUD38400)
00832 conn->setBaud(38400);
00833 }
00834 switchState(STATE_CONFIGURE);
00835 return 0;
00836 }
00837 else
00838 {
00839 ArLog::log(ArLog::Terse,
00840 "ArSick: Failed to connect to laser, could not send baud command.");
00841 switchState(STATE_NONE);
00842 failedConnect();
00843 return 2;
00844 }
00845 break;
00846 case STATE_CONFIGURE:
00847
00848 if (myStateStart.mSecSince() < 300)
00849 return 0;
00850 myPacket.empty();
00851 myPacket.byteToBuf(0x3b);
00852 myPacket.uByte2ToBuf(abs(ArMath::roundInt(myOffsetAmount * 2)));
00853 myPacket.uByte2ToBuf(abs(ArMath::roundInt(myIncrementAmount * 100)));
00854 myPacket.finalizePacket();
00855 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
00856 {
00857 switchState(STATE_WAIT_FOR_CONFIGURE_ACK);
00858 return 0;
00859 }
00860 else
00861 {
00862 ArLog::log(ArLog::Terse,
00863 "ArSick: Failed to connect to laser, could not send configure command.");
00864 switchState(STATE_NONE);
00865 failedConnect();
00866 return 2;
00867 }
00868 break;
00869 case STATE_WAIT_FOR_CONFIGURE_ACK:
00870 while ((packet = mySickPacketReceiver.receivePacket()) != NULL)
00871 {
00872 if (packet->getID() == 0xbb)
00873 {
00874 value = packet->bufToByte();
00875 if (value == 0)
00876 {
00877 ArLog::log(ArLog::Terse,
00878 "ArSick: Could not configure laser, failed connect.");
00879 switchState(STATE_NONE);
00880 failedConnect();
00881 return 2;
00882 }
00883 else if (value == 1)
00884 {
00885
00886
00887 switchState(STATE_INSTALL_MODE);
00888 return 0;
00889 }
00890 else
00891 {
00892 ArLog::log(ArLog::Terse,
00893 "ArSick: Could not configure laser, failed connect.");
00894 switchState(STATE_NONE);
00895 failedConnect();
00896 return 2;
00897 }
00898 }
00899 else if (packet->getID() == 0xb0)
00900 {
00901
00902 ArLog::log(ArLog::Terse, "ArSick: extra data packet while waiting for configure ack");
00903 myPacket.empty();
00904 myPacket.uByteToBuf(0x20);
00905 myPacket.uByteToBuf(0x25);
00906 myPacket.finalizePacket();
00907 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
00908 {
00909 switchState(STATE_CONFIGURE);
00910 return 0;
00911 }
00912 }
00913 else
00914 ArLog::log(ArLog::Terse, "ArSick: Got a 0x%x\n", packet->getID());
00915 }
00916 if (myStateStart.mSecSince() > 10000)
00917 {
00918 ArLog::log(ArLog::Terse,
00919 "ArSick: Failed to connect to laser, no configure acknowledgement received.");
00920 switchState(STATE_NONE);
00921 failedConnect();
00922 return 2;
00923 }
00924 break;
00925 case STATE_INSTALL_MODE:
00926 if (myStateStart.mSecSince() < 200)
00927 return 0;
00928 myPacket.empty();
00929 myPacket.byteToBuf(0x20);
00930 myPacket.byteToBuf(0x00);
00931 myPacket.strNToBuf("SICK_LMS", strlen("SICK_LMS"));
00932 myPacket.finalizePacket();
00933 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
00934 {
00935 switchState(STATE_WAIT_FOR_INSTALL_MODE_ACK);
00936 return 0;
00937 }
00938 else
00939 {
00940 ArLog::log(ArLog::Terse,
00941 "ArSick: Failed to connect to laser, could not send start command.");
00942 switchState(STATE_NONE);
00943 failedConnect();
00944 return 2;
00945 }
00946 break;
00947 case STATE_WAIT_FOR_INSTALL_MODE_ACK:
00948 while ((packet = mySickPacketReceiver.receivePacket()) != NULL)
00949 {
00950 if (packet->getID() == 0xa0)
00951 {
00952 value = packet->bufToByte();
00953 if (value == 0)
00954 {
00955
00956 switchState(STATE_SET_MODE);
00957 return 0;
00958 }
00959 else if (value == 1)
00960 {
00961 ArLog::log(ArLog::Terse,
00962 "ArSick: Could not start laser, incorrect password.");
00963 switchState(STATE_NONE);
00964 failedConnect();
00965 return 2;
00966 }
00967 else if (value == 2)
00968 {
00969 ArLog::log(ArLog::Terse,
00970 "ArSick: Could not start laser, LMI fault.");
00971 switchState(STATE_NONE);
00972 failedConnect();
00973 return 2;
00974 }
00975 else
00976 {
00977 ArLog::log(ArLog::Terse,
00978 "ArSick: Could not start laser, unknown problem.");
00979 switchState(STATE_NONE);
00980 failedConnect();
00981 return 2;
00982 }
00983 }
00984 else if (packet->getID() == 0xb0)
00985 {
00986
00987 ArLog::log(ArLog::Terse, "ArSick: extra data packet\n");
00988 myPacket.empty();
00989 myPacket.uByteToBuf(0x20);
00990 myPacket.uByteToBuf(0x25);
00991 myPacket.finalizePacket();
00992 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
00993 {
00994 switchState(STATE_INSTALL_MODE);
00995 return 0;
00996 }
00997 }
00998 else
00999 ArLog::log(ArLog::Terse, "ArSick: bad packet 0x%x\n", packet->getID());
01000 }
01001 if (myStateStart.mSecSince() > 10000)
01002 {
01003 ArLog::log(ArLog::Terse,
01004 "ArSick: Failed to connect to laser, no install mode ack received.");
01005 switchState(STATE_NONE);
01006 return 2;
01007 }
01008 break;
01009 case STATE_SET_MODE:
01010 if (myStateStart.mSecSince() < 200)
01011 return 0;
01012 myPacket.empty();
01013
01014 myPacket.byteToBuf(0x77);
01015
01016 myPacket.uByte2ToBuf(0);
01017
01018 myPacket.uByte2ToBuf(70);
01019
01020
01021
01022 myPacket.uByteToBuf(0);
01023
01024 myPacket.uByteToBuf(6);
01025
01026 myPacket.uByteToBuf(1);
01027
01028 myPacket.uByteToBuf(0);
01029
01030 myPacket.uByteToBuf(0);
01031
01032 myPacket.uByteToBuf(2);
01033
01034 myPacket.uByteToBuf(2);
01035
01036 myPacket.uByteToBuf(0);
01037
01038 myPacket.uByteToBuf(0);
01039
01040 myPacket.uByteToBuf(0);
01041
01042 myPacket.uByteToBuf(0);
01043
01044 myPacket.uByteToBuf(0);
01045
01046 myPacket.uByteToBuf(0);
01047
01048 myPacket.uByteToBuf(0);
01049
01050 myPacket.uByteToBuf(0);
01051
01052 myPacket.uByteToBuf(0);
01053
01054 myPacket.uByteToBuf(0);
01055
01056 myPacket.uByteToBuf(0);
01057
01058 myPacket.uByteToBuf(0);
01059
01060 myPacket.uByteToBuf(0);
01061
01062 myPacket.uByteToBuf(0);
01063
01064 myPacket.uByteToBuf(0);
01065
01066 myPacket.uByteToBuf(0);
01067
01068 myPacket.uByteToBuf(0);
01069
01070 myPacket.uByteToBuf(0);
01071
01072 myPacket.byte2ToBuf(0);
01073
01074 myPacket.uByteToBuf(0);
01075
01076 myPacket.finalizePacket();
01077
01078
01079 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
01080 {
01081
01082 switchState(STATE_WAIT_FOR_SET_MODE_ACK);
01083 return 0;
01084 }
01085 else
01086 {
01087 ArLog::log(ArLog::Terse,
01088 "ArSick: Failed to connect to laser, could not send set mode command.");
01089 switchState(STATE_NONE);
01090 failedConnect();
01091 return 2;
01092 }
01093 break;
01094 case STATE_WAIT_FOR_SET_MODE_ACK:
01095 while ((packet = mySickPacketReceiver.receivePacket()) != NULL)
01096 {
01097 if (packet->getID() == 0xF7)
01098 {
01099
01100
01101
01102 switchState(STATE_START_READINGS);
01103 return 0;
01104 }
01105 else if (packet->getID() == 0xb0)
01106 {
01107
01108 ArLog::log(ArLog::Terse, "ArSick: extra data packet\n");
01109 myPacket.empty();
01110 myPacket.uByteToBuf(0x20);
01111 myPacket.uByteToBuf(0x25);
01112 myPacket.finalizePacket();
01113 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
01114 {
01115 switchState(STATE_INSTALL_MODE);
01116 return 0;
01117 }
01118 }
01119 else if (packet->getID() == 0x92)
01120 {
01121 switchState(STATE_INSTALL_MODE);
01122 return 0;
01123 }
01124 else
01125 ArLog::log(ArLog::Terse, "ArSick: Got a 0x%x\n", packet->getID());
01126 }
01127 if (myStateStart.mSecSince() > 14000)
01128 {
01129 ArLog::log(ArLog::Terse,
01130 "ArSick: Failed to connect to laser, no set mode acknowledgement received.");
01131 switchState(STATE_NONE);
01132 failedConnect();
01133 return 2;
01134 }
01135 break;
01136 case STATE_START_READINGS:
01137 if (myStateStart.mSecSince() < 200)
01138 return 0;
01139 myPacket.empty();
01140 myPacket.byteToBuf(0x20);
01141 myPacket.byteToBuf(0x24);
01142 myPacket.finalizePacket();
01143 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
01144 {
01145 switchState(STATE_WAIT_FOR_START_ACK);
01146 return 0;
01147 }
01148 else
01149 {
01150 ArLog::log(ArLog::Terse,
01151 "ArSick: Failed to connect to laser, could not send start command.");
01152 switchState(STATE_NONE);
01153 failedConnect();
01154 return 2;
01155 }
01156 break;
01157 case STATE_WAIT_FOR_START_ACK:
01158 while ((packet = mySickPacketReceiver.receivePacket()) != NULL)
01159 {
01160 if (packet->getID() == 0xa0)
01161 {
01162 value = packet->bufToByte();
01163 if (value == 0)
01164 {
01165 ArLog::log(ArLog::Terse, "ArSick: Connected to the laser.");
01166 switchState(STATE_CONNECTED);
01167 madeConnection();
01168 return 1;
01169 }
01170 else if (value == 1)
01171 {
01172 ArLog::log(ArLog::Terse,
01173 "ArSick: Could not start laser laser, incorrect password.");
01174 switchState(STATE_NONE);
01175 failedConnect();
01176 return 2;
01177 }
01178 else if (value == 2)
01179 {
01180 ArLog::log(ArLog::Terse,
01181 "ArSick: Could not start laser laser, LMI fault.");
01182 switchState(STATE_NONE);
01183 failedConnect();
01184 return 2;
01185 }
01186 else
01187 {
01188 ArLog::log(ArLog::Terse,
01189 "ArSick: Could not start laser laser, unknown problem.");
01190 switchState(STATE_NONE);
01191 failedConnect();
01192 return 2;
01193 }
01194 }
01195 }
01196 if (myStateStart.mSecSince() > 1000)
01197 {
01198 ArLog::log(ArLog::Terse,
01199 "ArSick: Failed to connect to laser, no start acknowledgement received.");
01200 switchState(STATE_NONE);
01201 failedConnect();
01202 return 2;
01203 }
01204 break;
01205 default:
01206 ArLog::log(ArLog::Verbose, "ArSick: In bad connection state\n");
01207 break;
01208 }
01209 return 0;
01210 }
01211
01217 bool ArSick::internalConnectSim(void)
01218 {
01219 lockDevice();
01220 double offset = myOffsetAmount;
01221 double increment = myIncrementAmount;
01222 unlockDevice();
01223
01224 myRobot->lock();
01225
01226 if (myRobot->comInt(36, -ArMath::roundInt(offset)) &&
01227 myRobot->comInt(37, ArMath::roundInt(offset)) &&
01228 myRobot->comInt(38, ArMath::roundInt(increment * 100.0)) &&
01229 myRobot->comInt(35, 1))
01230 {
01231 myRobot->unlock();
01232 switchState(STATE_CONNECTED);
01233 madeConnection();
01234 ArLog::log(ArLog::Terse, "ArSick: Connected to simulated laser.");
01235 return true;
01236 }
01237 else
01238 {
01239 switchState(STATE_NONE);
01240 failedConnect();
01241 ArLog::log(ArLog::Terse,
01242 "ArSick: Failed to connect to simulated laser.");
01243 return false;
01244 }
01245 }
01246
01259 void ArSick::addConnectCB(ArFunctor *functor,
01260 ArListPos::Pos position)
01261 {
01262 if (position == ArListPos::FIRST)
01263 myConnectCBList.push_front(functor);
01264 else if (position == ArListPos::LAST)
01265 myConnectCBList.push_back(functor);
01266 else
01267 ArLog::log(ArLog::Terse,
01268 "ArSick::myConnectCallbackList: Invalid position.");
01269 }
01270
01275 void ArSick::remConnectCB(ArFunctor *functor)
01276 {
01277 myConnectCBList.remove(functor);
01278 }
01279
01280
01294 void ArSick::addFailedConnectCB(ArFunctor *functor,
01295 ArListPos::Pos position)
01296 {
01297 if (position == ArListPos::FIRST)
01298 myFailedConnectCBList.push_front(functor);
01299 else if (position == ArListPos::LAST)
01300 myFailedConnectCBList.push_back(functor);
01301 else
01302 ArLog::log(ArLog::Terse,
01303 "ArSick::myConnectCallbackList: Invalid position.");
01304 }
01305
01310 void ArSick::remFailedConnectCB(ArFunctor *functor)
01311 {
01312 myFailedConnectCBList.remove(functor);
01313 }
01314
01328 void ArSick::addDisconnectNormallyCB(ArFunctor *functor,
01329 ArListPos::Pos position)
01330 {
01331 if (position == ArListPos::FIRST)
01332 myDisconnectNormallyCBList.push_front(functor);
01333 else if (position == ArListPos::LAST)
01334 myDisconnectNormallyCBList.push_back(functor);
01335 else
01336 ArLog::log(ArLog::Terse,
01337 "ArSick::myConnectCallbackList: Invalid position.");
01338 }
01339
01344 void ArSick::remDisconnectNormallyCB(ArFunctor *functor)
01345 {
01346 myDisconnectNormallyCBList.remove(functor);
01347 }
01348
01365 void ArSick::addDisconnectOnErrorCB(ArFunctor *functor,
01366 ArListPos::Pos position)
01367 {
01368 if (position == ArListPos::FIRST)
01369 myDisconnectOnErrorCBList.push_front(functor);
01370 else if (position == ArListPos::LAST)
01371 myDisconnectOnErrorCBList.push_back(functor);
01372 else
01373 ArLog::log(ArLog::Terse,
01374 "ArSick::myConnectCallbackList: Invalid position");
01375 }
01376
01381 void ArSick::remDisconnectOnErrorCB(ArFunctor *functor)
01382 {
01383 myDisconnectOnErrorCBList.remove(functor);
01384 }
01385
01396 void ArSick::addDataCB(ArFunctor *functor,
01397 ArListPos::Pos position)
01398 {
01399 if (position == ArListPos::FIRST)
01400 myDataCBList.push_front(functor);
01401 else if (position == ArListPos::LAST)
01402 myDataCBList.push_back(functor);
01403 else
01404 ArLog::log(ArLog::Terse,
01405 "ArSick::addDataCB: Invalid position.");
01406 }
01407
01412 void ArSick::remDataCB(ArFunctor *functor)
01413 {
01414 myDataCBList.remove(functor);
01415 }
01416
01417 void ArSick::dropConnection(void)
01418 {
01419 std::list<ArFunctor *>::iterator it;
01420
01421 if (myState != STATE_CONNECTED)
01422 return;
01423
01424 myCurrentBuffer.reset();
01425 myCumulativeBuffer.reset();
01426 ArLog::log(ArLog::Terse,
01427 "ArSick: Lost connection to the laser because of error.");
01428 switchState(STATE_NONE);
01429 for (it = myDisconnectOnErrorCBList.begin();
01430 it != myDisconnectOnErrorCBList.end();
01431 it++)
01432 (*it)->invoke();
01433 if (myConn != NULL)
01434 myConn->close();
01435 }
01436
01437 void ArSick::failedConnect(void)
01438 {
01439 std::list<ArFunctor *>::iterator it;
01440
01441 switchState(STATE_NONE);
01442 for (it = myFailedConnectCBList.begin();
01443 it != myFailedConnectCBList.end();
01444 it++)
01445 (*it)->invoke();
01446 if (myConn != NULL)
01447 myConn->close();
01448 }
01449
01450 void ArSick::madeConnection(void)
01451 {
01452 std::list<ArFunctor *>::iterator it;
01453
01454 myLastReading.setToNow();
01455 for (it = myConnectCBList.begin(); it != myConnectCBList.end(); it++)
01456 (*it)->invoke();
01457 }
01458
01472 bool ArSick::disconnect(bool doNotLockRobotForSim)
01473 {
01474 std::list<ArFunctor *>::iterator it;
01475 bool ret;
01476 ArSerialConnection *conn;
01477
01478 myStateMutex.lock();
01479 if (myState == STATE_NONE)
01480 {
01481 myStateMutex.unlock();
01482 return true;
01483 }
01484
01485 if (myState != STATE_CONNECTED)
01486 {
01487 lockDevice();
01488 myConnLock.lock();
01489 myState = STATE_NONE;
01490 ret = myConn->close();
01491 myConnLock.unlock();
01492 unlockDevice();
01493 ArLog::log(ArLog::Terse, "ArSick: Disconnecting from laser that was not fully connected to...");
01494 ArLog::log(ArLog::Terse, "this may cause problems later.");
01495 myStateMutex.unlock();
01496 return ret;
01497 }
01498
01499 myCurrentBuffer.reset();
01500 myCumulativeBuffer.reset();
01501 ArLog::log(ArLog::Terse, "ArSick: Disconnecting from laser.");
01502 myState = STATE_NONE;
01503 myStateMutex.unlock();
01504 for (it = myDisconnectNormallyCBList.begin();
01505 it != myDisconnectNormallyCBList.end();
01506 it++)
01507 (*it)->invoke();
01508 if (myUseSim)
01509 {
01510 if (myRobot == NULL)
01511 return false;
01512 if (!doNotLockRobotForSim)
01513 myRobot->lock();
01514 ret = myRobot->comInt(35, 1);
01515 if (!doNotLockRobotForSim)
01516 myRobot->unlock();
01517 return ret;
01518 }
01519 else
01520 {
01521 myConnLock.lock();
01522 while (mySickPacketReceiver.receivePacket() != NULL);
01523 myPacket.empty();
01524 myPacket.uByteToBuf(0x20);
01525 myPacket.uByteToBuf(0x25);
01526 myPacket.finalizePacket();
01527 ret = myConn->write(myPacket.getBuf(), myPacket.getLength());
01528
01529 ArUtil::sleep(1000);
01530 myPacket.empty();
01531 myPacket.byteToBuf(0x20);
01532 myPacket.byteToBuf(0x42);
01533 myPacket.finalizePacket();
01534 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
01535 {
01536 ArUtil::sleep(20);
01537 if ((conn = dynamic_cast<ArSerialConnection *>(myConn)))
01538 conn->setBaud(9600);
01539 } else
01540 ret = false;
01541 ret = ret && myConn->close();
01542 myConnLock.unlock();
01543 ArUtil::sleep(300);
01544 return ret;
01545 }
01546 }
01547
01558 bool ArSick::blockingConnect(void)
01559 {
01560 int ret;
01561
01562 if (myUseSim)
01563 {
01564 return internalConnectSim();
01565 }
01566
01567 else
01568 {
01569 lockDevice();
01570 myConnLock.lock();
01571 switchState(STATE_INIT);
01572 unlockDevice();
01573 while (getRunningWithLock() && (ret = internalConnectHandler()) == 0)
01574 ArUtil::sleep(100);
01575 myConnLock.unlock();
01576 if (ret == 1)
01577 return true;
01578 else
01579 return false;
01580 }
01581 return false;
01582 }
01583
01600 bool ArSick::asyncConnect(void)
01601 {
01602 if (myState == STATE_CONNECTED)
01603 {
01604 ArLog::log(ArLog::Terse,"ArSick: already connected to laser.");
01605 return false;
01606 }
01607 if (myUseSim || getRunning() || myRunningOnRobot)
01608 {
01609 myStartConnect = true;
01610 return true;
01611 }
01612 else
01613 {
01614 ArLog::log(ArLog::Terse, "ArSick: Could not connect, to make an async connection either the sim needs to be used, the device needs to be run or runAsync, or the device needs to be runOnRobot.");
01615 return false;
01616 }
01617 }
01618
01626 bool ArSick::runOnRobot(void)
01627 {
01628 if (myRobot == NULL)
01629 return false;
01630 else
01631 {
01632 myRunningOnRobot = true;
01633 if (getRunning())
01634 stopRunning();
01635 return true;
01636 }
01637 }
01638
01639 void ArSick::processPacket(ArSickPacket *packet, ArPose pose,
01640 ArPose encoderPose,
01641 unsigned int counter,
01642 bool deinterlace,
01643 ArPose deinterlaceDelta)
01644 {
01645 std::list<ArFunctor *>::iterator it;
01646 unsigned int value;
01647 unsigned int numReadings;
01648 unsigned int i;
01649 double atDeg;
01650 unsigned int onReading;
01651 ArSensorReading *reading;
01652 int dist;
01653 std::list<ArSensorReading *>::iterator tempIt;
01654 int multiplier;
01655 ArTransform transform;
01656 std::list<double>::iterator ignoreIt;
01657 bool ignore;
01658
01659
01660
01661 if (packet->getID() == 0xb0)
01662 {
01663 value = packet->bufToUByte2();
01664 numReadings = value & 0x3ff;
01665
01666 if (!(value & ArUtil::BIT14) && !(value & ArUtil::BIT15))
01667 multiplier = 10;
01668 else if ((value & ArUtil::BIT14) && !(value & ArUtil::BIT15))
01669 multiplier = 1;
01670 else if (!(value & ArUtil::BIT14) && (value & ArUtil::BIT15))
01671 multiplier = 100;
01672 else
01673 {
01674 ArLog::log(ArLog::Terse,
01675 "ArSick::processPacket: bad distance configuration in packet\n");
01676 multiplier = 0;
01677 }
01678
01679
01680
01681
01682 while (myAssembleReadings->size() > numReadings)
01683 {
01684 ArLog::log(ArLog::Verbose, "ArSick::processPacket, too many readings, popping one.\n");
01685 tempIt = myAssembleReadings->begin();
01686 if (tempIt != myAssembleReadings->end())
01687 delete (*tempIt);
01688 myAssembleReadings->pop_front();
01689 }
01690
01691
01692 if (myAssembleReadings->size() == 0)
01693 for (i = 0; i < numReadings; i++)
01694 myAssembleReadings->push_back(new ArSensorReading);
01695
01696 transform.setTransform(pose);
01697
01698
01699 for (atDeg = mySensorPose.getTh() - myOffsetAmount, onReading = 0,
01700 myIter = myAssembleReadings->begin();
01701 (onReading < numReadings &&
01702 packet->getReadLength() < packet->getLength() - 4);
01703 myWhichReading++, atDeg += myIncrementAmount, myIter++, onReading++)
01704 {
01705 reading = (*myIter);
01706
01707
01708
01709
01710 value = packet->bufToUByte2() & 0x7fff;
01711 dist = value * multiplier ;
01712
01713
01714 ignore = false;
01715 for (ignoreIt = myIgnoreReadings.begin();
01716 ignoreIt != myIgnoreReadings.end();
01717 ignoreIt++)
01718 {
01719 if (ArMath::fabs(ArMath::subAngle(atDeg, *(ignoreIt))) < 1.0)
01720 {
01721 ignore = true;
01722 break;
01723 }
01724 }
01725 if (myMinRange != 0 && dist < (int)myMinRange)
01726 ignore = true;
01727 if (myMaxRange != 0 && dist > (int)myMaxRange)
01728 ignore = true;
01729 if (deinterlace && (onReading % 2) == 0)
01730 {
01731 reading->resetSensorPosition(
01732 ArMath::roundInt(mySensorPose.getX() + deinterlaceDelta.getX()),
01733 ArMath::roundInt(mySensorPose.getY() + deinterlaceDelta.getY()),
01734 ArMath::addAngle(atDeg, deinterlaceDelta.getTh()));
01735 reading->newData(dist, pose, encoderPose, transform, counter,
01736 packet->getTimeReceived(), ignore);
01737 }
01738 else
01739 {
01740 reading->resetSensorPosition(ArMath::roundInt(mySensorPose.getX()),
01741 ArMath::roundInt(mySensorPose.getY()),
01742 atDeg);
01743 reading->newData(dist, pose, encoderPose, transform, counter,
01744 packet->getTimeReceived(), ignore);
01745 }
01746
01747
01748
01749
01750
01751 tempIt = myIter;
01752 tempIt++;
01753 if (tempIt == myAssembleReadings->end() &&
01754 onReading + 1 != numReadings)
01755 {
01756 myAssembleReadings->push_back(new ArSensorReading);
01757 }
01758 }
01759
01760 myRawReadings = myAssembleReadings;
01761
01762 myAssembleReadings = myCurrentReadings;
01763 myCurrentReadings = myRawReadings;
01764
01765 myLastReading.setToNow();
01766 filterReadings();
01767
01768 if (myTimeLastSickPacket != time(NULL))
01769 {
01770 myTimeLastSickPacket = time(NULL);
01771 mySickPacCount = mySickPacCurrentCount;
01772 mySickPacCurrentCount = 0;
01773 }
01774 mySickPacCurrentCount++;
01775 for (it = myDataCBList.begin(); it != myDataCBList.end(); it++)
01776 (*it)->invoke();
01777 }
01778 }
01779
01780 void ArSick::runOnce(bool lockRobot)
01781 {
01782 ArSickPacket *packet;
01783 unsigned int counter;
01784 int ret;
01785 ArTime time;
01786 ArTime time2;
01787 ArPose pose;
01788 ArPose pose2;
01789 ArPose encoderPose;
01790
01791 if (myProcessImmediately && myRobot != NULL)
01792 {
01793 if (lockRobot)
01794 myRobot->lock();
01795 pose = myRobot->getPose();
01796 counter = myRobot->getCounter();
01797 if (lockRobot)
01798 myRobot->unlock();
01799 }
01800
01801 lockDevice();
01802 if (myState == STATE_CONNECTED && myTimeoutTime > 0 &&
01803 myLastReading.mSecSince() > myTimeoutTime * 1000)
01804 {
01805 dropConnection();
01806 unlockDevice();
01807 return;
01808 }
01809 if (myUseSim)
01810 {
01811 unlockDevice();
01812 return;
01813 }
01814 if (myState == STATE_CONNECTED)
01815 {
01816 unlockDevice();
01817 myConnLock.lock();
01818 packet = mySickPacketReceiver.receivePacket();
01819 myConnLock.unlock();
01820 lockDevice();
01821
01822 if (myRobot != NULL && packet != NULL && !myProcessImmediately)
01823 {
01824 myPackets.push_back(packet);
01825 }
01826 else if (myRobot != NULL && packet != NULL && myProcessImmediately)
01827 {
01828 unlockDevice();
01829 if (lockRobot && myInterpolation)
01830 myRobot->lock();
01831
01832
01833 if (myInterpolation && (ret = myRobot->getPoseInterpPosition(
01834 packet->getTimeReceived(), &pose)) < 0)
01835 pose = myRobot->getPose();
01836
01837
01838 if (myInterpolation && (ret = myRobot->getEncoderPoseInterpPosition(
01839 packet->getTimeReceived(), &encoderPose)) < 0)
01840 encoderPose = myRobot->getEncoderTransform().doInvTransform(pose);
01841 if (lockRobot && myInterpolation)
01842 myRobot->unlock();
01843 lockDevice();
01844 processPacket(packet, pose, encoderPose, counter, false, ArPose());
01845 }
01846 else if (packet != NULL)
01847 {
01848 processPacket(packet, pose, encoderPose, 0, false, ArPose());
01849 delete packet;
01850 }
01851 }
01852 unlockDevice();
01853 return;
01854
01855 }
01856
01857 int ArSick::getSickPacCount()
01858 {
01859 if (myTimeLastSickPacket == time(NULL))
01860 return mySickPacCount;
01861 if (myTimeLastSickPacket == time(NULL) - 1)
01862 return mySickPacCurrentCount;
01863 return 0;
01864 }
01865
01872 void ArSick::setFilterNearDist(double dist)
01873 {
01874 if (dist >= 0)
01875 myFilterNearDist = dist;
01876 else
01877 ArLog::log(ArLog::Terse, "ArSick::setFilterNearDist given a distance less than 0.\n");
01878
01879 }
01880
01887 double ArSick::getFilterNearDist(void)
01888 {
01889 return myFilterNearDist;
01890 }
01891
01892
01898 void ArSick::setFilterCumulativeInsertMaxDist(double dist)
01899 {
01900 if (dist >= 0)
01901 {
01902 myFilterCumulativeInsertMaxDist = dist;
01903 myFilterSquaredCumulativeInsertMaxDist = dist * dist;
01904 }
01905 else
01906 ArLog::log(ArLog::Terse, "ArSick::setFilterCumulativeMaxDistDist given a distance less than 0.\n");
01907 }
01908
01914 double ArSick::getFilterCumulativeInsertMaxDist(void)
01915 {
01916 return myFilterCumulativeInsertMaxDist;
01917 }
01918
01924 void ArSick::setFilterCumulativeNearDist(double dist)
01925 {
01926 if (dist >= 0)
01927 {
01928 myFilterCumulativeNearDist = dist;
01929 myFilterSquaredCumulativeNearDist = dist * dist;
01930 }
01931 else
01932 ArLog::log(ArLog::Terse, "ArSick::setFilterCumulativeNearDistDist given a distance less than 0.\n");
01933 }
01934
01940 double ArSick::getFilterCumulativeNearDist(void)
01941 {
01942 return myFilterCumulativeNearDist;
01943 }
01944
01952 void ArSick::setFilterCumulativeCleanDist(double dist)
01953 {
01954 if (dist >= 0)
01955 {
01956 myFilterCumulativeCleanDist = dist;
01957 myFilterSquaredCumulativeCleanDist = dist * dist;
01958 }
01959 else
01960 ArLog::log(ArLog::Terse, "ArSick::setFilterCumulativeCleanDistDist given a distance less than 0.\n");
01961 }
01962
01970 double ArSick::getFilterCumulativeCleanDist(void)
01971 {
01972 return myFilterCumulativeCleanDist;
01973 }
01974
01980 void ArSick::setFilterCleanCumulativeInterval(int milliSeconds)
01981 {
01982 if (milliSeconds >= 0)
01983 {
01984 myFilterCleanCumulativeInterval = milliSeconds;
01985 }
01986 else
01987 ArLog::log(ArLog::Terse, "ArSick::setFilterCleanCumulativeInterval given a time less than 0.\n");
01988 }
01989
01995 int ArSick::getFilterCleanCumulativeInterval(void)
01996 {
01997 return myFilterCleanCumulativeInterval;
01998 }
01999
02000
02001
02002 void ArSick::sensorInterpCallback(void)
02003 {
02004 std::list<ArSickPacket *>::iterator it;
02005 std::list<ArSickPacket *> processed;
02006 ArSickPacket *packet;
02007 ArTime time;
02008 ArPose pose;
02009 int ret;
02010 int retEncoder;
02011 ArPose encoderPose;
02012 ArPose deinterlaceEncoderPose;
02013 bool deinterlace;
02014 ArTime deinterlaceTime;
02015 ArPose deinterlaceDelta;
02016
02017 if (myRunningOnRobot)
02018 runOnce(false);
02019
02020 lockDevice();
02021 for (it = myPackets.begin(); it != myPackets.end(); it++)
02022 {
02023 packet = (*it);
02024 time = packet->getTimeReceived();
02025 time.addMSec(-13);
02026 if ((ret = myRobot->getPoseInterpPosition(time, &pose)) == 1 &&
02027 (retEncoder =
02028 myRobot->getEncoderPoseInterpPosition(time, &encoderPose)) == 1)
02029 {
02030 deinterlaceTime = packet->getTimeReceived();
02031 deinterlaceTime.addMSec(-27);
02032
02033 if (myIncrement == INCREMENT_HALF &&
02034 (myRobot->getEncoderPoseInterpPosition(
02035 deinterlaceTime, &deinterlaceEncoderPose)) == 1)
02036 deinterlace = true;
02037 else
02038 deinterlace = false;
02039
02040 ArTransform deltaTransform;
02041 deltaTransform.setTransform(encoderPose);
02042 deinterlaceDelta = deltaTransform.doInvTransform(deinterlaceEncoderPose);
02043
02044 processPacket(packet, pose, encoderPose, myRobot->getCounter(),
02045 deinterlace, deinterlaceDelta);
02046 processed.push_back(packet);
02047 }
02048 else if (ret < -1 || retEncoder < -1)
02049 {
02050 if (myRobot->isConnected())
02051 ArLog::log(ArLog::Normal, "ArSick::processPacket: too old to process\n");
02052 else
02053 {
02054 processPacket(packet, pose, encoderPose, myRobot->getCounter(), false,
02055 ArPose());
02056 }
02057 processed.push_back(packet);
02058 }
02059 else
02060 {
02061
02062
02063 }
02064 }
02065 while ((it = processed.begin()) != processed.end())
02066 {
02067 packet = (*it);
02068 myPackets.remove(packet);
02069 processed.pop_front();
02070 delete packet;
02071 }
02072 unlockDevice();
02073 }
02074
02075 void *ArSick::runThread(void *arg)
02076 {
02077 while (getRunningWithLock())
02078 {
02079 lockDevice();
02080 if (myStartConnect)
02081 {
02082 myStartConnect = false;
02083 switchState(STATE_INIT);
02084 if (myUseSim)
02085 {
02086 unlockDevice();
02087 internalConnectSim();
02088 }
02089 else
02090 {
02091 unlockDevice();
02092 while (getRunningWithLock())
02093 {
02094 lockDevice();
02095 myConnLock.lock();
02096 if (internalConnectHandler() != 0)
02097 {
02098 myConnLock.unlock();
02099 unlockDevice();
02100 break;
02101 }
02102 myConnLock.unlock();
02103 unlockDevice();
02104 ArUtil::sleep(1);
02105 }
02106 }
02107 } else
02108 unlockDevice();
02109 runOnce(true);
02110 ArUtil::sleep(1);
02111 }
02112 lockDevice();
02113 if (isConnected())
02114 {
02115 disconnect();
02116 }
02117 unlockDevice();
02118
02119 return NULL;
02120 }
02121
02129 void ArSick::applyTransform(ArTransform trans,
02130 bool doCumulative)
02131 {
02132 myCurrentBuffer.applyTransform(trans);
02133 std::list<ArSensorReading *>::iterator it;
02134
02135 for (it = myRawReadings->begin(); it != myRawReadings->end(); ++it)
02136 (*it)->applyTransform(trans);
02137
02138 if (doCumulative)
02139 myCumulativeBuffer.applyTransform(trans);
02140 }