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 "ArSick.h"
00029 #include "ArRobot.h"
00030 #include "ArSerialConnection.h"
00031 #include "ariaInternal.h"
00032 #include <time.h>
00033
00034 AREXPORT ArSick::ArSick(size_t currentBufferSize, size_t cumulativeBufferSize,
00035 const char *name, bool addAriaExitCB) :
00036 ArRangeDeviceThreaded(currentBufferSize, cumulativeBufferSize, name, 32500),
00037 myRobotConnectCB(this, &ArSick::robotConnectCallback),
00038 mySimPacketHandler(this, &ArSick::simPacketHandler),
00039 mySensorInterpCB(this, &ArSick::sensorInterpCallback),
00040 mySickPacketReceiver(0, true),
00041 myAriaExitCB(this, &ArSick::disconnect, true)
00042 {
00043 myAriaExitCB.setName("ArSickExit");
00044 if (addAriaExitCB)
00045 Aria::addExitCallback(&myAriaExitCB, 10);
00046 mySimPacketHandler.setName("ArSick");
00047 configure();
00048 setRangeInformation();
00049 setSensorPosition(0, 0, 0);
00050 myAssembleReadings = new std::list<ArSensorReading *>;
00051 myCurrentReadings = new std::list<ArSensorReading *>;
00052 myRawReadings = myCurrentReadings;
00053 myIter = myAssembleReadings->begin();
00054 myConn = NULL;
00055 myRobot = NULL;
00056 myStartConnect = false;
00057 myRunningOnRobot = false;
00058 switchState(STATE_NONE);
00059 myProcessImmediately = false;
00060 myInterpolation = true;
00061 myTimeoutTime = 8;
00062 myRealConfigured = false;
00063
00064
00065 setMinRange(125);
00066 setFilterNearDist(50);
00067 setFilterCumulativeMaxDist(6000);
00068 setFilterCumulativeInsertMaxDist(3000);
00069 setFilterCumulativeNearDist(200);
00070 setFilterCumulativeCleanDist(75);
00071 setFilterCumulativeMaxAge(30);
00072 setFilterCleanCumulativeInterval(1000);
00073
00074 myLastCleanedCumulative.setToNow();
00075
00076 setCurrentDrawingData(new ArDrawingData("polyDots",
00077 ArColor(0, 0, 255),
00078 80,
00079 75),
00080 true);
00081
00082 setCumulativeDrawingData(new ArDrawingData("polyDots",
00083 ArColor(125, 125, 125),
00084 100,
00085 60),
00086 true);
00087 }
00088
00089 AREXPORT ArSick::~ArSick()
00090 {
00091 if (myRobot != NULL)
00092 {
00093 myRobot->remRangeDevice(this);
00094 myRobot->remPacketHandler(&mySimPacketHandler);
00095 myRobot->remSensorInterpTask(&mySensorInterpCB);
00096 myRobot->addConnectCB(&myRobotConnectCB, ArListPos::FIRST);
00097 }
00098 lockDevice();
00099 if (isConnected())
00100 {
00101 disconnect();
00102 }
00103 unlockDevice();
00104 }
00105
00107 AREXPORT void ArSick::robotConnectCallback(void)
00108 {
00109 const ArRobotParams *params;
00110 if (myRealConfigured || !myRobot->isConnected())
00111 return;
00112 params = myRobot->getRobotParams();
00113 myLaserFlipped = params->getLaserFlipped();
00114 myPowerControl = params->getLaserPowerControlled();
00115
00116 if (myDegrees == DEGREES180)
00117 myOffsetAmount = 90;
00118 else if (myDegrees == DEGREES100)
00119 myOffsetAmount = 50;
00120 else
00121 {
00122 myOffsetAmount = 0;
00123 ArLog::log(ArLog::Terse,"ArSick::robotConnectCallback: bad degrees configured.\n");
00124 }
00125
00126
00127 if (myLaserFlipped)
00128 myOffsetAmount *= -1;
00129
00130 if (myIncrement == INCREMENT_ONE)
00131 myIncrementAmount = 1.0;
00132 else if (myIncrement == INCREMENT_HALF)
00133 myIncrementAmount = 0.5;
00134 else
00135 {
00136 myIncrementAmount = 0;
00137 ArLog::log(ArLog::Terse,"ArSick::robotConnectCallback: bad increment configured.\n");
00138 }
00139 if (myLaserFlipped)
00140 myIncrementAmount *= -1;
00141
00142 clearIgnoreReadings();
00143 ArArgumentBuilder builder;
00144 builder.add(myRobot->getRobotParams()->getLaserIgnore());
00145 size_t i;
00146 for (i = 0; i < builder.getArgc(); i++)
00147 {
00148 if (!builder.isArgDouble(i))
00149 {
00150 ArLog::log(ArLog::Normal, "ArRobotConfig::setIgnoreReadings: argument is not a double");
00151 }
00152 addIgnoreReading(builder.getArgDouble(i));
00153 }
00154
00155 setSensorPosition(params->getLaserX(), params->getLaserY(), params->getLaserTh());
00156 }
00157
00158 AREXPORT bool ArSick::isUsingSim(void)
00159 {
00160 return myUseSim;
00161 }
00162
00163 AREXPORT bool ArSick::isControllingPower(void)
00164 {
00165 return myPowerControl;
00166 }
00167
00168 AREXPORT bool ArSick::isLaserFlipped(void)
00169 {
00170 return myLaserFlipped;
00171 }
00172
00173 AREXPORT ArSick::Degrees ArSick::getDegrees(void)
00174 {
00175 return myDegrees;
00176 }
00177
00178 AREXPORT ArSick::Increment ArSick::getIncrement(void)
00179 {
00180 return myIncrement;
00181 }
00182
00183 AREXPORT ArSick::Bits ArSick::getBits(void) { return myBits; }
00184 AREXPORT ArSick::Units ArSick::getUnits(void) { return myUnits; }
00185
00186 AREXPORT void ArSick::setIsUsingSim(bool usingSim)
00187 {
00188 myUseSim = usingSim;
00189 }
00190
00191 AREXPORT void ArSick::setIsControllingPower(bool controlPower)
00192 {
00193 myPowerControl = controlPower;
00194 }
00195
00196 AREXPORT void ArSick::setIsLaserFlipped(bool laserFlipped)
00197 {
00198 myLaserFlipped = laserFlipped;
00199 }
00200
00201
00202 AREXPORT void ArSick::setSensorPosition(double x, double y, double th)
00203 {
00204 mySensorPose.setPose(x, y, th);
00205 }
00206
00207 AREXPORT void ArSick::setSensorPosition(ArPose pose)
00208 {
00209 mySensorPose = pose;
00210 }
00211
00212 AREXPORT ArPose ArSick::getSensorPosition(void)
00213 {
00214 return mySensorPose;
00215 }
00216
00217 AREXPORT double ArSick::getSensorPositionX(void)
00218 {
00219 return mySensorPose.getX();
00220 }
00221
00222 AREXPORT double ArSick::getSensorPositionY(void)
00223 {
00224 return mySensorPose.getY();
00225 }
00226
00227 AREXPORT double ArSick::getSensorPositionTh(void)
00228 {
00229 return mySensorPose.getTh();
00230 }
00231
00232
00233 AREXPORT void ArSick::setDeviceConnection(ArDeviceConnection *conn)
00234 {
00235 myConnLock.lock();
00236 myConn = conn;
00237 mySickPacketReceiver.setDeviceConnection(conn);
00238 myConnLock.unlock();
00239 }
00240
00241 AREXPORT ArDeviceConnection *ArSick::getDeviceConnection(void)
00242 {
00243 return myConn;
00244 }
00245
00255 AREXPORT void ArSick::setConnectionTimeoutTime(int mSecs)
00256 {
00257 if (mSecs > 0)
00258 myTimeoutTime = mSecs;
00259 else
00260 myTimeoutTime = 0;
00261 }
00262
00269 AREXPORT int ArSick::getConnectionTimeoutTime(void)
00270 {
00271 return myTimeoutTime;
00272 }
00273
00274 AREXPORT ArTime ArSick::getLastReadingTime(void)
00275 {
00276 return myLastReading;
00277 }
00278
00279 AREXPORT void ArSick::setRobot(ArRobot *robot)
00280 {
00281 myRobot = robot;
00282 if (myRobot != NULL)
00283 {
00284 myRobot->addPacketHandler(&mySimPacketHandler, ArListPos::LAST);
00285 myRobot->addSensorInterpTask("sick", 90, &mySensorInterpCB);
00286 myRobot->addConnectCB(&myRobotConnectCB, ArListPos::FIRST);
00287 if (myRobot->isConnected())
00288 robotConnectCallback();
00289 }
00290 ArRangeDevice::setRobot(robot);
00291 }
00292
00305 AREXPORT void ArSick::configure(bool useSim, bool powerControl,
00306 bool laserFlipped, BaudRate baud,
00307 Degrees deg, Increment incr)
00308 {
00309
00310 myUseSim = useSim;
00311 myPowerControl = powerControl;
00312 myLaserFlipped = laserFlipped;
00313 myBaud = baud;
00314 myDegrees = deg;
00315 myIncrement = incr;
00316
00317 if (myDegrees == DEGREES180)
00318 myOffsetAmount = 90;
00319 else if (myDegrees == DEGREES100)
00320 myOffsetAmount = 50;
00321 else
00322 {
00323 myOffsetAmount = 0;
00324 ArLog::log(ArLog::Terse,"ArSick::configure: bad degrees configured.\n");
00325 }
00326
00327 if (myLaserFlipped)
00328 myOffsetAmount *= -1;
00329
00330 if (myIncrement == INCREMENT_ONE)
00331 myIncrementAmount = 1.0;
00332 else if (myIncrement == INCREMENT_HALF)
00333 myIncrementAmount = 0.5;
00334 else
00335 {
00336 myIncrementAmount = 0;
00337 ArLog::log(ArLog::Terse,"ArSick::configure: bad increment configured.\n");
00338 }
00339
00340 if (myLaserFlipped)
00341 myIncrementAmount *= -1;
00342
00343 myRealConfigured = true;
00344 }
00345
00349 AREXPORT void ArSick::configureShort(bool useSim, BaudRate baud,
00350 Degrees deg, Increment incr)
00351 {
00352
00353 myUseSim = useSim;
00354 myPowerControl = true;
00355 myLaserFlipped = false;
00356 myBaud = baud;
00357 myDegrees = deg;
00358 myIncrement = incr;
00359
00360 if (myDegrees == DEGREES180)
00361 myOffsetAmount = 90;
00362 else if (myDegrees == DEGREES100)
00363 myOffsetAmount = 50;
00364 else
00365 {
00366 myOffsetAmount = 0;
00367 ArLog::log(ArLog::Terse,"ArSick::configureShort: bad degrees configured.\n");
00368 }
00369
00370 if (myLaserFlipped)
00371 myOffsetAmount *= -1;
00372
00373 if (myIncrement == INCREMENT_ONE)
00374 myIncrementAmount = 1.0;
00375 else if (myIncrement == INCREMENT_HALF)
00376 myIncrementAmount = 0.5;
00377 else
00378 {
00379 myIncrementAmount = 0;
00380 ArLog::log(ArLog::Terse,"ArSick::configureShort: bad increment configured.\n");
00381 }
00382 if (myLaserFlipped)
00383 myIncrementAmount *= -1;
00384
00385 myRealConfigured = false;
00386
00387 if (myRobot != NULL && myRobot->isConnected())
00388 robotConnectCallback();
00389 }
00390
00396 AREXPORT void ArSick::setRangeInformation(Bits bits, Units units)
00397 {
00398 myUnits = units;
00399 myBits = bits;
00400 }
00401
00402
00404 AREXPORT bool ArSick::simPacketHandler(ArRobotPacket *packet)
00405 {
00406 std::list<ArFunctor *>::iterator it;
00407
00408 unsigned int totalNumReadings;
00409 unsigned int readingNumber;
00410 double atDeg;
00411 unsigned int i;
00412 ArSensorReading *reading;
00413 std::list<ArSensorReading *>::iterator tempIt;
00414 unsigned int newReadings;
00415 int range;
00416 int refl = 0;
00417 ArPose encoderPose;
00418 std::list<double>::iterator ignoreIt;
00419 bool ignore;
00420
00421 if (packet->getID() != 0x60 && packet->getID() != 0x61)
00422 return false;
00423
00424 bool isExtendedPacket = (packet->getID() == 0x61);
00425
00426
00427
00428
00429 lockDevice();
00430
00431 if (!myUseSim)
00432 {
00433 ArLog::log(ArLog::Terse, "ArSick: Got a packet from the simulator with laser information, but the laser is not being simulated, major trouble.");
00434 unlockDevice();
00435 return true;
00436 }
00437 if(!isExtendedPacket)
00438 {
00439
00440 packet->bufToByte2();
00441 packet->bufToByte2();
00442 packet->bufToByte2();
00443 }
00444 totalNumReadings = packet->bufToByte2();
00445 readingNumber = packet->bufToByte2();
00446 newReadings = packet->bufToUByte();
00447 if (readingNumber == 0)
00448 {
00449 mySimPacketStart = myRobot->getPose();
00450 mySimPacketTrans = myRobot->getToGlobalTransform();
00451 mySimPacketEncoderTrans = myRobot->getEncoderTransform();
00452 mySimPacketCounter = myRobot->getCounter();
00453 }
00454
00455
00456 while (myAssembleReadings->size() > totalNumReadings)
00457 {
00458 ArLog::log(ArLog::Verbose, "ArSick::simPacketHandler, too many readings, popping one.\n");
00459 tempIt = myAssembleReadings->begin();
00460 if (tempIt != myAssembleReadings->end())
00461 delete (*tempIt);
00462 myAssembleReadings->pop_front();
00463 }
00464
00465
00466 if (myAssembleReadings->size() == 0)
00467 for (i = 0; i < totalNumReadings; i++)
00468 myAssembleReadings->push_back(new ArSensorReading);
00469
00470
00471
00472
00473 if ((readingNumber != myWhichReading + 1) ||
00474 totalNumReadings != myTotalNumReadings)
00475 {
00476
00477 myWhichReading = readingNumber;
00478 myTotalNumReadings = totalNumReadings;
00479 for (i = 0, myIter = myAssembleReadings->begin(); i < readingNumber; i++)
00480 {
00481 tempIt = myIter;
00482 tempIt++;
00483 if (tempIt == myAssembleReadings->end() && (i + 1 != myTotalNumReadings))
00484 myAssembleReadings->push_back(new ArSensorReading);
00485 myIter++;
00486 }
00487 }
00488 else
00489 {
00490
00491 myWhichReading = readingNumber;
00492 }
00493
00494 atDeg = (mySensorPose.getTh() - myOffsetAmount +
00495 readingNumber * myIncrementAmount);
00496
00497 encoderPose = mySimPacketEncoderTrans.doInvTransform(mySimPacketStart);
00498
00499 for (i = 0;
00500
00501
00502 i < newReadings;
00503 i++, myWhichReading++, atDeg += myIncrementAmount)
00504 {
00505 reading = (*myIter);
00506 range = packet->bufToUByte2();
00507 if(isExtendedPacket)
00508 {
00509 refl = packet->bufToUByte();
00510 packet->bufToUByte();
00511 packet->bufToUByte();
00512 }
00513 ignore = false;
00514 for (ignoreIt = myIgnoreReadings.begin();
00515 ignoreIt != myIgnoreReadings.end();
00516 ignoreIt++)
00517 {
00518
00519
00520 if (ArMath::fabs(ArMath::subAngle(atDeg, *(ignoreIt))) < 1.0)
00521 {
00522
00523 ignore = true;
00524 break;
00525 }
00526 }
00527 if (myMaxRange != 0 && range < (int)myMinRange)
00528 ignore = true;
00529 if (myMaxRange != 0 && range > (int)myMaxRange)
00530 ignore = true;
00531
00532 reading->resetSensorPosition(ArMath::roundInt(mySensorPose.getX()),
00533 ArMath::roundInt(mySensorPose.getY()),
00534 atDeg);
00535
00536 reading->newData(range, mySimPacketStart,
00537 encoderPose,
00538 mySimPacketTrans,
00539 mySimPacketCounter, packet->getTimeReceived(), ignore, refl);
00540
00541
00542 tempIt = myIter;
00543 tempIt++;
00544 if (tempIt == myAssembleReadings->end() &&
00545 myWhichReading + 1 != myTotalNumReadings)
00546 {
00547 myAssembleReadings->push_back(new ArSensorReading);
00548 }
00549 myIter++;
00550 }
00551
00552
00553
00554 if (newReadings + readingNumber >= totalNumReadings)
00555 {
00556
00557 myRawReadings = myAssembleReadings;
00558
00559 myAssembleReadings = myCurrentReadings;
00560 myCurrentReadings = myRawReadings;
00561
00562 filterReadings();
00563
00564 if (myTimeLastSickPacket != time(NULL))
00565 {
00566 myTimeLastSickPacket = time(NULL);
00567 mySickPacCount = mySickPacCurrentCount;
00568 mySickPacCurrentCount = 0;
00569 }
00570 mySickPacCurrentCount++;
00571 myLastReading.setToNow();
00572
00573 for (it = myDataCBList.begin(); it != myDataCBList.end(); it++)
00574 (*it)->invoke();
00575 }
00576
00577 unlockDevice();
00578 return true;
00579 }
00580
00596 void ArSick::filterReadings()
00597 {
00598 std::list<ArSensorReading *>::iterator sensIt;
00599 ArSensorReading *sReading;
00600 double x, y;
00601 double squaredDist;
00602 double lastX = 0.0, lastY = 0.0;
00603 unsigned int i;
00604 double squaredNearDist = myFilterNearDist * myFilterNearDist;
00605 ArTime len;
00606 len.setToNow();
00607
00608 bool clean;
00609 if (myFilterCleanCumulativeInterval == 0 ||
00610 myLastCleanedCumulative.mSecSince() > myFilterCleanCumulativeInterval)
00611 {
00612 myLastCleanedCumulative.setToNow();
00613 clean = true;
00614 }
00615 else
00616 {
00617 clean = false;
00618 }
00619
00620 sensIt = myRawReadings->begin();
00621 sReading = (*sensIt);
00622 myCurrentBuffer.setPoseTaken(sReading->getPoseTaken());
00623 myCurrentBuffer.setEncoderPoseTaken(sReading->getEncoderPoseTaken());
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 i = 0;
00636
00637 for (myCurrentBuffer.beginRedoBuffer();
00638 sensIt != myRawReadings->end();
00639 ++sensIt)
00640 {
00641 sReading = (*sensIt);
00642
00643
00644
00645
00646
00647 if (!sReading->getIgnoreThisReading())
00648 {
00649
00650 x = sReading->getX();
00651 y = sReading->getY();
00652
00653
00654
00655
00656
00657 if (squaredNearDist > 0.0000001)
00658 {
00659
00660 squaredDist = (x-lastX)*(x-lastX) + (y-lastY)*(y-lastY);
00661
00662 if (squaredDist > squaredNearDist)
00663 {
00664 lastX = x;
00665 lastY = y;
00666
00667
00668 filterAddAndCleanCumulative(x, y, clean);
00669
00670
00671
00672
00673
00674
00675 }
00676
00677 else
00678 {
00679 continue;
00680 }
00681 }
00682
00683
00684 else
00685 {
00686 filterAddAndCleanCumulative(x, y, clean);
00687 }
00688
00689 myCurrentBuffer.redoReading(x, y);
00690 i++;
00691 }
00692 }
00693 myCurrentBuffer.endRedoBuffer();
00694
00695
00696
00697
00698
00699 }
00700
00702 void ArSick::filterAddAndCleanCumulative(double x, double y, bool clean)
00703 {
00704 if (myCumulativeBuffer.getSize() == 0)
00705 return;
00706
00707
00708 std::list<ArPoseWithTime *>::iterator cit;
00709 bool addReading = true;
00710 double squaredDist;
00711
00712 ArLineSegment line;
00713 double xTaken = myCurrentBuffer.getPoseTaken().getX();
00714 double yTaken = myCurrentBuffer.getPoseTaken().getY();
00715 ArPose intersection;
00716 ArPoseWithTime reading(x, y);
00717
00718
00719 if (clean && myFilterSquaredCumulativeCleanDist < 1)
00720 clean = false;
00721
00722 squaredDist = ArMath::squaredDistanceBetween(x, y, xTaken, yTaken);
00723
00724
00725 if (!clean &&
00726 myFilterSquaredCumulativeInsertMaxDist > 1 &&
00727 squaredDist > myFilterSquaredCumulativeInsertMaxDist)
00728 return;
00729
00730
00731 if (clean)
00732 myCumulativeBuffer.beginInvalidationSweep();
00733
00734 for (cit = getCumulativeBuffer()->begin();
00735 cit != getCumulativeBuffer()->end();
00736 ++cit)
00737 {
00738
00739 if (myFilterSquaredCumulativeNearDist < .0000001 ||
00740 (ArMath::squaredDistanceBetween(x, y, (*cit)->getX(), (*cit)->getY()) <
00741 myFilterSquaredCumulativeNearDist))
00742 {
00743
00744
00745 if (!clean)
00746 return;
00747 addReading = false;
00748 }
00749
00750 if (clean)
00751 {
00752
00753 line.newEndPoints(x, y, xTaken, yTaken);
00754
00755
00756 if (line.getPerpPoint((*cit), &intersection) &&
00757 (intersection.squaredFindDistanceTo(*(*cit)) <
00758 myFilterSquaredCumulativeCleanDist) &&
00759 (intersection.squaredFindDistanceTo(reading) > 50 * 50))
00760 {
00761
00762 myCumulativeBuffer.invalidateReading(cit);
00763 }
00764 }
00765 }
00766
00767 if (clean)
00768 myCumulativeBuffer.endInvalidationSweep();
00769
00770 if (addReading)
00771 myCumulativeBuffer.addReading(x, y);
00772
00773 }
00774
00776 AREXPORT void ArSick::switchState(State state)
00777 {
00778 myStateMutex.lock();
00779 myState = state;
00780 myStateStart.setToNow();
00781 myStateMutex.unlock();
00782 }
00783
00788 AREXPORT int ArSick::internalConnectHandler(void)
00789 {
00790 ArSickPacket *packet;
00791 ArSerialConnection *conn;
00792 int value;
00793
00794 switch (myState)
00795 {
00796 case STATE_INIT:
00797 if (myConn->getStatus() != ArDeviceConnection::STATUS_OPEN)
00798 {
00799 if ((conn = dynamic_cast<ArSerialConnection *>(myConn)) != NULL)
00800 {
00801 conn->setBaud(9600);
00802 }
00803 if (!myConn->openSimple())
00804 {
00805 ArLog::log(ArLog::Terse,
00806 "ArSick: Failed to connect to laser, could not open port.");
00807 switchState(STATE_NONE);
00808 failedConnect();
00809 return 2;
00810 }
00811 }
00812 if (!myPowerControl)
00813 {
00814
00815
00816
00817
00818
00819
00820
00821 switchState(STATE_CHANGE_BAUD);
00822 return internalConnectHandler();
00823 }
00824 ArLog::log(ArLog::Terse, "ArSick: waiting for laser to power on.");
00825 myPacket.empty();
00826 myPacket.uByteToBuf(0x10);
00827 myPacket.finalizePacket();
00828 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
00829 {
00830 switchState(STATE_WAIT_FOR_POWER_ON);
00831 return 0;
00832 }
00833 else
00834 {
00835 ArLog::log(ArLog::Terse,
00836 "ArSick: Failed to connect to laser, could not send init.");
00837 switchState(STATE_NONE);
00838 failedConnect();
00839 return 2;
00840 }
00841 break;
00842 case STATE_WAIT_FOR_POWER_ON:
00843 while ((packet = mySickPacketReceiver.receivePacket()) != NULL)
00844 {
00845 if (packet->getID() == 0x90)
00846 {
00847 switchState(STATE_CHANGE_BAUD);
00848 return 0;
00849 }
00850 }
00851 if (myStateStart.secSince() > 65)
00852 {
00853 ArLog::log(ArLog::Terse,
00854 "ArSick: Failed to connect to laser, no poweron received.");
00855 switchState(STATE_NONE);
00856 failedConnect();
00857 return 2;
00858 }
00859 break;
00860 case STATE_CHANGE_BAUD:
00861 myPacket.empty();
00862 myPacket.byteToBuf(0x20);
00863 if (myBaud == BAUD9600)
00864 myPacket.byteToBuf(0x42);
00865 else if (myBaud == BAUD19200)
00866 myPacket.byteToBuf(0x41);
00867 else if (myBaud == BAUD38400)
00868 myPacket.byteToBuf(0x40);
00869 myPacket.finalizePacket();
00870 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
00871 {
00872 ArUtil::sleep(20);
00873 if ((conn = dynamic_cast<ArSerialConnection *>(myConn)))
00874 {
00875 if (myBaud == BAUD9600)
00876 conn->setBaud(9600);
00877 else if (myBaud == BAUD19200)
00878 conn->setBaud(19200);
00879 else if (myBaud == BAUD38400)
00880 conn->setBaud(38400);
00881 }
00882 switchState(STATE_CONFIGURE);
00883 return 0;
00884 }
00885 else
00886 {
00887 ArLog::log(ArLog::Terse,
00888 "ArSick: Failed to connect to laser, could not send baud command.");
00889 switchState(STATE_NONE);
00890 failedConnect();
00891 return 2;
00892 }
00893 break;
00894 case STATE_CONFIGURE:
00895
00896 if (myStateStart.mSecSince() < 300)
00897 return 0;
00898 myPacket.empty();
00899 myPacket.byteToBuf(0x3b);
00900 myPacket.uByte2ToBuf(abs(ArMath::roundInt(myOffsetAmount * 2)));
00901 myPacket.uByte2ToBuf(abs(ArMath::roundInt(myIncrementAmount * 100)));
00902 myPacket.finalizePacket();
00903 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
00904 {
00905 switchState(STATE_WAIT_FOR_CONFIGURE_ACK);
00906 return 0;
00907 }
00908 else
00909 {
00910 ArLog::log(ArLog::Terse,
00911 "ArSick: Failed to connect to laser, could not send configure command.");
00912 switchState(STATE_NONE);
00913 failedConnect();
00914 return 2;
00915 }
00916 break;
00917 case STATE_WAIT_FOR_CONFIGURE_ACK:
00918 while ((packet = mySickPacketReceiver.receivePacket()) != NULL)
00919 {
00920 if (packet->getID() == 0xbb)
00921 {
00922 value = packet->bufToByte();
00923 if (value == 0)
00924 {
00925 ArLog::log(ArLog::Terse,
00926 "ArSick: Could not configure laser, failed connect.");
00927 switchState(STATE_NONE);
00928 failedConnect();
00929 return 2;
00930 }
00931 else if (value == 1)
00932 {
00933
00934
00935 switchState(STATE_INSTALL_MODE);
00936 return 0;
00937 }
00938 else
00939 {
00940 ArLog::log(ArLog::Terse,
00941 "ArSick: Could not configure laser, failed connect.");
00942 switchState(STATE_NONE);
00943 failedConnect();
00944 return 2;
00945 }
00946 }
00947 else if (packet->getID() == 0xb0)
00948 {
00949
00950 ArLog::log(ArLog::Terse, "ArSick: extra data packet while waiting for configure ack");
00951 myPacket.empty();
00952 myPacket.uByteToBuf(0x20);
00953 myPacket.uByteToBuf(0x25);
00954 myPacket.finalizePacket();
00955 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
00956 {
00957 switchState(STATE_CONFIGURE);
00958 return 0;
00959 }
00960 }
00961 else
00962 ArLog::log(ArLog::Terse, "ArSick: Got a 0x%x\n", packet->getID());
00963 }
00964 if (myStateStart.mSecSince() > 10000)
00965 {
00966 ArLog::log(ArLog::Terse,
00967 "ArSick: Failed to connect to laser, no configure acknowledgement received.");
00968 switchState(STATE_NONE);
00969 failedConnect();
00970 return 2;
00971 }
00972 break;
00973 case STATE_INSTALL_MODE:
00974 if (myStateStart.mSecSince() < 200)
00975 return 0;
00976 myPacket.empty();
00977 myPacket.byteToBuf(0x20);
00978 myPacket.byteToBuf(0x00);
00979 myPacket.strNToBuf("SICK_LMS", strlen("SICK_LMS"));
00980 myPacket.finalizePacket();
00981 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
00982 {
00983 switchState(STATE_WAIT_FOR_INSTALL_MODE_ACK);
00984 return 0;
00985 }
00986 else
00987 {
00988 ArLog::log(ArLog::Terse,
00989 "ArSick: Failed to connect to laser, could not send start command.");
00990 switchState(STATE_NONE);
00991 failedConnect();
00992 return 2;
00993 }
00994 break;
00995 case STATE_WAIT_FOR_INSTALL_MODE_ACK:
00996 while ((packet = mySickPacketReceiver.receivePacket()) != NULL)
00997 {
00998 if (packet->getID() == 0xa0)
00999 {
01000 value = packet->bufToByte();
01001 if (value == 0)
01002 {
01003
01004 switchState(STATE_SET_MODE);
01005 return 0;
01006 }
01007 else if (value == 1)
01008 {
01009 ArLog::log(ArLog::Terse,
01010 "ArSick: Could not start laser, incorrect password.");
01011 switchState(STATE_NONE);
01012 failedConnect();
01013 return 2;
01014 }
01015 else if (value == 2)
01016 {
01017 ArLog::log(ArLog::Terse,
01018 "ArSick: Could not start laser, LMI fault.");
01019 switchState(STATE_NONE);
01020 failedConnect();
01021 return 2;
01022 }
01023 else
01024 {
01025 ArLog::log(ArLog::Terse,
01026 "ArSick: Could not start laser, unknown problem.");
01027 switchState(STATE_NONE);
01028 failedConnect();
01029 return 2;
01030 }
01031 }
01032 else if (packet->getID() == 0xb0)
01033 {
01034
01035 ArLog::log(ArLog::Terse, "ArSick: extra data packet\n");
01036 myPacket.empty();
01037 myPacket.uByteToBuf(0x20);
01038 myPacket.uByteToBuf(0x25);
01039 myPacket.finalizePacket();
01040 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
01041 {
01042 switchState(STATE_INSTALL_MODE);
01043 return 0;
01044 }
01045 }
01046 else
01047 ArLog::log(ArLog::Terse, "ArSick: bad packet 0x%x\n", packet->getID());
01048 }
01049 if (myStateStart.mSecSince() > 10000)
01050 {
01051 ArLog::log(ArLog::Terse,
01052 "ArSick: Failed to connect to laser, no install mode ack received.");
01053 switchState(STATE_NONE);
01054 return 2;
01055 }
01056 break;
01057 case STATE_SET_MODE:
01058 if (myStateStart.mSecSince() < 200)
01059 return 0;
01060 myPacket.empty();
01061
01062 myPacket.byteToBuf(0x77);
01063
01064 myPacket.uByte2ToBuf(0);
01065
01066 myPacket.uByte2ToBuf(70);
01067
01068
01069
01070 myPacket.uByteToBuf(0);
01071
01072
01073
01074 int maxRange;
01075 maxRange = 8;
01076 if (myBits == BITS_1REFLECTOR)
01077 {
01078 myPacket.uByteToBuf(5);
01079 maxRange *= 4;
01080 }
01081 else if (myBits == BITS_2REFLECTOR)
01082 {
01083 myPacket.uByteToBuf(3);
01084 maxRange *= 2;
01085 }
01086 else if (myBits == BITS_3REFLECTOR)
01087 {
01088 myPacket.uByteToBuf(1);
01089 maxRange *= 1;
01090 }
01091 else
01092 {
01093 ArLog::log(ArLog::Terse, "ArSick: Bits set to unknown value");
01094 myPacket.uByteToBuf(5);
01095 maxRange *= 4;
01096 }
01097
01098
01099
01100 if (myUnits == UNITS_1MM)
01101 {
01102 maxRange *= 1000;
01103 myPacket.uByteToBuf(1);
01104 }
01105 else if (myUnits == UNITS_10CM)
01106 {
01107 maxRange = 150000;
01108 myPacket.uByteToBuf(2);
01109 }
01110 else if (myUnits == UNITS_1CM)
01111 {
01112 maxRange *= 10000;
01113 myPacket.uByteToBuf(0);
01114 }
01115 else
01116 {
01117 ArLog::log(ArLog::Terse, "ArSick: Units set to unknown value");
01118 maxRange *= 1000;
01119 myPacket.uByteToBuf(1);
01120 }
01121 setMaxRange(maxRange);
01122
01123 myPacket.uByteToBuf(0);
01124
01125 myPacket.uByteToBuf(0);
01126
01127 myPacket.uByteToBuf(2);
01128
01129 myPacket.uByteToBuf(2);
01130
01131 myPacket.uByteToBuf(0);
01132
01133 myPacket.uByteToBuf(0);
01134
01135 myPacket.uByteToBuf(0);
01136
01137 myPacket.uByteToBuf(0);
01138
01139 myPacket.uByteToBuf(0);
01140
01141 myPacket.uByteToBuf(0);
01142
01143 myPacket.uByteToBuf(0);
01144
01145 myPacket.uByteToBuf(0);
01146
01147 myPacket.uByteToBuf(0);
01148
01149 myPacket.uByteToBuf(0);
01150
01151 myPacket.uByteToBuf(0);
01152
01153 myPacket.uByteToBuf(0);
01154
01155 myPacket.uByteToBuf(0);
01156
01157 myPacket.uByteToBuf(0);
01158
01159 myPacket.uByteToBuf(0);
01160
01161 myPacket.uByteToBuf(0);
01162
01163 myPacket.uByteToBuf(0);
01164
01165 myPacket.uByteToBuf(0);
01166
01167 myPacket.byte2ToBuf(0);
01168
01169 myPacket.uByteToBuf(0);
01170
01171 myPacket.finalizePacket();
01172
01173
01174 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
01175 {
01176
01177 switchState(STATE_WAIT_FOR_SET_MODE_ACK);
01178 return 0;
01179 }
01180 else
01181 {
01182 ArLog::log(ArLog::Terse,
01183 "ArSick: Failed to connect to laser, could not send set mode command.");
01184 switchState(STATE_NONE);
01185 failedConnect();
01186 return 2;
01187 }
01188 break;
01189 case STATE_WAIT_FOR_SET_MODE_ACK:
01190 while ((packet = mySickPacketReceiver.receivePacket()) != NULL)
01191 {
01192 if (packet->getID() == 0xF7)
01193 {
01194
01195
01196
01197 switchState(STATE_START_READINGS);
01198 return 0;
01199 }
01200 else if (packet->getID() == 0xb0)
01201 {
01202
01203 ArLog::log(ArLog::Terse, "ArSick: extra data packet\n");
01204 myPacket.empty();
01205 myPacket.uByteToBuf(0x20);
01206 myPacket.uByteToBuf(0x25);
01207 myPacket.finalizePacket();
01208 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
01209 {
01210 switchState(STATE_INSTALL_MODE);
01211 return 0;
01212 }
01213 }
01214 else if (packet->getID() == 0x92)
01215 {
01216 switchState(STATE_INSTALL_MODE);
01217 return 0;
01218 }
01219 else
01220 ArLog::log(ArLog::Terse, "ArSick: Got a 0x%x\n", packet->getID());
01221 }
01222 if (myStateStart.mSecSince() > 14000)
01223 {
01224 ArLog::log(ArLog::Terse,
01225 "ArSick: Failed to connect to laser, no set mode acknowledgement received.");
01226 switchState(STATE_NONE);
01227 failedConnect();
01228 return 2;
01229 }
01230 break;
01231 case STATE_START_READINGS:
01232 if (myStateStart.mSecSince() < 200)
01233 return 0;
01234 myPacket.empty();
01235 myPacket.byteToBuf(0x20);
01236 myPacket.byteToBuf(0x24);
01237 myPacket.finalizePacket();
01238 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
01239 {
01240 switchState(STATE_WAIT_FOR_START_ACK);
01241 return 0;
01242 }
01243 else
01244 {
01245 ArLog::log(ArLog::Terse,
01246 "ArSick: Failed to connect to laser, could not send start command.");
01247 switchState(STATE_NONE);
01248 failedConnect();
01249 return 2;
01250 }
01251 break;
01252 case STATE_WAIT_FOR_START_ACK:
01253 while ((packet = mySickPacketReceiver.receivePacket()) != NULL)
01254 {
01255 if (packet->getID() == 0xa0)
01256 {
01257 value = packet->bufToByte();
01258 if (value == 0)
01259 {
01260 ArLog::log(ArLog::Terse, "ArSick: Connected to the laser.");
01261 switchState(STATE_CONNECTED);
01262 madeConnection();
01263 return 1;
01264 }
01265 else if (value == 1)
01266 {
01267 ArLog::log(ArLog::Terse,
01268 "ArSick: Could not start laser laser, incorrect password.");
01269 switchState(STATE_NONE);
01270 failedConnect();
01271 return 2;
01272 }
01273 else if (value == 2)
01274 {
01275 ArLog::log(ArLog::Terse,
01276 "ArSick: Could not start laser laser, LMI fault.");
01277 switchState(STATE_NONE);
01278 failedConnect();
01279 return 2;
01280 }
01281 else
01282 {
01283 ArLog::log(ArLog::Terse,
01284 "ArSick: Could not start laser laser, unknown problem.");
01285 switchState(STATE_NONE);
01286 failedConnect();
01287 return 2;
01288 }
01289 }
01290 }
01291 if (myStateStart.mSecSince() > 1000)
01292 {
01293 ArLog::log(ArLog::Terse,
01294 "ArSick: Failed to connect to laser, no start acknowledgement received.");
01295 switchState(STATE_NONE);
01296 failedConnect();
01297 return 2;
01298 }
01299 break;
01300 default:
01301 ArLog::log(ArLog::Verbose, "ArSick: In bad connection state\n");
01302 break;
01303 }
01304 return 0;
01305 }
01306
01312 AREXPORT bool ArSick::internalConnectSim(void)
01313 {
01314 lockDevice();
01315 double offset = myOffsetAmount;
01316 double increment = myIncrementAmount;
01317 unlockDevice();
01318
01319 myRobot->lock();
01320
01321 if (myRobot->comInt(36, -ArMath::roundInt(offset)) &&
01322 myRobot->comInt(37, ArMath::roundInt(offset)) &&
01323 myRobot->comInt(38, ArMath::roundInt(increment * 100.0)) &&
01324 myRobot->comInt(35, 2))
01326 {
01327 myRobot->unlock();
01328 switchState(STATE_CONNECTED);
01329 madeConnection();
01330 ArLog::log(ArLog::Terse, "ArSick: Connected to simulated laser.");
01331 return true;
01332 }
01333 else
01334 {
01335 switchState(STATE_NONE);
01336 failedConnect();
01337 ArLog::log(ArLog::Terse,
01338 "ArSick: Failed to connect to simulated laser.");
01339 return false;
01340 }
01341 }
01342
01354 AREXPORT void ArSick::addConnectCB(ArFunctor *functor,
01355 ArListPos::Pos position)
01356 {
01357 if (position == ArListPos::FIRST)
01358 myConnectCBList.push_front(functor);
01359 else if (position == ArListPos::LAST)
01360 myConnectCBList.push_back(functor);
01361 else
01362 ArLog::log(ArLog::Terse,
01363 "ArSick::myConnectCallbackList: Invalid position.");
01364 }
01365
01370 AREXPORT void ArSick::remConnectCB(ArFunctor *functor)
01371 {
01372 myConnectCBList.remove(functor);
01373 }
01374
01375
01388 AREXPORT void ArSick::addFailedConnectCB(ArFunctor *functor,
01389 ArListPos::Pos position)
01390 {
01391 if (position == ArListPos::FIRST)
01392 myFailedConnectCBList.push_front(functor);
01393 else if (position == ArListPos::LAST)
01394 myFailedConnectCBList.push_back(functor);
01395 else
01396 ArLog::log(ArLog::Terse,
01397 "ArSick::myConnectCallbackList: Invalid position.");
01398 }
01399
01404 AREXPORT void ArSick::remFailedConnectCB(ArFunctor *functor)
01405 {
01406 myFailedConnectCBList.remove(functor);
01407 }
01408
01422 AREXPORT void ArSick::addDisconnectNormallyCB(ArFunctor *functor,
01423 ArListPos::Pos position)
01424 {
01425 if (position == ArListPos::FIRST)
01426 myDisconnectNormallyCBList.push_front(functor);
01427 else if (position == ArListPos::LAST)
01428 myDisconnectNormallyCBList.push_back(functor);
01429 else
01430 ArLog::log(ArLog::Terse,
01431 "ArSick::myConnectCallbackList: Invalid position.");
01432 }
01433
01438 AREXPORT void ArSick::remDisconnectNormallyCB(ArFunctor *functor)
01439 {
01440 myDisconnectNormallyCBList.remove(functor);
01441 }
01442
01459 AREXPORT void ArSick::addDisconnectOnErrorCB(ArFunctor *functor,
01460 ArListPos::Pos position)
01461 {
01462 if (position == ArListPos::FIRST)
01463 myDisconnectOnErrorCBList.push_front(functor);
01464 else if (position == ArListPos::LAST)
01465 myDisconnectOnErrorCBList.push_back(functor);
01466 else
01467 ArLog::log(ArLog::Terse,
01468 "ArSick::myConnectCallbackList: Invalid position");
01469 }
01470
01475 AREXPORT void ArSick::remDisconnectOnErrorCB(ArFunctor *functor)
01476 {
01477 myDisconnectOnErrorCBList.remove(functor);
01478 }
01479
01490 AREXPORT void ArSick::addDataCB(ArFunctor *functor,
01491 ArListPos::Pos position)
01492 {
01493 if (position == ArListPos::FIRST)
01494 myDataCBList.push_front(functor);
01495 else if (position == ArListPos::LAST)
01496 myDataCBList.push_back(functor);
01497 else
01498 ArLog::log(ArLog::Terse,
01499 "ArSick::addDataCB: Invalid position.");
01500 }
01501
01506 AREXPORT void ArSick::remDataCB(ArFunctor *functor)
01507 {
01508 myDataCBList.remove(functor);
01509 }
01510
01512 AREXPORT void ArSick::dropConnection(void)
01513 {
01514 std::list<ArFunctor *>::iterator it;
01515
01516 if (myState != STATE_CONNECTED)
01517 return;
01518
01519 myCurrentBuffer.reset();
01520 myCumulativeBuffer.reset();
01521 ArLog::log(ArLog::Terse,
01522 "ArSick: Lost connection to the laser because of error.");
01523 switchState(STATE_NONE);
01524 for (it = myDisconnectOnErrorCBList.begin();
01525 it != myDisconnectOnErrorCBList.end();
01526 it++)
01527 (*it)->invoke();
01528 if (myConn != NULL)
01529 myConn->close();
01530 }
01531
01533 AREXPORT void ArSick::failedConnect(void)
01534 {
01535 std::list<ArFunctor *>::iterator it;
01536
01537 switchState(STATE_NONE);
01538 for (it = myFailedConnectCBList.begin();
01539 it != myFailedConnectCBList.end();
01540 it++)
01541 (*it)->invoke();
01542 if (myConn != NULL)
01543 myConn->close();
01544 }
01545
01547 AREXPORT void ArSick::madeConnection(void)
01548 {
01549 std::list<ArFunctor *>::iterator it;
01550
01551 myLastReading.setToNow();
01552 for (it = myConnectCBList.begin(); it != myConnectCBList.end(); it++)
01553 (*it)->invoke();
01554 }
01555
01569 AREXPORT bool ArSick::disconnect(bool doNotLockRobotForSim)
01570 {
01571 std::list<ArFunctor *>::iterator it;
01572 bool ret;
01573 ArSerialConnection *conn;
01574
01575 myStateMutex.lock();
01576 if (myState == STATE_NONE)
01577 {
01578 myStateMutex.unlock();
01579 return true;
01580 }
01581
01582 if (myState != STATE_CONNECTED)
01583 {
01584 lockDevice();
01585 myConnLock.lock();
01586 myState = STATE_NONE;
01587 ret = myConn->close();
01588 myConnLock.unlock();
01589 unlockDevice();
01590 ArLog::log(ArLog::Terse, "ArSick: Disconnecting from laser that was not fully connected to...");
01591 ArLog::log(ArLog::Terse, "this may cause problems later.");
01592 myStateMutex.unlock();
01593 return ret;
01594 }
01595
01596 myCurrentBuffer.reset();
01597 myCumulativeBuffer.reset();
01598 ArLog::log(ArLog::Terse, "ArSick: Disconnecting from laser.");
01599 myState = STATE_NONE;
01600 myStateMutex.unlock();
01601 for (it = myDisconnectNormallyCBList.begin();
01602 it != myDisconnectNormallyCBList.end();
01603 it++)
01604 (*it)->invoke();
01605 if (myUseSim)
01606 {
01607 if (myRobot == NULL)
01608 return false;
01609 if (!doNotLockRobotForSim)
01610 myRobot->lock();
01611 ret = myRobot->comInt(35, 2);
01613 if (!doNotLockRobotForSim)
01614 myRobot->unlock();
01615 return ret;
01616 }
01617 else
01618 {
01619 myConnLock.lock();
01620 while (mySickPacketReceiver.receivePacket() != NULL);
01621 myPacket.empty();
01622 myPacket.uByteToBuf(0x20);
01623 myPacket.uByteToBuf(0x25);
01624 myPacket.finalizePacket();
01625 ret = myConn->write(myPacket.getBuf(), myPacket.getLength());
01626
01627 ArUtil::sleep(1000);
01628 myPacket.empty();
01629 myPacket.byteToBuf(0x20);
01630 myPacket.byteToBuf(0x42);
01631 myPacket.finalizePacket();
01632 if (myConn->write(myPacket.getBuf(), myPacket.getLength()))
01633 {
01634 ArUtil::sleep(20);
01635 if ((conn = dynamic_cast<ArSerialConnection *>(myConn)))
01636 conn->setBaud(9600);
01637 } else
01638 ret = false;
01639 ret = ret && myConn->close();
01640 myConnLock.unlock();
01641 ArUtil::sleep(300);
01642 return ret;
01643 }
01644 }
01645
01666 AREXPORT bool ArSick::blockingConnect(void)
01667 {
01668 int ret;
01669
01670 if (myUseSim)
01671 {
01672 return internalConnectSim();
01673 }
01674
01675 else
01676 {
01677 if (myConn == NULL)
01678 {
01679 ArLog::log(ArLog::Terse, "ArSick: Invalid device connection, cannot connect.");
01680 return false;
01681 }
01682
01683 lockDevice();
01684 myConnLock.lock();
01685 switchState(STATE_INIT);
01686 unlockDevice();
01687 while (getRunningWithLock() && (ret = internalConnectHandler()) == 0)
01688 ArUtil::sleep(100);
01689 myConnLock.unlock();
01690 if (ret == 1)
01691 return true;
01692 else
01693 return false;
01694 }
01695 return false;
01696 }
01697
01714 AREXPORT bool ArSick::asyncConnect(void)
01715 {
01716 if (myState == STATE_CONNECTED)
01717 {
01718 ArLog::log(ArLog::Terse,"ArSick: already connected to laser.");
01719 return false;
01720 }
01721 if (myUseSim || getRunning() || myRunningOnRobot)
01722 {
01723 myStartConnect = true;
01724 return true;
01725 }
01726 else
01727 {
01728 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.");
01729 return false;
01730 }
01731 }
01732
01741 AREXPORT bool ArSick::runOnRobot(void)
01742 {
01743 if (myRobot == NULL)
01744 return false;
01745 else
01746 {
01747 myRunningOnRobot = true;
01748 if (getRunning())
01749 stopRunning();
01750 return true;
01751 }
01752 }
01753
01755 AREXPORT void ArSick::processPacket(ArSickPacket *packet, ArPose pose,
01756 ArPose encoderPose,
01757 unsigned int counter,
01758 bool deinterlace,
01759 ArPose deinterlaceDelta)
01760 {
01761 std::list<ArFunctor *>::iterator it;
01762 unsigned int rawValue;
01763 unsigned int value;
01764 unsigned int reflector = 0;
01765 unsigned int numReadings;
01766 unsigned int i;
01767 double atDeg;
01768 unsigned int onReading;
01769 ArSensorReading *reading;
01770 int dist;
01771 std::list<ArSensorReading *>::iterator tempIt;
01772 int multiplier;
01773 ArTransform transform;
01774 std::list<double>::iterator ignoreIt;
01775 bool ignore;
01776
01777 ArTime arTime;
01778 arTime = packet->getTimeReceived();
01779 arTime.addMSec(-13);
01780
01781 ArTime deinterlaceTime;
01782 deinterlaceTime = packet->getTimeReceived();
01783 deinterlaceTime.addMSec(-27);
01784
01785
01786
01787 if (packet->getID() == 0xb0)
01788 {
01789 value = packet->bufToUByte2();
01790 numReadings = value & 0x3ff;
01791
01792 if (!(value & ArUtil::BIT14) && !(value & ArUtil::BIT15))
01793 multiplier = 10;
01794 else if ((value & ArUtil::BIT14) && !(value & ArUtil::BIT15))
01795 multiplier = 1;
01796 else if (!(value & ArUtil::BIT14) && (value & ArUtil::BIT15))
01797 multiplier = 100;
01798 else
01799 {
01800 ArLog::log(ArLog::Terse,
01801 "ArSick::processPacket: bad distance configuration in packet\n");
01802 multiplier = 0;
01803 }
01804
01805
01806
01807
01808 while (myAssembleReadings->size() > numReadings)
01809 {
01810 ArLog::log(ArLog::Verbose, "ArSick::processPacket, too many readings, popping one.\n");
01811 tempIt = myAssembleReadings->begin();
01812 if (tempIt != myAssembleReadings->end())
01813 delete (*tempIt);
01814 myAssembleReadings->pop_front();
01815 }
01816
01817
01818 if (myAssembleReadings->size() == 0)
01819 for (i = 0; i < numReadings; i++)
01820 myAssembleReadings->push_back(new ArSensorReading);
01821
01822 transform.setTransform(pose);
01823
01824
01825 for (atDeg = mySensorPose.getTh() - myOffsetAmount, onReading = 0,
01826 myIter = myAssembleReadings->begin();
01827 (onReading < numReadings &&
01828 packet->getReadLength() < packet->getLength() - 4);
01829 myWhichReading++, atDeg += myIncrementAmount, myIter++, onReading++)
01830 {
01831 reading = (*myIter);
01832
01833
01834
01835
01836
01837 rawValue = packet->bufToUByte2();
01838 if (myBits == BITS_1REFLECTOR)
01839 {
01840 dist = (rawValue & 0x7fff) * multiplier;
01841 reflector = ((rawValue & 0x8000) >> 15) << 2;
01842 }
01843 else if (myBits == BITS_2REFLECTOR)
01844 {
01845 dist = (rawValue & 0x3fff) * multiplier;
01846 reflector = ((rawValue & 0xc000) >> 14) << 1 ;
01847 }
01848 else if (myBits == BITS_3REFLECTOR)
01849 {
01850 dist = (rawValue & 0x1fff) * multiplier;
01851 reflector = ((rawValue & 0xe000) >> 13);
01852 }
01853
01854
01855 else
01856 {
01857 dist = (rawValue & 0x7fff) * multiplier;
01858 reflector = 0;
01859 }
01860
01861
01862
01863 reflector = reflector << 5;
01864
01865 ignore = false;
01866 for (ignoreIt = myIgnoreReadings.begin();
01867 ignoreIt != myIgnoreReadings.end();
01868 ignoreIt++)
01869 {
01870 if (ArMath::fabs(ArMath::subAngle(atDeg, *(ignoreIt))) < 1.0)
01871 {
01872 ignore = true;
01873 break;
01874 }
01875 }
01876 if (myMinRange != 0 && dist < (int)myMinRange)
01877 ignore = true;
01878 if (myMaxRange != 0 && dist > (int)myMaxRange)
01879 ignore = true;
01880 if (deinterlace && (onReading % 2) == 0)
01881 {
01882 reading->resetSensorPosition(
01883 ArMath::roundInt(mySensorPose.getX() + deinterlaceDelta.getX()),
01884 ArMath::roundInt(mySensorPose.getY() + deinterlaceDelta.getY()),
01885 ArMath::addAngle(atDeg, deinterlaceDelta.getTh()));
01886 reading->newData(dist, pose, encoderPose, transform, counter,
01887 deinterlaceTime, ignore, reflector);
01888 }
01889 else
01890 {
01891 reading->resetSensorPosition(ArMath::roundInt(mySensorPose.getX()),
01892 ArMath::roundInt(mySensorPose.getY()),
01893 atDeg);
01894 reading->newData(dist, pose, encoderPose, transform, counter,
01895 arTime, ignore, reflector);
01896 }
01897
01898
01899
01900
01901
01902 tempIt = myIter;
01903 tempIt++;
01904 if (tempIt == myAssembleReadings->end() &&
01905 onReading + 1 != numReadings)
01906 {
01907 myAssembleReadings->push_back(new ArSensorReading);
01908 }
01909 }
01910
01911 myRawReadings = myAssembleReadings;
01912
01913 myAssembleReadings = myCurrentReadings;
01914 myCurrentReadings = myRawReadings;
01915
01916 myLastReading.setToNow();
01917 filterReadings();
01918
01919 if (myTimeLastSickPacket != time(NULL))
01920 {
01921 myTimeLastSickPacket = time(NULL);
01922 mySickPacCount = mySickPacCurrentCount;
01923 mySickPacCurrentCount = 0;
01924 }
01925 mySickPacCurrentCount++;
01926 for (it = myDataCBList.begin(); it != myDataCBList.end(); it++)
01927 (*it)->invoke();
01928 }
01929 }
01930
01932 AREXPORT void ArSick::runOnce(bool lockRobot)
01933 {
01934 ArSickPacket *packet;
01935 unsigned int counter;
01936 int ret;
01937 ArTime time;
01938 ArTime time2;
01939 ArPose pose;
01940 ArPose pose2;
01941 ArPose encoderPose;
01942
01943 if (myProcessImmediately && myRobot != NULL)
01944 {
01945 if (lockRobot)
01946 myRobot->lock();
01947 pose = myRobot->getPose();
01948 counter = myRobot->getCounter();
01949 if (lockRobot)
01950 myRobot->unlock();
01951 }
01952
01953 lockDevice();
01954 if (myState == STATE_CONNECTED && myTimeoutTime > 0 &&
01955 myLastReading.mSecSince() > myTimeoutTime * 1000)
01956 {
01957 dropConnection();
01958 unlockDevice();
01959 return;
01960 }
01961 if (myUseSim)
01962 {
01963 unlockDevice();
01964 return;
01965 }
01966 if (myState == STATE_CONNECTED)
01967 {
01968 unlockDevice();
01969 myConnLock.lock();
01970 packet = mySickPacketReceiver.receivePacket();
01971 myConnLock.unlock();
01972 lockDevice();
01973
01974 if (myRobot != NULL && packet != NULL && !myProcessImmediately)
01975 {
01976 myPackets.push_back(packet);
01977 }
01978 else if (myRobot != NULL && packet != NULL && myProcessImmediately)
01979 {
01980 unlockDevice();
01981 if (lockRobot && myInterpolation)
01982 myRobot->lock();
01983
01984
01985 if (myInterpolation && (ret = myRobot->getPoseInterpPosition(
01986 packet->getTimeReceived(), &pose)) < 0)
01987 pose = myRobot->getPose();
01988
01989
01990 if (myInterpolation && (ret = myRobot->getEncoderPoseInterpPosition(
01991 packet->getTimeReceived(), &encoderPose)) < 0)
01992 encoderPose = myRobot->getEncoderTransform().doInvTransform(pose);
01993 if (lockRobot && myInterpolation)
01994 myRobot->unlock();
01995 lockDevice();
01996 processPacket(packet, pose, encoderPose, counter, false, ArPose());
01997 }
01998 else if (packet != NULL)
01999 {
02000 processPacket(packet, pose, encoderPose, 0, false, ArPose());
02001 delete packet;
02002 }
02003 }
02004 unlockDevice();
02005 return;
02006
02007 }
02008
02009 AREXPORT int ArSick::getSickPacCount()
02010 {
02011 if (myTimeLastSickPacket == time(NULL))
02012 return mySickPacCount;
02013 if (myTimeLastSickPacket == time(NULL) - 1)
02014 return mySickPacCurrentCount;
02015 return 0;
02016 }
02017
02024 AREXPORT void ArSick::setFilterNearDist(double dist)
02025 {
02026 if (dist >= 0)
02027 myFilterNearDist = dist;
02028 else
02029 ArLog::log(ArLog::Terse, "ArSick::setFilterNearDist given a distance less than 0.\n");
02030
02031 }
02032
02039 AREXPORT double ArSick::getFilterNearDist(void)
02040 {
02041 return myFilterNearDist;
02042 }
02043
02044
02050 AREXPORT void ArSick::setFilterCumulativeInsertMaxDist(double dist)
02051 {
02052 if (dist >= 0)
02053 {
02054 myFilterCumulativeInsertMaxDist = dist;
02055 myFilterSquaredCumulativeInsertMaxDist = dist * dist;
02056 }
02057 else
02058 ArLog::log(ArLog::Terse, "ArSick::setFilterCumulativeMaxDistDist given a distance less than 0.\n");
02059 }
02060
02066 AREXPORT double ArSick::getFilterCumulativeInsertMaxDist(void)
02067 {
02068 return myFilterCumulativeInsertMaxDist;
02069 }
02070
02076 AREXPORT void ArSick::setFilterCumulativeNearDist(double dist)
02077 {
02078 if (dist >= 0)
02079 {
02080 myFilterCumulativeNearDist = dist;
02081 myFilterSquaredCumulativeNearDist = dist * dist;
02082 }
02083 else
02084 ArLog::log(ArLog::Terse, "ArSick::setFilterCumulativeNearDistDist given a distance less than 0.\n");
02085 }
02086
02092 AREXPORT double ArSick::getFilterCumulativeNearDist(void)
02093 {
02094 return myFilterCumulativeNearDist;
02095 }
02096
02104 AREXPORT void ArSick::setFilterCumulativeCleanDist(double dist)
02105 {
02106 if (dist >= 0)
02107 {
02108 myFilterCumulativeCleanDist = dist;
02109 myFilterSquaredCumulativeCleanDist = dist * dist;
02110 }
02111 else
02112 ArLog::log(ArLog::Terse, "ArSick::setFilterCumulativeCleanDistDist given a distance less than 0.\n");
02113 }
02114
02122 AREXPORT double ArSick::getFilterCumulativeCleanDist(void)
02123 {
02124 return myFilterCumulativeCleanDist;
02125 }
02126
02132 AREXPORT void ArSick::setFilterCleanCumulativeInterval(int milliSeconds)
02133 {
02134 if (milliSeconds >= 0)
02135 {
02136 myFilterCleanCumulativeInterval = milliSeconds;
02137 }
02138 else
02139 ArLog::log(ArLog::Terse, "ArSick::setFilterCleanCumulativeInterval given a time less than 0.\n");
02140 }
02141
02147 AREXPORT int ArSick::getFilterCleanCumulativeInterval(void)
02148 {
02149 return myFilterCleanCumulativeInterval;
02150 }
02151
02152
02153
02155 AREXPORT void ArSick::sensorInterpCallback(void)
02156 {
02157 std::list<ArSickPacket *>::iterator it;
02158 std::list<ArSickPacket *> processed;
02159 ArSickPacket *packet;
02160 ArTime time;
02161 ArPose pose;
02162 int ret;
02163 int retEncoder;
02164 ArPose encoderPose;
02165 ArPose deinterlaceEncoderPose;
02166 bool deinterlace;
02167 ArTime deinterlaceTime;
02168 ArPose deinterlaceDelta;
02169
02170 if (myRunningOnRobot)
02171 runOnce(false);
02172
02173 lockDevice();
02174
02175 if (myIncrement == INCREMENT_HALF)
02176 adjustRawReadings(true);
02177 else
02178 adjustRawReadings(false);
02179
02180 for (it = myPackets.begin(); it != myPackets.end(); it++)
02181 {
02182 packet = (*it);
02183 time = packet->getTimeReceived();
02184 time.addMSec(-13);
02185 if ((ret = myRobot->getPoseInterpPosition(time, &pose)) == 1 &&
02186 (retEncoder =
02187 myRobot->getEncoderPoseInterpPosition(time, &encoderPose)) == 1)
02188 {
02189 deinterlaceTime = packet->getTimeReceived();
02190 deinterlaceTime.addMSec(-27);
02191
02192 if (myIncrement == INCREMENT_HALF &&
02193 (myRobot->getEncoderPoseInterpPosition(
02194 deinterlaceTime, &deinterlaceEncoderPose)) == 1)
02195 deinterlace = true;
02196 else
02197 deinterlace = false;
02198
02199 ArTransform deltaTransform;
02200 deltaTransform.setTransform(encoderPose);
02201 deinterlaceDelta = deltaTransform.doInvTransform(deinterlaceEncoderPose);
02202
02203 processPacket(packet, pose, encoderPose, myRobot->getCounter(),
02204 deinterlace, deinterlaceDelta);
02205 processed.push_back(packet);
02206 }
02207 else if (ret < -1 || retEncoder < -1)
02208 {
02209 if (myRobot->isConnected())
02210 ArLog::log(ArLog::Normal, "ArSick::processPacket: too old to process\n");
02211 else
02212 {
02213 processPacket(packet, pose, encoderPose, myRobot->getCounter(), false,
02214 ArPose());
02215 }
02216 processed.push_back(packet);
02217 }
02218 else
02219 {
02220
02221
02222 }
02223 }
02224 while ((it = processed.begin()) != processed.end())
02225 {
02226 packet = (*it);
02227 myPackets.remove(packet);
02228 processed.pop_front();
02229 delete packet;
02230 }
02231 unlockDevice();
02232 }
02233
02235 AREXPORT void *ArSick::runThread(void *arg)
02236 {
02237 while (getRunningWithLock())
02238 {
02239 lockDevice();
02240 if (myStartConnect)
02241 {
02242 myStartConnect = false;
02243 switchState(STATE_INIT);
02244 if (myUseSim)
02245 {
02246 unlockDevice();
02247 internalConnectSim();
02248 }
02249 else
02250 {
02251 unlockDevice();
02252 while (getRunningWithLock())
02253 {
02254 lockDevice();
02255 myConnLock.lock();
02256 if (internalConnectHandler() != 0)
02257 {
02258 myConnLock.unlock();
02259 unlockDevice();
02260 break;
02261 }
02262 myConnLock.unlock();
02263 unlockDevice();
02264 ArUtil::sleep(1);
02265 }
02266 }
02267 } else
02268 unlockDevice();
02269 runOnce(true);
02270 ArUtil::sleep(1);
02271 }
02272 lockDevice();
02273 if (isConnected())
02274 {
02275 disconnect();
02276 }
02277 unlockDevice();
02278
02279 return NULL;
02280 }
02281
02290 AREXPORT void ArSick::applyTransform(ArTransform trans,
02291 bool doCumulative)
02292 {
02293 myCurrentBuffer.applyTransform(trans);
02294 std::list<ArSensorReading *>::iterator it;
02295
02296 for (it = myRawReadings->begin(); it != myRawReadings->end(); ++it)
02297 (*it)->applyTransform(trans);
02298
02299 if (doCumulative)
02300 myCumulativeBuffer.applyTransform(trans);
02301 }