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 <time.h>
00029 #include <ctype.h>
00030
00031 #include "ArRobot.h"
00032 #include "ArLog.h"
00033 #include "ArDeviceConnection.h"
00034 #include "ArTcpConnection.h"
00035 #include "ArSerialConnection.h"
00036 #include "ArLogFileConnection.h"
00037 #include "ariaUtil.h"
00038 #include "ArSocket.h"
00039 #include "ArCommands.h"
00040 #include "ArRobotTypes.h"
00041 #include "ArSignalHandler.h"
00042 #include "ArPriorityResolver.h"
00043 #include "ArAction.h"
00044 #include "ArRangeDevice.h"
00045 #include "ArRobotConfigPacketReader.h"
00046 #include "ariaInternal.h"
00047
00069 AREXPORT ArRobot::ArRobot(const char *name, bool obsolete,
00070 bool doSigHandle, bool normalInit,
00071 bool addAriaExitCallback) :
00072 myMotorPacketCB(this, &ArRobot::processMotorPacket),
00073 myEncoderPacketCB(this, &ArRobot::processEncoderPacket),
00074 myIOPacketCB(this, &ArRobot::processIOPacket),
00075 myPacketHandlerCB(this, &ArRobot::packetHandler),
00076 myActionHandlerCB(this, &ArRobot::actionHandler),
00077 myStateReflectorCB(this, &ArRobot::stateReflector),
00078 myRobotLockerCB(this, &ArRobot::robotLocker),
00079 myRobotUnlockerCB(this, &ArRobot::robotUnlocker),
00080 myKeyHandlerExitCB(this, &ArRobot::keyHandlerExit),
00081 myGetCycleWarningTimeCB(this, &ArRobot::getCycleWarningTime),
00082 myGetNoTimeWarningThisCycleCB(this, &ArRobot::getNoTimeWarningThisCycle),
00083 myBatteryAverager(20),
00084 myRealBatteryAverager(20),
00085 myAriaExitCB(this, &ArRobot::ariaExitCallback)
00086 {
00087 setName(name);
00088 myAriaExitCB.setName("ArRobotExit");
00089 myNoTimeWarningThisCycle = false;
00090 myGlobalPose.setPose(0, 0, 0);
00091
00092 myParams = new ArRobotGeneric("");
00093
00094 myMotorPacketCB.setName("ArRobot::motorPacket");
00095 myEncoderPacketCB.setName("ArRobot::encoderPacket");
00096 myIOPacketCB.setName("ArRobot::IOPacket");
00097
00098 myPtz = NULL;
00099 myKeyHandler = NULL;
00100 myKeyHandlerCB = NULL;
00101
00102 myConn = NULL;
00103
00104 myOwnTheResolver = false;
00105
00106 myBlockingConnectRun = false;
00107 myAsyncConnectFlag = false;
00108
00109 myLogMovementSent = false;
00110 myLogMovementReceived = false;
00111 myLogVelocitiesReceived = false;
00112 myLogActions = false;
00113 myLastVel = 0;
00114 myLastRotVel = 0;
00115 myLastHeading = 0;
00116 myLastCalculatedRotVel = 0;
00117
00118 myPacketsSentTracking = false;
00119 myPacketsReceivedTracking = false;
00120 myPacketsReceivedTrackingCount = false;
00121 myPacketsReceivedTrackingStarted.setToNow();
00122
00123 myCycleTime = 100;
00124 myCycleWarningTime = 250;
00125 myConnectionCycleMultiplier = 2;
00126 myTimeoutTime = 8000;
00127 myStabilizingTime = 0;
00128 myCounter = 1;
00129 myResolver = NULL;
00130 myNumSonar = 0;
00131
00132 myRequestedIOPackets = false;
00133 myRequestedEncoderPackets = false;
00134 myEncoderCorrectionCB = NULL;
00135
00136 myCycleChained = true;
00137
00138 myMoveDoneDist = 40;
00139 myHeadingDoneDiff = 3;
00140
00141 myOrigRobotConfig = NULL;
00142 reset();
00143 if (normalInit)
00144 init();
00145
00146 mySyncLoop.setRobot(this);
00147
00148 if (doSigHandle)
00149 Aria::addRobot(this);
00150 if (addAriaExitCallback)
00151 {
00152 Aria::addExitCallback(&myAriaExitCB, 0);
00153 myAddedAriaExitCB = true;
00154 }
00155 else
00156 {
00157 myAddedAriaExitCB = false;
00158 }
00159
00160 myConnectWithNoParams = false;
00161 }
00162
00163
00164
00165 AREXPORT ArRobot::~ArRobot()
00166 {
00167 ArResolver::ActionMap::iterator it;
00168
00169 stopRunning();
00170 delete mySyncTaskRoot;
00171 ArUtil::deleteSetPairs(mySonars.begin(), mySonars.end());
00172 Aria::delRobot(this);
00173
00174 if (myKeyHandlerCB != NULL)
00175 delete myKeyHandlerCB;
00176
00177 for (it = myActions.begin(); it != myActions.end(); ++it)
00178 {
00179 (*it).second->setRobot(NULL);
00180 }
00181 }
00182
00183
00188 AREXPORT void ArRobot::init(void)
00189 {
00190 setUpPacketHandlers();
00191 setUpSyncList();
00192 myOwnTheResolver = true;
00193 myResolver = new ArPriorityResolver;
00194 }
00195
00206 AREXPORT void ArRobot::run(bool stopRunIfNotConnected)
00207 {
00208 if (mySyncLoop.getRunning())
00209 {
00210 ArLog::log(ArLog::Terse,
00211 "The robot is already running, cannot run it again.");
00212 return;
00213 }
00214 mySyncLoop.setRunning(true);
00215 mySyncLoop.stopRunIfNotConnected(stopRunIfNotConnected);
00216 mySyncLoop.runInThisThread();
00217 }
00218
00224 AREXPORT bool ArRobot::isRunning(void) const
00225 {
00226 return mySyncLoop.getRunning();
00227 }
00228
00238 AREXPORT void ArRobot::runAsync(bool stopRunIfNotConnected)
00239 {
00240 if (mySyncLoop.getRunning())
00241 {
00242 ArLog::log(ArLog::Terse,
00243 "The robot is already running, cannot run it again.");
00244 return;
00245 }
00246 mySyncLoop.stopRunIfNotConnected(stopRunIfNotConnected);
00247
00248
00249 mySyncLoop.create(true, false);
00250 }
00251
00260 AREXPORT void ArRobot::stopRunning(bool doDisconnect)
00261 {
00262 if (myKeyHandler != NULL)
00263 myKeyHandler->restore();
00264 mySyncLoop.stopRunning();
00265 myBlockingConnectRun = false;
00266 if (doDisconnect && (isConnected() || myIsStabilizing))
00267 {
00268 waitForRunExit();
00269 disconnect();
00270 }
00271 wakeAllWaitingThreads();
00272 }
00273
00274 AREXPORT void ArRobot::setUpSyncList(void)
00275 {
00276 mySyncTaskRoot = new ArSyncTask("SyncTasks");
00277 mySyncTaskRoot->setWarningTimeCB(&myGetCycleWarningTimeCB);
00278 mySyncTaskRoot->setNoTimeWarningCB(&myGetNoTimeWarningThisCycleCB);
00279 mySyncTaskRoot->addNewLeaf("Packet Handler", 85, &myPacketHandlerCB);
00280 mySyncTaskRoot->addNewLeaf("Robot Locker", 70, &myRobotLockerCB);
00281 mySyncTaskRoot->addNewBranch("Sensor Interp", 65);
00282 mySyncTaskRoot->addNewLeaf("Action Handler", 55, &myActionHandlerCB);
00283 mySyncTaskRoot->addNewLeaf("State Reflector", 45, &myStateReflectorCB);
00284 mySyncTaskRoot->addNewBranch("User Tasks", 25);
00285 mySyncTaskRoot->addNewLeaf("Robot Unlocker", 20, &myRobotUnlockerCB);
00286 }
00287
00288
00289 AREXPORT void ArRobot::setUpPacketHandlers(void)
00290 {
00291 addPacketHandler(&myMotorPacketCB, ArListPos::FIRST);
00292 addPacketHandler(&myEncoderPacketCB, ArListPos::LAST);
00293 addPacketHandler(&myIOPacketCB, ArListPos::LAST);
00294 }
00295
00296 void ArRobot::reset(void)
00297 {
00298 resetOdometer();
00299 myInterpolation.reset();
00300 myEncoderInterpolation.reset();
00301 if (myOrigRobotConfig != NULL)
00302 delete myOrigRobotConfig;
00303 myOrigRobotConfig = new ArRobotConfigPacketReader(this, true);
00304 myFirstEncoderPose = true;
00305
00306
00307
00308
00309
00310 myTransVelMax = 0;
00311 myTransAccel = 0;
00312 myTransDecel = 0;
00313 myRotVelMax = 0;
00314 myRotAccel = 0;
00315 myRotDecel = 0;
00316
00317 myRobotLengthFront = 0;
00318 myRobotLengthRear = 0;
00319
00320 myLeftVel = 0;
00321 myRightVel = 0;
00322 myBatteryVoltage = 13;
00323 myBatteryAverager.clear();
00324 myBatteryAverager.add(myBatteryVoltage);
00325 myStallValue = 0;
00326 myControl = 0;
00327 myFlags = 0;
00328 myFaultFlags = 0;
00329 myHasFaultFlags = 0;
00330 myCompass = 0;
00331 myAnalogPortSelected = 0;
00332 myAnalog = 0;
00333 myDigIn = 0;
00334 myDigOut = 0;
00335 myIOAnalogSize = 0;
00336 myIODigInSize = 0;
00337 myIODigOutSize = 0;
00338 myLastIOPacketReceivedTime.setSec(0);
00339 myLastIOPacketReceivedTime.setMSec(0);
00340 myVel = 0;
00341 myRotVel = 0;
00342 myChargeState = CHARGING_UNKNOWN;
00343 myLastX = 0;
00344 myLastY = 0;
00345 myLastTh = 0;
00346 mySentPulse = false;
00347 myIsConnected = false;
00348 myIsStabilizing = false;
00349
00350 myTransVal = 0;
00351 myTransVal2 = 0;
00352 myTransType = TRANS_NONE;
00353 myLastTransVal = 0;
00354 myLastTransVal2 = 0;
00355 myLastTransType = TRANS_NONE;
00356 myLastTransSent.setToNow();
00357 myActionTransSet = false;
00358 myLastActionRotStopped = false;
00359 myLastActionRotHeading = false;
00360
00361 myRotVal = 0;
00362 myLastRotVal = 0;
00363 myRotType = ROT_NONE;
00364 myLastRotType = ROT_NONE;
00365 myLastRotSent.setToNow();
00366 myActionRotSet = false;
00367
00368 myLastPulseSent.setToNow();
00369
00370 myDirectPrecedenceTime = 0;
00371 myStateReflectionRefreshTime = 500;
00372
00373 myActionDesired.reset();
00374
00375 myMotorPacCurrentCount = 0;
00376 myMotorPacCount = 0;
00377 myTimeLastMotorPacket = 0;
00378
00379 mySonarPacCurrentCount = 0;
00380 mySonarPacCount = 0;
00381 myTimeLastSonarPacket = 0;
00382
00383 myLeftEncoder = 0;
00384 myRightEncoder = 0;
00385
00386 myWarnedAboutExtraSonar = false;
00387 }
00388
00389 AREXPORT void ArRobot::setTransVelMax(double vel)
00390 {
00391 if (vel > myAbsoluteMaxTransVel)
00392 {
00393 ArLog::log(ArLog::Terse, "ArRobot: setTransVelMax of %g is over the absolute max of %g, capping it", vel, myAbsoluteMaxTransVel);
00394 vel = myAbsoluteMaxTransVel;
00395 }
00396 myTransVelMax = vel;
00397 }
00398
00399 AREXPORT void ArRobot::setTransAccel(double acc)
00400 {
00401 if (acc > myAbsoluteMaxTransAccel)
00402 {
00403 ArLog::log(ArLog::Terse, "ArRobot: setTransAccel of %g is over the absolute max of %g, capping it", acc, myAbsoluteMaxTransAccel);
00404 acc = myAbsoluteMaxTransAccel;
00405 }
00406 myTransAccel = acc;
00407 }
00408
00409 AREXPORT void ArRobot::setTransDecel(double decel)
00410 {
00411 if (fabs(decel) > myAbsoluteMaxTransDecel)
00412 {
00413 ArLog::log(ArLog::Terse, "ArRobot: setTransDecel of %g is over the absolute max of %g, capping it", decel, myAbsoluteMaxTransDecel);
00414 decel = myAbsoluteMaxTransDecel;
00415 }
00416 myTransDecel = ArMath::fabs(decel);
00417 }
00418
00419 AREXPORT void ArRobot::setRotVelMax(double vel)
00420 {
00421 if (vel > myAbsoluteMaxRotVel)
00422 {
00423 ArLog::log(ArLog::Terse, "ArRobot: rotVelMax of %g is over the absolute max of %g, capping it", vel, myAbsoluteMaxRotVel);
00424 vel = myAbsoluteMaxRotVel;
00425 }
00426 myRotVelMax = vel;
00427 }
00428
00429 AREXPORT void ArRobot::setRotAccel(double acc)
00430 {
00431 if (acc > myAbsoluteMaxRotAccel)
00432 {
00433 ArLog::log(ArLog::Terse, "ArRobot: setRotAccel of %g is over the absolute max of %g, capping it", acc, myAbsoluteMaxRotAccel);
00434 acc = myAbsoluteMaxRotAccel;
00435 }
00436 myRotAccel = acc;
00437 }
00438
00439 AREXPORT void ArRobot::setRotDecel(double decel)
00440 {
00441 if (fabs(decel) > myAbsoluteMaxRotDecel)
00442 {
00443 ArLog::log(ArLog::Terse, "ArRobot: setRotDecel of %g is over the absolute max of %g, capping it", decel, myAbsoluteMaxRotDecel);
00444 decel = myAbsoluteMaxRotDecel;
00445 }
00446 myRotDecel = ArMath::fabs(decel);
00447 }
00448
00449 AREXPORT double ArRobot::getTransVelMax(void) const
00450 {
00451 return myTransVelMax;
00452 }
00453
00454 AREXPORT double ArRobot::getTransAccel(void) const
00455 {
00456 return myTransAccel;
00457 }
00458
00459 AREXPORT double ArRobot::getTransDecel(void) const
00460 {
00461 return myTransDecel;
00462 }
00463
00464 AREXPORT double ArRobot::getRotVelMax(void) const
00465 {
00466 return myRotVelMax;
00467 }
00468
00469 AREXPORT double ArRobot::getRotAccel(void) const
00470 {
00471 return myRotAccel;
00472 }
00473
00474 AREXPORT double ArRobot::getRotDecel(void) const
00475 {
00476 return myRotDecel;
00477 }
00478
00487 AREXPORT void ArRobot::setDeviceConnection(ArDeviceConnection *connection)
00488 {
00489 myConn = connection;
00490 mySender.setDeviceConnection(myConn);
00491 myReceiver.setDeviceConnection(myConn);
00492 }
00493
00502 AREXPORT ArDeviceConnection *ArRobot::getDeviceConnection(void) const
00503 {
00504 return myConn;
00505 }
00506
00517 AREXPORT void ArRobot::setConnectionTimeoutTime(int mSecs)
00518 {
00519 if (mSecs > 0)
00520 myTimeoutTime = mSecs;
00521 else
00522 myTimeoutTime = 0;
00523 }
00524
00531 AREXPORT int ArRobot::getConnectionTimeoutTime(void) const
00532 {
00533 return myTimeoutTime;
00534 }
00535
00541 AREXPORT ArTime ArRobot::getLastPacketTime(void) const
00542 {
00543 return myLastPacketReceivedTime;
00544 }
00576 AREXPORT bool ArRobot::asyncConnect(void)
00577 {
00578 if (!mySyncLoop.getRunning() || isConnected())
00579 return false;
00580
00581 myAsyncConnectFlag = true;
00582 myBlockingConnectRun = false;
00583 myAsyncConnectState = -1;
00584 return true;
00585 }
00586
00617 AREXPORT bool ArRobot::blockingConnect(void)
00618 {
00619 int ret = 0;
00620
00621 lock();
00622 if (myIsConnected)
00623 disconnect();
00624 myBlockingConnectRun = true;
00625 myAsyncConnectState = -1;
00626 while ((ret = asyncConnectHandler(true)) == 0 && myBlockingConnectRun)
00627 ArUtil::sleep(ArMath::roundInt(getCycleTime() * .80));
00628 unlock();
00629 if (ret == 1)
00630 return true;
00631 else
00632 return false;
00633 }
00634
00650 AREXPORT int ArRobot::asyncConnectHandler(bool tryHarderToConnect)
00651 {
00652 int ret = 0;
00653 ArRobotPacket *packet;
00654 ArRobotPacket *tempPacket = NULL;
00655 char robotSubType[255];
00656 int i;
00657 int len;
00658 std::string str;
00659 ArTime endTime;
00660 int timeToWait;
00661 ArSerialConnection *serConn;
00662
00663 endTime.setToNow();
00664 endTime.addMSec(getCycleTime()*myConnectionCycleMultiplier);
00665
00666 myNoTimeWarningThisCycle = true;
00667
00668
00669 if (myAsyncConnectState == -1)
00670 {
00671 myAsyncConnectSentChangeBaud = false;
00672 myAsyncConnectNoPacketCount = 0;
00673 myAsyncConnectTimesTried = 0;
00674 reset();
00675 if (myConn == NULL)
00676 {
00677 ArLog::log(ArLog::Terse, "Cannot connect, no connection has been set.");
00678 failedConnect();
00679 return 2;
00680 }
00681
00682 if (myConn->getStatus() != ArDeviceConnection::STATUS_OPEN)
00683 {
00684 if (!myConn->openSimple())
00685 {
00686
00687
00688 ArLog::log(ArLog::Terse,
00689 "Could not connect, because open on the device connection failed.");
00690 failedConnect();
00691 return 2;
00692 }
00693 }
00694
00695
00696 if (dynamic_cast<ArLogFileConnection *>(myConn))
00697 {
00698 ArLogFileConnection *con = dynamic_cast<ArLogFileConnection *>(myConn);
00699 myRobotName = con->myName;
00700 myRobotType = con->myType;
00701 myRobotSubType = con->mySubtype;
00702 if (con->havePose)
00703 moveTo(con->myPose);
00704 setCycleChained(false);
00705 madeConnection();
00706 finishedConnection();
00707 return 1;
00708 }
00709
00710
00711 if (dynamic_cast<ArSerialConnection *>(myConn))
00712 {
00713 myConn->write("WMS2\15", strlen("WMS2\15"));
00714 }
00715
00716 while ( endTime.mSecTo() > 0 && myReceiver.receivePacket(0) != NULL);
00717
00718 myAsyncConnectState = 0;
00719 return 0;
00720 }
00721
00722 if (myAsyncConnectState >= 3)
00723 {
00724 bool handled;
00725 std::list<ArRetFunctor1<bool, ArRobotPacket *> *>::iterator it;
00726 while ((packet = myReceiver.receivePacket(0)) != NULL)
00727 {
00728
00729 for (handled = false, it = myPacketHandlerList.begin();
00730 it != myPacketHandlerList.end() && handled == false;
00731 it++)
00732 {
00733 if ((*it) != NULL && (*it)->invokeR(packet))
00734 handled = true;
00735 else
00736 packet->resetRead();
00737 }
00738 }
00739 }
00740
00741 if (myAsyncConnectState == 3)
00742 {
00743
00744 if (!myOrigRobotConfig->hasPacketArrived())
00745 {
00746 myOrigRobotConfig->requestPacket();
00747 }
00748
00749
00750 if (myOrigRobotConfig->hasPacketArrived() ||
00751 myAsyncStartedConnection.mSecSince() > 1000)
00752 {
00753 bool gotConfig;
00754
00755 if (myOrigRobotConfig->hasPacketArrived())
00756 {
00757 gotConfig = true;
00758 setAbsoluteMaxTransVel(myOrigRobotConfig->getTransVelTop());
00759 setAbsoluteMaxTransAccel(myOrigRobotConfig->getTransAccelTop());
00760 setAbsoluteMaxTransDecel(myOrigRobotConfig->getTransAccelTop());
00761 setAbsoluteMaxRotVel(myOrigRobotConfig->getRotVelTop());
00762 setAbsoluteMaxRotAccel(myOrigRobotConfig->getRotAccelTop());
00763 setAbsoluteMaxRotDecel(myOrigRobotConfig->getRotAccelTop());
00764 setTransVelMax(myOrigRobotConfig->getTransVelMax());
00765 setTransAccel(myOrigRobotConfig->getTransAccel());
00766 setTransDecel(myOrigRobotConfig->getTransDecel());
00767 setRotVelMax(myOrigRobotConfig->getRotVelMax());
00768 setRotAccel(myOrigRobotConfig->getRotAccel());
00769 setRotDecel(myOrigRobotConfig->getRotDecel());
00770 }
00771
00772 else
00773 {
00774 gotConfig = false;
00775 setAbsoluteMaxTransVel(myParams->getAbsoluteMaxVelocity());
00776 setAbsoluteMaxTransAccel(1000);
00777 setAbsoluteMaxTransDecel(1000);
00778 setAbsoluteMaxRotVel(myParams->getAbsoluteMaxRotVelocity());
00779 setAbsoluteMaxRotAccel(100);
00780 setAbsoluteMaxRotDecel(100);
00781 }
00782
00783
00784
00785
00786 if (ArMath::fabs(myParams->getTransVelMax()) > 1)
00787 setTransVelMax(myParams->getTransVelMax());
00788 else if (!gotConfig)
00789 setTransVelMax(myParams->getAbsoluteMaxVelocity());
00790 if (ArMath::fabs(myParams->getRotVelMax()) > 1)
00791 setRotVelMax(myParams->getRotVelMax());
00792 else if (!gotConfig)
00793 setRotVelMax(myParams->getAbsoluteMaxRotVelocity());
00794 if (ArMath::fabs(myParams->getTransAccel()) > 1)
00795 setTransAccel(myParams->getTransAccel());
00796 if (ArMath::fabs(myParams->getTransDecel()) > 1)
00797 setTransDecel(myParams->getTransDecel());
00798 if (ArMath::fabs(myParams->getRotAccel()) > 1)
00799 setRotAccel(myParams->getRotAccel());
00800 if (ArMath::fabs(myParams->getRotDecel()) > 1)
00801 setRotDecel(myParams->getRotDecel());
00802 myAsyncConnectState = 4;
00803 }
00804 else
00805 return 0;
00806 }
00807
00808 if (myAsyncConnectState == 4)
00809 {
00810 serConn = dynamic_cast<ArSerialConnection *>(myConn);
00811
00812
00813 if (!myOrigRobotConfig->hasPacketArrived() ||
00814 !myOrigRobotConfig->getResetBaud() ||
00815 serConn == NULL ||
00816 myParams->getSwitchToBaudRate() == 0)
00817 {
00818
00819 if (serConn != NULL)
00820 myAsyncConnectStartBaud = serConn->getBaud();
00821 myAsyncConnectState = 5;
00822 }
00823
00824 else if (!myAsyncConnectSentChangeBaud)
00825 {
00826
00827 if (serConn != NULL)
00828 myAsyncConnectStartBaud = serConn->getBaud();
00829
00830 int baudNum = -1;
00831
00832
00833 while ((packet = myReceiver.receivePacket(0)) != NULL);
00834 if (myParams->getSwitchToBaudRate() == 9600)
00835 baudNum = 0;
00836 else if (myParams->getSwitchToBaudRate() == 19200)
00837 baudNum = 1;
00838 else if (myParams->getSwitchToBaudRate() == 38400)
00839 baudNum = 2;
00840 else if (myParams->getSwitchToBaudRate() == 57600)
00841 baudNum = 3;
00842 else if (myParams->getSwitchToBaudRate() == 115200)
00843 baudNum = 4;
00844 else
00845 {
00846 ArLog::log(ArLog::Normal, "Warning: SwitchToBaud is set to %d baud, ignoring.",
00847 myParams->getSwitchToBaudRate());
00848 ArLog::log(ArLog::Normal, "\tGood bauds are 9600 19200 38400 56800 116200.");
00849 myAsyncConnectState = 5;
00850 baudNum = -1;
00851 return 0;
00852 }
00853 if (baudNum != -1)
00854 {
00855
00856 comInt(ArCommands::HOSTBAUD, baudNum);
00857 ArUtil::sleep(10);
00858 myAsyncConnectSentChangeBaud = true;
00859 myAsyncConnectStartedChangeBaud.setToNow();
00860 serConn->setBaud(myParams->getSwitchToBaudRate());
00861
00862 ArUtil::sleep(10);
00863 com(0);
00864 return 0;
00865 }
00866 }
00867
00868 else
00869 {
00870 packet = myReceiver.receivePacket(100);
00871 com(0);
00872
00873 if (packet != NULL)
00874 {
00875 myAsyncConnectState = 5;
00876 }
00877
00878 else if (myAsyncConnectStartedChangeBaud.mSecSince() > 900)
00879 {
00880 ArLog::log(ArLog::Verbose, "Controller did not switch to baud, reset to %d baud.", myAsyncConnectStartBaud);
00881 serConn->setBaud(myAsyncConnectStartBaud);
00882 myAsyncConnectState = 5;
00883 }
00884 else
00885 return 0;
00886 }
00887 }
00888
00889 if (myAsyncConnectState == 5)
00890 {
00891 if (!myIsStabilizing)
00892 startStabilization();
00893 if (myStabilizingTime == 0 ||
00894 myStartedStabilizing.mSecSince() > myStabilizingTime)
00895 {
00896 finishedConnection();
00897 return 1;
00898 }
00899 else
00900 return 0;
00901 }
00902
00903
00904
00905
00906 myAsyncConnectTimesTried++;
00907 ArLog::log(ArLog::Normal, "Syncing %d", myAsyncConnectState);
00908 mySender.com(myAsyncConnectState);
00909
00910 packet = myReceiver.receivePacket(1000);
00911
00912 if (packet != NULL)
00913 {
00914 ret = packet->getID();
00915
00916
00917 if (ret == 50)
00918 {
00919 ArLog::log(ArLog::Normal, "Attempting to close previous connection.");
00920 comInt(ArCommands::CLOSE,1);
00921 while (endTime.mSecTo() > 0)
00922 {
00923 timeToWait = endTime.mSecTo();
00924 if (timeToWait < 0)
00925 timeToWait = 0;
00926 tempPacket = myReceiver.receivePacket(timeToWait);
00927 if (tempPacket != NULL)
00928 ArLog::log(ArLog::Verbose, "Got in another packet!");
00929 if (tempPacket != NULL && tempPacket->getID() == 50)
00930 comInt(ArCommands::CLOSE,1);
00931 }
00932 myAsyncConnectState = 0;
00933 }
00934 else if (ret == 255)
00935 {
00936 ArLog::log(ArLog::Normal, "Attempting to correct syncCount");
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948 while ((tempPacket = myReceiver.receivePacket(0)) != NULL);
00949
00950 if (tempPacket != NULL && tempPacket->getID() == 0)
00951 myAsyncConnectState = 1;
00952 else
00953 myAsyncConnectState = 0;
00954 return 0;
00955 }
00956 else if (ret != myAsyncConnectState++)
00957 {
00958 myAsyncConnectState = 0;
00959 }
00960 }
00961 else
00962 {
00963 ArLog::log(ArLog::Normal, "No packet.");
00964 myAsyncConnectNoPacketCount++;
00965 if ((myAsyncConnectNoPacketCount > 5
00966 && myAsyncConnectNoPacketCount >= myAsyncConnectTimesTried)
00967 || (myAsyncConnectNoPacketCount > 10))
00968 {
00969 ArLog::log(ArLog::Terse, "Could not connect, no robot responding.");
00970 failedConnect();
00971 return 2;
00972 }
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003 if (myAsyncConnectNoPacketCount == 2 &&
01004 myAsyncConnectNoPacketCount >= myAsyncConnectTimesTried &&
01005 (serConn = dynamic_cast<ArSerialConnection *>(myConn)) != NULL)
01006 {
01007 int origBaud;
01008 ArLog::log(ArLog::Normal, "Trying to close possible old connection");
01009 origBaud = serConn->getBaud();
01010 serConn->setBaud(9600);
01011 comInt(ArCommands::CLOSE,1);
01012 ArUtil::sleep(3);
01013 serConn->setBaud(38400);
01014 comInt(ArCommands::CLOSE,1);
01015 ArUtil::sleep(3);
01016 serConn->setBaud(115200);
01017 comInt(ArCommands::CLOSE,1);
01018 ArUtil::sleep(3);
01019 serConn->setBaud(19200);
01020 comInt(ArCommands::CLOSE,1);
01021 ArUtil::sleep(3);
01022 serConn->setBaud(57600);
01023 comInt(ArCommands::CLOSE,1);
01024 ArUtil::sleep(3);
01025 serConn->setBaud(origBaud);
01026 }
01027
01028 if (myAsyncConnectNoPacketCount > 3)
01029 {
01030 ArLog::log(ArLog::Normal,
01031 " Robot may be connected but not open, trying to dislodge.");
01032 mySender.comInt(ArCommands::OPEN,1);
01033 }
01034
01035 myAsyncConnectState = 0;
01036 }
01037
01038
01039 if (myAsyncConnectState == 3 && packet != NULL)
01040 {
01041 char nameBuf[512];
01042 ArLog::log(ArLog::Terse, "Connected to robot.");
01043 packet->bufToStr(nameBuf, 512);
01044 myRobotName = nameBuf;
01045 ArLog::log(ArLog::Normal, "Name: %s", myRobotName.c_str());
01046 packet->bufToStr(nameBuf, 512);
01047 myRobotType = nameBuf;
01048 ArLog::log(ArLog::Normal, "Type: %s", myRobotType.c_str());
01049 packet->bufToStr(nameBuf, 512);
01050 myRobotSubType = nameBuf;
01051 strcpy(robotSubType, myRobotSubType.c_str());
01052 len = strlen(robotSubType);
01053 for (i = 0; i < len; i++)
01054 robotSubType[i] = tolower(robotSubType[i]);
01055 myRobotSubType = robotSubType;
01056 ArLog::log(ArLog::Normal, "Subtype: %s", myRobotSubType.c_str());
01057 ArUtil::sleep(getCycleTime());
01058 mySender.comInt(ArCommands::OPEN,1);
01059 if (!madeConnection())
01060 {
01061 mySender.comInt(ArCommands::CLOSE,1);
01062 failedConnect();
01063 return 2;
01064 }
01065
01066
01067
01068
01069 myAsyncStartedConnection.setToNow();
01070 return asyncConnectHandler(tryHarderToConnect);
01071 }
01072 if (myAsyncConnectTimesTried > 50)
01073 {
01074 failedConnect();
01075 return 2;
01076 }
01077 return 0;
01078 }
01079
01083 AREXPORT bool ArRobot::loadParamFile(const char *file)
01084 {
01085 if (myParams != NULL)
01086 delete myParams;
01087
01088 myParams = new ArRobotGeneric("");
01089 if (!myParams->parseFile(file, false, true))
01090 {
01091 ArLog::log(ArLog::Normal, "ArRobot::loadParamFile: Could not find file '%s' to load.", file);
01092 return false;
01093 }
01094 processParamFile();
01095 ArLog::log(ArLog::Normal, "Loaded robot parameters from %s.", file);
01096 return true;
01097 }
01098
01099 AREXPORT void ArRobot::processParamFile(void)
01100 {
01101 for (int i = 0; i < myParams->getNumSonar(); ++i)
01102 {
01103
01104
01105 if (mySonars.find(i) == mySonars.end())
01106 {
01107 mySonars[i] = new ArSensorReading(myParams->getSonarX(i),
01108 myParams->getSonarY(i),
01109 myParams->getSonarTh(i));
01110 mySonars[i]->setIgnoreThisReading(true);
01111 }
01112 else
01113 {
01114 mySonars[i]->resetSensorPosition(myParams->getSonarX(i),
01115 myParams->getSonarY(i),
01116 myParams->getSonarTh(i));
01117 mySonars[i]->setIgnoreThisReading(true);
01118 }
01119 if ((i + 1) > myNumSonar)
01120 myNumSonar = i + 1;
01121 }
01122
01123
01124 myAbsoluteMaxTransVel = myParams->getAbsoluteMaxVelocity();
01125 myAbsoluteMaxRotVel = myParams->getAbsoluteMaxRotVelocity();
01126
01127 if (myParams->getRobotLengthFront() == 0)
01128 myRobotLengthFront = myParams->getRobotLength() / 2.0;
01129 else
01130 myRobotLengthFront = myParams->getRobotLengthFront();
01131
01132 if (myParams->getRobotLengthRear() == 0)
01133 myRobotLengthRear = myParams->getRobotLength() / 2.0;
01134 else
01135 myRobotLengthRear = myParams->getRobotLengthRear();
01136 }
01137
01138
01139 AREXPORT bool ArRobot::madeConnection(void)
01140 {
01141 std::string subTypeParamName;
01142 std::string paramFileName;
01143 bool loadedSubTypeParam;
01144 bool loadedNameParam;
01145 bool hadDefault = true;
01146
01147 if (myParams != NULL)
01148 delete myParams;
01149
01150
01151 if (ArUtil::strcmp(myRobotSubType, "p2dx") == 0)
01152 myParams = new ArRobotP2DX;
01153 else if (ArUtil::strcmp(myRobotSubType, "p2ce") == 0)
01154 myParams = new ArRobotP2CE;
01155 else if (ArUtil::strcmp(myRobotSubType, "p2de") == 0)
01156 myParams = new ArRobotP2DXe;
01157 else if (ArUtil::strcmp(myRobotSubType, "p2df") == 0)
01158 myParams = new ArRobotP2DF;
01159 else if (ArUtil::strcmp(myRobotSubType, "p2d8") == 0)
01160 myParams = new ArRobotP2D8;
01161 else if (ArUtil::strcmp(myRobotSubType, "amigo") == 0)
01162 myParams = new ArRobotAmigo;
01163 else if (ArUtil::strcmp(myRobotSubType, "amigo-sh") == 0)
01164 myParams = new ArRobotAmigoSh;
01165 else if (ArUtil::strcmp(myRobotSubType, "p2at") == 0)
01166 myParams = new ArRobotP2AT;
01167 else if (ArUtil::strcmp(myRobotSubType, "p2at8") == 0)
01168 myParams = new ArRobotP2AT8;
01169 else if (ArUtil::strcmp(myRobotSubType, "p2it") == 0)
01170 myParams = new ArRobotP2IT;
01171 else if (ArUtil::strcmp(myRobotSubType, "p2pb") == 0)
01172 myParams = new ArRobotP2PB;
01173 else if (ArUtil::strcmp(myRobotSubType, "p2pp") == 0)
01174 myParams = new ArRobotP2PP;
01175 else if (ArUtil::strcmp(myRobotSubType, "p3at") == 0)
01176 myParams = new ArRobotP3AT;
01177 else if (ArUtil::strcmp(myRobotSubType, "p3dx") == 0)
01178 myParams = new ArRobotP3DX;
01179 else if (ArUtil::strcmp(myRobotSubType, "perfpb") == 0)
01180 myParams = new ArRobotPerfPB;
01181 else if (ArUtil::strcmp(myRobotSubType, "pion1m") == 0)
01182 myParams = new ArRobotPion1M;
01183 else if (ArUtil::strcmp(myRobotSubType, "pion1x") == 0)
01184 myParams = new ArRobotPion1X;
01185 else if (ArUtil::strcmp(myRobotSubType, "psos1m") == 0)
01186 myParams = new ArRobotPsos1M;
01187 else if (ArUtil::strcmp(myRobotSubType, "psos43m") == 0)
01188 myParams = new ArRobotPsos43M;
01189 else if (ArUtil::strcmp(myRobotSubType, "psos1x") == 0)
01190 myParams = new ArRobotPsos1X;
01191 else if (ArUtil::strcmp(myRobotSubType, "pionat") == 0)
01192 myParams = new ArRobotPionAT;
01193 else if (ArUtil::strcmp(myRobotSubType, "mappr") == 0)
01194 myParams = new ArRobotMapper;
01195 else if (ArUtil::strcmp(myRobotSubType, "powerbot") == 0)
01196 myParams = new ArRobotPowerBot;
01197 else if (ArUtil::strcmp(myRobotSubType, "p2d8+") == 0)
01198 myParams = new ArRobotP2D8Plus;
01199 else if (ArUtil::strcmp(myRobotSubType, "p2at8+") == 0)
01200 myParams = new ArRobotP2AT8Plus;
01201 else if (ArUtil::strcmp(myRobotSubType, "perfpb+") == 0)
01202 myParams = new ArRobotPerfPBPlus;
01203 else if (ArUtil::strcmp(myRobotSubType, "p3dx-sh") == 0)
01204 myParams = new ArRobotP3DXSH;
01205 else if (ArUtil::strcmp(myRobotSubType, "p3at-sh") == 0)
01206 myParams = new ArRobotP3ATSH;
01207 else if (ArUtil::strcmp(myRobotSubType, "p3atiw-sh") == 0)
01208 myParams = new ArRobotP3ATIWSH;
01209 else if (ArUtil::strcmp(myRobotSubType, "patrolbot-sh") == 0)
01210 myParams = new ArRobotPatrolBotSH;
01211 else if (ArUtil::strcmp(myRobotSubType, "peoplebot-sh") == 0)
01212 myParams = new ArRobotPeopleBotSH;
01213 else if (ArUtil::strcmp(myRobotSubType, "powerbot-sh") == 0)
01214 myParams = new ArRobotPowerBotSH;
01215 else if (ArUtil::strcmp(myRobotSubType, "wheelchair-sh") == 0)
01216 myParams = new ArRobotWheelchairSH;
01217 else
01218 {
01219 hadDefault = false;
01220 myParams = new ArRobotGeneric(myRobotName.c_str());
01221 }
01222
01223
01224 paramFileName = Aria::getDirectory();
01225 paramFileName += "params/";
01226 paramFileName += myRobotSubType;
01227 paramFileName += ".p";
01228 if ((loadedSubTypeParam = myParams->parseFile(paramFileName.c_str(), true, true)))
01229 ArLog::log(ArLog::Normal,
01230 "Loaded robot parameters from %s.p",
01231 myRobotSubType.c_str());
01232
01233
01234
01235
01236
01237 paramFileName = Aria::getDirectory();
01238 paramFileName += "params/";
01239 paramFileName += myRobotName;
01240 paramFileName += ".p";
01241 if ((loadedNameParam = myParams->parseFile(paramFileName.c_str(),
01242 true, true)))
01243 {
01244 if (loadedSubTypeParam)
01245 ArLog::log(ArLog::Normal,
01246 "Loaded robot parameters from %s.p on top of %s.p robot parameters",
01247 myRobotName.c_str(), myRobotSubType.c_str());
01248 else
01249 ArLog::log(ArLog::Normal, "Loaded robot parameters from %s.p",
01250 myRobotName.c_str());
01251 }
01252
01253 if (!loadedSubTypeParam && !loadedNameParam)
01254 {
01255 if (hadDefault)
01256 ArLog::log(ArLog::Normal, "Using default parameters for a %s robot",
01257 myRobotSubType.c_str());
01258 else
01259 {
01260 ArLog::log(ArLog::Terse, "Error: Have no parameters for this robot, bad configuration or out of date Aria");
01261
01262
01263
01264
01265 if (!myConnectWithNoParams)
01266 return false;
01267 }
01268 }
01269
01270 processParamFile();
01271
01272 if (myParams->getRequestIOPackets() || myRequestedIOPackets)
01273 comInt(ArCommands::IOREQUEST, 2);
01274
01275 if(myParams->getRequestEncoderPackets() || myRequestedEncoderPackets)
01276 comInt(ArCommands::ENCODER, 2);
01277
01278 return true;
01279 }
01280
01286 AREXPORT void ArRobot::requestEncoderPackets(void)
01287 {
01288 comInt(ArCommands::ENCODER, 2);
01289 myRequestedEncoderPackets = true;
01290 }
01291
01292 AREXPORT void ArRobot::requestIOPackets(void)
01293 {
01294 comInt(ArCommands::IOREQUEST, 2);
01295 myRequestedIOPackets = true;
01296 }
01297
01298 AREXPORT void ArRobot::stopEncoderPackets(void)
01299 {
01300 comInt(ArCommands::ENCODER, 0);
01301 myRequestedEncoderPackets = false;
01302 }
01303
01304 AREXPORT void ArRobot::stopIOPackets(void)
01305 {
01306 comInt(ArCommands::IOREQUEST, 0);
01307 myRequestedIOPackets = false;
01308 }
01309
01310 AREXPORT void ArRobot::startStabilization(void)
01311 {
01312 std::list<ArFunctor *>::iterator it;
01313 myIsStabilizing = true;
01314 myStartedStabilizing.setToNow();
01315
01316 for (it = myStabilizingCBList.begin();
01317 it != myStabilizingCBList.end();
01318 it++)
01319 (*it)->invoke();
01320
01321 }
01322
01323 AREXPORT void ArRobot::finishedConnection(void)
01324 {
01325 std::list<ArFunctor *>::iterator it;
01326
01327 myIsStabilizing = false;
01328 myIsConnected = true;
01329 myAsyncConnectFlag = false;
01330 myBlockingConnectRun = false;
01331 resetOdometer();
01332
01333 for (it = myConnectCBList.begin(); it != myConnectCBList.end(); it++)
01334 (*it)->invoke();
01335 myLastPacketReceivedTime.setToNow();
01336
01337 wakeAllConnWaitingThreads();
01338 }
01339
01340 AREXPORT void ArRobot::failedConnect(void)
01341 {
01342 std::list<ArFunctor *>::iterator it;
01343
01344 myAsyncConnectFlag = false;
01345 myBlockingConnectRun = false;
01346 ArLog::log(ArLog::Terse, "Failed to connect to robot.");
01347 myIsConnected = false;
01348 for (it = myFailedConnectCBList.begin();
01349 it != myFailedConnectCBList.end();
01350 it++)
01351 (*it)->invoke();
01352
01353 if (myConn != NULL)
01354 myConn->close();
01355 wakeAllConnOrFailWaitingThreads();
01356 }
01357
01367 AREXPORT bool ArRobot::disconnect(void)
01368 {
01369 std::list<ArFunctor *>::iterator it;
01370 bool ret;
01371 ArSerialConnection *serConn;
01372
01373 if (!myIsConnected && !myIsStabilizing)
01374 return true;
01375
01376 ArLog::log(ArLog::Terse, "Disconnecting from robot.");
01377 myNoTimeWarningThisCycle = true;
01378 myIsConnected = false;
01379 myIsStabilizing = false;
01380 if (myIsConnected)
01381 {
01382 for (it = myDisconnectNormallyCBList.begin();
01383 it != myDisconnectNormallyCBList.end();
01384 it++)
01385 (*it)->invoke();
01386 }
01387 ret = mySender.comInt(ArCommands::CLOSE, 1);
01388 ArUtil::sleep(1000);
01389 if (ret == true)
01390 {
01391 if (myConn != NULL)
01392 {
01393 ret = myConn->close();
01394 if ((serConn = dynamic_cast<ArSerialConnection *>(myConn)) != NULL)
01395 serConn->setBaud(myAsyncConnectStartBaud);
01396 }
01397 else
01398 ret = false;
01399 }
01400 else if (myConn != NULL)
01401 myConn->close();
01402
01403 return ret;
01404 }
01405
01406 AREXPORT void ArRobot::dropConnection(void)
01407 {
01408 std::list<ArFunctor *>::iterator it;
01409
01410 if (!myIsConnected)
01411 return;
01412
01413 ArLog::log(ArLog::Terse, "Lost connection to the robot because of error.");
01414 myIsConnected = false;
01415 for (it = myDisconnectOnErrorCBList.begin();
01416 it != myDisconnectOnErrorCBList.end();
01417 it++)
01418 (*it)->invoke();
01419
01420 if (myConn != NULL)
01421 myConn->close();
01422 return;
01423 }
01424
01425 AREXPORT void ArRobot::cancelConnection(void)
01426 {
01427
01428
01429 ArLog::log(ArLog::Verbose, "Cancelled connection to the robot because of command.");
01430 myIsConnected = false;
01431 myNoTimeWarningThisCycle = true;
01432 myIsStabilizing = false;
01433 return;
01434 }
01435
01445 AREXPORT void ArRobot::stop(void)
01446 {
01447 comInt(ArCommands::VEL, 0);
01448 comInt(ArCommands::RVEL, 0);
01449 setVel(0);
01450 setRotVel(0);
01451 myLastActionTransVal = 0;
01452 myLastActionRotStopped = true;
01453 myLastActionRotHeading = false;
01454 }
01455
01462 AREXPORT void ArRobot::setVel(double velocity)
01463 {
01464 myTransType = TRANS_VEL;
01465 myTransVal = velocity;
01466 myTransVal2 = 0;
01467 myTransSetTime.setToNow();
01468 }
01469
01484 AREXPORT void ArRobot::setVel2(double leftVelocity, double rightVelocity)
01485 {
01486 myTransType = TRANS_VEL2;
01487 myTransVal = leftVelocity;
01488 myTransVal2 = rightVelocity;
01489 myRotType = ROT_IGNORE;
01490 myRotVal = 0;
01491 myTransSetTime.setToNow();
01492 }
01493
01504 AREXPORT void ArRobot::move(double distance)
01505 {
01506 myTransType = TRANS_DIST_NEW;
01507 myTransDistStart = getPose();
01508 myTransVal = distance;
01509 myTransVal2 = 0;
01510 myTransSetTime.setToNow();
01511 }
01512
01527 AREXPORT bool ArRobot::isMoveDone(double delta)
01528 {
01529 if (fabs(delta) < 0.001)
01530 delta = myMoveDoneDist;
01531 if (myTransType != TRANS_DIST && myTransType != TRANS_DIST_NEW)
01532 return true;
01533 if (myTransDistStart.findDistanceTo(getPose()) <
01534 fabs(myTransVal) - delta)
01535 return false;
01536 return true;
01537 }
01538
01539
01552 AREXPORT bool ArRobot::isHeadingDone(double delta) const
01553 {
01554 if (fabs(delta) < 0.001)
01555 delta = myHeadingDoneDiff;
01556 if (myRotType != ROT_HEADING)
01557 return true;
01558 if(fabs(ArMath::subAngle(getTh(), myRotVal)) > delta)
01559 return false;
01560 return true;
01561 }
01562
01563
01564
01571 AREXPORT void ArRobot::setHeading(double heading)
01572 {
01573 myRotVal = heading;
01574 myRotType = ROT_HEADING;
01575 myRotSetTime.setToNow();
01576 if (myTransType == TRANS_VEL2)
01577 {
01578 myTransType = TRANS_IGNORE;
01579 myTransVal = 0;
01580 myTransVal2 = 0;
01581 }
01582 }
01583
01590 AREXPORT void ArRobot::setRotVel(double velocity)
01591 {
01592 myRotVal = velocity;
01593 myRotType = ROT_VEL;
01594 myRotSetTime.setToNow();
01595 if (myTransType == TRANS_VEL2)
01596 {
01597 myTransType = TRANS_IGNORE;
01598 myTransVal = 0;
01599 myTransVal2 = 0;
01600 }
01601 }
01602
01609 AREXPORT void ArRobot::setDeltaHeading(double deltaHeading)
01610 {
01611 myRotVal = ArMath::addAngle(getTh(), deltaHeading);
01612 myRotType = ROT_HEADING;
01613 myRotSetTime.setToNow();
01614 if (myTransType == TRANS_VEL2)
01615 {
01616 myTransType = TRANS_IGNORE;
01617 myTransVal = 0;
01618 myTransVal2 = 0;
01619 }
01620 }
01621
01635 AREXPORT bool ArRobot::setAbsoluteMaxTransVel(double maxVel)
01636 {
01637 if (maxVel < 0)
01638 return false;
01639 myAbsoluteMaxTransVel = maxVel;
01640 if (getTransVelMax() > myAbsoluteMaxTransVel)
01641 setTransVelMax(myAbsoluteMaxTransVel);
01642 return true;
01643 }
01644
01658 AREXPORT bool ArRobot::setAbsoluteMaxTransAccel(double maxAccel)
01659 {
01660 if (maxAccel < 0)
01661 return false;
01662 myAbsoluteMaxTransAccel = maxAccel;
01663 if (getTransAccel() > myAbsoluteMaxTransAccel)
01664 setTransAccel(myAbsoluteMaxTransAccel);
01665 return true;
01666 }
01667
01681 AREXPORT bool ArRobot::setAbsoluteMaxTransDecel(double maxDecel)
01682 {
01683 if (maxDecel < 0)
01684 return false;
01685 myAbsoluteMaxTransDecel = maxDecel;
01686 if (getTransDecel() > myAbsoluteMaxTransDecel)
01687 setTransDecel(myAbsoluteMaxTransDecel);
01688 return true;
01689 }
01690
01702 AREXPORT bool ArRobot::setAbsoluteMaxRotVel(double maxVel)
01703 {
01704 if (maxVel < 0)
01705 return false;
01706 myAbsoluteMaxRotVel = maxVel;
01707 if (getRotVelMax() > myAbsoluteMaxRotVel)
01708 setRotVelMax(myAbsoluteMaxRotVel);
01709 return true;
01710 }
01711
01725 AREXPORT bool ArRobot::setAbsoluteMaxRotAccel(double maxAccel)
01726 {
01727 if (maxAccel < 0)
01728 return false;
01729 myAbsoluteMaxRotAccel = maxAccel;
01730 if (getRotAccel() > myAbsoluteMaxRotAccel)
01731 setRotAccel(myAbsoluteMaxRotAccel);
01732 return true;
01733 }
01734
01748 AREXPORT bool ArRobot::setAbsoluteMaxRotDecel(double maxDecel)
01749 {
01750 if (maxDecel < 0)
01751 return false;
01752 myAbsoluteMaxRotDecel = maxDecel;
01753 if (getRotDecel() > myAbsoluteMaxRotDecel)
01754 setRotDecel(myAbsoluteMaxRotDecel);
01755 return true;
01756 }
01757
01762 AREXPORT int ArRobot::getIOAnalog(int num) const
01763 {
01764 if (num <= getIOAnalogSize())
01765 return myIOAnalog[num];
01766 else
01767 return 0;
01768 }
01769
01773 AREXPORT double ArRobot::getIOAnalogVoltage(int num) const
01774 {
01775 if (num <= getIOAnalogSize())
01776 {
01777 return (myIOAnalog[num] & 0xfff) * .0048828;
01778 }
01779 else
01780 return 0;
01781 }
01782
01783 AREXPORT unsigned char ArRobot::getIODigIn(int num) const
01784 {
01785 if (num <= getIODigInSize())
01786 return myIODigIn[num];
01787 else
01788 return (unsigned char) 0;
01789 }
01790
01791 AREXPORT unsigned char ArRobot::getIODigOut(int num) const
01792 {
01793 if (num <= getIODigOutSize())
01794 return myIODigOut[num];
01795 else
01796 return (unsigned char) 0;
01797 }
01798
01802 AREXPORT const ArRobotParams *ArRobot::getRobotParams(void) const
01803 {
01804 return myParams;
01805 }
01806
01811 AREXPORT const ArRobotConfigPacketReader *ArRobot::getOrigRobotConfig(void) const
01812 {
01813 return myOrigRobotConfig;
01814 }
01815
01832 AREXPORT void ArRobot::addPacketHandler(
01833 ArRetFunctor1<bool, ArRobotPacket *> *functor,
01834 ArListPos::Pos position)
01835 {
01836 if (position == ArListPos::FIRST)
01837 myPacketHandlerList.push_front(functor);
01838 else if (position == ArListPos::LAST)
01839 myPacketHandlerList.push_back(functor);
01840 else
01841 ArLog::log(ArLog::Terse, "ArRobot::addPacketHandler: Invalid position.");
01842
01843 }
01844
01849 AREXPORT void ArRobot::remPacketHandler(
01850 ArRetFunctor1<bool, ArRobotPacket *> *functor)
01851 {
01852 myPacketHandlerList.remove(functor);
01853 }
01854
01865 AREXPORT void ArRobot::addConnectCB(ArFunctor *functor,
01866 ArListPos::Pos position)
01867 {
01868 if (position == ArListPos::FIRST)
01869 myConnectCBList.push_front(functor);
01870 else if (position == ArListPos::LAST)
01871 myConnectCBList.push_back(functor);
01872 else
01873 ArLog::log(ArLog::Terse,
01874 "ArRobot::addConnectCallback: Invalid position.");
01875 }
01876
01881 AREXPORT void ArRobot::remConnectCB(ArFunctor *functor)
01882 {
01883 myConnectCBList.remove(functor);
01884 }
01885
01886
01900 AREXPORT void ArRobot::addFailedConnectCB(ArFunctor *functor,
01901 ArListPos::Pos position)
01902 {
01903 if (position == ArListPos::FIRST)
01904 myFailedConnectCBList.push_front(functor);
01905 else if (position == ArListPos::LAST)
01906 myFailedConnectCBList.push_back(functor);
01907 else
01908 ArLog::log(ArLog::Terse,
01909 "ArRobot::addFailedCallback: Invalid position.");
01910 }
01911
01916 AREXPORT void ArRobot::remFailedConnectCB(ArFunctor *functor)
01917 {
01918 myFailedConnectCBList.remove(functor);
01919 }
01920
01932 AREXPORT void ArRobot::addDisconnectNormallyCB(ArFunctor *functor,
01933 ArListPos::Pos position)
01934 {
01935 if (position == ArListPos::FIRST)
01936 myDisconnectNormallyCBList.push_front(functor);
01937 else if (position == ArListPos::LAST)
01938 myDisconnectNormallyCBList.push_back(functor);
01939 else
01940 ArLog::log(ArLog::Terse,
01941 "ArRobot::addDisconnectNormallyCB: Invalid position.");
01942 }
01943
01948 AREXPORT void ArRobot::remDisconnectNormallyCB(ArFunctor *functor)
01949 {
01950 myDisconnectNormallyCBList.remove(functor);
01951 }
01952
01969 AREXPORT void ArRobot::addDisconnectOnErrorCB(ArFunctor *functor,
01970 ArListPos::Pos position)
01971 {
01972 if (position == ArListPos::FIRST)
01973 myDisconnectOnErrorCBList.push_front(functor);
01974 else if (position == ArListPos::LAST)
01975 myDisconnectOnErrorCBList.push_back(functor);
01976 else
01977 ArLog::log(ArLog::Terse,
01978 "ArRobot::addDisconnectOnErrorCB: Invalid position");
01979 }
01980
01985 AREXPORT void ArRobot::remDisconnectOnErrorCB(ArFunctor *functor)
01986 {
01987 myDisconnectOnErrorCBList.remove(functor);
01988 }
01989
02001 AREXPORT void ArRobot::addRunExitCB(ArFunctor *functor,
02002 ArListPos::Pos position)
02003 {
02004 if (position == ArListPos::FIRST)
02005 myRunExitCBList.push_front(functor);
02006 else if (position == ArListPos::LAST)
02007 myRunExitCBList.push_back(functor);
02008 else
02009 ArLog::log(ArLog::Terse, "ArRobot::addRunExitCB: Invalid position");
02010 }
02011
02016 AREXPORT void ArRobot::remRunExitCB(ArFunctor *functor)
02017 {
02018 myRunExitCBList.remove(functor);
02019 }
02020
02033 AREXPORT void ArRobot::addStabilizingCB(ArFunctor *functor,
02034 ArListPos::Pos position)
02035 {
02036 if (position == ArListPos::FIRST)
02037 myStabilizingCBList.push_front(functor);
02038 else if (position == ArListPos::LAST)
02039 myStabilizingCBList.push_back(functor);
02040 else
02041 ArLog::log(ArLog::Terse,
02042 "ArRobot::addConnectCallback: Invalid position.");
02043 }
02044
02049 AREXPORT void ArRobot::remStabilizingCB(ArFunctor *functor)
02050 {
02051 myStabilizingCBList.remove(functor);
02052 }
02053
02054
02055 AREXPORT std::list<ArFunctor *> * ArRobot::getRunExitListCopy()
02056 {
02057 return(new std::list<ArFunctor *>(myRunExitCBList));
02058 }
02059
02075 AREXPORT ArRobot::WaitState ArRobot::waitForConnect(unsigned int msecs)
02076 {
02077 int ret;
02078
02079 if (isConnected())
02080 return(WAIT_CONNECTED);
02081
02082 if (msecs == 0)
02083 ret=myConnectCond.wait();
02084 else
02085 ret=myConnectCond.timedWait(msecs);
02086
02087 if (ret == ArCondition::STATUS_WAIT_INTR)
02088 return(WAIT_INTR);
02089 else if (ret == ArCondition::STATUS_WAIT_TIMEDOUT)
02090 return(WAIT_TIMEDOUT);
02091 else if (ret == 0)
02092 return(WAIT_CONNECTED);
02093 else
02094 return(WAIT_FAIL);
02095 }
02096
02106 AREXPORT ArRobot::WaitState
02107 ArRobot::waitForConnectOrConnFail(unsigned int msecs)
02108 {
02109 int ret;
02110
02111 if (isConnected())
02112 return(WAIT_CONNECTED);
02113
02114 if (msecs == 0)
02115 ret=myConnOrFailCond.wait();
02116 else
02117 ret=myConnOrFailCond.timedWait(msecs);
02118
02119 if (ret == ArCondition::STATUS_WAIT_INTR)
02120 return(WAIT_INTR);
02121 else if (ret == ArCondition::STATUS_WAIT_TIMEDOUT)
02122 return(WAIT_TIMEDOUT);
02123 else if (ret == 0)
02124 {
02125 if (isConnected())
02126 return(WAIT_CONNECTED);
02127 else
02128 return(WAIT_FAILED_CONN);
02129 }
02130 else
02131 return(WAIT_FAIL);
02132 }
02133
02142 AREXPORT ArRobot::WaitState ArRobot::waitForRunExit(unsigned int msecs)
02143 {
02144 int ret;
02145
02146 if (!isRunning())
02147 return(WAIT_RUN_EXIT);
02148
02149 if (msecs == 0)
02150 ret=myRunExitCond.wait();
02151 else
02152 ret=myRunExitCond.timedWait(msecs);
02153
02154 if (ret == ArCondition::STATUS_WAIT_INTR)
02155 return(WAIT_INTR);
02156 else if (ret == ArCondition::STATUS_WAIT_TIMEDOUT)
02157 return(WAIT_TIMEDOUT);
02158 else if (ret == 0)
02159 return(WAIT_RUN_EXIT);
02160 else
02161 return(WAIT_FAIL);
02162 }
02163
02171 AREXPORT void ArRobot::wakeAllWaitingThreads()
02172 {
02173 wakeAllConnWaitingThreads();
02174 wakeAllRunExitWaitingThreads();
02175 }
02176
02182 AREXPORT void ArRobot::wakeAllConnWaitingThreads()
02183 {
02184 myConnectCond.broadcast();
02185 myConnOrFailCond.broadcast();
02186 }
02187
02194 AREXPORT void ArRobot::wakeAllConnOrFailWaitingThreads()
02195 {
02196 myConnOrFailCond.broadcast();
02197 }
02198
02204 AREXPORT void ArRobot::wakeAllRunExitWaitingThreads()
02205 {
02206 myRunExitCond.broadcast();
02207 }
02208
02216 AREXPORT ArSyncTask *ArRobot::getSyncTaskRoot(void)
02217 {
02218 return mySyncTaskRoot;
02219 }
02220
02237 AREXPORT bool ArRobot::addUserTask(const char *name, int position,
02238 ArFunctor *functor,
02239 ArTaskState::State *state)
02240 {
02241 ArSyncTask *proc;
02242 if (mySyncTaskRoot == NULL)
02243 return false;
02244
02245 proc = mySyncTaskRoot->findNonRecursive("User Tasks");
02246 if (proc == NULL)
02247 return false;
02248
02249 proc->addNewLeaf(name, position, functor, state);
02250 return true;
02251 }
02252
02257 AREXPORT void ArRobot::remUserTask(const char *name)
02258 {
02259 ArSyncTask *proc;
02260 ArSyncTask *userProc;
02261
02262 if (mySyncTaskRoot == NULL)
02263 return;
02264
02265 proc = mySyncTaskRoot->findNonRecursive("User Tasks");
02266 if (proc == NULL)
02267 return;
02268
02269 userProc = proc->findNonRecursive(name);
02270 if (userProc == NULL)
02271 return;
02272
02273
02274 delete userProc;
02275
02276 }
02277
02282 AREXPORT void ArRobot::remUserTask(ArFunctor *functor)
02283 {
02284 ArSyncTask *proc;
02285 ArSyncTask *userProc;
02286
02287 if (mySyncTaskRoot == NULL)
02288 return;
02289
02290 proc = mySyncTaskRoot->findNonRecursive("User Tasks");
02291 if (proc == NULL)
02292 return;
02293
02294
02295 userProc = proc->findNonRecursive(functor);
02296 if (userProc == NULL)
02297 return;
02298
02299
02300 delete userProc;
02301
02302 }
02303
02315 AREXPORT bool ArRobot::addSensorInterpTask(const char *name, int position,
02316 ArFunctor *functor,
02317 ArTaskState::State *state)
02318 {
02319 ArSyncTask *proc;
02320 if (mySyncTaskRoot == NULL)
02321 return false;
02322
02323 proc = mySyncTaskRoot->findNonRecursive("Sensor Interp");
02324 if (proc == NULL)
02325 return false;
02326
02327 proc->addNewLeaf(name, position, functor, state);
02328 return true;
02329 }
02330
02335 AREXPORT void ArRobot::remSensorInterpTask(const char *name)
02336 {
02337 ArSyncTask *proc;
02338 ArSyncTask *sensorInterpProc;
02339
02340 if (mySyncTaskRoot == NULL)
02341 return;
02342
02343 proc = mySyncTaskRoot->findNonRecursive("Sensor Interp");
02344 if (proc == NULL)
02345 return;
02346
02347 sensorInterpProc = proc->findNonRecursive(name);
02348 if (sensorInterpProc == NULL)
02349 return;
02350
02351
02352 delete sensorInterpProc;
02353
02354 }
02355
02360 AREXPORT void ArRobot::remSensorInterpTask(ArFunctor *functor)
02361 {
02362 ArSyncTask *proc;
02363 ArSyncTask *sensorInterpProc;
02364
02365 if (mySyncTaskRoot == NULL)
02366 return;
02367
02368 proc = mySyncTaskRoot->findNonRecursive("Sensor Interp");
02369 if (proc == NULL)
02370 return;
02371
02372
02373 sensorInterpProc = proc->findNonRecursive(functor);
02374 if (sensorInterpProc == NULL)
02375 return;
02376
02377
02378 delete sensorInterpProc;
02379
02380 }
02381
02385 AREXPORT void ArRobot::logUserTasks(void) const
02386 {
02387 ArSyncTask *proc;
02388 if (mySyncTaskRoot == NULL)
02389 return;
02390
02391 proc = mySyncTaskRoot->findNonRecursive("User Tasks");
02392 if (proc == NULL)
02393 return;
02394
02395 proc->log();
02396 }
02397
02401 AREXPORT void ArRobot::logAllTasks(void) const
02402 {
02403 if (mySyncTaskRoot != NULL)
02404 mySyncTaskRoot->log();
02405 }
02406
02412 AREXPORT ArSyncTask *ArRobot::findUserTask(const char *name)
02413 {
02414 ArSyncTask *proc;
02415 if (mySyncTaskRoot == NULL)
02416 return NULL;
02417
02418 proc = mySyncTaskRoot->findNonRecursive("User Tasks");
02419 if (proc == NULL)
02420 return NULL;
02421
02422 return proc->find(name);
02423 }
02424
02430 AREXPORT ArSyncTask *ArRobot::findUserTask(ArFunctor *functor)
02431 {
02432 ArSyncTask *proc;
02433 if (mySyncTaskRoot == NULL)
02434 return NULL;
02435
02436 proc = mySyncTaskRoot->findNonRecursive("User Tasks");
02437 if (proc == NULL)
02438 return NULL;
02439
02440 return proc->find(functor);
02441 }
02442
02448 AREXPORT ArSyncTask *ArRobot::findTask(const char *name)
02449 {
02450 if (mySyncTaskRoot != NULL)
02451 return mySyncTaskRoot->find(name);
02452 else
02453 return NULL;
02454
02455 }
02456
02462 AREXPORT ArSyncTask *ArRobot::findTask(ArFunctor *functor)
02463 {
02464 if (mySyncTaskRoot != NULL)
02465 return mySyncTaskRoot->find(functor);
02466 else
02467 return NULL;
02468
02469 }
02470
02492 AREXPORT bool ArRobot::addAction(ArAction *action, int priority)
02493 {
02494 if (action == NULL)
02495 {
02496 ArLog::log(ArLog::Terse,
02497 "ArRobot::addAction: an attempt was made to add a NULL action pointer");
02498 return false;
02499 }
02500
02501 action->setRobot(this);
02502 myActions.insert(std::pair<int, ArAction *>(priority, action));
02503 return true;
02504 }
02505
02516 AREXPORT bool ArRobot::remAction(const char *actionName)
02517 {
02518 ArResolver::ActionMap::iterator it;
02519 ArAction *act;
02520
02521 for (it = myActions.begin(); it != myActions.end(); ++it)
02522 {
02523 act = (*it).second;
02524 if (strcmp(actionName, act->getName()) == 0)
02525 break;
02526 }
02527 if (it != myActions.end())
02528 {
02529 myActions.erase(it);
02530 return true;
02531 }
02532 return false;
02533
02534 }
02535
02546 AREXPORT bool ArRobot::remAction(ArAction *action)
02547 {
02548 ArResolver::ActionMap::iterator it;
02549 ArAction *act;
02550
02551 for (it = myActions.begin(); it != myActions.end(); ++it)
02552 {
02553 act = (*it).second;
02554 if (act == action)
02555 break;
02556 }
02557 if (it != myActions.end())
02558 {
02559 myActions.erase(it);
02560 return true;
02561 }
02562 return false;
02563
02564 }
02565
02566
02576 AREXPORT ArAction *ArRobot::findAction(const char *actionName)
02577 {
02578 ArResolver::ActionMap::reverse_iterator it;
02579 ArAction *act;
02580
02581 for (it = myActions.rbegin(); it != myActions.rend(); ++it)
02582 {
02583 act = (*it).second;
02584 if (strcmp(actionName, act->getName()) == 0)
02585 return act;
02586 }
02587 return NULL;
02588 }
02589
02600 AREXPORT ArResolver::ActionMap *ArRobot::getActionMap(void)
02601 {
02602 return &myActions;
02603 }
02604
02605 AREXPORT void ArRobot::deactivateActions(void)
02606 {
02607 ArResolver::ActionMap *am;
02608 ArResolver::ActionMap::iterator amit;
02609
02610 am = getActionMap();
02611 if (am == NULL)
02612 {
02613 ArLog::log(ArLog::Terse,
02614 "ArRobot::deactivateActions: NULL action map... failed.");
02615 return;
02616 }
02617 for (amit = am->begin(); amit != am->end(); amit++)
02618 (*amit).second->deactivate();
02619
02620
02621 }
02622
02623
02624 AREXPORT void ArRobot::logActions(bool logDeactivated) const
02625 {
02626 ArResolver::ActionMap::const_reverse_iterator it;
02627 int lastPriority;
02628 bool first = true;
02629 const ArAction *action;
02630
02631 if (logDeactivated)
02632 ArLog::log(ArLog::Terse, "The action list (%d total):",
02633 myActions.size());
02634 else
02635 ArLog::log(ArLog::Terse, "The active action list:");
02636
02637 for (it = myActions.rbegin(); it != myActions.rend(); ++it)
02638 {
02639 action = (*it).second;
02640 if ((logDeactivated || action->isActive()) &&
02641 (first || lastPriority != (*it).first))
02642 {
02643 ArLog::log(ArLog::Terse, "Priority %d:", (*it).first);
02644 first = false;
02645 lastPriority = (*it).first;
02646 }
02647 action->log(false);
02648 }
02649 }
02650
02651 AREXPORT ArResolver *ArRobot::getResolver(void)
02652 {
02653 return myResolver;
02654 }
02655
02656 AREXPORT void ArRobot::setResolver(ArResolver *resolver)
02657 {
02658 if (myOwnTheResolver)
02659 {
02660 delete myResolver;
02661 myResolver = NULL;
02662 }
02663
02664 myResolver = resolver;
02665 }
02666
02678 AREXPORT void ArRobot::stateReflector(void)
02679 {
02680 short transVal;
02681 short transVal2;
02682 short maxVel;
02683 short maxNegVel;
02684 double maxTransVel;
02685 double maxNegTransVel;
02686 double maxRotVel;
02687 double transAccel;
02688 double transDecel;
02689 short rotVal;
02690 double rotAccel;
02691 double rotDecel;
02692 bool rotStopped = false;
02693 bool rotHeading = false;
02694 double encTh;
02695 double rawTh;
02696
02697
02698 if (!myIsConnected)
02699 return;
02700
02701 myTryingToMove = false;
02702
02703
02704 if ((myTransType != TRANS_NONE && myDirectPrecedenceTime == 0) ||
02705 (myTransType != TRANS_NONE && myDirectPrecedenceTime != 0 &&
02706 myTransSetTime.mSecSince() < myDirectPrecedenceTime))
02707 {
02708 myActionTransSet = false;
02709 transVal = ArMath::roundShort(myTransVal);
02710 transVal2 = 0;
02711
02712 if (hasSettableVelMaxes() &&
02713 ArMath::fabs(myLastSentTransVelMax - myTransVelMax) >= 1)
02714 {
02715 comInt(ArCommands::SETV,
02716 ArMath::roundShort(myTransVelMax));
02717 myLastSentTransVelMax = myTransVelMax;
02718 if (myLogMovementSent)
02719 ArLog::log(ArLog::Normal, "Non-action trans max vel of %d",
02720 ArMath::roundShort(myTransVelMax));
02721 }
02722
02723 if (hasSettableAccsDecs() && ArMath::fabs(myTransAccel) > 1 &&
02724 ArMath::fabs(myLastSentTransAccel - myTransAccel) >= 1)
02725 {
02726 comInt(ArCommands::SETA,
02727 ArMath::roundShort(myTransAccel));
02728 myLastSentTransAccel = myTransAccel;
02729 if (myLogMovementSent)
02730 ArLog::log(ArLog::Normal, "Non-action trans accel of %d",
02731 ArMath::roundShort(myTransAccel));
02732 }
02733
02734 if (hasSettableAccsDecs() && ArMath::fabs(myTransDecel) > 1 &&
02735 ArMath::fabs(myLastSentTransDecel - myTransDecel) >= 1)
02736 {
02737 comInt(ArCommands::SETA,
02738 -ArMath::roundShort(myTransDecel));
02739 myLastSentTransDecel = myTransDecel;
02740 if (myLogMovementSent)
02741 ArLog::log(ArLog::Normal, "Non-action trans decel of %d",
02742 -ArMath::roundShort(myTransDecel));
02743 }
02744
02745 if (myTransType == TRANS_VEL)
02746 {
02747 maxVel = ArMath::roundShort(myTransVelMax);
02748 if (transVal > maxVel)
02749 transVal = maxVel;
02750 if (transVal < -maxVel)
02751 transVal = -maxVel;
02752 if (myLastTransVal != transVal || myLastTransType != myTransType ||
02753 (myLastTransSent.mSecSince() >= myStateReflectionRefreshTime))
02754 {
02755 comInt(ArCommands::VEL, ArMath::roundShort(transVal));
02756 myLastTransSent.setToNow();
02757 if (myLogMovementSent)
02758 ArLog::log(ArLog::Normal, "Non-action trans vel of %d",
02759 ArMath::roundShort(transVal));
02760
02761 }
02762 if (fabs((double)transVal) > (double).5)
02763 myTryingToMove = true;
02764 }
02765 else if (myTransType == TRANS_VEL2)
02766 {
02767 if (ArMath::roundShort(myTransVal/myParams->getVel2Divisor()) > 128)
02768 transVal = 128;
02769 else if (ArMath::roundShort(myTransVal/myParams->getVel2Divisor()) < -128)
02770 transVal = -128;
02771 else
02772 transVal = ArMath::roundShort(myTransVal/myParams->getVel2Divisor());
02773 if (ArMath::roundShort(myTransVal2/myParams->getVel2Divisor()) > 128)
02774 transVal2 = 128;
02775 else if (ArMath::roundShort(myTransVal2/myParams->getVel2Divisor()) < -128)
02776 transVal2 = -128;
02777 else
02778 transVal2 = ArMath::roundShort(myTransVal2/myParams->getVel2Divisor());
02779 if (myLastTransVal != transVal || myLastTransVal2 != transVal2 ||
02780 myLastTransType != myTransType ||
02781 (myLastTransSent.mSecSince() >= myStateReflectionRefreshTime))
02782 {
02783 com2Bytes(ArCommands::VEL2, transVal, transVal2);
02784 myLastTransSent.setToNow();
02785 if (myLogMovementSent)
02786 ArLog::log(ArLog::Normal, "Non-action vel2 of %d %d",
02787 transVal, transVal2);
02788
02789 }
02790 if (fabs((double)transVal) > (double).5 || fabs((double)transVal2) > (double).5)
02791 myTryingToMove = true;
02792 }
02793 else if (myTransType == TRANS_DIST_NEW || myTransType == TRANS_DIST)
02794 {
02795
02796 if (!myParams->hasMoveCommand())
02797 {
02798 double distGone;
02799 double distToGo;
02800 double vel;
02801
02802 myTransType = TRANS_DIST;
02803 distGone = myTransDistStart.findDistanceTo(getPose());
02804 distToGo = fabs(fabs(myTransVal) - distGone);
02805 if (distGone > fabs(myTransVal) ||
02806 (distToGo < 10 && fabs(getVel()) < 30))
02807 {
02808 comInt(ArCommands::VEL, 0);
02809 myTransType = TRANS_VEL;
02810 myTransVal = 0;
02811 }
02812 else
02813 myTryingToMove = true;
02814 vel = sqrt(distToGo * 200 * 2);
02815 if (vel > getTransVelMax())
02816 vel = getTransVelMax();
02817 if (myTransVal < 0)
02818 vel *= -1;
02819 comInt(ArCommands::VEL, ArMath::roundShort(vel));
02820 if (myLogMovementSent)
02821 ArLog::log(ArLog::Normal, "Non-action move-helper of %d",
02822 ArMath::roundShort(vel));
02823 }
02824 else if (myParams->hasMoveCommand() && myTransType == TRANS_DIST_NEW)
02825 {
02826 comInt(ArCommands::MOVE, transVal);
02827 myLastTransSent.setToNow();
02828 myTransType = TRANS_DIST;
02829 if (myLogMovementSent)
02830 ArLog::log(ArLog::Normal, "Non-action move of %d",
02831 transVal);
02832 myTryingToMove = true;
02833 }
02834 else if (myTransType == TRANS_DIST &&
02835 (myLastTransSent.mSecSince() >= myStateReflectionRefreshTime))
02836 {
02837 com(0);
02838 myLastPulseSent.setToNow();
02839 myLastTransSent.setToNow();
02840
02841 if (myLogMovementSent)
02842 ArLog::log(ArLog::Normal, "Non-action pulse for dist");
02843 }
02844
02845 }
02846 else if (myTransType == TRANS_IGNORE)
02847 {
02848
02849 }
02850 else
02851 ArLog::log(ArLog::Terse,
02852 "ArRobot::stateReflector: Invalid translational type %d.",
02853 myTransType);
02854 myLastTransVal = transVal;
02855 myLastTransVal2 = transVal2;
02856 myLastTransType = myTransType;
02857 }
02858 else
02859 {
02860 if (hasSettableVelMaxes() &&
02861 ArMath::fabs(myLastSentTransVelMax - myTransVelMax) >= 1)
02862 {
02863 comInt(ArCommands::SETV,
02864 ArMath::roundShort(myTransVelMax));
02865 myLastSentTransVelMax = myTransVelMax;
02866 if (myLogMovementSent)
02867 ArLog::log(ArLog::Normal, "Action-but-robot trans max vel of %d",
02868 ArMath::roundShort(myTransVelMax));
02869 }
02870
02871
02872 if (myActionDesired.getTransAccelStrength() >=
02873 ArActionDesired::MIN_STRENGTH)
02874 {
02875 transAccel = ArMath::roundShort(myActionDesired.getTransAccel());
02876 if (hasSettableAccsDecs() && ArMath::fabs(transAccel) > 1 &&
02877 ArMath::fabs(myLastSentTransAccel - transAccel) >= 1)
02878 {
02879 comInt(ArCommands::SETA,
02880 ArMath::roundShort(transAccel));
02881 myLastSentTransAccel = transAccel;
02882 if (myLogMovementSent)
02883 ArLog::log(ArLog::Normal, "Action trans accel of %d",
02884 ArMath::roundShort(transAccel));
02885 }
02886 }
02887 else if (hasSettableAccsDecs() && ArMath::fabs(myTransAccel) > 1 &&
02888 ArMath::fabs(myLastSentTransAccel - myTransAccel) >= 1)
02889 {
02890 comInt(ArCommands::SETA,
02891 ArMath::roundShort(myTransAccel));
02892 myLastSentTransAccel = myTransAccel;
02893 if (myLogMovementSent)
02894 ArLog::log(ArLog::Normal, "Action-but-robot trans accel of %d",
02895 ArMath::roundShort(myTransAccel));
02896 }
02897
02898 if (myActionDesired.getTransDecelStrength() >=
02899 ArActionDesired::MIN_STRENGTH)
02900 {
02901 transDecel = ArMath::roundShort(myActionDesired.getTransDecel());
02902 if (hasSettableAccsDecs() && ArMath::fabs(transDecel) > 1 &&
02903 ArMath::fabs(myLastSentTransDecel - transDecel) >= 1)
02904 {
02905 comInt(ArCommands::SETA,
02906 -ArMath::roundShort(transDecel));
02907 myLastSentTransDecel = transDecel;
02908 if (myLogMovementSent)
02909 ArLog::log(ArLog::Normal, "Action trans decel of %d",
02910 -ArMath::roundShort(transDecel));
02911 }
02912 }
02913 else if (hasSettableAccsDecs() && ArMath::fabs(myTransDecel) > 1 &&
02914 ArMath::fabs(myLastSentTransDecel - myTransDecel) >= 1)
02915 {
02916 comInt(ArCommands::SETA,
02917 -ArMath::roundShort(myTransDecel));
02918 myLastSentTransDecel = myTransDecel;
02919 if (myLogMovementSent)
02920 ArLog::log(ArLog::Normal, "Action-but-robot trans decel of %d",
02921 -ArMath::roundShort(myTransDecel));
02922 }
02923
02924 if (myActionDesired.getMaxVelStrength() >= ArActionDesired::MIN_STRENGTH)
02925 {
02926 maxTransVel = myActionDesired.getMaxVel();
02927 if (maxTransVel > myTransVelMax)
02928 maxTransVel = myTransVelMax;
02929 }
02930 else
02931 maxTransVel = myTransVelMax;
02932
02933 if (myActionDesired.getMaxNegVelStrength() >=
02934 ArActionDesired::MIN_STRENGTH)
02935 {
02936 maxNegTransVel = -ArMath::fabs(myActionDesired.getMaxNegVel());
02937 if (maxNegTransVel < -myTransVelMax)
02938 maxNegTransVel = -myTransVelMax;
02939 }
02940 else
02941 maxNegTransVel = -myTransVelMax;
02942
02943 if (myActionDesired.getVelStrength() >= ArActionDesired::MIN_STRENGTH)
02944 {
02945 transVal = ArMath::roundShort(myActionDesired.getVel());
02946 myActionTransSet = true;
02947 }
02948 else
02949 {
02950 transVal = myLastActionTransVal;
02951 }
02952
02953 if (fabs((double)transVal) > (double).5)
02954 myTryingToMove = true;
02955
02956 maxVel = ArMath::roundShort(maxTransVel);
02957 maxNegVel = ArMath::roundShort(maxNegTransVel);
02958 if (transVal > maxVel)
02959 transVal = maxVel;
02960 if (transVal < maxNegVel)
02961 transVal = maxNegVel;
02962
02963 if (myActionTransSet &&
02964 (myLastTransSent.mSecSince() >= myStateReflectionRefreshTime ||
02965 transVal != myLastActionTransVal))
02966 {
02967 comInt(ArCommands::VEL, ArMath::roundShort(transVal));
02968 myLastTransSent.setToNow();
02969 if (myLogMovementSent)
02970 ArLog::log(ArLog::Normal, "Action trans vel of %d",
02971 ArMath::roundShort(transVal));
02972 }
02973 myLastActionTransVal = transVal;
02974 }
02975
02976
02977 if ((myRotType != ROT_NONE && myDirectPrecedenceTime == 0) ||
02978 (myRotType != ROT_NONE && myDirectPrecedenceTime != 0 &&
02979 myRotSetTime.mSecSince() < myDirectPrecedenceTime))
02980 {
02981 if (hasSettableVelMaxes() &&
02982 ArMath::fabs(myLastSentRotVelMax - myRotVelMax) >= 1)
02983 {
02984 comInt(ArCommands::SETRV,
02985 ArMath::roundShort(myRotVelMax));
02986 myLastSentRotVelMax = myRotVelMax;
02987 }
02988 if (hasSettableAccsDecs() && ArMath::fabs(myRotAccel) > 1 &&
02989 ArMath::fabs(myLastSentRotAccel - myRotAccel) >= 1)
02990 {
02991 comInt(ArCommands::SETRA,
02992 ArMath::roundShort(myRotAccel));
02993 myLastSentRotAccel = myRotAccel;
02994 if (myLogMovementSent)
02995 ArLog::log(ArLog::Normal, "%25sNon-action rot accel of %d", "",
02996 ArMath::roundShort(myRotAccel));
02997 }
02998 if (hasSettableAccsDecs() && ArMath::fabs(myRotDecel) > 1 &&
02999 ArMath::fabs(myLastSentRotDecel - myRotDecel) >= 1)
03000 {
03001 comInt(ArCommands::SETRA,
03002 -ArMath::roundShort(myRotDecel));
03003 myLastSentRotDecel = myRotDecel;
03004 if (myLogMovementSent)
03005 ArLog::log(ArLog::Normal, "%25sNon-action rot decel of %d", "",
03006 -ArMath::roundShort(myRotDecel));
03007 }
03008
03009 myActionRotSet = false;
03010 rotVal = ArMath::roundShort(myRotVal);
03011 if (myRotType == ROT_HEADING)
03012 {
03013 encTh = ArMath::subAngle(myRotVal, myEncoderTransform.getTh());
03014 rawTh = ArMath::addAngle(encTh,
03015 ArMath::subAngle(myRawEncoderPose.getTh(),
03016 myEncoderPose.getTh()));
03017 rotVal = ArMath::roundShort(rawTh);
03018
03019
03020
03021
03022 if (myLastRotVal != rotVal || myLastRotType != myRotType ||
03023 fabs(ArMath::subAngle(rotVal, getTh())) > 1 ||
03024 (myLastRotSent.mSecSince() >= myStateReflectionRefreshTime))
03025 {
03026 comInt(ArCommands::HEAD, rotVal);
03027 myLastRotSent.setToNow();
03028
03029 if (myLogMovementSent)
03030 ArLog::log(ArLog::Normal,
03031 "%25sNon-action rot heading of %d (encoder %d, raw %d)",
03032 "",
03033 ArMath::roundShort(myRotVal),
03034 ArMath::roundShort(encTh),
03035 ArMath::roundShort(rotVal));
03036 }
03037 if (fabs(ArMath::subAngle(rotVal, getTh())) > 1)
03038 myTryingToMove = true;
03039 }
03040 else if (myRotType == ROT_VEL)
03041 {
03042 if (myLastRotVal != rotVal || myLastRotType != myRotType ||
03043 (myLastRotSent.mSecSince() >= myStateReflectionRefreshTime))
03044 {
03045 comInt(ArCommands::RVEL, rotVal);
03046 myLastRotSent.setToNow();
03047 if (myLogMovementSent)
03048 ArLog::log(ArLog::Normal, "%25sNon-action rot vel of %d", "",
03049 rotVal);
03050
03051 if (fabs((double)rotVal) > (double).5)
03052 myTryingToMove = true;
03053 }
03054 }
03055 else if (myRotType == ROT_IGNORE)
03056 {
03057
03058 }
03059 else
03060 ArLog::log(ArLog::Terse,
03061 "ArRobot::stateReflector: Invalid rotation type %d.",
03062 myRotType);
03063 myLastRotVal = rotVal;
03064 myLastRotType = myRotType;
03065 }
03066 else
03067 {
03068
03069 if (myActionDesired.getMaxRotVelStrength() >=
03070 ArActionDesired::MIN_STRENGTH)
03071 {
03072 maxRotVel = myActionDesired.getMaxRotVel();
03073 if (maxRotVel > myAbsoluteMaxRotVel)
03074 maxRotVel = myAbsoluteMaxRotVel;
03075 maxRotVel = ArMath::roundShort(maxRotVel);
03076 if (ArMath::fabs(myLastSentRotVelMax - maxRotVel) >= 1)
03077 {
03078 myLastSentRotVelMax = maxRotVel;
03079 comInt(ArCommands::SETRV,
03080 ArMath::roundShort(maxRotVel));
03081 if (myLogMovementSent)
03082 ArLog::log(ArLog::Normal, "%25sAction rot vel max of %d", "",
03083 ArMath::roundShort(maxRotVel));
03084 }
03085 }
03086 else if (hasSettableVelMaxes() &&
03087 ArMath::fabs(myLastSentRotVelMax - myRotVelMax) >= 1)
03088 {
03089 comInt(ArCommands::SETRV,
03090 ArMath::roundShort(myRotVelMax));
03091 myLastSentRotVelMax = myRotVelMax;
03092 if (myLogMovementSent)
03093 ArLog::log(ArLog::Normal,
03094 "%25sAction-but-robot rot vel max of %d",
03095 "", ArMath::roundShort(myRotVelMax));
03096 }
03097
03098 if (myActionDesired.getRotAccelStrength() >= ArActionDesired::MIN_STRENGTH)
03099 {
03100 rotAccel = ArMath::roundShort(myActionDesired.getRotAccel());
03101 if (ArMath::fabs(myLastSentRotAccel - rotAccel) >= 1)
03102 {
03103 comInt(ArCommands::SETRA,
03104 ArMath::roundShort(rotAccel));
03105 myLastSentRotAccel = rotAccel;
03106 if (myLogMovementSent)
03107 ArLog::log(ArLog::Normal, "%25sAction rot accel of %d", "",
03108 ArMath::roundShort(rotAccel));
03109 }
03110 }
03111 else if (hasSettableAccsDecs() && ArMath::fabs(myRotAccel) > 1 &&
03112 ArMath::fabs(myLastSentRotAccel - myRotAccel) >= 1)
03113 {
03114 comInt(ArCommands::SETRA,
03115 ArMath::roundShort(myRotAccel));
03116 myLastSentRotAccel = myRotAccel;
03117 if (myLogMovementSent)
03118 ArLog::log(ArLog::Normal, "%25sAction-but-robot rot accel of %d",
03119 "", ArMath::roundShort(myRotAccel));
03120 }
03121
03122 if (myActionDesired.getRotDecelStrength() >= ArActionDesired::MIN_STRENGTH)
03123 {
03124 rotDecel = ArMath::roundShort(myActionDesired.getRotDecel());
03125 if (ArMath::fabs(myLastSentRotDecel - rotDecel) >= 1)
03126 {
03127 comInt(ArCommands::SETRA,
03128 -ArMath::roundShort(rotDecel));
03129 myLastSentRotDecel = rotDecel;
03130 if (myLogMovementSent)
03131 ArLog::log(ArLog::Normal, "%25sAction rot decel of %d", "",
03132 -ArMath::roundShort(rotDecel));
03133 }
03134 }
03135 else if (hasSettableAccsDecs() && ArMath::fabs(myRotDecel) > 1 &&
03136 ArMath::fabs(myLastSentRotDecel - myRotDecel) >= 1)
03137 {
03138 comInt(ArCommands::SETRA,
03139 -ArMath::roundShort(myRotDecel));
03140 myLastSentRotDecel = myRotDecel;
03141 if (myLogMovementSent)
03142 ArLog::log(ArLog::Normal, "%25sAction-but-robot rot decel of %d",
03143 "", -ArMath::roundShort(myRotDecel));
03144 }
03145
03146
03147
03148 if (myActionDesired.getDeltaHeadingStrength() >=
03149 ArActionDesired::MIN_STRENGTH)
03150 {
03151 if (ArMath::roundShort(myActionDesired.getDeltaHeading()) == 0)
03152 {
03153 rotStopped = true;
03154 rotVal = 0;
03155 rotHeading = false;
03156 }
03157 else
03158 {
03159
03160
03161 encTh = ArMath::subAngle(
03162 ArMath::addAngle(myActionDesired.getDeltaHeading(),
03163 getTh()),
03164 myEncoderTransform.getTh());
03165
03166 rawTh = ArMath::addAngle(encTh,
03167 ArMath::subAngle(myRawEncoderPose.getTh(),
03168 myEncoderPose.getTh()));
03169 rotVal = ArMath::roundShort(rawTh);
03170 rotStopped = false;
03171 rotHeading = true;
03172 myTryingToMove = true;
03173 }
03174 myActionRotSet = true;
03175 }
03176 else if (myActionDesired.getRotVelStrength() >=
03177 ArActionDesired::MIN_STRENGTH)
03178 {
03179 if (ArMath::roundShort(myActionDesired.getRotVel()) == 0)
03180 {
03181 rotStopped = true;
03182 rotVal = 0;
03183 rotHeading = false;
03184 }
03185 else
03186 {
03187 rotStopped = false;
03188 rotVal = ArMath::roundShort(myActionDesired.getRotVel());
03189 rotHeading = false;
03190 myTryingToMove = true;
03191 }
03192 myActionRotSet = true;
03193 }
03194 else
03195 {
03196 rotStopped = myLastActionRotStopped;
03197 rotVal = myLastActionRotVal;
03198 rotHeading = myLastActionRotHeading;
03199 }
03200
03201 if (myActionRotSet &&
03202 (myLastRotSent.mSecSince() > myStateReflectionRefreshTime ||
03203 rotStopped != myLastActionRotStopped ||
03204 rotVal != myLastActionRotVal ||
03205 rotHeading != myLastActionRotHeading))
03206 {
03207 if (rotStopped)
03208 {
03209 comInt(ArCommands::RVEL, 0);
03210 if (myLogMovementSent)
03211 ArLog::log(ArLog::Normal,
03212 "%25sAction rot vel of 0 (rotStopped)",
03213 "");
03214 }
03215 else if (rotHeading)
03216 {
03217 comInt(ArCommands::HEAD, rotVal);
03218 if (myLogMovementSent)
03219 ArLog::log(ArLog::Normal,
03220 "%25sAction rot heading of %d (encoder %d, raw %d)",
03221 "",
03222 ArMath::roundShort(ArMath::addAngle(
03223 myActionDesired.getDeltaHeading(),
03224 getTh())),
03225 ArMath::roundShort(encTh),
03226 ArMath::roundShort(rotVal));
03227 }
03228 else
03229 {
03230 comInt(ArCommands::RVEL, rotVal);
03231 if (myLogMovementSent)
03232 ArLog::log(ArLog::Normal, "%25sAction rot vel of %d", "",
03233 rotVal);
03234 }
03235 myLastRotSent.setToNow();
03236 }
03237
03238 myLastActionRotVal = rotVal;
03239 myLastActionRotStopped = rotStopped;
03240 myLastActionRotHeading = rotHeading;
03241 }
03242
03243 if (myLastRotSent.mSecSince() > myStateReflectionRefreshTime &&
03244 myLastTransSent.mSecSince() > myStateReflectionRefreshTime &&
03245 myLastPulseSent.mSecSince() > myStateReflectionRefreshTime)
03246 {
03247 com(ArCommands::PULSE);
03248 myLastPulseSent.setToNow();
03249 if (myLogMovementSent)
03250 ArLog::log(ArLog::Normal, "Pulse");
03251
03252 }
03253 }
03254
03255 AREXPORT bool ArRobot::handlePacket(ArRobotPacket *packet)
03256 {
03257 std::list<ArRetFunctor1<bool, ArRobotPacket *> *>::iterator it;
03258 bool handled;
03259
03260 lock();
03261
03262 myLastPacketReceivedTime = packet->getTimeReceived();
03263 if (packet->getID() == 0xff)
03264 {
03265 ArLog::log(ArLog::Terse, "Losing connection because robot was reset.");
03266 dropConnection();
03267 unlock();
03268 return false;
03269 }
03270
03271 for (handled = false, it = myPacketHandlerList.begin();
03272 it != myPacketHandlerList.end() && handled == false;
03273 it++)
03274 {
03275 if ((*it) != NULL && (*it)->invokeR(packet))
03276 handled = true;
03277 else
03278 packet->resetRead();
03279 }
03280 if (!handled)
03281 ArLog::log(ArLog::Normal,
03282 "No packet handler wanted packet with ID: 0x%x",
03283 packet->getID());
03284 unlock();
03285 return handled;
03286 }
03287
03288
03292 AREXPORT long int ArRobot::getLeftEncoder()
03293 {
03294 return myLeftEncoder;
03295 }
03296
03300 AREXPORT long int ArRobot::getRightEncoder()
03301 {
03302 return myRightEncoder;
03303 }
03304
03305
03310 AREXPORT void ArRobot::robotLocker(void)
03311 {
03312 lock();
03313 }
03314
03319 AREXPORT void ArRobot::robotUnlocker(void)
03320 {
03321 unlock();
03322 }
03323
03330 AREXPORT void ArRobot::packetHandler(void)
03331 {
03332 ArRobotPacket *packet;
03333 int timeToWait;
03334 ArTime start;
03335 bool sipHandled = false;
03336
03337 if (myAsyncConnectFlag)
03338 {
03339 lock();
03340 asyncConnectHandler(false);
03341 unlock();
03342 return;
03343 }
03344
03345 if (!isConnected())
03346 return;
03347
03348 start.setToNow();
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361 packet = NULL;
03362
03363 while ((packet = myReceiver.receivePacket(0)) != NULL)
03364 {
03365 if (myPacketsReceivedTracking)
03366 {
03367 ArLog::log(ArLog::Normal,
03368 "Rcvd: prePacket (%ld) 0x%x at %ld (%ld)",
03369 myPacketsReceivedTrackingCount,
03370 packet->getID(), start.mSecSince(),
03371 myPacketsReceivedTrackingStarted.mSecSince());
03372 myPacketsReceivedTrackingCount++;
03373 }
03374
03375 handlePacket(packet);
03376 if ((packet->getID() & 0xf0) == 0x30)
03377 sipHandled = true;
03378 packet = NULL;
03379
03380
03381 if ((getOrigRobotConfig()->hasPacketArrived() &&
03382 start.mSecSince() > getOrigRobotConfig()->getSipCycleTime() / 2) ||
03383 (!getOrigRobotConfig()->hasPacketArrived() &&
03384 (unsigned int) start.mSecSince() > myCycleTime / 2))
03385 {
03386 break;
03387 }
03388 }
03389
03390 if (isCycleChained())
03391 timeToWait = getCycleTime() * 2 - start.mSecSince();
03392
03393
03394 while (isCycleChained() && !sipHandled && isRunning() &&
03395 (packet = myReceiver.receivePacket(timeToWait)) != NULL)
03396 {
03397 if (myPacketsReceivedTracking)
03398 {
03399 ArLog::log(ArLog::Normal, "Rcvd: Packet (%ld) 0x%x at %ld (%ld)",
03400 myPacketsReceivedTrackingCount,
03401 packet->getID(), start.mSecSince(),
03402 myPacketsReceivedTrackingStarted.mSecSince());
03403 myPacketsReceivedTrackingCount++;
03404 }
03405
03406 handlePacket(packet);
03407 if ((packet->getID() & 0xf0) == 0x30)
03408 break;
03409 timeToWait = getCycleTime() * 2 - start.mSecSince();
03410 if (timeToWait < 0)
03411 timeToWait = 0;
03412 }
03413
03414 if (myTimeoutTime > 0 &&
03415 ((-myLastPacketReceivedTime.mSecTo()) > myTimeoutTime))
03416 {
03417 ArLog::log(ArLog::Terse,
03418 "Losing connection because nothing received from robot in %d milliseconds.",
03419 myTimeoutTime);
03420 dropConnection();
03421 }
03422
03423 if (myPacketsReceivedTracking)
03424 ArLog::log(ArLog::Normal, "Rcvd: time taken %ld", start.mSecSince());
03425
03426 }
03427
03435 AREXPORT void ArRobot::actionHandler(void)
03436 {
03437 ArActionDesired *actDesired;
03438
03439 if (myResolver == NULL || myActions.size() == 0 || !isConnected())
03440 return;
03441
03442 actDesired = myResolver->resolve(&myActions, this, myLogActions);
03443
03444 myActionDesired.reset();
03445
03446 if (actDesired == NULL)
03447 return;
03448
03449 myActionDesired.merge(actDesired);
03450
03451 if (myLogActions)
03452 {
03453 ArLog::log(ArLog::Normal, "Final resolved desired:");
03454 myActionDesired.log();
03455 }
03456 }
03457
03466 AREXPORT void ArRobot::setCycleWarningTime(unsigned int ms)
03467 {
03468 myCycleWarningTime = ms;
03469
03470 }
03471
03480 AREXPORT unsigned int ArRobot::getCycleWarningTime(void) const
03481 {
03482 return myCycleWarningTime;
03483 }
03484
03493 AREXPORT unsigned int ArRobot::getCycleWarningTime(void)
03494 {
03495 return myCycleWarningTime;
03496 }
03497
03505 AREXPORT void ArRobot::setCycleTime(unsigned int ms)
03506 {
03507 myCycleTime = ms;
03508 }
03509
03522 AREXPORT void ArRobot::setStabilizingTime(int mSecs)
03523 {
03524 if (mSecs > 0)
03525 myStabilizingTime = mSecs;
03526 else
03527 myStabilizingTime = 0;
03528 }
03529
03535 AREXPORT int ArRobot::getStabilizingTime(void) const
03536 {
03537 return myStabilizingTime;
03538 }
03539
03547 AREXPORT unsigned int ArRobot::getCycleTime(void) const
03548 {
03549 return myCycleTime;
03550 }
03551
03552
03553
03562 AREXPORT void ArRobot::setConnectionCycleMultiplier(unsigned int multiplier)
03563 {
03564 myConnectionCycleMultiplier = multiplier;
03565 }
03566
03574 AREXPORT unsigned int ArRobot::getConnectionCycleMultiplier(void) const
03575 {
03576 return myConnectionCycleMultiplier;
03577 }
03578
03579
03586 AREXPORT void ArRobot::loopOnce(void)
03587 {
03588 if (mySyncTaskRoot != NULL)
03589 mySyncTaskRoot->run();
03590
03591 incCounter();
03592 }
03593
03594
03595
03596
03597 AREXPORT bool ArRobot::isLeftTableSensingIRTriggered(void) const
03598 {
03599 if (myParams->haveTableSensingIR())
03600 {
03601 if (myParams->haveNewTableSensingIR() && myIODigInSize > 3)
03602 return !(getIODigIn(3) & ArUtil::BIT1);
03603 else
03604 return !(getDigIn() & ArUtil::BIT0);
03605 }
03606 return 0;
03607 }
03608
03609 AREXPORT bool ArRobot::isRightTableSensingIRTriggered(void) const
03610 {
03611 if (myParams->haveTableSensingIR())
03612 {
03613 if (myParams->haveNewTableSensingIR() && myIODigInSize > 3)
03614 return !(getIODigIn(3) & ArUtil::BIT0);
03615 else
03616 return !(getDigIn() & ArUtil::BIT1);
03617 }
03618 return 0;
03619 }
03620
03621 AREXPORT bool ArRobot::isLeftBreakBeamTriggered(void) const
03622 {
03623 if (myParams->haveTableSensingIR())
03624 {
03625 if (myParams->haveNewTableSensingIR() && myIODigInSize > 3)
03626 return !(getIODigIn(3) & ArUtil::BIT2);
03627 else
03628 return !(getDigIn() & ArUtil::BIT3);
03629 }
03630 return 0;
03631 }
03632
03633 AREXPORT bool ArRobot::isRightBreakBeamTriggered(void) const
03634 {
03635 if (myParams->haveTableSensingIR())
03636 {
03637 if (myParams->haveNewTableSensingIR() && myIODigInSize > 3)
03638 return !(getIODigIn(3) & ArUtil::BIT3);
03639 else
03640 return !(getDigIn() & ArUtil::BIT2);
03641 }
03642 return 0;
03643 }
03644
03645 AREXPORT int ArRobot::getMotorPacCount(void) const
03646 {
03647 if (myTimeLastMotorPacket == time(NULL))
03648 return myMotorPacCount;
03649 if (myTimeLastMotorPacket == time(NULL) - 1)
03650 return myMotorPacCurrentCount;
03651 return 0;
03652 }
03653
03654 AREXPORT int ArRobot::getSonarPacCount(void) const
03655 {
03656 if (myTimeLastSonarPacket == time(NULL))
03657 return mySonarPacCount;
03658 if (myTimeLastSonarPacket == time(NULL) - 1)
03659 return mySonarPacCurrentCount;
03660 return 0;
03661 }
03662
03663
03664 AREXPORT bool ArRobot::processMotorPacket(ArRobotPacket *packet)
03665 {
03666 int x, y, th, qx, qy, qth;
03667 double deltaX, deltaY, deltaTh;
03668
03669 int numReadings;
03670 int sonarNum;
03671 int sonarRange;
03672
03673 if (packet->getID() != 0x32 && packet->getID() != 0x33)
03674 return false;
03675
03676
03677 if (myTimeLastMotorPacket != time(NULL))
03678 {
03679 myTimeLastMotorPacket = time(NULL);
03680 myMotorPacCount = myMotorPacCurrentCount;
03681 myMotorPacCurrentCount = 0;
03682 }
03683 myMotorPacCurrentCount++;
03684
03685 x = (packet->bufToUByte2() & 0x7fff);
03686 y = (packet->bufToUByte2() & 0x7fff);
03687 th = packet->bufToByte2();
03688
03689 if (myFirstEncoderPose)
03690 {
03691 qx = 0;
03692 qy = 0;
03693 qth = 0;
03694 myFirstEncoderPose = false;
03695 myRawEncoderPose.setPose(
03696 myParams->getDistConvFactor() * x,
03697 myParams->getDistConvFactor() * y,
03698 ArMath::radToDeg(myParams->getAngleConvFactor() * (double)th));
03699 myEncoderPose = myRawEncoderPose;
03700 myEncoderTransform.setTransform(myEncoderPose, myGlobalPose);
03701 }
03702 else
03703 {
03704 qx = x - myLastX;
03705 qy = y - myLastY;
03706 qth = th - myLastTh;
03707 }
03708
03709
03710
03711 myLastX = x;
03712 myLastY = y;
03713 myLastTh = th;
03714
03715 if (qx > 0x1000)
03716 qx -= 0x8000;
03717 if (qx < -0x1000)
03718 qx += 0x8000;
03719
03720 if (qy > 0x1000)
03721 qy -= 0x8000;
03722 if (qy < -0x1000)
03723 qy += 0x8000;
03724
03725 deltaX = myParams->getDistConvFactor() * (double)qx;
03726 deltaY = myParams->getDistConvFactor() * (double)qy;
03727 deltaTh = ArMath::radToDeg(myParams->getAngleConvFactor() * (double)qth);
03728
03729
03730
03731
03732
03733
03734
03735 myLeftVel = myParams->getVelConvFactor() * packet->bufToByte2();
03736 myRightVel = myParams->getVelConvFactor() * packet->bufToByte2();
03737 myVel = (myLeftVel + myRightVel)/2.0;
03738
03739 myBatteryVoltage = packet->bufToUByte() * .1;
03740 myBatteryAverager.add(myBatteryVoltage);
03741 myStallValue = packet->bufToByte2();
03742
03743
03744
03745
03746 myControl = ArMath::fixAngle(ArMath::radToDeg(myParams->getAngleConvFactor() *
03747 (packet->bufToByte2() - th)));
03748 myFlags = packet->bufToUByte2();
03749 myCompass = 2*packet->bufToUByte();
03750
03751 for (numReadings = packet->bufToByte(); numReadings > 0; numReadings--)
03752 {
03753 sonarNum = packet->bufToByte();
03754 sonarRange = ArMath::roundInt(
03755 (double)packet->bufToUByte2() * myParams->getRangeConvFactor());
03756 processNewSonar(sonarNum, sonarRange, packet->getTimeReceived());
03757 }
03758
03759 if (packet->getDataLength() - packet->getDataReadLength() > 0)
03760 {
03761 myAnalogPortSelected = packet->bufToUByte2();
03762 myAnalog = packet->bufToByte();
03763 myDigIn = packet->bufToByte();
03764 myDigOut = packet->bufToByte();
03765 }
03766
03767 if (packet->getDataLength() - packet->getDataReadLength() > 0)
03768 myRealBatteryVoltage = packet->bufToUByte2() * .1;
03769 else
03770 myRealBatteryVoltage = myBatteryVoltage;
03771
03772 myRealBatteryAverager.add(myRealBatteryVoltage);
03773
03774 if (packet->getDataLength() - packet->getDataReadLength() > 0)
03775 myChargeState = (ChargeState) packet->bufToUByte();
03776 else
03777 myChargeState = CHARGING_UNKNOWN;
03778
03779 if (packet->getDataLength() - packet->getDataReadLength() > 0)
03780 myRotVel = (double)packet->bufToByte2() / 10.0;
03781 else
03782 myRotVel = ArMath::radToDeg((myRightVel - myLeftVel) / 2.0 *
03783 myParams->getDiffConvFactor());
03784
03785 if (packet->getDataLength() - packet->getDataReadLength() > 0)
03786 {
03787 myHasFaultFlags = true;
03788 myFaultFlags = packet->bufToUByte2();
03789 }
03790 else
03791 {
03792 myHasFaultFlags = false;
03793 myFaultFlags = packet->bufToUByte2();
03794 }
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841 myRawEncoderPose.setX(myRawEncoderPose.getX() + deltaX);
03842 myRawEncoderPose.setY(myRawEncoderPose.getY() + deltaY);
03843 myRawEncoderPose.setTh(myRawEncoderPose.getTh() + deltaTh);
03844
03845
03846
03847 if (myEncoderCorrectionCB != NULL)
03848 {
03849 ArPoseWithTime deltaPose(deltaX, deltaY, deltaTh,
03850 packet->getTimeReceived());
03851 deltaTh = myEncoderCorrectionCB->invokeR(deltaPose);
03852 ArTransform trans(ArPose(0, 0, myRawEncoderPose.getTh()),
03853 ArPose(0, 0,
03854 ArMath::addAngle(myEncoderPose.getTh(),
03855 deltaTh)));
03856
03857 ArPose rotatedDelta = trans.doTransform(ArPose(deltaX, deltaY, 0));
03858
03859 deltaX = rotatedDelta.getX();
03860 deltaY = rotatedDelta.getY();
03861 }
03862
03863 myEncoderPose.setTime(packet->getTimeReceived());
03864 myEncoderPose.setX(myEncoderPose.getX() + deltaX);
03865 myEncoderPose.setY(myEncoderPose.getY() + deltaY);
03866 myEncoderPose.setTh(ArMath::addAngle(myEncoderPose.getTh(), deltaTh));
03867
03868 myGlobalPose = myEncoderTransform.doTransform(myEncoderPose);
03869
03870 myOdometerDegrees += fabs(deltaTh);
03871 myOdometerDistance += sqrt(fabs(deltaX * deltaX + deltaY * deltaY));
03872
03873 if (myLogMovementReceived)
03874 ArLog::log(ArLog::Normal,
03875 "Global (%5.0f %5.0f %5.0f) Encoder (%5.0f %5.0f %5.0f) Raw (%5.0f %5.0f %5.0f) Rawest (%5d %5d %5d) Delta (%5.0f %5.0f %5.0f) Conv %5.2f",
03876 myGlobalPose.getX(), myGlobalPose.getY(),
03877 myGlobalPose.getTh(),
03878 myEncoderPose.getX(), myEncoderPose.getY(),
03879 myEncoderPose.getTh(),
03880 myRawEncoderPose.getX(), myRawEncoderPose.getY(),
03881 myRawEncoderPose.getTh(), x, y, th, deltaX, deltaY, deltaTh,
03882 myParams->getDistConvFactor());
03883
03884 if (myLogVelocitiesReceived)
03885 ArLog::log(ArLog::Normal,
03886 " TransVel: %4.0f RotVel: %4.0f(%4.0f) Heading %4.0f TransAcc %4.0f RotAcc %4.0f(%4.0f)",
03887 myVel, myRotVel, myLastHeading - getTh(), getTh(),
03888 myVel - myLastVel, myRotVel - myLastRotVel,
03889 myLastCalculatedRotVel - (myLastHeading - getTh()));
03890 myLastVel = myVel;
03891 myLastRotVel = myRotVel;
03892 myLastHeading = getTh();
03893 myLastCalculatedRotVel = myLastHeading - getTh();
03894
03895
03896
03897 myInterpolation.addReading(packet->getTimeReceived(), myGlobalPose);
03898 myEncoderInterpolation.addReading(packet->getTimeReceived(), myEncoderPose);
03899
03900 return true;
03901 }
03902
03903 AREXPORT void ArRobot::processNewSonar(char number, int range,
03904 ArTime timeReceived)
03905 {
03914 std::map<int, ArSensorReading *>::iterator it;
03915 ArSensorReading *sonar;
03916 ArTransform encoderTrans;
03917 ArPose encoderPose;
03918
03919 if ((it = mySonars.find(number)) != mySonars.end())
03920 {
03921 sonar = (*it).second;
03922 sonar->newData(range, getPose(), getEncoderPose(), getToGlobalTransform(),
03923 getCounter(), timeReceived);
03924 if (myTimeLastSonarPacket != time(NULL))
03925 {
03926 myTimeLastSonarPacket = time(NULL);
03927 mySonarPacCount = mySonarPacCurrentCount;
03928 mySonarPacCurrentCount = 0;
03929 }
03930 mySonarPacCurrentCount++;
03931 }
03932 else if (!myWarnedAboutExtraSonar)
03933 {
03934 ArLog::log(ArLog::Normal, "Robot gave back extra sonar reading! Either the parameter file for the robot or the firmware needs updating.");
03935 myWarnedAboutExtraSonar = true;
03936 }
03937 }
03938
03939
03940
03941 AREXPORT bool ArRobot::processEncoderPacket(ArRobotPacket *packet)
03942 {
03943 if (packet->getID() != 0x90)
03944 return false;
03945 myLeftEncoder = packet->bufToByte4();
03946 myRightEncoder = packet->bufToByte4();
03947 return true;
03948 }
03949
03950 AREXPORT bool ArRobot::processIOPacket(ArRobotPacket *packet)
03951 {
03952 int i, num;
03953
03954 if (packet->getID() != 0xf0)
03955 return false;
03956
03957 myLastIOPacketReceivedTime = packet->getTimeReceived();
03958
03959
03960 num = packet->bufToUByte();
03961 for (i = 0; i < num; ++i)
03962 myIODigIn[i] = packet->bufToUByte();
03963 myIODigInSize = num;
03964
03965
03966 num = packet->bufToUByte();
03967 for (i = 0; i < num; ++i)
03968 myIODigOut[i] = packet->bufToUByte();
03969 myIODigOutSize = num;
03970
03971
03972 num = packet->bufToUByte();
03973 for (i = 0; i < num; ++i)
03974 myIOAnalog[i] = packet->bufToUByte2();
03975 myIOAnalogSize = num;
03976
03977 return true;
03978 }
03979
03989 AREXPORT int ArRobot::getSonarRange(int num) const
03990 {
03991 std::map<int, ArSensorReading *>::const_iterator it;
03992
03993 if ((it = mySonars.find(num)) != mySonars.end())
03994 return (*it).second->getRange();
03995 else
03996 return -1;
03997 }
03998
04009 AREXPORT bool ArRobot::isSonarNew(int num) const
04010 {
04011 std::map<int, ArSensorReading *>::const_iterator it;
04012
04013 if ((it = mySonars.find(num)) != mySonars.end())
04014 return (*it).second->isNew(getCounter());
04015 else
04016 return false;
04017 }
04018
04031 AREXPORT ArSensorReading *ArRobot::getSonarReading(int num) const
04032 {
04033 std::map<int, ArSensorReading *>::const_iterator it;
04034
04035 if ((it = mySonars.find(num)) != mySonars.end())
04036 return (*it).second;
04037 else
04038 return NULL;
04039 }
04040
04041
04047 AREXPORT bool ArRobot::com(unsigned char command)
04048 {
04049 if (myPacketsSentTracking)
04050 ArLog::log(ArLog::Normal, "Sent: com(%d)", command);
04051 return mySender.com(command);
04052 }
04053
04060 AREXPORT bool ArRobot::comInt(unsigned char command, short int argument)
04061 {
04062 if (myPacketsSentTracking)
04063 ArLog::log(ArLog::Normal, "Sent: comInt(%d, %d)", command, argument);
04064 return mySender.comInt(command, argument);
04065 }
04066
04074 AREXPORT bool ArRobot::com2Bytes(unsigned char command, char high, char low)
04075 {
04076 if (myPacketsSentTracking)
04077 ArLog::log(ArLog::Normal, "Sent: com2Bytes(%d, %d, %d)", command,
04078 high, low);
04079 return mySender.com2Bytes(command, high, low);
04080 }
04081
04088 AREXPORT bool ArRobot::comStr(unsigned char command, const char *argument)
04089 {
04090 if (myPacketsSentTracking)
04091 ArLog::log(ArLog::Normal, "Sent: comStr(%d, '%s')", command,
04092 argument);
04093 return mySender.comStr(command, argument);
04094 }
04095
04105 AREXPORT bool ArRobot::comStrN(unsigned char command, const char *str,
04106 int size)
04107 {
04108 if (myPacketsSentTracking)
04109 {
04110 char strBuf[512];
04111 strncpy(strBuf, str, size);
04112 strBuf[size] = '\0';
04113 ArLog::log(ArLog::Normal, "Sent: comStrN(%d, '%s') (size %d)",
04114 command, strBuf, size);
04115 }
04116 return mySender.comStrN(command, str, size);
04117 }
04118
04119 AREXPORT bool ArRobot::comDataN(unsigned char command, const char* data, int size)
04120 {
04121 if(myPacketsSentTracking)
04122 {
04123 ArLog::log(ArLog::Normal, "Sent: comDataN(%d, <data...>) (size %d)", command, size);
04124 }
04125 return mySender.comDataN(command, data, size);
04126 }
04127
04128
04129 AREXPORT int ArRobot::getClosestSonarRange(double startAngle, double endAngle) const
04130 {
04131 int num;
04132 num = getClosestSonarNumber(startAngle, endAngle);
04133 if (num == -1)
04134 return -1;
04135 else
04136 return getSonarRange(num);
04137 }
04138
04139 AREXPORT int ArRobot::getClosestSonarNumber(double startAngle, double endAngle) const
04140 {
04141 int i;
04142 ArSensorReading *sonar;
04143 int closestReading;
04144 int closestSonar;
04145 bool noReadings = true;
04146
04147 for (i = 0; i < getNumSonar(); i++)
04148 {
04149 sonar = getSonarReading(i);
04150 if (sonar == NULL)
04151 {
04152 ArLog::log(ArLog::Terse, "Have an empty sonar at number %d, there should be %d sonar.", i, getNumSonar());
04153 continue;
04154 }
04155 if (ArMath::angleBetween(sonar->getSensorTh(), startAngle, endAngle))
04156 {
04157 if (noReadings)
04158 {
04159 closestReading = sonar->getRange();
04160 closestSonar = i;
04161 noReadings = false;
04162 }
04163 else if (sonar->getRange() < closestReading)
04164 {
04165 closestReading = sonar->getRange();
04166 closestSonar = i;
04167 }
04168 }
04169 }
04170
04171 if (noReadings)
04172 return -1;
04173 else
04174 return closestSonar;
04175 }
04176
04177 AREXPORT void ArRobot::addRangeDevice(ArRangeDevice *device)
04178 {
04179 device->setRobot(this);
04180 myRangeDeviceList.push_front(device);
04181 }
04182
04186 AREXPORT void ArRobot::remRangeDevice(const char *name)
04187 {
04188 std::list<ArRangeDevice *>::iterator it;
04189 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
04190 {
04191 if (strcmp(name, (*it)->getName()) == 0)
04192 {
04193 myRangeDeviceList.erase(it);
04194 return;
04195 }
04196 }
04197 }
04198
04202 AREXPORT void ArRobot::remRangeDevice(ArRangeDevice *device)
04203 {
04204 std::list<ArRangeDevice *>::iterator it;
04205 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
04206 {
04207 if ((*it) == device)
04208 {
04209 myRangeDeviceList.erase(it);
04210 return;
04211 }
04212 }
04213 }
04214
04219 AREXPORT ArRangeDevice *ArRobot::findRangeDevice(const char *name)
04220 {
04221 std::list<ArRangeDevice *>::iterator it;
04222 ArRangeDevice *device;
04223
04224 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
04225 {
04226 device = (*it);
04227 if (strcmp(name, device->getName()) == 0)
04228 {
04229 return device;
04230 }
04231 }
04232 return NULL;
04233 }
04234
04239 AREXPORT const ArRangeDevice *ArRobot::findRangeDevice(const char *name) const
04240 {
04241 std::list<ArRangeDevice *>::const_iterator it;
04242 ArRangeDevice *device;
04243
04244 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
04245 {
04246 device = (*it);
04247 if (strcmp(name, device->getName()) == 0)
04248 {
04249 return device;
04250 }
04251 }
04252 return NULL;
04253 }
04254
04261 AREXPORT std::list<ArRangeDevice *> *ArRobot::getRangeDeviceList(void)
04262 {
04263 return &myRangeDeviceList;
04264 }
04265
04269 AREXPORT bool ArRobot::hasRangeDevice(ArRangeDevice *device) const
04270 {
04271 std::list<ArRangeDevice *>::const_iterator it;
04272 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
04273 {
04274 if ((*it) == device)
04275 return true;
04276 }
04277 return false;
04278 }
04279
04294 AREXPORT double ArRobot::checkRangeDevicesCurrentPolar(
04295 double startAngle, double endAngle, double *angle,
04296 const ArRangeDevice **rangeDevice,
04297 bool useLocationDependentDevices) const
04298 {
04299 double closest = 32000;
04300 double closeAngle, tempDist, tempAngle;
04301 std::list<ArRangeDevice *>::const_iterator it;
04302 ArRangeDevice *device;
04303 bool foundOne = false;
04304 const ArRangeDevice *closestRangeDevice = NULL;
04305
04306 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
04307 {
04308 device = (*it);
04309 device->lockDevice();
04310 if (!useLocationDependentDevices && device->isLocationDependent())
04311 {
04312 device->unlockDevice();
04313 continue;
04314 }
04315 if (!foundOne ||
04316 (tempDist = device->currentReadingPolar(startAngle, endAngle,
04317 &tempAngle)) < closest)
04318 {
04319 if (!foundOne)
04320 {
04321 closest = device->currentReadingPolar(startAngle, endAngle,
04322 &closeAngle);
04323 closestRangeDevice = device;
04324 }
04325 else
04326 {
04327 closest = tempDist;
04328 closeAngle = tempAngle;
04329 closestRangeDevice = device;
04330 }
04331 foundOne = true;
04332 }
04333 device->unlockDevice();
04334 }
04335 if (!foundOne)
04336 return -1;
04337 if (angle != NULL)
04338 *angle = closeAngle;
04339 if (rangeDevice != NULL)
04340 *rangeDevice = closestRangeDevice;
04341 return closest;
04342
04343 }
04344
04345
04358 AREXPORT double ArRobot::checkRangeDevicesCumulativePolar(
04359 double startAngle, double endAngle, double *angle,
04360 const ArRangeDevice **rangeDevice,
04361 bool useLocationDependentDevices) const
04362 {
04363 double closest = 32000;
04364 double closeAngle, tempDist, tempAngle;
04365 std::list<ArRangeDevice *>::const_iterator it;
04366 ArRangeDevice *device;
04367 bool foundOne = false;
04368 const ArRangeDevice *closestRangeDevice = NULL;
04369
04370 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
04371 {
04372 device = (*it);
04373 device->lockDevice();
04374 if (!useLocationDependentDevices && device->isLocationDependent())
04375 {
04376 device->unlockDevice();
04377 continue;
04378 }
04379 if (!foundOne ||
04380 (tempDist = device->cumulativeReadingPolar(startAngle, endAngle,
04381 &tempAngle)) < closest)
04382 {
04383 if (!foundOne)
04384 {
04385 closest = device->cumulativeReadingPolar(startAngle, endAngle,
04386 &closeAngle);
04387 closestRangeDevice = device;
04388 }
04389 else
04390 {
04391 closest = tempDist;
04392 closeAngle = tempAngle;
04393 closestRangeDevice = device;
04394 }
04395 foundOne = true;
04396 }
04397 device->unlockDevice();
04398 }
04399 if (!foundOne)
04400 return -1;
04401 if (angle != NULL)
04402 *angle = closeAngle;
04403 if (rangeDevice != NULL)
04404 *rangeDevice = closestRangeDevice;
04405 return closest;
04406
04407 }
04408
04425 AREXPORT double ArRobot::checkRangeDevicesCurrentBox(
04426 double x1, double y1, double x2, double y2, ArPose *readingPos,
04427 const ArRangeDevice **rangeDevice,
04428 bool useLocationDependentDevices) const
04429 {
04430
04431 double closest = 32000;
04432 double tempDist;
04433 ArPose closestPos, tempPos;
04434 std::list<ArRangeDevice *>::const_iterator it;
04435 ArRangeDevice *device;
04436 bool foundOne = false;
04437 const ArRangeDevice *closestRangeDevice = NULL;
04438
04439 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
04440 {
04441 device = (*it);
04442 device->lockDevice();
04443 if (!useLocationDependentDevices && device->isLocationDependent())
04444 {
04445 device->unlockDevice();
04446 continue;
04447 }
04448 if (!foundOne ||
04449 (tempDist = device->currentReadingBox(x1, y1, x2, y2, &tempPos)) < closest)
04450 {
04451 if (!foundOne)
04452 {
04453 closest = device->currentReadingBox(x1, y1, x2, y2, &closestPos);
04454 closestRangeDevice = device;
04455 }
04456 else
04457 {
04458 closest = tempDist;
04459 closestPos = tempPos;
04460 closestRangeDevice = device;
04461 }
04462 foundOne = true;
04463 }
04464 device->unlockDevice();
04465 }
04466 if (!foundOne)
04467 return -1;
04468 if (readingPos != NULL)
04469 *readingPos = closestPos;
04470 if (rangeDevice != NULL)
04471 *rangeDevice = closestRangeDevice;
04472 return closest;
04473 }
04474
04491 AREXPORT double ArRobot::checkRangeDevicesCumulativeBox(
04492 double x1, double y1, double x2, double y2, ArPose *readingPos,
04493 const ArRangeDevice **rangeDevice,
04494 bool useLocationDependentDevices) const
04495 {
04496
04497 double closest = 32000;
04498 double tempDist;
04499 ArPose closestPos, tempPos;
04500 std::list<ArRangeDevice *>::const_iterator it;
04501 ArRangeDevice *device;
04502 bool foundOne = false;
04503 const ArRangeDevice *closestRangeDevice = NULL;
04504
04505 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
04506 {
04507 device = (*it);
04508 device->lockDevice();
04509 if (!useLocationDependentDevices && device->isLocationDependent())
04510 {
04511 device->unlockDevice();
04512 continue;
04513 }
04514 if (!foundOne ||
04515 (tempDist = device->cumulativeReadingBox(x1, y1, x2, y2, &tempPos)) < closest)
04516 {
04517 if (!foundOne)
04518 {
04519 closest = device->cumulativeReadingBox(x1, y1, x2, y2, &closestPos);
04520 closestRangeDevice = device;
04521 }
04522 else
04523 {
04524 closest = tempDist;
04525 closestPos = tempPos;
04526 closestRangeDevice = device;
04527 }
04528 foundOne = true;
04529 }
04530 device->unlockDevice();
04531 }
04532 if (!foundOne)
04533 return -1;
04534 if (readingPos != NULL)
04535 *readingPos = closestPos;
04536 if (rangeDevice != NULL)
04537 *rangeDevice = closestRangeDevice;
04538 return closest;
04539 }
04540
04553 AREXPORT void ArRobot::moveTo(ArPose pose, bool doCumulative)
04554 {
04555 std::list<ArRangeDevice *>::iterator it;
04556 ArSensorReading *son;
04557 int i;
04558
04559
04560
04561 ArTransform localTransform;
04562 localTransform = getToLocalTransform();
04563
04564 myEncoderTransform.setTransform(myEncoderPose, pose);
04565 myGlobalPose = myEncoderTransform.doTransform(myEncoderPose);
04566
04567 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); it++)
04568 {
04569 (*it)->lockDevice();
04570 (*it)->applyTransform(localTransform, doCumulative);
04571 (*it)->applyTransform(getToGlobalTransform(), doCumulative);
04572 (*it)->unlockDevice();
04573 }
04574
04575 for (i = 0; i < getNumSonar(); i++)
04576 {
04577 son = getSonarReading(i);
04578 if (son != NULL)
04579 {
04580 son->applyTransform(localTransform);
04581 son->applyTransform(getToGlobalTransform());
04582 }
04583 }
04584
04585
04586 }
04587
04603 AREXPORT void ArRobot::moveTo(ArPose poseTo, ArPose poseFrom,
04604 bool doCumulative)
04605 {
04606 std::list<ArRangeDevice *>::iterator it;
04607 ArSensorReading *son;
04608 int i;
04609
04610 ArPose result = myEncoderTransform.doInvTransform(poseFrom);
04611
04612
04613
04614 ArTransform localTransform;
04615 localTransform = getToLocalTransform();
04616
04617 myEncoderTransform.setTransform(result, poseTo);
04618 myGlobalPose = myEncoderTransform.doTransform(myEncoderPose);
04619
04620 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); it++)
04621 {
04622 (*it)->lockDevice();
04623 (*it)->applyTransform(localTransform, doCumulative);
04624 (*it)->applyTransform(getToGlobalTransform(), doCumulative);
04625 (*it)->unlockDevice();
04626 }
04627
04628 for (i = 0; i < getNumSonar(); i++)
04629 {
04630 son = getSonarReading(i);
04631 if (son != NULL)
04632 {
04633 son->applyTransform(localTransform);
04634 son->applyTransform(getToGlobalTransform());
04635 }
04636 }
04637
04638
04639 }
04640
04645 AREXPORT void ArRobot::setEncoderTransform(ArPose deadReconPos,
04646 ArPose globalPos)
04647 {
04648 myEncoderTransform.setTransform(deadReconPos, globalPos);
04649 myGlobalPose = myEncoderTransform.doTransform(myEncoderPose);
04650 }
04651
04655 AREXPORT void ArRobot::setEncoderTransform(ArPose transformPos)
04656 {
04657 myEncoderTransform.setTransform(transformPos);
04658 myGlobalPose = myEncoderTransform.doTransform(myEncoderPose);
04659 }
04660
04664 AREXPORT ArTransform ArRobot::getEncoderTransform(void) const
04665 {
04666 return myEncoderTransform;
04667 }
04668
04672 AREXPORT void ArRobot::setDeadReconPose(ArPose pose)
04673 {
04674 myEncoderPose.setPose(pose);
04675 myEncoderTransform.setTransform(myEncoderPose, myGlobalPose);
04676 myGlobalPose = myEncoderTransform.doTransform(myEncoderPose);
04677 }
04678
04679
04684 AREXPORT ArTransform ArRobot::getToGlobalTransform(void) const
04685 {
04686 ArTransform trans;
04687 ArPose origin(0, 0, 0);
04688 ArPose pose = getPose();
04689
04690 trans.setTransform(origin, pose);
04691 return trans;
04692 }
04693
04698 AREXPORT ArTransform ArRobot::getToLocalTransform(void) const
04699 {
04700 ArTransform trans;
04701 ArPose origin(0, 0, 0);
04702 ArPose pose = getPose();
04703
04704 trans.setTransform(pose, origin);
04705 return trans;
04706 }
04707
04715 AREXPORT void ArRobot::applyTransform(ArTransform trans, bool doCumulative)
04716 {
04717 std::list<ArRangeDevice *>::iterator it;
04718 ArSensorReading *son;
04719 int i;
04720
04721 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); it++)
04722 {
04723 (*it)->lockDevice();
04724 (*it)->applyTransform(trans, doCumulative);
04725 (*it)->unlockDevice();
04726 }
04727
04728 for (i = 0; i < getNumSonar(); i++)
04729 {
04730 son = getSonarReading(i);
04731 if (son != NULL)
04732 son->applyTransform(trans);
04733 }
04734 }
04735
04736 AREXPORT const char *ArRobot::getName(void) const
04737 {
04738 return myName.c_str();
04739 }
04740
04741 AREXPORT void ArRobot::setName(const char * name)
04742 {
04743 std::list<ArRobot *> *robotList;
04744 std::list<ArRobot *>::iterator it;
04745 int i;
04746 char buf[1024];
04747
04748 if (name != NULL)
04749 {
04750 myName = name;
04751 }
04752 else
04753 {
04754
04755
04756
04757 robotList = Aria::getRobotList();
04758 for (i = 1, it = robotList->begin(); it != robotList->end(); it++, i++)
04759 {
04760 if (this == (*it))
04761 {
04762 if (i == 1)
04763 myName = "robot";
04764 else
04765 {
04766 sprintf(buf, "robot%d", i);
04767 myName = buf;
04768 }
04769 return;
04770 }
04771 }
04772 sprintf(buf, "robot%d", robotList->size());
04773 myName = buf;
04774 }
04775 }
04776
04787 AREXPORT void ArRobot::setEncoderCorrectionCallback(
04788 ArRetFunctor1<double, ArPoseWithTime> *functor)
04789 {
04790 myEncoderCorrectionCB = functor;
04791 }
04798 AREXPORT ArRetFunctor1<double, ArPoseWithTime> *
04799 ArRobot::getEncoderCorrectionCallback(void) const
04800 {
04801 return myEncoderCorrectionCB;
04802 }
04803
04814 AREXPORT void ArRobot::setDirectMotionPrecedenceTime(int mSec)
04815 {
04816 if (mSec < 0)
04817 myDirectPrecedenceTime = 0;
04818 else
04819 myDirectPrecedenceTime = mSec;
04820 }
04821
04831 AREXPORT unsigned int ArRobot::getDirectMotionPrecedenceTime(void) const
04832 {
04833 return myDirectPrecedenceTime;
04834 }
04835
04836
04843 AREXPORT void ArRobot::clearDirectMotion(void)
04844 {
04845 myTransType = TRANS_NONE;
04846 myLastTransType = TRANS_NONE;
04847 myRotType = ROT_NONE;
04848 myLastRotType = ROT_NONE;
04849 myLastActionTransVal = 0;
04850 myLastActionRotStopped = true;
04851 myLastActionRotHeading = false;
04852 }
04853
04861 AREXPORT void ArRobot::stopStateReflection(void)
04862 {
04863 myTransType = TRANS_IGNORE;
04864 myLastTransType = TRANS_IGNORE;
04865 myRotType = ROT_IGNORE;
04866 myLastRotType = ROT_IGNORE;
04867 }
04868
04873 AREXPORT bool ArRobot::isDirectMotion(void) const
04874 {
04875 if (myTransType == TRANS_NONE && myLastTransType == TRANS_NONE &&
04876 myRotType == ROT_NONE && myLastRotType == ROT_NONE)
04877 return false;
04878 else
04879 return true;
04880 }
04881
04882
04886 AREXPORT void ArRobot::enableMotors()
04887 {
04888 comInt(ArCommands::ENABLE, 1);
04889 }
04890
04894 AREXPORT void ArRobot::disableMotors()
04895 {
04896 comInt(ArCommands::ENABLE, 0);
04897 }
04898
04902 AREXPORT void ArRobot::enableSonar()
04903 {
04904 comInt(ArCommands::SONAR, 1);
04905 }
04906
04910 AREXPORT void ArRobot::disableSonar()
04911 {
04912 comInt(ArCommands::SONAR, 0);
04913 }
04914
04915
04924 AREXPORT void ArRobot::setStateReflectionRefreshTime(int mSec)
04925 {
04926 if (mSec < 0)
04927 myStateReflectionRefreshTime = 0;
04928 else
04929 myStateReflectionRefreshTime = mSec;
04930 }
04931
04939 AREXPORT int ArRobot::getStateReflectionRefreshTime(void) const
04940 {
04941 return myStateReflectionRefreshTime;
04942 }
04943
04959 AREXPORT void ArRobot::attachKeyHandler(ArKeyHandler *keyHandler,
04960 bool exitOnEscape,
04961 bool useExitNotShutdown)
04962 {
04963 if (myKeyHandlerCB != NULL)
04964 delete myKeyHandlerCB;
04965 myKeyHandlerCB = new ArFunctorC<ArKeyHandler>(keyHandler,
04966 &ArKeyHandler::checkKeys);
04967 addSensorInterpTask("Key Handler", 50, myKeyHandlerCB);
04968
04969 myKeyHandler = keyHandler;
04970 myKeyHandlerUseExitNotShutdown = useExitNotShutdown;
04971 if (exitOnEscape)
04972 keyHandler->addKeyHandler(ArKeyHandler::ESCAPE, &myKeyHandlerExitCB);
04973 }
04974
04975 AREXPORT ArKeyHandler *ArRobot::getKeyHandler(void) const
04976 {
04977 return myKeyHandler;
04978 }
04979
04980 AREXPORT void ArRobot::keyHandlerExit(void)
04981 {
04982 ArLog::log(ArLog::Terse, "Escape was pressed, program is exiting.");
04983
04984
04985 if (myKeyHandlerUseExitNotShutdown)
04986 Aria::exit();
04987 stopRunning();
04988 unlock();
04989 Aria::shutdown();
04990 }
04991
04992 AREXPORT void ArRobot::setPacketsReceivedTracking(bool packetsReceivedTracking)
04993 {
04994 myPacketsReceivedTracking = packetsReceivedTracking;
04995 myPacketsReceivedTrackingCount = 0;
04996 myPacketsReceivedTrackingStarted.setToNow();
04997 }
04998
04999 AREXPORT void ArRobot::ariaExitCallback(void)
05000 {
05001 mySyncLoop.stopRunIfNotConnected(false);
05002 disconnect();
05003 }
05004
05010 AREXPORT ArRobot::ChargeState ArRobot::getChargeState(void) const
05011 {
05012 return myChargeState;
05013 }
05014
05015 AREXPORT void ArRobot::resetOdometer(void)
05016 {
05017 myOdometerDistance = 0;
05018 myOdometerDegrees = 0;
05019 myOdometerStart.setToNow();
05020 }