00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "ArExport.h"
00028 #include "ariaOSDef.h"
00029 #include <time.h>
00030 #include <ctype.h>
00031
00032 #include "ArRobot.h"
00033 #include "ArLog.h"
00034 #include "ArDeviceConnection.h"
00035 #include "ArTcpConnection.h"
00036 #include "ArSerialConnection.h"
00037 #include "ArLogFileConnection.h"
00038 #include "ariaUtil.h"
00039 #include "ArSocket.h"
00040 #include "ArCommands.h"
00041 #include "ArRobotTypes.h"
00042 #include "ArSignalHandler.h"
00043 #include "ArPriorityResolver.h"
00044 #include "ArAction.h"
00045 #include "ArRangeDevice.h"
00046 #include "ArRobotConfigPacketReader.h"
00047 #include "ariaInternal.h"
00048
00069 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 myPtz = NULL;
00095 myKeyHandler = NULL;
00096 myKeyHandlerCB = NULL;
00097
00098 myConn = NULL;
00099
00100 myOwnTheResolver = false;
00101
00102 myBlockingConnectRun = false;
00103 myAsyncConnectFlag = false;
00104
00105 myLogMovementSent = false;
00106 myLogMovementReceived = false;
00107 myLogVelocitiesReceived = false;
00108
00109 myPacketsSentTracking = false;
00110 myPacketsReceivedTracking = false;
00111 myPacketsReceivedTrackingCount = false;
00112 myPacketsReceivedTrackingStarted.setToNow();
00113
00114 myCycleTime = 100;
00115 myCycleWarningTime = 250;
00116 myConnectionCycleMultiplier = 2;
00117 myTimeoutTime = 8000;
00118 myStabilizingTime = 0;
00119 myCounter = 1;
00120 myResolver = NULL;
00121 myNumSonar = 0;
00122
00123 myRequestedIOPackets = false;
00124 myRequestedEncoderPackets = false;
00125 myEncoderCorrectionCB = NULL;
00126
00127 myCycleChained = true;
00128
00129 myMoveDoneDist = 40;
00130 myHeadingDoneDiff = 3;
00131
00132 myOrigRobotConfig = NULL;
00133 reset();
00134 if (normalInit)
00135 init();
00136
00137 mySyncLoop.setRobot(this);
00138
00139 if (doSigHandle)
00140 Aria::addRobot(this);
00141 if (addAriaExitCallback)
00142 {
00143 Aria::addExitCallback(&myAriaExitCB, 0);
00144 myAddedAriaExitCB = true;
00145 }
00146 else
00147 {
00148 myAddedAriaExitCB = false;
00149 }
00150 }
00151
00152
00153
00154 ArRobot::~ArRobot()
00155 {
00156 ArResolver::ActionMap::iterator it;
00157
00158 stopRunning();
00159 delete mySyncTaskRoot;
00160 ArUtil::deleteSetPairs(mySonars.begin(), mySonars.end());
00161 Aria::delRobot(this);
00162
00163 if (myKeyHandlerCB != NULL)
00164 delete myKeyHandlerCB;
00165
00166 for (it = myActions.begin(); it != myActions.end(); ++it)
00167 {
00168 (*it).second->setRobot(NULL);
00169 }
00170 }
00171
00172
00177 void ArRobot::init(void)
00178 {
00179 setUpPacketHandlers();
00180 setUpSyncList();
00181 myOwnTheResolver = true;
00182 myResolver = new ArPriorityResolver;
00183 }
00184
00195 void ArRobot::run(bool stopRunIfNotConnected)
00196 {
00197 if (mySyncLoop.getRunning())
00198 {
00199 ArLog::log(ArLog::Terse,
00200 "The robot is already running, cannot run it again.");
00201 return;
00202 }
00203 mySyncLoop.setRunning(true);
00204 mySyncLoop.stopRunIfNotConnected(stopRunIfNotConnected);
00205 mySyncLoop.runInThisThread();
00206 }
00207
00213 bool ArRobot::isRunning(void) const
00214 {
00215 return mySyncLoop.getRunning();
00216 }
00217
00227 void ArRobot::runAsync(bool stopRunIfNotConnected)
00228 {
00229 if (mySyncLoop.getRunning())
00230 {
00231 ArLog::log(ArLog::Terse,
00232 "The robot is already running, cannot run it again.");
00233 return;
00234 }
00235 mySyncLoop.stopRunIfNotConnected(stopRunIfNotConnected);
00236
00237
00238 mySyncLoop.create(true, false);
00239 }
00240
00249 void ArRobot::stopRunning(bool doDisconnect)
00250 {
00251 if (myKeyHandler != NULL)
00252 myKeyHandler->restore();
00253 mySyncLoop.stopRunning();
00254 myBlockingConnectRun = false;
00255 if (doDisconnect && (isConnected() || myIsStabilizing))
00256 {
00257 waitForRunExit();
00258 disconnect();
00259 }
00260 wakeAllWaitingThreads();
00261 }
00262
00263 void ArRobot::setUpSyncList(void)
00264 {
00265 mySyncTaskRoot = new ArSyncTask("SyncTasks");
00266 mySyncTaskRoot->setWarningTimeCB(&myGetCycleWarningTimeCB);
00267 mySyncTaskRoot->setNoTimeWarningCB(&myGetNoTimeWarningThisCycleCB);
00268 mySyncTaskRoot->addNewLeaf("Packet Handler", 85, &myPacketHandlerCB);
00269 mySyncTaskRoot->addNewLeaf("Robot Locker", 70, &myRobotLockerCB);
00270 mySyncTaskRoot->addNewBranch("Sensor Interp", 65);
00271 mySyncTaskRoot->addNewLeaf("Action Handler", 55, &myActionHandlerCB);
00272 mySyncTaskRoot->addNewLeaf("State Reflector", 45, &myStateReflectorCB);
00273 mySyncTaskRoot->addNewBranch("User Tasks", 25);
00274 mySyncTaskRoot->addNewLeaf("Robot Unlocker", 20, &myRobotUnlockerCB);
00275 }
00276
00277
00278 void ArRobot::setUpPacketHandlers(void)
00279 {
00280 addPacketHandler(&myMotorPacketCB, ArListPos::FIRST);
00281 addPacketHandler(&myEncoderPacketCB, ArListPos::LAST);
00282 addPacketHandler(&myIOPacketCB, ArListPos::LAST);
00283 }
00284
00285 void ArRobot::reset(void)
00286 {
00287 myInterpolation.reset();
00288 myEncoderInterpolation.reset();
00289 if (myOrigRobotConfig != NULL)
00290 delete myOrigRobotConfig;
00291 myOrigRobotConfig = new ArRobotConfigPacketReader(this, true);
00292 myFirstEncoderPose = true;
00293
00294
00295
00296
00297
00298 myTransVelMax = 0;
00299 myTransAccel = 0;
00300 myTransDecel = 0;
00301 myRotVelMax = 0;
00302 myRotAccel = 0;
00303 myRotDecel = 0;
00304
00305 myLeftVel = 0;
00306 myRightVel = 0;
00307 myBatteryVoltage = 13;
00308 myBatteryAverager.clear();
00309 myBatteryAverager.add(myBatteryVoltage);
00310 myStallValue = 0;
00311 myControl = 0;
00312 myFlags = 0;
00313 myCompass = 0;
00314 myAnalogPortSelected = 0;
00315 myAnalog = 0;
00316 myDigIn = 0;
00317 myDigOut = 0;
00318 myIOAnalogSize = 0;
00319 myIODigInSize = 0;
00320 myIODigOutSize = 0;
00321 myLastIOPacketReceivedTime.setSec(0);
00322 myLastIOPacketReceivedTime.setMSec(0);
00323 myVel = 0;
00324 myRotVel = 0;
00325 myChargeState = CHARGING_UNKNOWN;
00326 myLastX = 0;
00327 myLastY = 0;
00328 myLastTh = 0;
00329 mySentPulse = false;
00330 myIsConnected = false;
00331 myIsStabilizing = false;
00332
00333 myTransVal = 0;
00334 myTransVal2 = 0;
00335 myTransType = TRANS_NONE;
00336 myLastTransVal = 0;
00337 myLastTransVal2 = 0;
00338 myLastTransType = TRANS_NONE;
00339 myLastTransSent.setToNow();
00340 myActionTransSet = false;
00341 myLastActionRotStopped = false;
00342 myLastActionRotHeading = false;
00343
00344 myRotVal = 0;
00345 myLastRotVal = 0;
00346 myRotType = ROT_NONE;
00347 myLastRotType = ROT_NONE;
00348 myLastRotSent.setToNow();
00349 myActionRotSet = false;
00350
00351 myLastPulseSent.setToNow();
00352
00353 myDirectPrecedenceTime = 0;
00354 myStateReflectionRefreshTime = 500;
00355
00356 myActionDesired.reset();
00357
00358 myMotorPacCurrentCount = 0;
00359 myMotorPacCount = 0;
00360 myTimeLastMotorPacket = 0;
00361
00362 mySonarPacCurrentCount = 0;
00363 mySonarPacCount = 0;
00364 myTimeLastSonarPacket = 0;
00365
00366 myLeftEncoder = 0;
00367 myRightEncoder = 0;
00368
00369 myWarnedAboutExtraSonar = false;
00370 }
00371
00372 void ArRobot::setTransVelMax(double vel)
00373 {
00374 if (vel > myAbsoluteMaxTransVel)
00375 {
00376 ArLog::log(ArLog::Terse, "ArRobot: transVelMax of %g is over the absolute max of %g, ignoring", vel, myAbsoluteMaxTransVel);
00377 return;
00378 }
00379 myTransVelMax = vel;
00380 }
00381
00382 void ArRobot::setTransAccel(double acc)
00383 {
00384 myTransAccel = acc;
00385 }
00386
00387 void ArRobot::setTransDecel(double decel)
00388 {
00389 myTransDecel = ArMath::fabs(decel);
00390 }
00391
00392 void ArRobot::setRotVelMax(double vel)
00393 {
00394 if (vel > myAbsoluteMaxRotVel)
00395 {
00396 ArLog::log(ArLog::Terse, "ArRobot: rotVelMax of %g is over the absolute max of %g, ignoring", vel, myAbsoluteMaxRotVel);
00397 return;
00398 }
00399 myRotVelMax = vel;
00400 }
00401
00402 void ArRobot::setRotAccel(double acc)
00403 {
00404 myRotAccel = acc;
00405 }
00406
00407 void ArRobot::setRotDecel(double decel)
00408 {
00409 myRotDecel = ArMath::fabs(decel);
00410 }
00411
00412 double ArRobot::getTransVelMax(void) const
00413 {
00414 return myTransVelMax;
00415 }
00416
00417 double ArRobot::getTransAccel(void) const
00418 {
00419 return myTransAccel;
00420 }
00421
00422 double ArRobot::getTransDecel(void) const
00423 {
00424 return myTransDecel;
00425 }
00426
00427 double ArRobot::getRotVelMax(void) const
00428 {
00429 return myRotVelMax;
00430 }
00431
00432 double ArRobot::getRotAccel(void) const
00433 {
00434 return myRotAccel;
00435 }
00436
00437 double ArRobot::getRotDecel(void) const
00438 {
00439 return myRotDecel;
00440 }
00441
00450 void ArRobot::setDeviceConnection(ArDeviceConnection *connection)
00451 {
00452 myConn = connection;
00453 mySender.setDeviceConnection(myConn);
00454 myReceiver.setDeviceConnection(myConn);
00455 }
00456
00465 ArDeviceConnection *ArRobot::getDeviceConnection(void) const
00466 {
00467 return myConn;
00468 }
00469
00480 void ArRobot::setConnectionTimeoutTime(int mSecs)
00481 {
00482 if (mSecs > 0)
00483 myTimeoutTime = mSecs;
00484 else
00485 myTimeoutTime = 0;
00486 }
00487
00494 int ArRobot::getConnectionTimeoutTime(void) const
00495 {
00496 return myTimeoutTime;
00497 }
00498
00504 ArTime ArRobot::getLastPacketTime(void) const
00505 {
00506 return myLastPacketReceivedTime;
00507 }
00539 bool ArRobot::asyncConnect(void)
00540 {
00541 if (!mySyncLoop.getRunning() || isConnected())
00542 return false;
00543
00544 myAsyncConnectFlag = true;
00545 myBlockingConnectRun = false;
00546 myAsyncConnectState = -1;
00547 return true;
00548 }
00549
00580 bool ArRobot::blockingConnect(void)
00581 {
00582 int ret = 0;
00583
00584 lock();
00585 if (myIsConnected)
00586 disconnect();
00587 myBlockingConnectRun = true;
00588 myAsyncConnectState = -1;
00589 while ((ret = asyncConnectHandler(true)) == 0 && myBlockingConnectRun)
00590 ArUtil::sleep(ArMath::roundInt(getCycleTime() * .80));
00591 unlock();
00592 if (ret == 1)
00593 return true;
00594 else
00595 return false;
00596 }
00597
00613 int ArRobot::asyncConnectHandler(bool tryHarderToConnect)
00614 {
00615 int ret = 0;
00616 ArRobotPacket *packet;
00617 ArRobotPacket *tempPacket = NULL;
00618 char robotSubType[255];
00619 int i;
00620 int len;
00621 std::string str;
00622 ArTime endTime;
00623 int timeToWait;
00624 ArSerialConnection *serConn;
00625
00626 endTime.setToNow();
00627 endTime.addMSec(getCycleTime()*myConnectionCycleMultiplier);
00628
00629 myNoTimeWarningThisCycle = true;
00630
00631
00632 if (myAsyncConnectState == -1)
00633 {
00634 myAsyncConnectSentChangeBaud = false;
00635 myAsyncConnectNoPacketCount = 0;
00636 myAsyncConnectTimesTried = 0;
00637 reset();
00638 if (myConn == NULL)
00639 {
00640 ArLog::log(ArLog::Terse, "Cannot connect, no connection has been set.");
00641 failedConnect();
00642 return 2;
00643 }
00644
00645 if (myConn->getStatus() != ArDeviceConnection::STATUS_OPEN)
00646 {
00647 if (!myConn->openSimple())
00648 {
00649
00650
00651 ArLog::log(ArLog::Terse,
00652 "Could not connect, because open on the device connection failed.");
00653 failedConnect();
00654 return 2;
00655 }
00656 }
00657
00658
00659 if (dynamic_cast<ArLogFileConnection *>(myConn))
00660 {
00661 ArLogFileConnection *con = dynamic_cast<ArLogFileConnection *>(myConn);
00662 myRobotName = con->myName;
00663 myRobotType = con->myType;
00664 myRobotSubType = con->mySubtype;
00665 if (con->havePose)
00666 moveTo(con->myPose);
00667 setCycleChained(false);
00668 madeConnection();
00669 finishedConnection();
00670 return 1;
00671 }
00672
00673
00674 if (dynamic_cast<ArSerialConnection *>(myConn))
00675 {
00676 myConn->write("WMS2\15", strlen("WMS2\15"));
00677 }
00678
00679 while ( endTime.mSecTo() > 0 && myReceiver.receivePacket(0) != NULL);
00680
00681 myAsyncConnectState = 0;
00682 return 0;
00683 }
00684
00685 if (myAsyncConnectState >= 3)
00686 {
00687 bool handled;
00688 std::list<ArRetFunctor1<bool, ArRobotPacket *> *>::iterator it;
00689 while ((packet = myReceiver.receivePacket(0)) != NULL)
00690 {
00691
00692 for (handled = false, it = myPacketHandlerList.begin();
00693 it != myPacketHandlerList.end() && handled == false;
00694 it++)
00695 {
00696 if ((*it) != NULL && (*it)->invokeR(packet))
00697 handled = true;
00698 else
00699 packet->resetRead();
00700 }
00701 }
00702 }
00703
00704 if (myAsyncConnectState == 3)
00705 {
00706
00707 if (!myOrigRobotConfig->hasPacketArrived())
00708 {
00709 myOrigRobotConfig->requestPacket();
00710 }
00711
00712
00713 if (myOrigRobotConfig->hasPacketArrived() ||
00714 myAsyncStartedConnection.mSecSince() > 1000)
00715 {
00716 bool gotConfig;
00717
00718 if (myOrigRobotConfig->hasPacketArrived())
00719 {
00720 gotConfig = true;
00721 setAbsoluteMaxTransVel(myOrigRobotConfig->getTransVelTop());
00722 setAbsoluteMaxRotVel(myOrigRobotConfig->getRotVelTop());
00723 setTransVelMax(myOrigRobotConfig->getTransVelMax());
00724 setTransAccel(myOrigRobotConfig->getTransAccel());
00725 setTransDecel(myOrigRobotConfig->getTransDecel());
00726 setRotVelMax(myOrigRobotConfig->getRotVelMax());
00727 setRotAccel(myOrigRobotConfig->getRotAccel());
00728 setRotDecel(myOrigRobotConfig->getRotDecel());
00729 }
00730
00731 else
00732 {
00733 gotConfig = false;
00734 setAbsoluteMaxTransVel(myParams->getAbsoluteMaxVelocity());
00735 setAbsoluteMaxRotVel(myParams->getAbsoluteMaxRotVelocity());
00736 }
00737
00738
00739
00740
00741 if (ArMath::fabs(myParams->getTransVelMax()) > 1)
00742 setTransVelMax(myParams->getTransVelMax());
00743 else if (!gotConfig)
00744 setTransVelMax(myParams->getAbsoluteMaxVelocity());
00745 if (ArMath::fabs(myParams->getRotVelMax()) > 1)
00746 setRotVelMax(myParams->getRotVelMax());
00747 else if (!gotConfig)
00748 setRotVelMax(myParams->getAbsoluteMaxRotVelocity());
00749 if (ArMath::fabs(myParams->getTransAccel()) > 1)
00750 setTransAccel(myParams->getTransAccel());
00751 if (ArMath::fabs(myParams->getTransDecel()) > 1)
00752 setTransDecel(myParams->getTransDecel());
00753 if (ArMath::fabs(myParams->getRotAccel()) > 1)
00754 setRotAccel(myParams->getRotAccel());
00755 if (ArMath::fabs(myParams->getRotDecel()) > 1)
00756 setRotDecel(myParams->getRotDecel());
00757 myAsyncConnectState = 4;
00758 }
00759 else
00760 return 0;
00761 }
00762
00763 if (myAsyncConnectState == 4)
00764 {
00765 serConn = dynamic_cast<ArSerialConnection *>(myConn);
00766
00767
00768 if (!myOrigRobotConfig->hasPacketArrived() ||
00769 !myOrigRobotConfig->getResetBaud() ||
00770 serConn == NULL ||
00771 myParams->getSwitchToBaudRate() == 0)
00772 {
00773
00774 if (serConn != NULL)
00775 myAsyncConnectStartBaud = serConn->getBaud();
00776 myAsyncConnectState = 5;
00777 }
00778
00779 else if (!myAsyncConnectSentChangeBaud)
00780 {
00781
00782 if (serConn != NULL)
00783 myAsyncConnectStartBaud = serConn->getBaud();
00784
00785 int baudNum = -1;
00786
00787
00788 while ((packet = myReceiver.receivePacket(0)) != NULL);
00789 if (myParams->getSwitchToBaudRate() == 9600)
00790 baudNum = 0;
00791 else if (myParams->getSwitchToBaudRate() == 19200)
00792 baudNum = 1;
00793 else if (myParams->getSwitchToBaudRate() == 38400)
00794 baudNum = 2;
00795 else if (myParams->getSwitchToBaudRate() == 57600)
00796 baudNum = 3;
00797 else if (myParams->getSwitchToBaudRate() == 115200)
00798 baudNum = 4;
00799 else
00800 {
00801 ArLog::log(ArLog::Normal, "Warning: SwitchToBaud is set to %d baud, ignoring.",
00802 myParams->getSwitchToBaudRate());
00803 ArLog::log(ArLog::Normal, "\tGood bauds are 9600 19200 38400 56800 116200.");
00804 myAsyncConnectState = 5;
00805 baudNum = -1;
00806 return 0;
00807 }
00808 if (baudNum != -1)
00809 {
00810
00811 comInt(ArCommands::HOSTBAUD, baudNum);
00812 ArUtil::sleep(10);
00813 myAsyncConnectSentChangeBaud = true;
00814 myAsyncConnectStartedChangeBaud.setToNow();
00815 serConn->setBaud(myParams->getSwitchToBaudRate());
00816
00817 ArUtil::sleep(10);
00818 com(0);
00819 return 0;
00820 }
00821 }
00822
00823 else
00824 {
00825 packet = myReceiver.receivePacket(100);
00826 com(0);
00827
00828 if (packet != NULL)
00829 {
00830 myAsyncConnectState = 5;
00831 }
00832
00833 else if (myAsyncConnectStartedChangeBaud.mSecSince() > 900)
00834 {
00835 ArLog::log(ArLog::Verbose, "Controller did not switch to baud, reset to %d baud.", myAsyncConnectStartBaud);
00836 serConn->setBaud(myAsyncConnectStartBaud);
00837 myAsyncConnectState = 5;
00838 }
00839 else
00840 return 0;
00841 }
00842 }
00843
00844 if (myAsyncConnectState == 5)
00845 {
00846 if (!myIsStabilizing)
00847 startStabilization();
00848 if (myStabilizingTime == 0 ||
00849 myStartedStabilizing.mSecSince() > myStabilizingTime)
00850 {
00851 finishedConnection();
00852 return 1;
00853 }
00854 else
00855 return 0;
00856 }
00857
00858
00859
00860
00861 myAsyncConnectTimesTried++;
00862 ArLog::log(ArLog::Normal, "Syncing %d", myAsyncConnectState);
00863 mySender.com(myAsyncConnectState);
00864
00865 packet = myReceiver.receivePacket(1000);
00866
00867 if (packet != NULL)
00868 {
00869 ret = packet->getID();
00870
00871
00872 if (ret == 50)
00873 {
00874 ArLog::log(ArLog::Normal, "Attempting to close previous connection.");
00875 comInt(ArCommands::CLOSE,1);
00876 while (endTime.mSecTo() > 0)
00877 {
00878 timeToWait = endTime.mSecTo();
00879 if (timeToWait < 0)
00880 timeToWait = 0;
00881 tempPacket = myReceiver.receivePacket(timeToWait);
00882 if (tempPacket != NULL)
00883 ArLog::log(ArLog::Verbose, "Got in another packet!");
00884 if (tempPacket != NULL && tempPacket->getID() == 50)
00885 comInt(ArCommands::CLOSE,1);
00886 }
00887 myAsyncConnectState = 0;
00888 }
00889 else if (ret == 255)
00890 {
00891 ArLog::log(ArLog::Normal, "Attempting to correct syncCount");
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903 while ((tempPacket = myReceiver.receivePacket(0)) != NULL);
00904
00905 if (tempPacket != NULL && tempPacket->getID() == 0)
00906 myAsyncConnectState = 1;
00907 else
00908 myAsyncConnectState = 0;
00909 return 0;
00910 }
00911 else if (ret != myAsyncConnectState++)
00912 {
00913 myAsyncConnectState = 0;
00914 }
00915 }
00916 else
00917 {
00918 ArLog::log(ArLog::Normal, "No packet.");
00919 myAsyncConnectNoPacketCount++;
00920 if ((myAsyncConnectNoPacketCount > 5
00921 && myAsyncConnectNoPacketCount >= myAsyncConnectTimesTried)
00922 || (myAsyncConnectNoPacketCount > 10))
00923 {
00924 ArLog::log(ArLog::Terse, "Could not connect, no robot responding.");
00925 failedConnect();
00926 return 2;
00927 }
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958 if (myAsyncConnectNoPacketCount == 2 &&
00959 myAsyncConnectNoPacketCount >= myAsyncConnectTimesTried &&
00960 (serConn = dynamic_cast<ArSerialConnection *>(myConn)) != NULL)
00961 {
00962 int origBaud;
00963 ArLog::log(ArLog::Normal, "Trying to close possible old connection");
00964 origBaud = serConn->getBaud();
00965 serConn->setBaud(9600);
00966 comInt(ArCommands::CLOSE,1);
00967 ArUtil::sleep(3);
00968 serConn->setBaud(38400);
00969 comInt(ArCommands::CLOSE,1);
00970 ArUtil::sleep(3);
00971 serConn->setBaud(115200);
00972 comInt(ArCommands::CLOSE,1);
00973 ArUtil::sleep(3);
00974 serConn->setBaud(19200);
00975 comInt(ArCommands::CLOSE,1);
00976 ArUtil::sleep(3);
00977 serConn->setBaud(57600);
00978 comInt(ArCommands::CLOSE,1);
00979 ArUtil::sleep(3);
00980 serConn->setBaud(origBaud);
00981 }
00982
00983 if (myAsyncConnectNoPacketCount > 3)
00984 {
00985 ArLog::log(ArLog::Normal,
00986 " Robot may be connected but not open, trying to dislodge.");
00987 mySender.comInt(ArCommands::OPEN,1);
00988 }
00989
00990 myAsyncConnectState = 0;
00991 }
00992
00993
00994 if (myAsyncConnectState == 3 && packet != NULL)
00995 {
00996 char nameBuf[512];
00997 ArLog::log(ArLog::Terse, "Connected to robot.");
00998 packet->bufToStr(nameBuf, 512);
00999 myRobotName = nameBuf;
01000 ArLog::log(ArLog::Normal, "Name: %s", myRobotName.c_str());
01001 packet->bufToStr(nameBuf, 512);
01002 myRobotType = nameBuf;
01003 ArLog::log(ArLog::Normal, "Type: %s", myRobotType.c_str());
01004 packet->bufToStr(nameBuf, 512);
01005 myRobotSubType = nameBuf;
01006 strcpy(robotSubType, myRobotSubType.c_str());
01007 len = strlen(robotSubType);
01008 for (i = 0; i < len; i++)
01009 robotSubType[i] = tolower(robotSubType[i]);
01010 myRobotSubType = robotSubType;
01011 ArLog::log(ArLog::Normal, "Subtype: %s", myRobotSubType.c_str());
01012 ArUtil::sleep(getCycleTime());
01013 mySender.comInt(ArCommands::OPEN,1);
01014 if (!madeConnection())
01015 {
01016 mySender.comInt(ArCommands::CLOSE,1);
01017 failedConnect();
01018 return 2;
01019 }
01020
01021
01022
01023
01024 myAsyncStartedConnection.setToNow();
01025 return asyncConnectHandler(tryHarderToConnect);
01026 }
01027 if (myAsyncConnectTimesTried > 50)
01028 {
01029 failedConnect();
01030 return 2;
01031 }
01032 return 0;
01033 }
01034
01038 bool ArRobot::loadParamFile(const char *file)
01039 {
01040 if (myParams != NULL)
01041 delete myParams;
01042
01043 myParams = new ArRobotGeneric("");
01044 if (!myParams->parseFile(file, false, true))
01045 {
01046 ArLog::log(ArLog::Normal, "ArRobot::loadParamFile: Could not find file '%s' to load.", file);
01047 return false;
01048 }
01049 processParamFile();
01050 ArLog::log(ArLog::Normal, "Loaded robot parameters from %s.", file);
01051 return true;
01052 }
01053
01054 void ArRobot::processParamFile(void)
01055 {
01056 for (int i = 0; i < myParams->getNumSonar(); ++i)
01057 {
01058
01059
01060 if (mySonars.find(i) == mySonars.end())
01061 {
01062 mySonars[i] = new ArSensorReading(myParams->getSonarX(i),
01063 myParams->getSonarY(i),
01064 myParams->getSonarTh(i));
01065 mySonars[i]->setIgnoreThisReading(true);
01066 }
01067 else
01068 {
01069 mySonars[i]->resetSensorPosition(myParams->getSonarX(i),
01070 myParams->getSonarY(i),
01071 myParams->getSonarTh(i));
01072 mySonars[i]->setIgnoreThisReading(true);
01073 }
01074 if ((i + 1) > myNumSonar)
01075 myNumSonar = i + 1;
01076 }
01077
01078
01079 myAbsoluteMaxTransVel = myParams->getAbsoluteMaxVelocity();
01080 myAbsoluteMaxRotVel = myParams->getAbsoluteMaxRotVelocity();
01081 }
01082
01083
01084 bool ArRobot::madeConnection(void)
01085 {
01086 std::string subTypeParamName;
01087 std::string paramFileName;
01088 bool loadedSubTypeParam;
01089 bool loadedNameParam;
01090 bool hadDefault = true;
01091
01092 if (myParams != NULL)
01093 delete myParams;
01094
01095
01096 if (ArUtil::strcmp(myRobotSubType, "p2dx") == 0)
01097 myParams = new ArRobotP2DX;
01098 else if (ArUtil::strcmp(myRobotSubType, "p2ce") == 0)
01099 myParams = new ArRobotP2CE;
01100 else if (ArUtil::strcmp(myRobotSubType, "p2de") == 0)
01101 myParams = new ArRobotP2DXe;
01102 else if (ArUtil::strcmp(myRobotSubType, "p2df") == 0)
01103 myParams = new ArRobotP2DF;
01104 else if (ArUtil::strcmp(myRobotSubType, "p2d8") == 0)
01105 myParams = new ArRobotP2D8;
01106 else if (ArUtil::strcmp(myRobotSubType, "amigo") == 0)
01107 myParams = new ArRobotAmigo;
01108 else if (ArUtil::strcmp(myRobotSubType, "amigo-sh") == 0)
01109 myParams = new ArRobotAmigoSh;
01110 else if (ArUtil::strcmp(myRobotSubType, "p2at") == 0)
01111 myParams = new ArRobotP2AT;
01112 else if (ArUtil::strcmp(myRobotSubType, "p2at8") == 0)
01113 myParams = new ArRobotP2AT8;
01114 else if (ArUtil::strcmp(myRobotSubType, "p2it") == 0)
01115 myParams = new ArRobotP2IT;
01116 else if (ArUtil::strcmp(myRobotSubType, "p2pb") == 0)
01117 myParams = new ArRobotP2PB;
01118 else if (ArUtil::strcmp(myRobotSubType, "p2pp") == 0)
01119 myParams = new ArRobotP2PP;
01120 else if (ArUtil::strcmp(myRobotSubType, "p3at") == 0)
01121 myParams = new ArRobotP3AT;
01122 else if (ArUtil::strcmp(myRobotSubType, "p3dx") == 0)
01123 myParams = new ArRobotP3DX;
01124 else if (ArUtil::strcmp(myRobotSubType, "perfpb") == 0)
01125 myParams = new ArRobotPerfPB;
01126 else if (ArUtil::strcmp(myRobotSubType, "pion1m") == 0)
01127 myParams = new ArRobotPion1M;
01128 else if (ArUtil::strcmp(myRobotSubType, "pion1x") == 0)
01129 myParams = new ArRobotPion1X;
01130 else if (ArUtil::strcmp(myRobotSubType, "psos1m") == 0)
01131 myParams = new ArRobotPsos1M;
01132 else if (ArUtil::strcmp(myRobotSubType, "psos43m") == 0)
01133 myParams = new ArRobotPsos43M;
01134 else if (ArUtil::strcmp(myRobotSubType, "psos1x") == 0)
01135 myParams = new ArRobotPsos1X;
01136 else if (ArUtil::strcmp(myRobotSubType, "pionat") == 0)
01137 myParams = new ArRobotPionAT;
01138 else if (ArUtil::strcmp(myRobotSubType, "mappr") == 0)
01139 myParams = new ArRobotMapper;
01140 else if (ArUtil::strcmp(myRobotSubType, "powerbot") == 0)
01141 myParams = new ArRobotPowerBot;
01142 else if (ArUtil::strcmp(myRobotSubType, "p2d8+") == 0)
01143 myParams = new ArRobotP2D8Plus;
01144 else if (ArUtil::strcmp(myRobotSubType, "p2at8+") == 0)
01145 myParams = new ArRobotP2AT8Plus;
01146 else if (ArUtil::strcmp(myRobotSubType, "perfpb+") == 0)
01147 myParams = new ArRobotPerfPBPlus;
01148 else if (ArUtil::strcmp(myRobotSubType, "p3dx-sh") == 0)
01149 myParams = new ArRobotP3DXSH;
01150 else if (ArUtil::strcmp(myRobotSubType, "p3at-sh") == 0)
01151 myParams = new ArRobotP3ATSH;
01152 else if (ArUtil::strcmp(myRobotSubType, "p3atiw-sh") == 0)
01153 myParams = new ArRobotP3ATIWSH;
01154 else if (ArUtil::strcmp(myRobotSubType, "patrolbot-sh") == 0)
01155 myParams = new ArRobotPatrolBotSH;
01156 else if (ArUtil::strcmp(myRobotSubType, "peoplebot-sh") == 0)
01157 myParams = new ArRobotPeopleBotSH;
01158 else if (ArUtil::strcmp(myRobotSubType, "powerbot-sh") == 0)
01159 myParams = new ArRobotPowerBotSH;
01160 else if (ArUtil::strcmp(myRobotSubType, "wheelchair-sh") == 0)
01161 myParams = new ArRobotWheelchairSH;
01162 else
01163 {
01164 hadDefault = false;
01165 myParams = new ArRobotGeneric(myRobotName.c_str());
01166 }
01167
01168
01169 paramFileName = Aria::getDirectory();
01170 paramFileName += "params/";
01171 paramFileName += myRobotSubType;
01172 paramFileName += ".p";
01173 if ((loadedSubTypeParam = myParams->parseFile(paramFileName.c_str(), true, true)))
01174 ArLog::log(ArLog::Normal,
01175 "Loaded robot parameters from %s.p",
01176 myRobotSubType.c_str());
01177
01178
01179
01180
01181
01182 paramFileName = Aria::getDirectory();
01183 paramFileName += "params/";
01184 paramFileName += myRobotName;
01185 paramFileName += ".p";
01186 if ((loadedNameParam = myParams->parseFile(paramFileName.c_str(),
01187 true, true)))
01188 {
01189 if (loadedSubTypeParam)
01190 ArLog::log(ArLog::Normal,
01191 "Loaded robot parameters from %s.p on top of %s.p robot parameters",
01192 myRobotName.c_str(), myRobotSubType.c_str());
01193 else
01194 ArLog::log(ArLog::Normal, "Loaded robot parameters from %s.p",
01195 myRobotName.c_str());
01196 }
01197
01198 if (!loadedSubTypeParam && !loadedNameParam)
01199 {
01200 if (hadDefault)
01201 ArLog::log(ArLog::Normal, "Using default parameters for a %s robot",
01202 myRobotSubType.c_str());
01203 else
01204 {
01205 ArLog::log(ArLog::Terse, "Error: Have no parameters for this robot, bad configuration or out of date Aria");
01206 return false;
01207 }
01208 }
01209
01210 processParamFile();
01211
01212 if (myParams->getRequestIOPackets() || myRequestedIOPackets)
01213 comInt(ArCommands::IOREQUEST, 2);
01214
01215 if(myParams->getRequestEncoderPackets() || myRequestedEncoderPackets)
01216 comInt(ArCommands::ENCODER, 2);
01217
01218 return true;
01219 }
01220
01221 void ArRobot::requestEncoderPackets(void)
01222 {
01223 comInt(ArCommands::ENCODER, 2);
01224 myRequestedEncoderPackets = true;
01225 }
01226
01227 void ArRobot::requestIOPackets(void)
01228 {
01229 comInt(ArCommands::IOREQUEST, 2);
01230 myRequestedIOPackets = true;
01231 }
01232
01233 void ArRobot::stopEncoderPackets(void)
01234 {
01235 comInt(ArCommands::ENCODER, 0);
01236 myRequestedEncoderPackets = false;
01237 }
01238
01239 void ArRobot::stopIOPackets(void)
01240 {
01241 comInt(ArCommands::IOREQUEST, 0);
01242 myRequestedIOPackets = false;
01243 }
01244
01245 void ArRobot::startStabilization(void)
01246 {
01247 std::list<ArFunctor *>::iterator it;
01248 myIsStabilizing = true;
01249 myStartedStabilizing.setToNow();
01250
01251 for (it = myStabilizingCBList.begin();
01252 it != myStabilizingCBList.end();
01253 it++)
01254 (*it)->invoke();
01255
01256 }
01257
01258 void ArRobot::finishedConnection(void)
01259 {
01260 std::list<ArFunctor *>::iterator it;
01261
01262 myIsStabilizing = false;
01263 myIsConnected = true;
01264 myAsyncConnectFlag = false;
01265 myBlockingConnectRun = false;
01266
01267 for (it = myConnectCBList.begin(); it != myConnectCBList.end(); it++)
01268 (*it)->invoke();
01269 myLastPacketReceivedTime.setToNow();
01270
01271 wakeAllConnWaitingThreads();
01272 }
01273
01274 void ArRobot::failedConnect(void)
01275 {
01276 std::list<ArFunctor *>::iterator it;
01277
01278 myAsyncConnectFlag = false;
01279 myBlockingConnectRun = false;
01280 ArLog::log(ArLog::Terse, "Failed to connect to robot.");
01281 myIsConnected = false;
01282 for (it = myFailedConnectCBList.begin();
01283 it != myFailedConnectCBList.end();
01284 it++)
01285 (*it)->invoke();
01286
01287 if (myConn != NULL)
01288 myConn->close();
01289 wakeAllConnOrFailWaitingThreads();
01290 }
01291
01301 bool ArRobot::disconnect(void)
01302 {
01303 std::list<ArFunctor *>::iterator it;
01304 bool ret;
01305 ArSerialConnection *serConn;
01306
01307 if (!myIsConnected && !myIsStabilizing)
01308 return true;
01309
01310 ArLog::log(ArLog::Terse, "Disconnecting from robot.");
01311 myNoTimeWarningThisCycle = true;
01312 myIsConnected = false;
01313 myIsStabilizing = false;
01314 if (myIsConnected)
01315 {
01316 for (it = myDisconnectNormallyCBList.begin();
01317 it != myDisconnectNormallyCBList.end();
01318 it++)
01319 (*it)->invoke();
01320 }
01321 ret = mySender.comInt(ArCommands::CLOSE, 1);
01322 ArUtil::sleep(1000);
01323 if (ret == true)
01324 {
01325 if (myConn != NULL)
01326 {
01327 ret = myConn->close();
01328 if ((serConn = dynamic_cast<ArSerialConnection *>(myConn)) != NULL)
01329 serConn->setBaud(myAsyncConnectStartBaud);
01330 }
01331 else
01332 ret = false;
01333 }
01334 else if (myConn != NULL)
01335 myConn->close();
01336
01337 return ret;
01338 }
01339
01340 void ArRobot::dropConnection(void)
01341 {
01342 std::list<ArFunctor *>::iterator it;
01343
01344 if (!myIsConnected)
01345 return;
01346
01347 ArLog::log(ArLog::Terse, "Lost connection to the robot because of error.");
01348 myIsConnected = false;
01349 for (it = myDisconnectOnErrorCBList.begin();
01350 it != myDisconnectOnErrorCBList.end();
01351 it++)
01352 (*it)->invoke();
01353
01354 if (myConn != NULL)
01355 myConn->close();
01356 return;
01357 }
01358
01359 void ArRobot::cancelConnection(void)
01360 {
01361
01362
01363 ArLog::log(ArLog::Verbose, "Cancelled connection to the robot because of command.");
01364 myIsConnected = false;
01365 myNoTimeWarningThisCycle = true;
01366 myIsStabilizing = false;
01367 return;
01368 }
01369
01379 void ArRobot::stop(void)
01380 {
01381 comInt(ArCommands::VEL, 0);
01382 comInt(ArCommands::RVEL, 0);
01383 setVel(0);
01384 setRotVel(0);
01385 myLastActionTransVal = 0;
01386 myLastActionRotStopped = true;
01387 myLastActionRotHeading = false;
01388 }
01389
01396 void ArRobot::setVel(double velocity)
01397 {
01398 myTransType = TRANS_VEL;
01399 myTransVal = velocity;
01400 myTransVal2 = 0;
01401 myTransSetTime.setToNow();
01402 }
01403
01418 void ArRobot::setVel2(double leftVelocity, double rightVelocity)
01419 {
01420 myTransType = TRANS_VEL2;
01421 myTransVal = leftVelocity;
01422 myTransVal2 = rightVelocity;
01423 myRotType = ROT_IGNORE;
01424 myRotVal = 0;
01425 myTransSetTime.setToNow();
01426 }
01427
01435 void ArRobot::move(double distance)
01436 {
01437 myTransType = TRANS_DIST_NEW;
01438 myTransDistStart = getPose();
01439 myTransVal = distance;
01440 myTransVal2 = 0;
01441 myTransSetTime.setToNow();
01442 }
01443
01458 bool ArRobot::isMoveDone(double delta)
01459 {
01460 if (fabs(delta) < 0.001)
01461 delta = myMoveDoneDist;
01462 if (myTransType != TRANS_DIST && myTransType != TRANS_DIST_NEW)
01463 return true;
01464 if (myTransDistStart.findDistanceTo(getPose()) <
01465 fabs(myTransVal) - delta)
01466 return false;
01467 return true;
01468 }
01469
01470
01483 bool ArRobot::isHeadingDone(double delta) const
01484 {
01485 if (fabs(delta) < 0.001)
01486 delta = myHeadingDoneDiff;
01487 if (myRotType != ROT_HEADING)
01488 return true;
01489 if(fabs(ArMath::subAngle(getTh(), myRotVal)) > delta)
01490 return false;
01491 return true;
01492 }
01493
01494
01495
01502 void ArRobot::setHeading(double heading)
01503 {
01504 myRotVal = heading;
01505 myRotType = ROT_HEADING;
01506 myRotSetTime.setToNow();
01507 if (myTransType == TRANS_VEL2)
01508 {
01509 myTransType = TRANS_IGNORE;
01510 myTransVal = 0;
01511 myTransVal2 = 0;
01512 }
01513 }
01514
01521 void ArRobot::setRotVel(double velocity)
01522 {
01523 myRotVal = velocity;
01524 myRotType = ROT_VEL;
01525 myRotSetTime.setToNow();
01526 if (myTransType == TRANS_VEL2)
01527 {
01528 myTransType = TRANS_IGNORE;
01529 myTransVal = 0;
01530 myTransVal2 = 0;
01531 }
01532 }
01533
01540 void ArRobot::setDeltaHeading(double deltaHeading)
01541 {
01542 myRotVal = ArMath::addAngle(getTh(), deltaHeading);
01543 myRotType = ROT_HEADING;
01544 myRotSetTime.setToNow();
01545 if (myTransType == TRANS_VEL2)
01546 {
01547 myTransType = TRANS_IGNORE;
01548 myTransVal = 0;
01549 myTransVal2 = 0;
01550 }
01551 }
01552
01566 bool ArRobot::setAbsoluteMaxTransVel(double maxVel)
01567 {
01568 if (maxVel < 0)
01569 return false;
01570 myAbsoluteMaxTransVel = maxVel;
01571 if (getTransVelMax() > myAbsoluteMaxTransVel)
01572 setTransVelMax(myAbsoluteMaxTransVel);
01573 return true;
01574 }
01575
01587 bool ArRobot::setAbsoluteMaxRotVel(double maxVel)
01588 {
01589 if (maxVel < 0)
01590 return false;
01591 myAbsoluteMaxRotVel = maxVel;
01592 if (getRotVelMax() > myAbsoluteMaxRotVel)
01593 setRotVelMax(myAbsoluteMaxRotVel);
01594 return true;
01595 }
01596
01601 int ArRobot::getIOAnalog(int num) const
01602 {
01603 if (num <= getIOAnalogSize())
01604 return myIOAnalog[num];
01605 else
01606 return 0;
01607 }
01608
01612 double ArRobot::getIOAnalogVoltage(int num) const
01613 {
01614 if (num <= getIOAnalogSize())
01615 {
01616 return (myIOAnalog[num] & 0xfff) * .0048828;
01617 }
01618 else
01619 return 0;
01620 }
01621
01622 unsigned char ArRobot::getIODigIn(int num) const
01623 {
01624 if (num <= getIODigInSize())
01625 return myIODigIn[num];
01626 else
01627 return (unsigned char) 0;
01628 }
01629
01630 unsigned char ArRobot::getIODigOut(int num) const
01631 {
01632 if (num <= getIODigOutSize())
01633 return myIODigOut[num];
01634 else
01635 return (unsigned char) 0;
01636 }
01637
01641 const ArRobotParams *ArRobot::getRobotParams(void) const
01642 {
01643 return myParams;
01644 }
01645
01650 const ArRobotConfigPacketReader *ArRobot::getOrigRobotConfig(void) const
01651 {
01652 return myOrigRobotConfig;
01653 }
01654
01665 void ArRobot::addPacketHandler(
01666 ArRetFunctor1<bool, ArRobotPacket *> *functor,
01667 ArListPos::Pos position)
01668 {
01669 if (position == ArListPos::FIRST)
01670 myPacketHandlerList.push_front(functor);
01671 else if (position == ArListPos::LAST)
01672 myPacketHandlerList.push_back(functor);
01673 else
01674 ArLog::log(ArLog::Terse, "ArRobot::addPacketHandler: Invalid position.");
01675
01676 }
01677
01682 void ArRobot::remPacketHandler(
01683 ArRetFunctor1<bool, ArRobotPacket *> *functor)
01684 {
01685 myPacketHandlerList.remove(functor);
01686 }
01687
01698 void ArRobot::addConnectCB(ArFunctor *functor,
01699 ArListPos::Pos position)
01700 {
01701 if (position == ArListPos::FIRST)
01702 myConnectCBList.push_front(functor);
01703 else if (position == ArListPos::LAST)
01704 myConnectCBList.push_back(functor);
01705 else
01706 ArLog::log(ArLog::Terse,
01707 "ArRobot::addConnectCallback: Invalid position.");
01708 }
01709
01714 void ArRobot::remConnectCB(ArFunctor *functor)
01715 {
01716 myConnectCBList.remove(functor);
01717 }
01718
01719
01733 void ArRobot::addFailedConnectCB(ArFunctor *functor,
01734 ArListPos::Pos position)
01735 {
01736 if (position == ArListPos::FIRST)
01737 myFailedConnectCBList.push_front(functor);
01738 else if (position == ArListPos::LAST)
01739 myFailedConnectCBList.push_back(functor);
01740 else
01741 ArLog::log(ArLog::Terse,
01742 "ArRobot::addFailedCallback: Invalid position.");
01743 }
01744
01749 void ArRobot::remFailedConnectCB(ArFunctor *functor)
01750 {
01751 myFailedConnectCBList.remove(functor);
01752 }
01753
01765 void ArRobot::addDisconnectNormallyCB(ArFunctor *functor,
01766 ArListPos::Pos position)
01767 {
01768 if (position == ArListPos::FIRST)
01769 myDisconnectNormallyCBList.push_front(functor);
01770 else if (position == ArListPos::LAST)
01771 myDisconnectNormallyCBList.push_back(functor);
01772 else
01773 ArLog::log(ArLog::Terse,
01774 "ArRobot::addDisconnectNormallyCB: Invalid position.");
01775 }
01776
01781 void ArRobot::remDisconnectNormallyCB(ArFunctor *functor)
01782 {
01783 myDisconnectNormallyCBList.remove(functor);
01784 }
01785
01802 void ArRobot::addDisconnectOnErrorCB(ArFunctor *functor,
01803 ArListPos::Pos position)
01804 {
01805 if (position == ArListPos::FIRST)
01806 myDisconnectOnErrorCBList.push_front(functor);
01807 else if (position == ArListPos::LAST)
01808 myDisconnectOnErrorCBList.push_back(functor);
01809 else
01810 ArLog::log(ArLog::Terse,
01811 "ArRobot::addDisconnectOnErrorCB: Invalid position");
01812 }
01813
01818 void ArRobot::remDisconnectOnErrorCB(ArFunctor *functor)
01819 {
01820 myDisconnectOnErrorCBList.remove(functor);
01821 }
01822
01834 void ArRobot::addRunExitCB(ArFunctor *functor,
01835 ArListPos::Pos position)
01836 {
01837 if (position == ArListPos::FIRST)
01838 myRunExitCBList.push_front(functor);
01839 else if (position == ArListPos::LAST)
01840 myRunExitCBList.push_back(functor);
01841 else
01842 ArLog::log(ArLog::Terse, "ArRobot::addRunExitCB: Invalid position");
01843 }
01844
01849 void ArRobot::remRunExitCB(ArFunctor *functor)
01850 {
01851 myRunExitCBList.remove(functor);
01852 }
01853
01866 void ArRobot::addStabilizingCB(ArFunctor *functor,
01867 ArListPos::Pos position)
01868 {
01869 if (position == ArListPos::FIRST)
01870 myStabilizingCBList.push_front(functor);
01871 else if (position == ArListPos::LAST)
01872 myStabilizingCBList.push_back(functor);
01873 else
01874 ArLog::log(ArLog::Terse,
01875 "ArRobot::addConnectCallback: Invalid position.");
01876 }
01877
01882 void ArRobot::remStabilizingCB(ArFunctor *functor)
01883 {
01884 myStabilizingCBList.remove(functor);
01885 }
01886
01887
01888 std::list<ArFunctor *> * ArRobot::getRunExitListCopy()
01889 {
01890 return(new std::list<ArFunctor *>(myRunExitCBList));
01891 }
01892
01908 ArRobot::WaitState ArRobot::waitForConnect(unsigned int msecs)
01909 {
01910 int ret;
01911
01912 if (isConnected())
01913 return(WAIT_CONNECTED);
01914
01915 if (msecs == 0)
01916 ret=myConnectCond.wait();
01917 else
01918 ret=myConnectCond.timedWait(msecs);
01919
01920 if (ret == ArCondition::STATUS_WAIT_INTR)
01921 return(WAIT_INTR);
01922 else if (ret == ArCondition::STATUS_WAIT_TIMEDOUT)
01923 return(WAIT_TIMEDOUT);
01924 else if (ret == 0)
01925 return(WAIT_CONNECTED);
01926 else
01927 return(WAIT_FAIL);
01928 }
01929
01939 ArRobot::WaitState
01940 ArRobot::waitForConnectOrConnFail(unsigned int msecs)
01941 {
01942 int ret;
01943
01944 if (isConnected())
01945 return(WAIT_CONNECTED);
01946
01947 if (msecs == 0)
01948 ret=myConnOrFailCond.wait();
01949 else
01950 ret=myConnOrFailCond.timedWait(msecs);
01951
01952 if (ret == ArCondition::STATUS_WAIT_INTR)
01953 return(WAIT_INTR);
01954 else if (ret == ArCondition::STATUS_WAIT_TIMEDOUT)
01955 return(WAIT_TIMEDOUT);
01956 else if (ret == 0)
01957 {
01958 if (isConnected())
01959 return(WAIT_CONNECTED);
01960 else
01961 return(WAIT_FAILED_CONN);
01962 }
01963 else
01964 return(WAIT_FAIL);
01965 }
01966
01975 ArRobot::WaitState ArRobot::waitForRunExit(unsigned int msecs)
01976 {
01977 int ret;
01978
01979 if (!isRunning())
01980 return(WAIT_RUN_EXIT);
01981
01982 if (msecs == 0)
01983 ret=myRunExitCond.wait();
01984 else
01985 ret=myRunExitCond.timedWait(msecs);
01986
01987 if (ret == ArCondition::STATUS_WAIT_INTR)
01988 return(WAIT_INTR);
01989 else if (ret == ArCondition::STATUS_WAIT_TIMEDOUT)
01990 return(WAIT_TIMEDOUT);
01991 else if (ret == 0)
01992 return(WAIT_RUN_EXIT);
01993 else
01994 return(WAIT_FAIL);
01995 }
01996
02004 void ArRobot::wakeAllWaitingThreads()
02005 {
02006 wakeAllConnWaitingThreads();
02007 wakeAllRunExitWaitingThreads();
02008 }
02009
02015 void ArRobot::wakeAllConnWaitingThreads()
02016 {
02017 myConnectCond.broadcast();
02018 myConnOrFailCond.broadcast();
02019 }
02020
02027 void ArRobot::wakeAllConnOrFailWaitingThreads()
02028 {
02029 myConnOrFailCond.broadcast();
02030 }
02031
02037 void ArRobot::wakeAllRunExitWaitingThreads()
02038 {
02039 myRunExitCond.broadcast();
02040 }
02041
02049 ArSyncTask *ArRobot::getSyncTaskRoot(void)
02050 {
02051 return mySyncTaskRoot;
02052 }
02053
02070 bool ArRobot::addUserTask(const char *name, int position,
02071 ArFunctor *functor,
02072 ArTaskState::State *state)
02073 {
02074 ArSyncTask *proc;
02075 if (mySyncTaskRoot == NULL)
02076 return false;
02077
02078 proc = mySyncTaskRoot->findNonRecursive("User Tasks");
02079 if (proc == NULL)
02080 return false;
02081
02082 proc->addNewLeaf(name, position, functor, state);
02083 return true;
02084 }
02085
02090 void ArRobot::remUserTask(const char *name)
02091 {
02092 ArSyncTask *proc;
02093 ArSyncTask *userProc;
02094
02095 if (mySyncTaskRoot == NULL)
02096 return;
02097
02098 proc = mySyncTaskRoot->findNonRecursive("User Tasks");
02099 if (proc == NULL)
02100 return;
02101
02102 userProc = proc->findNonRecursive(name);
02103 if (userProc == NULL)
02104 return;
02105
02106
02107 delete userProc;
02108
02109 }
02110
02115 void ArRobot::remUserTask(ArFunctor *functor)
02116 {
02117 ArSyncTask *proc;
02118 ArSyncTask *userProc;
02119
02120 if (mySyncTaskRoot == NULL)
02121 return;
02122
02123 proc = mySyncTaskRoot->findNonRecursive("User Tasks");
02124 if (proc == NULL)
02125 return;
02126
02127
02128 userProc = proc->findNonRecursive(functor);
02129 if (userProc == NULL)
02130 return;
02131
02132
02133 delete userProc;
02134
02135 }
02136
02148 bool ArRobot::addSensorInterpTask(const char *name, int position,
02149 ArFunctor *functor,
02150 ArTaskState::State *state)
02151 {
02152 ArSyncTask *proc;
02153 if (mySyncTaskRoot == NULL)
02154 return false;
02155
02156 proc = mySyncTaskRoot->findNonRecursive("Sensor Interp");
02157 if (proc == NULL)
02158 return false;
02159
02160 proc->addNewLeaf(name, position, functor, state);
02161 return true;
02162 }
02163
02168 void ArRobot::remSensorInterpTask(const char *name)
02169 {
02170 ArSyncTask *proc;
02171 ArSyncTask *sensorInterpProc;
02172
02173 if (mySyncTaskRoot == NULL)
02174 return;
02175
02176 proc = mySyncTaskRoot->findNonRecursive("Sensor Interp");
02177 if (proc == NULL)
02178 return;
02179
02180 sensorInterpProc = proc->findNonRecursive(name);
02181 if (sensorInterpProc == NULL)
02182 return;
02183
02184
02185 delete sensorInterpProc;
02186
02187 }
02188
02193 void ArRobot::remSensorInterpTask(ArFunctor *functor)
02194 {
02195 ArSyncTask *proc;
02196 ArSyncTask *sensorInterpProc;
02197
02198 if (mySyncTaskRoot == NULL)
02199 return;
02200
02201 proc = mySyncTaskRoot->findNonRecursive("Sensor Interp");
02202 if (proc == NULL)
02203 return;
02204
02205
02206 sensorInterpProc = proc->findNonRecursive(functor);
02207 if (sensorInterpProc == NULL)
02208 return;
02209
02210
02211 delete sensorInterpProc;
02212
02213 }
02214
02218 void ArRobot::logUserTasks(void) const
02219 {
02220 ArSyncTask *proc;
02221 if (mySyncTaskRoot == NULL)
02222 return;
02223
02224 proc = mySyncTaskRoot->findNonRecursive("User Tasks");
02225 if (proc == NULL)
02226 return;
02227
02228 proc->log();
02229 }
02230
02234 void ArRobot::logAllTasks(void) const
02235 {
02236 if (mySyncTaskRoot != NULL)
02237 mySyncTaskRoot->log();
02238 }
02239
02245 ArSyncTask *ArRobot::findUserTask(const char *name)
02246 {
02247 ArSyncTask *proc;
02248 if (mySyncTaskRoot == NULL)
02249 return NULL;
02250
02251 proc = mySyncTaskRoot->findNonRecursive("User Tasks");
02252 if (proc == NULL)
02253 return NULL;
02254
02255 return proc->find(name);
02256 }
02257
02263 ArSyncTask *ArRobot::findUserTask(ArFunctor *functor)
02264 {
02265 ArSyncTask *proc;
02266 if (mySyncTaskRoot == NULL)
02267 return NULL;
02268
02269 proc = mySyncTaskRoot->findNonRecursive("User Tasks");
02270 if (proc == NULL)
02271 return NULL;
02272
02273 return proc->find(functor);
02274 }
02275
02281 ArSyncTask *ArRobot::findTask(const char *name)
02282 {
02283 if (mySyncTaskRoot != NULL)
02284 return mySyncTaskRoot->find(name);
02285 else
02286 return NULL;
02287
02288 }
02289
02295 ArSyncTask *ArRobot::findTask(ArFunctor *functor)
02296 {
02297 if (mySyncTaskRoot != NULL)
02298 return mySyncTaskRoot->find(functor);
02299 else
02300 return NULL;
02301
02302 }
02303
02317 bool ArRobot::addAction(ArAction *action, int priority)
02318 {
02319 if (action == NULL)
02320 {
02321 ArLog::log(ArLog::Terse,
02322 "ArRobot::addAction: an attempt was made to add a NULL action pointer");
02323 return false;
02324 }
02325
02326 action->setRobot(this);
02327 myActions.insert(std::pair<int, ArAction *>(priority, action));
02328 return true;
02329 }
02330
02338 bool ArRobot::remAction(const char *actionName)
02339 {
02340 ArResolver::ActionMap::iterator it;
02341 ArAction *act;
02342
02343 for (it = myActions.begin(); it != myActions.end(); ++it)
02344 {
02345 act = (*it).second;
02346 if (strcmp(actionName, act->getName()) == 0)
02347 break;
02348 }
02349 if (it != myActions.end())
02350 {
02351 myActions.erase(it);
02352 return true;
02353 }
02354 return false;
02355
02356 }
02357
02365 bool ArRobot::remAction(ArAction *action)
02366 {
02367 ArResolver::ActionMap::iterator it;
02368 ArAction *act;
02369
02370 for (it = myActions.begin(); it != myActions.end(); ++it)
02371 {
02372 act = (*it).second;
02373 if (act == action)
02374 break;
02375 }
02376 if (it != myActions.end())
02377 {
02378 myActions.erase(it);
02379 return true;
02380 }
02381 return false;
02382
02383 }
02384
02385
02392 ArAction *ArRobot::findAction(const char *actionName)
02393 {
02394 ArResolver::ActionMap::reverse_iterator it;
02395 ArAction *act;
02396
02397 for (it = myActions.rbegin(); it != myActions.rend(); ++it)
02398 {
02399 act = (*it).second;
02400 if (strcmp(actionName, act->getName()) == 0)
02401 return act;
02402 }
02403 return NULL;
02404 }
02405
02415 ArResolver::ActionMap *ArRobot::getActionMap(void)
02416 {
02417 return &myActions;
02418 }
02419
02420 void ArRobot::deactivateActions(void)
02421 {
02422 ArResolver::ActionMap *am;
02423 ArResolver::ActionMap::iterator amit;
02424
02425 am = getActionMap();
02426 if (am == NULL)
02427 {
02428 ArLog::log(ArLog::Terse,
02429 "ArRobot::deactivateActions: NULL action map... failed.");
02430 return;
02431 }
02432 for (amit = am->begin(); amit != am->end(); amit++)
02433 (*amit).second->deactivate();
02434
02435
02436 }
02437
02438
02439 void ArRobot::logActions(void) const
02440 {
02441 ArResolver::ActionMap::const_reverse_iterator it;
02442 int lastPriority;
02443 bool first = true;
02444
02445 ArLog::log(ArLog::Terse, "The action list (%d of them):\n", myActions.size());
02446 for (it = myActions.rbegin(); it != myActions.rend(); ++it)
02447 {
02448 if (first || lastPriority != (*it).first)
02449 {
02450 ArLog::log(ArLog::Terse, "Priority %d:", (*it).first);
02451 first = false;
02452 lastPriority = (*it).first;
02453 }
02454 (*it).second->log(false);
02455 }
02456
02457 }
02458
02459 ArResolver *ArRobot::getResolver(void)
02460 {
02461 return myResolver;
02462 }
02463
02464 void ArRobot::setResolver(ArResolver *resolver)
02465 {
02466 if (myOwnTheResolver)
02467 {
02468 delete myResolver;
02469 myResolver = NULL;
02470 }
02471
02472 myResolver = resolver;
02473 }
02474
02486 void ArRobot::stateReflector(void)
02487 {
02488 short transVal;
02489 short transVal2;
02490 short maxVel;
02491 short maxNegVel;
02492 double maxTransVel;
02493 double maxNegTransVel;
02494 double maxRotVel;
02495 double transAccel;
02496 double transDecel;
02497 short rotVal;
02498 double rotAccel;
02499 double rotDecel;
02500 bool rotStopped = false;
02501 bool rotHeading = false;
02502 double encTh;
02503 double rawTh;
02504
02505
02506 if (!myIsConnected)
02507 return;
02508
02509
02510 if ((myTransType != TRANS_NONE && myDirectPrecedenceTime == 0) ||
02511 (myTransType != TRANS_NONE && myDirectPrecedenceTime != 0 &&
02512 myTransSetTime.mSecSince() < myDirectPrecedenceTime))
02513 {
02514 myActionTransSet = false;
02515 transVal = ArMath::roundShort(myTransVal);
02516 transVal2 = 0;
02517
02518 if (hasSettableVelMaxes() &&
02519 ArMath::fabs(myLastSentTransVelMax - myTransVelMax) >= 1)
02520 {
02521 comInt(ArCommands::SETV,
02522 ArMath::roundShort(myTransVelMax));
02523 myLastSentTransVelMax = myTransVelMax;
02524 if (myLogMovementSent)
02525 ArLog::log(ArLog::Normal, "Non-action trans max vel of %d",
02526 ArMath::roundShort(myTransVelMax));
02527 }
02528
02529 if (hasSettableAccsDecs() && ArMath::fabs(myTransAccel) > 1 &&
02530 ArMath::fabs(myLastSentTransAccel - myTransAccel) >= 1)
02531 {
02532 comInt(ArCommands::SETA,
02533 ArMath::roundShort(myTransAccel));
02534 myLastSentTransAccel = myTransAccel;
02535 if (myLogMovementSent)
02536 ArLog::log(ArLog::Normal, "Non-action trans accel of %d",
02537 ArMath::roundShort(myTransAccel));
02538 }
02539
02540 if (hasSettableAccsDecs() && ArMath::fabs(myTransDecel) > 1 &&
02541 ArMath::fabs(myLastSentTransDecel - myTransDecel) >= 1)
02542 {
02543 comInt(ArCommands::SETA,
02544 -ArMath::roundShort(myTransDecel));
02545 myLastSentTransDecel = myTransDecel;
02546 if (myLogMovementSent)
02547 ArLog::log(ArLog::Normal, "Non-action trans decel of %d",
02548 -ArMath::roundShort(myTransDecel));
02549 }
02550
02551 if (myTransType == TRANS_VEL)
02552 {
02553 maxVel = ArMath::roundShort(myTransVelMax);
02554 if (transVal > maxVel)
02555 transVal = maxVel;
02556 if (transVal < -maxVel)
02557 transVal = -maxVel;
02558 if (myLastTransVal != transVal || myLastTransType != myTransType ||
02559 (myLastTransSent.mSecSince() >= myStateReflectionRefreshTime))
02560 {
02561 comInt(ArCommands::VEL, ArMath::roundShort(transVal));
02562 myLastTransSent.setToNow();
02563 if (myLogMovementSent)
02564 ArLog::log(ArLog::Normal, "Non-action trans vel of %d",
02565 ArMath::roundShort(transVal));
02566
02567 }
02568 }
02569 else if (myTransType == TRANS_VEL2)
02570 {
02571 if (ArMath::roundShort(myTransVal/myParams->getVel2Divisor()) > 128)
02572 transVal = 128;
02573 else if (ArMath::roundShort(myTransVal/myParams->getVel2Divisor()) < -128)
02574 transVal = -128;
02575 else
02576 transVal = ArMath::roundShort(myTransVal/myParams->getVel2Divisor());
02577 if (ArMath::roundShort(myTransVal2/myParams->getVel2Divisor()) > 128)
02578 transVal2 = 128;
02579 else if (ArMath::roundShort(myTransVal2/myParams->getVel2Divisor()) < -128)
02580 transVal2 = -128;
02581 else
02582 transVal2 = ArMath::roundShort(myTransVal2/myParams->getVel2Divisor());
02583 if (myLastTransVal != transVal || myLastTransVal2 != transVal2 ||
02584 myLastTransType != myTransType ||
02585 (myLastTransSent.mSecSince() >= myStateReflectionRefreshTime))
02586 {
02587 com2Bytes(ArCommands::VEL2, transVal, transVal2);
02588 myLastTransSent.setToNow();
02589 if (myLogMovementSent)
02590 ArLog::log(ArLog::Normal, "Non-action vel2 of %d %d",
02591 transVal, transVal2);
02592
02593 }
02594 }
02595 else if (myTransType == TRANS_DIST_NEW || myTransType == TRANS_DIST)
02596 {
02597
02598 if (!myParams->hasMoveCommand())
02599 {
02600 double distGone;
02601 double distToGo;
02602 double vel;
02603
02604 myTransType = TRANS_DIST;
02605 distGone = myTransDistStart.findDistanceTo(getPose());
02606 distToGo = fabs(fabs(myTransVal) - distGone);
02607 if (distGone > fabs(myTransVal) ||
02608 (distToGo < 10 && fabs(getVel()) < 30))
02609 {
02610 comInt(ArCommands::VEL, 0);
02611 myTransType = TRANS_VEL;
02612 myTransVal = 0;
02613 }
02614 vel = sqrt(distToGo * 200 * 2);
02615 if (vel > getTransVelMax())
02616 vel = getTransVelMax();
02617 if (myTransVal < 0)
02618 vel *= -1;
02619 comInt(ArCommands::VEL, ArMath::roundShort(vel));
02620 if (myLogMovementSent)
02621 ArLog::log(ArLog::Normal, "Non-action move-helper of %d",
02622 ArMath::roundShort(vel));
02623 }
02624 else if (myParams->hasMoveCommand() && myTransType == TRANS_DIST_NEW)
02625 {
02626 comInt(ArCommands::MOVE, transVal);
02627 myLastTransSent.setToNow();
02628 myTransType = TRANS_DIST;
02629 if (myLogMovementSent)
02630 ArLog::log(ArLog::Normal, "Non-action move of %d",
02631 transVal);
02632 }
02633 else if (myTransType == TRANS_DIST &&
02634 (myLastTransSent.mSecSince() >= myStateReflectionRefreshTime))
02635 {
02636 com(0);
02637 myLastPulseSent.setToNow();
02638 myLastTransSent.setToNow();
02639
02640 if (myLogMovementSent)
02641 ArLog::log(ArLog::Normal, "Non-action pulse for dist");
02642 }
02643
02644 }
02645 else if (myTransType == TRANS_IGNORE)
02646 {
02647
02648 }
02649 else
02650 ArLog::log(ArLog::Terse,
02651 "ArRobot::stateReflector: Invalid translational type %d.",
02652 myTransType);
02653 myLastTransVal = transVal;
02654 myLastTransVal2 = transVal2;
02655 myLastTransType = myTransType;
02656 }
02657 else
02658 {
02659 if (hasSettableVelMaxes() &&
02660 ArMath::fabs(myLastSentTransVelMax - myTransVelMax) >= 1)
02661 {
02662 comInt(ArCommands::SETV,
02663 ArMath::roundShort(myTransVelMax));
02664 myLastSentTransVelMax = myTransVelMax;
02665 if (myLogMovementSent)
02666 ArLog::log(ArLog::Normal, "Action-but-robot trans max vel of %d",
02667 ArMath::roundShort(myTransVelMax));
02668 }
02669
02670
02671 if (myActionDesired.getTransAccelStrength() >=
02672 ArActionDesired::MIN_STRENGTH)
02673 {
02674 transAccel = ArMath::roundShort(myActionDesired.getTransAccel());
02675 if (hasSettableAccsDecs() && ArMath::fabs(transAccel) > 1 &&
02676 ArMath::fabs(myLastSentTransAccel - transAccel) >= 1)
02677 {
02678 comInt(ArCommands::SETA,
02679 ArMath::roundShort(transAccel));
02680 myLastSentTransAccel = transAccel;
02681 if (myLogMovementSent)
02682 ArLog::log(ArLog::Normal, "Action trans accel of %d",
02683 ArMath::roundShort(transAccel));
02684 }
02685 }
02686 else if (hasSettableAccsDecs() && ArMath::fabs(myTransAccel) > 1 &&
02687 ArMath::fabs(myLastSentTransAccel - myTransAccel) >= 1)
02688 {
02689 comInt(ArCommands::SETA,
02690 ArMath::roundShort(myTransAccel));
02691 myLastSentTransAccel = myTransAccel;
02692 if (myLogMovementSent)
02693 ArLog::log(ArLog::Normal, "Action-but-robot trans accel of %d",
02694 ArMath::roundShort(myTransAccel));
02695 }
02696
02697 if (myActionDesired.getTransDecelStrength() >=
02698 ArActionDesired::MIN_STRENGTH)
02699 {
02700 transDecel = ArMath::roundShort(myActionDesired.getTransDecel());
02701 if (hasSettableAccsDecs() && ArMath::fabs(transDecel) > 1 &&
02702 ArMath::fabs(myLastSentTransDecel - transDecel) >= 1)
02703 {
02704 comInt(ArCommands::SETA,
02705 -ArMath::roundShort(transDecel));
02706 myLastSentTransDecel = transDecel;
02707 if (myLogMovementSent)
02708 ArLog::log(ArLog::Normal, "Action trans decel of %d",
02709 -ArMath::roundShort(transDecel));
02710 }
02711 }
02712 else if (hasSettableAccsDecs() && ArMath::fabs(myTransDecel) > 1 &&
02713 ArMath::fabs(myLastSentTransDecel - myTransDecel) >= 1)
02714 {
02715 comInt(ArCommands::SETA,
02716 -ArMath::roundShort(myTransDecel));
02717 myLastSentTransDecel = myTransDecel;
02718 if (myLogMovementSent)
02719 ArLog::log(ArLog::Normal, "Action-but-robot trans decel of %d",
02720 -ArMath::roundShort(myTransDecel));
02721 }
02722
02723 if (myActionDesired.getMaxVelStrength() >= ArActionDesired::MIN_STRENGTH)
02724 {
02725 maxTransVel = myActionDesired.getMaxVel();
02726 if (maxTransVel > myTransVelMax)
02727 maxTransVel = myTransVelMax;
02728 }
02729 else
02730 maxTransVel = myTransVelMax;
02731
02732 if (myActionDesired.getMaxNegVelStrength() >=
02733 ArActionDesired::MIN_STRENGTH)
02734 {
02735 maxNegTransVel = -ArMath::fabs(myActionDesired.getMaxNegVel());
02736 if (maxNegTransVel < -myTransVelMax)
02737 maxNegTransVel = -myTransVelMax;
02738 }
02739 else
02740 maxNegTransVel = -myTransVelMax;
02741
02742 if (myActionDesired.getVelStrength() >= ArActionDesired::MIN_STRENGTH)
02743 {
02744 transVal = ArMath::roundShort(myActionDesired.getVel());
02745 myActionTransSet = true;
02746 }
02747 else
02748 {
02749 transVal = myLastActionTransVal;
02750 }
02751
02752 maxVel = ArMath::roundShort(maxTransVel);
02753 maxNegVel = ArMath::roundShort(maxNegTransVel);
02754 if (transVal > maxVel)
02755 transVal = maxVel;
02756 if (transVal < maxNegVel)
02757 transVal = maxNegVel;
02758
02759 if (myActionTransSet &&
02760 (myLastTransSent.mSecSince() >= myStateReflectionRefreshTime ||
02761 transVal != myLastActionTransVal))
02762 {
02763 comInt(ArCommands::VEL, ArMath::roundShort(transVal));
02764 myLastTransSent.setToNow();
02765 if (myLogMovementSent)
02766 ArLog::log(ArLog::Normal, "Action trans vel of %d",
02767 ArMath::roundShort(transVal));
02768 }
02769 myLastActionTransVal = transVal;
02770 }
02771
02772
02773 if ((myRotType != ROT_NONE && myDirectPrecedenceTime == 0) ||
02774 (myRotType != ROT_NONE && myDirectPrecedenceTime != 0 &&
02775 myRotSetTime.mSecSince() < myDirectPrecedenceTime))
02776 {
02777 if (hasSettableVelMaxes() &&
02778 ArMath::fabs(myLastSentRotVelMax - myRotVelMax) >= 1)
02779 {
02780 comInt(ArCommands::SETRV,
02781 ArMath::roundShort(myRotVelMax));
02782 myLastSentRotVelMax = myRotVelMax;
02783 }
02784 if (hasSettableAccsDecs() && ArMath::fabs(myRotAccel) > 1 &&
02785 ArMath::fabs(myLastSentRotAccel - myRotAccel) >= 1)
02786 {
02787 comInt(ArCommands::SETRA,
02788 ArMath::roundShort(myRotAccel));
02789 myLastSentRotAccel = myRotAccel;
02790 if (myLogMovementSent)
02791 ArLog::log(ArLog::Normal, "%25sNon-action rot accel of %d", "",
02792 ArMath::roundShort(myRotAccel));
02793 }
02794 if (hasSettableAccsDecs() && ArMath::fabs(myRotDecel) > 1 &&
02795 ArMath::fabs(myLastSentRotDecel - myRotDecel) >= 1)
02796 {
02797 comInt(ArCommands::SETRA,
02798 -ArMath::roundShort(myRotDecel));
02799 myLastSentRotDecel = myRotDecel;
02800 if (myLogMovementSent)
02801 ArLog::log(ArLog::Normal, "%25sNon-action rot decel of %d", "",
02802 -ArMath::roundShort(myRotDecel));
02803 }
02804
02805 myActionRotSet = false;
02806 rotVal = ArMath::roundShort(myRotVal);
02807 if (myRotType == ROT_HEADING)
02808 {
02809 encTh = ArMath::subAngle(myRotVal, myEncoderTransform.getTh());
02810 rawTh = ArMath::addAngle(encTh,
02811 ArMath::subAngle(myRawEncoderPose.getTh(),
02812 myEncoderPose.getTh()));
02813 rotVal = ArMath::roundShort(rawTh);
02814
02815
02816
02817
02818 if (myLastRotVal != rotVal || myLastRotType != myRotType ||
02819 fabs(ArMath::subAngle(rotVal, getTh())) > 1 ||
02820 (myLastRotSent.mSecSince() >= myStateReflectionRefreshTime))
02821 {
02822 comInt(ArCommands::HEAD, rotVal);
02823 myLastRotSent.setToNow();
02824
02825 if (myLogMovementSent)
02826 ArLog::log(ArLog::Normal,
02827 "%25sNon-action rot heading of %d (encoder %d, raw %d)",
02828 "",
02829 ArMath::roundShort(myRotVal),
02830 ArMath::roundShort(encTh),
02831 ArMath::roundShort(rotVal));
02832 }
02833 }
02834 else if (myRotType == ROT_VEL)
02835 {
02836 if (myLastRotVal != rotVal || myLastRotType != myRotType ||
02837 (myLastRotSent.mSecSince() >= myStateReflectionRefreshTime))
02838 {
02839 comInt(ArCommands::RVEL, rotVal);
02840 myLastRotSent.setToNow();
02841 if (myLogMovementSent)
02842 ArLog::log(ArLog::Normal, "%25sNon-action rot vel of %d", "",
02843 rotVal);
02844
02845 }
02846 }
02847 else if (myRotType == ROT_IGNORE)
02848 {
02849
02850 }
02851 else
02852 ArLog::log(ArLog::Terse,
02853 "ArRobot::stateReflector: Invalid rotation type %d.",
02854 myRotType);
02855 myLastRotVal = rotVal;
02856 myLastRotType = myRotType;
02857 }
02858 else
02859 {
02860
02861 if (myActionDesired.getMaxRotVelStrength() >=
02862 ArActionDesired::MIN_STRENGTH)
02863 {
02864 maxRotVel = myActionDesired.getMaxRotVel();
02865 if (maxRotVel > myAbsoluteMaxRotVel)
02866 maxRotVel = myAbsoluteMaxRotVel;
02867 maxRotVel = ArMath::roundShort(maxRotVel);
02868 if (ArMath::fabs(myLastSentRotVelMax - maxRotVel) >= 1)
02869 {
02870 myLastSentRotVelMax = maxRotVel;
02871 comInt(ArCommands::SETRV,
02872 ArMath::roundShort(maxRotVel));
02873 if (myLogMovementSent)
02874 ArLog::log(ArLog::Normal, "%25sAction rot vel max of %d", "",
02875 ArMath::roundShort(maxRotVel));
02876 }
02877 }
02878 else if (hasSettableVelMaxes() &&
02879 ArMath::fabs(myLastSentRotVelMax - myRotVelMax) >= 1)
02880 {
02881 comInt(ArCommands::SETRV,
02882 ArMath::roundShort(myRotVelMax));
02883 myLastSentRotVelMax = myRotVelMax;
02884 if (myLogMovementSent)
02885 ArLog::log(ArLog::Normal,
02886 "%25sAction-but-robot rot vel max of %d",
02887 "", ArMath::roundShort(myRotVelMax));
02888 }
02889
02890 if (myActionDesired.getRotAccelStrength() >= ArActionDesired::MIN_STRENGTH)
02891 {
02892 rotAccel = ArMath::roundShort(myActionDesired.getRotAccel());
02893 if (ArMath::fabs(myLastSentRotAccel - rotAccel) >= 1)
02894 {
02895 comInt(ArCommands::SETRA,
02896 ArMath::roundShort(rotAccel));
02897 myLastSentRotAccel = rotAccel;
02898 if (myLogMovementSent)
02899 ArLog::log(ArLog::Normal, "%25sAction rot accel of %d", "",
02900 ArMath::roundShort(rotAccel));
02901 }
02902 }
02903 else if (hasSettableAccsDecs() && ArMath::fabs(myRotAccel) > 1 &&
02904 ArMath::fabs(myLastSentRotAccel - myRotAccel) >= 1)
02905 {
02906 comInt(ArCommands::SETRA,
02907 ArMath::roundShort(myRotAccel));
02908 myLastSentRotAccel = myRotAccel;
02909 if (myLogMovementSent)
02910 ArLog::log(ArLog::Normal, "%25sAction-but-robot rot accel of %d",
02911 "", ArMath::roundShort(myRotAccel));
02912 }
02913
02914 if (myActionDesired.getRotDecelStrength() >= ArActionDesired::MIN_STRENGTH)
02915 {
02916 rotDecel = ArMath::roundShort(myActionDesired.getRotDecel());
02917 if (ArMath::fabs(myLastSentRotDecel - rotDecel) >= 1)
02918 {
02919 comInt(ArCommands::SETRA,
02920 -ArMath::roundShort(rotDecel));
02921 myLastSentRotDecel = rotDecel;
02922 if (myLogMovementSent)
02923 ArLog::log(ArLog::Normal, "%25sAction rot decel of %d", "",
02924 -ArMath::roundShort(rotDecel));
02925 }
02926 }
02927 else if (hasSettableAccsDecs() && ArMath::fabs(myRotDecel) > 1 &&
02928 ArMath::fabs(myLastSentRotDecel - myRotDecel) >= 1)
02929 {
02930 comInt(ArCommands::SETRA,
02931 -ArMath::roundShort(myRotDecel));
02932 myLastSentRotDecel = myRotDecel;
02933 if (myLogMovementSent)
02934 ArLog::log(ArLog::Normal, "%25sAction-but-robot rot decel of %d",
02935 "", -ArMath::roundShort(myRotDecel));
02936 }
02937
02938
02939
02940 if (myActionDesired.getDeltaHeadingStrength() >=
02941 ArActionDesired::MIN_STRENGTH)
02942 {
02943 if (ArMath::roundShort(myActionDesired.getDeltaHeading()) == 0)
02944 {
02945 rotStopped = true;
02946 rotVal = 0;
02947 rotHeading = false;
02948 }
02949 else
02950 {
02951
02952
02953 encTh = ArMath::subAngle(
02954 ArMath::addAngle(myActionDesired.getDeltaHeading(),
02955 getTh()),
02956 myEncoderTransform.getTh());
02957
02958 rawTh = ArMath::addAngle(encTh,
02959 ArMath::subAngle(myRawEncoderPose.getTh(),
02960 myEncoderPose.getTh()));
02961 rotVal = ArMath::roundShort(rawTh);
02962 rotStopped = false;
02963 rotHeading = true;
02964 }
02965 myActionRotSet = true;
02966 }
02967 else if (myActionDesired.getRotVelStrength() >=
02968 ArActionDesired::MIN_STRENGTH)
02969 {
02970 if (ArMath::roundShort(myActionDesired.getRotVel()) == 0)
02971 {
02972 rotStopped = true;
02973 rotVal = 0;
02974 rotHeading = false;
02975 }
02976 else
02977 {
02978 rotStopped = false;
02979 rotVal = ArMath::roundShort(myActionDesired.getRotVel());
02980 rotHeading = false;
02981 }
02982 myActionRotSet = true;
02983 }
02984 else
02985 {
02986 rotStopped = myLastActionRotStopped;
02987 rotVal = myLastActionRotVal;
02988 rotHeading = myLastActionRotHeading;
02989 }
02990
02991 if (myActionRotSet &&
02992 (myLastRotSent.mSecSince() > myStateReflectionRefreshTime ||
02993 rotStopped != myLastActionRotStopped ||
02994 rotVal != myLastActionRotVal ||
02995 rotHeading != myLastActionRotHeading))
02996 {
02997 if (rotStopped)
02998 {
02999 comInt(ArCommands::RVEL, 0);
03000 if (myLogMovementSent)
03001 ArLog::log(ArLog::Normal,
03002 "%25sAction rot vel of 0 (rotStopped)",
03003 "");
03004 }
03005 else if (rotHeading)
03006 {
03007 comInt(ArCommands::HEAD, rotVal);
03008 if (myLogMovementSent)
03009 ArLog::log(ArLog::Normal,
03010 "%25sAction rot heading of %d (encoder %d, raw %d)",
03011 "",
03012 ArMath::roundShort(ArMath::addAngle(
03013 myActionDesired.getDeltaHeading(),
03014 getTh())),
03015 ArMath::roundShort(encTh),
03016 ArMath::roundShort(rotVal));
03017 }
03018 else
03019 {
03020 comInt(ArCommands::RVEL, rotVal);
03021 if (myLogMovementSent)
03022 ArLog::log(ArLog::Normal, "%25sAction rot vel of %d", "",
03023 rotVal);
03024 }
03025 myLastRotSent.setToNow();
03026 }
03027
03028 myLastActionRotVal = rotVal;
03029 myLastActionRotStopped = rotStopped;
03030 myLastActionRotHeading = rotHeading;
03031 }
03032
03033 if (myLastRotSent.mSecSince() > myStateReflectionRefreshTime &&
03034 myLastTransSent.mSecSince() > myStateReflectionRefreshTime &&
03035 myLastPulseSent.mSecSince() > myStateReflectionRefreshTime)
03036 {
03037 com(ArCommands::PULSE);
03038 myLastPulseSent.setToNow();
03039 if (myLogMovementSent)
03040 ArLog::log(ArLog::Normal, "Pulse");
03041
03042 }
03043 }
03044
03045 bool ArRobot::handlePacket(ArRobotPacket *packet)
03046 {
03047 std::list<ArRetFunctor1<bool, ArRobotPacket *> *>::iterator it;
03048 bool handled;
03049
03050 lock();
03051
03052 myLastPacketReceivedTime = packet->getTimeReceived();
03053 if (packet->getID() == 0xff)
03054 {
03055 ArLog::log(ArLog::Terse, "Losing connection because robot was reset.");
03056 dropConnection();
03057 unlock();
03058 return false;
03059 }
03060
03061 for (handled = false, it = myPacketHandlerList.begin();
03062 it != myPacketHandlerList.end() && handled == false;
03063 it++)
03064 {
03065 if ((*it) != NULL && (*it)->invokeR(packet))
03066 handled = true;
03067 else
03068 packet->resetRead();
03069 }
03070 if (!handled)
03071 ArLog::log(ArLog::Normal,
03072 "No packet handler wanted packet with ID: 0x%x",
03073 packet->getID());
03074 unlock();
03075 return handled;
03076 }
03077
03078
03079
03080
03081
03082 long int ArRobot::getLeftEncoder()
03083 {
03084 return myLeftEncoder;
03085 }
03086
03087
03088
03089
03090 long int ArRobot::getRightEncoder()
03091 {
03092 return myRightEncoder;
03093 }
03094
03095
03100 void ArRobot::robotLocker(void)
03101 {
03102 lock();
03103 }
03104
03109 void ArRobot::robotUnlocker(void)
03110 {
03111 unlock();
03112 }
03113
03120 void ArRobot::packetHandler(void)
03121 {
03122 ArRobotPacket *packet;
03123 int timeToWait;
03124 ArTime start;
03125 bool sipHandled = false;
03126
03127 if (myAsyncConnectFlag)
03128 {
03129 lock();
03130 asyncConnectHandler(false);
03131 unlock();
03132 return;
03133 }
03134
03135 if (!isConnected())
03136 return;
03137
03138 start.setToNow();
03139
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151 packet = NULL;
03152
03153 while ((packet = myReceiver.receivePacket(0)) != NULL)
03154 {
03155 if (myPacketsReceivedTracking)
03156 {
03157 ArLog::log(ArLog::Normal,
03158 "Rcvd: prePacket (%ld) 0x%x at %ld (%ld)",
03159 myPacketsReceivedTrackingCount,
03160 packet->getID(), start.mSecSince(),
03161 myPacketsReceivedTrackingStarted.mSecSince());
03162 myPacketsReceivedTrackingCount++;
03163 }
03164
03165 handlePacket(packet);
03166 if ((packet->getID() & 0xf0) == 0x30)
03167 sipHandled = true;
03168 packet = NULL;
03169
03170
03171 if ((getOrigRobotConfig()->hasPacketArrived() &&
03172 start.mSecSince() > getOrigRobotConfig()->getSipCycleTime() / 2) ||
03173 (!getOrigRobotConfig()->hasPacketArrived() &&
03174 (unsigned int) start.mSecSince() > myCycleTime / 2))
03175 {
03176 break;
03177 }
03178 }
03179
03180 if (isCycleChained())
03181 timeToWait = getCycleTime() * 2 - start.mSecSince();
03182
03183
03184 while (isCycleChained() && !sipHandled && isRunning() &&
03185 (packet = myReceiver.receivePacket(timeToWait)) != NULL)
03186 {
03187 if (myPacketsReceivedTracking)
03188 {
03189 ArLog::log(ArLog::Normal, "Rcvd: Packet (%ld) 0x%x at %ld (%ld)",
03190 myPacketsReceivedTrackingCount,
03191 packet->getID(), start.mSecSince(),
03192 myPacketsReceivedTrackingStarted.mSecSince());
03193 myPacketsReceivedTrackingCount++;
03194 }
03195
03196 handlePacket(packet);
03197 if ((packet->getID() & 0xf0) == 0x30)
03198 break;
03199 timeToWait = getCycleTime() * 2 - start.mSecSince();
03200 if (timeToWait < 0)
03201 timeToWait = 0;
03202 }
03203
03204 if (myTimeoutTime > 0 &&
03205 ((-myLastPacketReceivedTime.mSecTo()) > myTimeoutTime))
03206 {
03207 ArLog::log(ArLog::Terse,
03208 "Losing connection because nothing received from robot in %d milliseconds.",
03209 myTimeoutTime);
03210 dropConnection();
03211 }
03212
03213 if (myPacketsReceivedTracking)
03214 ArLog::log(ArLog::Normal, "Rcvd: time taken %ld", start.mSecSince());
03215
03216 }
03217
03225 void ArRobot::actionHandler(void)
03226 {
03227 ArActionDesired *actDesired;
03228
03229 if (myResolver == NULL || myActions.size() == 0 || !isConnected())
03230 return;
03231
03232 actDesired = myResolver->resolve(&myActions, this);
03233
03234 myActionDesired.reset();
03235
03236 if (actDesired == NULL)
03237 return;
03238
03239 myActionDesired.merge(actDesired);
03240 }
03241
03250 void ArRobot::setCycleWarningTime(unsigned int ms)
03251 {
03252 myCycleWarningTime = ms;
03253
03254 }
03255
03264 unsigned int ArRobot::getCycleWarningTime(void) const
03265 {
03266 return myCycleWarningTime;
03267 }
03268
03277 unsigned int ArRobot::getCycleWarningTime(void)
03278 {
03279 return myCycleWarningTime;
03280 }
03281
03289 void ArRobot::setCycleTime(unsigned int ms)
03290 {
03291 myCycleTime = ms;
03292 }
03293
03306 void ArRobot::setStabilizingTime(int mSecs)
03307 {
03308 if (mSecs > 0)
03309 myStabilizingTime = mSecs;
03310 else
03311 myStabilizingTime = 0;
03312 }
03313
03319 int ArRobot::getStabilizingTime(void) const
03320 {
03321 return myStabilizingTime;
03322 }
03323
03331 unsigned int ArRobot::getCycleTime(void) const
03332 {
03333 return myCycleTime;
03334 }
03335
03336
03337
03346 void ArRobot::setConnectionCycleMultiplier(unsigned int multiplier)
03347 {
03348 myConnectionCycleMultiplier = multiplier;
03349 }
03350
03358 unsigned int ArRobot::getConnectionCycleMultiplier(void) const
03359 {
03360 return myConnectionCycleMultiplier;
03361 }
03362
03363
03370 void ArRobot::loopOnce(void)
03371 {
03372 if (mySyncTaskRoot != NULL)
03373 mySyncTaskRoot->run();
03374
03375 incCounter();
03376 }
03377
03378
03379
03380
03381 bool ArRobot::isLeftTableSensingIRTriggered(void) const
03382 {
03383 if (myParams->haveTableSensingIR())
03384 {
03385 if (myParams->haveNewTableSensingIR() && myIODigInSize > 3)
03386 return !(getIODigIn(3) & ArUtil::BIT1);
03387 else
03388 return !(getDigIn() & ArUtil::BIT0);
03389 }
03390 return 0;
03391 }
03392
03393 bool ArRobot::isRightTableSensingIRTriggered(void) const
03394 {
03395 if (myParams->haveTableSensingIR())
03396 {
03397 if (myParams->haveNewTableSensingIR() && myIODigInSize > 3)
03398 return !(getIODigIn(3) & ArUtil::BIT0);
03399 else
03400 return !(getDigIn() & ArUtil::BIT1);
03401 }
03402 return 0;
03403 }
03404
03405 bool ArRobot::isLeftBreakBeamTriggered(void) const
03406 {
03407 if (myParams->haveTableSensingIR())
03408 {
03409 if (myParams->haveNewTableSensingIR() && myIODigInSize > 3)
03410 return !(getIODigIn(3) & ArUtil::BIT2);
03411 else
03412 return !(getDigIn() & ArUtil::BIT3);
03413 }
03414 return 0;
03415 }
03416
03417 bool ArRobot::isRightBreakBeamTriggered(void) const
03418 {
03419 if (myParams->haveTableSensingIR())
03420 {
03421 if (myParams->haveNewTableSensingIR() && myIODigInSize > 3)
03422 return !(getIODigIn(3) & ArUtil::BIT3);
03423 else
03424 return !(getDigIn() & ArUtil::BIT2);
03425 }
03426 return 0;
03427 }
03428
03429 int ArRobot::getMotorPacCount(void) const
03430 {
03431 if (myTimeLastMotorPacket == time(NULL))
03432 return myMotorPacCount;
03433 if (myTimeLastMotorPacket == time(NULL) - 1)
03434 return myMotorPacCurrentCount;
03435 return 0;
03436 }
03437
03438 int ArRobot::getSonarPacCount(void) const
03439 {
03440 if (myTimeLastSonarPacket == time(NULL))
03441 return mySonarPacCount;
03442 if (myTimeLastSonarPacket == time(NULL) - 1)
03443 return mySonarPacCurrentCount;
03444 return 0;
03445 }
03446
03447
03448 bool ArRobot::processMotorPacket(ArRobotPacket *packet)
03449 {
03450 int x, y, th, qx, qy, qth;
03451 double deltaX, deltaY, deltaTh;
03452
03453 int numReadings;
03454 int sonarNum;
03455 int sonarRange;
03456
03457 if (packet->getID() != 0x32 && packet->getID() != 0x33)
03458 return false;
03459
03460
03461 if (myTimeLastMotorPacket != time(NULL))
03462 {
03463 myTimeLastMotorPacket = time(NULL);
03464 myMotorPacCount = myMotorPacCurrentCount;
03465 myMotorPacCurrentCount = 0;
03466 }
03467 myMotorPacCurrentCount++;
03468
03469 x = (packet->bufToUByte2() & 0x7fff);
03470 y = (packet->bufToUByte2() & 0x7fff);
03471 th = packet->bufToByte2();
03472
03473 if (myFirstEncoderPose)
03474 {
03475 qx = 0;
03476 qy = 0;
03477 qth = 0;
03478 myFirstEncoderPose = false;
03479 myRawEncoderPose.setPose(
03480 myParams->getDistConvFactor() * x,
03481 myParams->getDistConvFactor() * y,
03482 ArMath::radToDeg(myParams->getAngleConvFactor() * (double)th));
03483 myEncoderPose = myRawEncoderPose;
03484 myEncoderTransform.setTransform(myEncoderPose, myGlobalPose);
03485 }
03486 else
03487 {
03488 qx = x - myLastX;
03489 qy = y - myLastY;
03490 qth = th - myLastTh;
03491 }
03492
03493
03494
03495 myLastX = x;
03496 myLastY = y;
03497 myLastTh = th;
03498
03499 if (qx > 0x1000)
03500 qx -= 0x8000;
03501 if (qx < -0x1000)
03502 qx += 0x8000;
03503
03504 if (qy > 0x1000)
03505 qy -= 0x8000;
03506 if (qy < -0x1000)
03507 qy += 0x8000;
03508
03509 deltaX = myParams->getDistConvFactor() * (double)qx;
03510 deltaY = myParams->getDistConvFactor() * (double)qy;
03511 deltaTh = ArMath::radToDeg(myParams->getAngleConvFactor() * (double)qth);
03512
03513
03514
03515
03516
03517
03518
03519 myLeftVel = myParams->getVelConvFactor() * packet->bufToByte2();
03520 myRightVel = myParams->getVelConvFactor() * packet->bufToByte2();
03521 myVel = (myLeftVel + myRightVel)/2.0;
03522 myRotVel = ArMath::radToDeg((myRightVel - myLeftVel) / 2.0 *
03523 myParams->getDiffConvFactor());
03524
03525 myBatteryVoltage = packet->bufToUByte() * .1;
03526 myBatteryAverager.add(myBatteryVoltage);
03527 myStallValue = packet->bufToByte2();
03528
03529
03530
03531
03532 myControl = ArMath::fixAngle(ArMath::radToDeg(myParams->getAngleConvFactor() *
03533 (packet->bufToByte2() - th)));
03534 myFlags = packet->bufToUByte2();
03535 myCompass = 2*packet->bufToUByte();
03536
03537 for (numReadings = packet->bufToByte(); numReadings > 0; numReadings--)
03538 {
03539 sonarNum = packet->bufToByte();
03540 sonarRange = ArMath::roundInt(
03541 (double)packet->bufToUByte2() * myParams->getRangeConvFactor());
03542 processNewSonar(sonarNum, sonarRange, packet->getTimeReceived());
03543 }
03544
03545 if (packet->getDataLength() - packet->getDataReadLength() > 0)
03546 {
03547 myAnalogPortSelected = packet->bufToUByte2();
03548 myAnalog = packet->bufToByte();
03549 myDigIn = packet->bufToByte();
03550 myDigOut = packet->bufToByte();
03551 }
03552
03553 if (packet->getDataLength() - packet->getDataReadLength() > 0)
03554 myRealBatteryVoltage = packet->bufToUByte2() * .1;
03555 else
03556 myRealBatteryVoltage = myBatteryVoltage;
03557
03558 myRealBatteryAverager.add(myRealBatteryVoltage);
03559
03560 if (packet->getDataLength() - packet->getDataReadLength() > 0)
03561 myChargeState = (ChargeState) packet->bufToUByte();
03562 else
03563 myChargeState = CHARGING_UNKNOWN;
03564
03565
03566
03567
03568
03569
03570
03571
03572
03573
03574
03575
03576
03577
03578
03579
03580
03581
03582
03583
03584
03585
03586
03587
03588
03589
03590
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606
03607
03608
03609
03610
03611 myRawEncoderPose.setX(myRawEncoderPose.getX() + deltaX);
03612 myRawEncoderPose.setY(myRawEncoderPose.getY() + deltaY);
03613 myRawEncoderPose.setTh(myRawEncoderPose.getTh() + deltaTh);
03614
03615
03616
03617 if (myEncoderCorrectionCB != NULL)
03618 {
03619 ArPoseWithTime deltaPose(deltaX, deltaY, deltaTh,
03620 packet->getTimeReceived());
03621 deltaTh = myEncoderCorrectionCB->invokeR(deltaPose);
03622 ArTransform trans(ArPose(0, 0, myRawEncoderPose.getTh()),
03623 ArPose(0, 0,
03624 ArMath::addAngle(myEncoderPose.getTh(),
03625 deltaTh)));
03626
03627 ArPose rotatedDelta = trans.doTransform(ArPose(deltaX, deltaY, 0));
03628
03629 deltaX = rotatedDelta.getX();
03630 deltaY = rotatedDelta.getY();
03631 }
03632
03633 myEncoderPose.setTime(packet->getTimeReceived());
03634 myEncoderPose.setX(myEncoderPose.getX() + deltaX);
03635 myEncoderPose.setY(myEncoderPose.getY() + deltaY);
03636 myEncoderPose.setTh(ArMath::addAngle(myEncoderPose.getTh(), deltaTh));
03637
03638 myGlobalPose = myEncoderTransform.doTransform(myEncoderPose);
03639
03640 if (myLogMovementReceived)
03641 ArLog::log(ArLog::Normal,
03642 "Global (%5.0f %5.0f %5.0f) Encoder (%5.0f %5.0f %5.0f) Raw (%5.0f %5.0f %5.0f)",
03643 myGlobalPose.getX(), myGlobalPose.getY(),
03644 myGlobalPose.getTh(),
03645 myEncoderPose.getX(), myEncoderPose.getY(),
03646 myEncoderPose.getTh(),
03647 myRawEncoderPose.getX(), myRawEncoderPose.getY(),
03648 myRawEncoderPose.getTh());
03649
03650 if (myLogVelocitiesReceived)
03651 ArLog::log(ArLog::Normal,
03652 " TransVel: %5.0f RotVel: %5.0f LeftVel: %5.0f RightVel: %5.0f Heading %5.0f",
03653 getVel(), getRotVel(), getLeftVel(), getRightVel(),
03654 getTh());
03655
03656
03657
03658 myInterpolation.addReading(packet->getTimeReceived(), myGlobalPose);
03659 myEncoderInterpolation.addReading(packet->getTimeReceived(), myEncoderPose);
03660
03661 return true;
03662 }
03663
03664 void ArRobot::processNewSonar(char number, int range,
03665 ArTime timeReceived)
03666 {
03675 std::map<int, ArSensorReading *>::iterator it;
03676 ArSensorReading *sonar;
03677 ArTransform encoderTrans;
03678 ArPose encoderPose;
03679
03680 if ((it = mySonars.find(number)) != mySonars.end())
03681 {
03682 sonar = (*it).second;
03683 sonar->newData(range, getPose(), getEncoderPose(), getToGlobalTransform(),
03684 getCounter(), timeReceived);
03685 if (myTimeLastSonarPacket != time(NULL))
03686 {
03687 myTimeLastSonarPacket = time(NULL);
03688 mySonarPacCount = mySonarPacCurrentCount;
03689 mySonarPacCurrentCount = 0;
03690 }
03691 mySonarPacCurrentCount++;
03692 }
03693 else if (!myWarnedAboutExtraSonar)
03694 {
03695 ArLog::log(ArLog::Normal, "Robot gave back extra sonar reading! Either the parameter file for the robot or the firmware needs updating.");
03696 myWarnedAboutExtraSonar = true;
03697 }
03698 }
03699
03700
03701
03702 bool ArRobot::processEncoderPacket(ArRobotPacket *packet)
03703 {
03704 if (packet->getID() != 0x90)
03705 return false;
03706 myLeftEncoder = packet->bufToByte4();
03707 myRightEncoder = packet->bufToByte4();
03708 return true;
03709 }
03710
03711 bool ArRobot::processIOPacket(ArRobotPacket *packet)
03712 {
03713 int i, num;
03714
03715 if (packet->getID() != 0xf0)
03716 return false;
03717
03718 myLastIOPacketReceivedTime = packet->getTimeReceived();
03719
03720
03721 num = packet->bufToUByte();
03722 for (i = 0; i < num; ++i)
03723 myIODigIn[i] = packet->bufToUByte();
03724 myIODigInSize = num;
03725
03726
03727 num = packet->bufToUByte();
03728 for (i = 0; i < num; ++i)
03729 myIODigOut[i] = packet->bufToUByte();
03730 myIODigOutSize = num;
03731
03732
03733 num = packet->bufToUByte();
03734 for (i = 0; i < num; ++i)
03735 myIOAnalog[i] = packet->bufToUByte2();
03736 myIOAnalogSize = num;
03737
03738 return true;
03739 }
03740
03750 int ArRobot::getSonarRange(int num) const
03751 {
03752 std::map<int, ArSensorReading *>::const_iterator it;
03753
03754 if ((it = mySonars.find(num)) != mySonars.end())
03755 return (*it).second->getRange();
03756 else
03757 return -1;
03758 }
03759
03768 bool ArRobot::isSonarNew(int num) const
03769 {
03770 std::map<int, ArSensorReading *>::const_iterator it;
03771
03772 if ((it = mySonars.find(num)) != mySonars.end())
03773 return (*it).second->isNew(getCounter());
03774 else
03775 return false;
03776 }
03777
03790 ArSensorReading *ArRobot::getSonarReading(int num) const
03791 {
03792 std::map<int, ArSensorReading *>::const_iterator it;
03793
03794 if ((it = mySonars.find(num)) != mySonars.end())
03795 return (*it).second;
03796 else
03797 return NULL;
03798 }
03799
03800
03806 bool ArRobot::com(unsigned char command)
03807 {
03808 if (myPacketsSentTracking)
03809 ArLog::log(ArLog::Normal, "Sent: com(%d)", command);
03810 return mySender.com(command);
03811 }
03812
03819 bool ArRobot::comInt(unsigned char command, short int argument)
03820 {
03821 if (myPacketsSentTracking)
03822 ArLog::log(ArLog::Normal, "Sent: comInt(%d, %d)", command, argument);
03823 return mySender.comInt(command, argument);
03824 }
03825
03833 bool ArRobot::com2Bytes(unsigned char command, char high, char low)
03834 {
03835 if (myPacketsSentTracking)
03836 ArLog::log(ArLog::Normal, "Sent: com2Bytes(%d, %d, %d)", command,
03837 high, low);
03838 return mySender.com2Bytes(command, high, low);
03839 }
03840
03847 bool ArRobot::comStr(unsigned char command, const char *argument)
03848 {
03849 if (myPacketsSentTracking)
03850 ArLog::log(ArLog::Normal, "Sent: comStr(%d, '%s')", command,
03851 argument);
03852 return mySender.comStr(command, argument);
03853 }
03854
03862 bool ArRobot::comStrN(unsigned char command, const char *str,
03863 int size)
03864 {
03865 if (myPacketsSentTracking)
03866 {
03867 char strBuf[512];
03868 strncpy(strBuf, str, size);
03869 strBuf[size] = '\0';
03870 ArLog::log(ArLog::Normal, "Sent: comStrN(%d, '%s') (size %d)",
03871 command, strBuf, size);
03872 }
03873 return mySender.comStrN(command, str, size);
03874 }
03875
03876 int ArRobot::getClosestSonarRange(double startAngle, double endAngle) const
03877 {
03878 int num;
03879 num = getClosestSonarNumber(startAngle, endAngle);
03880 if (num == -1)
03881 return -1;
03882 else
03883 return getSonarRange(num);
03884 }
03885
03886 int ArRobot::getClosestSonarNumber(double startAngle, double endAngle) const
03887 {
03888 int i;
03889 ArSensorReading *sonar;
03890 int closestReading;
03891 int closestSonar;
03892 bool noReadings = true;
03893
03894 for (i = 0; i < getNumSonar(); i++)
03895 {
03896 sonar = getSonarReading(i);
03897 if (sonar == NULL)
03898 {
03899 ArLog::log(ArLog::Terse, "Have an empty sonar at number %d, there should be %d sonar.", i, getNumSonar());
03900 continue;
03901 }
03902 if (ArMath::angleBetween(sonar->getSensorTh(), startAngle, endAngle))
03903 {
03904 if (noReadings)
03905 {
03906 closestReading = sonar->getRange();
03907 closestSonar = i;
03908 noReadings = false;
03909 }
03910 else if (sonar->getRange() < closestReading)
03911 {
03912 closestReading = sonar->getRange();
03913 closestSonar = i;
03914 }
03915 }
03916 }
03917
03918 if (noReadings)
03919 return -1;
03920 else
03921 return closestSonar;
03922 }
03923
03924 void ArRobot::addRangeDevice(ArRangeDevice *device)
03925 {
03926 device->setRobot(this);
03927 myRangeDeviceList.push_front(device);
03928 }
03929
03933 void ArRobot::remRangeDevice(const char *name)
03934 {
03935 std::list<ArRangeDevice *>::iterator it;
03936 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
03937 {
03938 if (strcmp(name, (*it)->getName()) == 0)
03939 {
03940 myRangeDeviceList.erase(it);
03941 return;
03942 }
03943 }
03944 }
03945
03949 void ArRobot::remRangeDevice(ArRangeDevice *device)
03950 {
03951 std::list<ArRangeDevice *>::iterator it;
03952 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
03953 {
03954 if ((*it) == device)
03955 {
03956 myRangeDeviceList.erase(it);
03957 return;
03958 }
03959 }
03960 }
03961
03966 ArRangeDevice *ArRobot::findRangeDevice(const char *name)
03967 {
03968 std::list<ArRangeDevice *>::iterator it;
03969 ArRangeDevice *device;
03970
03971 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
03972 {
03973 device = (*it);
03974 if (strcmp(name, device->getName()) == 0)
03975 {
03976 return device;
03977 }
03978 }
03979 return NULL;
03980 }
03981
03986 const ArRangeDevice *ArRobot::findRangeDevice(const char *name) const
03987 {
03988 std::list<ArRangeDevice *>::const_iterator it;
03989 ArRangeDevice *device;
03990
03991 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
03992 {
03993 device = (*it);
03994 if (strcmp(name, device->getName()) == 0)
03995 {
03996 return device;
03997 }
03998 }
03999 return NULL;
04000 }
04001
04008 std::list<ArRangeDevice *> *ArRobot::getRangeDeviceList(void)
04009 {
04010 return &myRangeDeviceList;
04011 }
04012
04016 bool ArRobot::hasRangeDevice(ArRangeDevice *device) const
04017 {
04018 std::list<ArRangeDevice *>::const_iterator it;
04019 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
04020 {
04021 if ((*it) == device)
04022 return true;
04023 }
04024 return false;
04025 }
04026
04046 double ArRobot::checkRangeDevicesCurrentPolar(double startAngle,
04047 double endAngle,
04048 double *angle) const
04049 {
04050 double closest, closeAngle, tempDist, tempAngle;
04051 std::list<ArRangeDevice *>::const_iterator it;
04052 ArRangeDevice *device;
04053 bool foundOne = false;
04054
04055 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
04056 {
04057 device = (*it);
04058 device->lockDevice();
04059 if (!foundOne ||
04060 (tempDist = device->currentReadingPolar(startAngle, endAngle,
04061 &tempAngle)) < closest)
04062 {
04063 if (!foundOne)
04064 {
04065 closest = device->currentReadingPolar(startAngle, endAngle,
04066 &closeAngle);
04067 }
04068 else
04069 {
04070 closest = tempDist;
04071 closeAngle = tempAngle;
04072 }
04073 foundOne = true;
04074 }
04075 device->unlockDevice();
04076 }
04077 if (!foundOne)
04078 return -1;
04079 if (angle != NULL)
04080 *angle = closeAngle;
04081 return closest;
04082
04083 }
04084
04104 double ArRobot::checkRangeDevicesCumulativePolar(double startAngle,
04105 double endAngle,
04106 double *angle) const
04107 {
04108 double closest, closeAngle, tempDist, tempAngle;
04109 std::list<ArRangeDevice *>::const_iterator it;
04110 ArRangeDevice *device;
04111 bool foundOne = false;
04112
04113 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
04114 {
04115 device = (*it);
04116 device->lockDevice();
04117 if (!foundOne ||
04118 (tempDist = device->cumulativeReadingPolar(startAngle, endAngle,
04119 &tempAngle)) < closest)
04120 {
04121 if (!foundOne)
04122 {
04123 closest = device->cumulativeReadingPolar(startAngle, endAngle,
04124 &closeAngle);
04125 }
04126 else
04127 {
04128 closest = tempDist;
04129 closeAngle = tempAngle;
04130 }
04131 foundOne = true;
04132 }
04133 device->unlockDevice();
04134 }
04135 if (!foundOne)
04136 return -1;
04137 if (angle != NULL)
04138 *angle = closeAngle;
04139 return closest;
04140
04141 }
04142
04159 double ArRobot::checkRangeDevicesCurrentBox(double x1, double y1,
04160 double x2, double y2,
04161 ArPose *readingPos) const
04162 {
04163
04164 double closest, tempDist;
04165 ArPose closestPos, tempPos;
04166 std::list<ArRangeDevice *>::const_iterator it;
04167 ArRangeDevice *device;
04168 bool foundOne = false;
04169
04170 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
04171 {
04172 device = (*it);
04173 device->lockDevice();
04174 if (!foundOne ||
04175 (tempDist = device->currentReadingBox(x1, y1, x2, y2, &tempPos)) < closest)
04176 {
04177 if (!foundOne)
04178 {
04179 closest = device->currentReadingBox(x1, y1, x2, y2, &closestPos);
04180 }
04181 else
04182 {
04183 closest = tempDist;
04184 closestPos = tempPos;
04185 }
04186 foundOne = true;
04187 }
04188 device->unlockDevice();
04189 }
04190 if (!foundOne)
04191 return -1;
04192 if (readingPos != NULL)
04193 *readingPos = closestPos;
04194 return closest;
04195 }
04196
04213 double ArRobot::checkRangeDevicesCumulativeBox(double x1, double y1,
04214 double x2, double y2,
04215 ArPose *readingPos) const
04216 {
04217
04218 double closest, tempDist;
04219 ArPose closestPos, tempPos;
04220 std::list<ArRangeDevice *>::const_iterator it;
04221 ArRangeDevice *device;
04222 bool foundOne = false;
04223
04224 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); ++it)
04225 {
04226 device = (*it);
04227 device->lockDevice();
04228 if (!foundOne ||
04229 (tempDist = device->cumulativeReadingBox(x1, y1, x2, y2, &tempPos)) < closest)
04230 {
04231 if (!foundOne)
04232 {
04233 closest = device->cumulativeReadingBox(x1, y1, x2, y2, &closestPos);
04234 }
04235 else
04236 {
04237 closest = tempDist;
04238 closestPos = tempPos;
04239 }
04240 foundOne = true;
04241 }
04242 device->unlockDevice();
04243 }
04244 if (!foundOne)
04245 return -1;
04246 if (readingPos != NULL)
04247 *readingPos = closestPos;
04248 return closest;
04249 }
04250
04255 void ArRobot::moveTo(ArPose pose, bool doCumulative)
04256 {
04257 std::list<ArRangeDevice *>::iterator it;
04258 ArSensorReading *son;
04259 int i;
04260
04261
04262
04263 ArTransform localTransform;
04264 localTransform = getToLocalTransform();
04265
04266 myEncoderTransform.setTransform(myEncoderPose, pose);
04267 myGlobalPose = myEncoderTransform.doTransform(myEncoderPose);
04268
04269 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); it++)
04270 {
04271 (*it)->lockDevice();
04272 (*it)->applyTransform(localTransform, doCumulative);
04273 (*it)->applyTransform(getToGlobalTransform(), doCumulative);
04274 (*it)->unlockDevice();
04275 }
04276
04277 for (i = 0; i < getNumSonar(); i++)
04278 {
04279 son = getSonarReading(i);
04280 if (son != NULL)
04281 {
04282 son->applyTransform(localTransform);
04283 son->applyTransform(getToGlobalTransform());
04284 }
04285 }
04286
04287
04288 }
04289
04295 void ArRobot::moveTo(ArPose poseTo, ArPose poseFrom,
04296 bool doCumulative)
04297 {
04298 std::list<ArRangeDevice *>::iterator it;
04299 ArSensorReading *son;
04300 int i;
04301
04302 ArPose result = myEncoderTransform.doInvTransform(poseFrom);
04303
04304
04305
04306 ArTransform localTransform;
04307 localTransform = getToLocalTransform();
04308
04309 myEncoderTransform.setTransform(result, poseTo);
04310 myGlobalPose = myEncoderTransform.doTransform(myEncoderPose);
04311
04312 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); it++)
04313 {
04314 (*it)->lockDevice();
04315 (*it)->applyTransform(localTransform, doCumulative);
04316 (*it)->applyTransform(getToGlobalTransform(), doCumulative);
04317 (*it)->unlockDevice();
04318 }
04319
04320 for (i = 0; i < getNumSonar(); i++)
04321 {
04322 son = getSonarReading(i);
04323 if (son != NULL)
04324 {
04325 son->applyTransform(localTransform);
04326 son->applyTransform(getToGlobalTransform());
04327 }
04328 }
04329
04330
04331 }
04332
04337 void ArRobot::setEncoderTransform(ArPose deadReconPos,
04338 ArPose globalPos)
04339 {
04340 myEncoderTransform.setTransform(deadReconPos, globalPos);
04341 myGlobalPose = myEncoderTransform.doTransform(myEncoderPose);
04342 }
04343
04347 void ArRobot::setEncoderTransform(ArPose transformPos)
04348 {
04349 myEncoderTransform.setTransform(transformPos);
04350 myGlobalPose = myEncoderTransform.doTransform(myEncoderPose);
04351 }
04352
04356 ArTransform ArRobot::getEncoderTransform(void) const
04357 {
04358 return myEncoderTransform;
04359 }
04360
04364 void ArRobot::setDeadReconPose(ArPose pose)
04365 {
04366 myEncoderPose.setPose(pose);
04367 myEncoderTransform.setTransform(myEncoderPose, myGlobalPose);
04368 myGlobalPose = myEncoderTransform.doTransform(myEncoderPose);
04369 }
04370
04371
04376 ArTransform ArRobot::getToGlobalTransform(void) const
04377 {
04378 ArTransform trans;
04379 ArPose origin(0, 0, 0);
04380 ArPose pose = getPose();
04381
04382 trans.setTransform(origin, pose);
04383 return trans;
04384 }
04385
04390 ArTransform ArRobot::getToLocalTransform(void) const
04391 {
04392 ArTransform trans;
04393 ArPose origin(0, 0, 0);
04394 ArPose pose = getPose();
04395
04396 trans.setTransform(pose, origin);
04397 return trans;
04398 }
04399
04407 void ArRobot::applyTransform(ArTransform trans, bool doCumulative)
04408 {
04409 std::list<ArRangeDevice *>::iterator it;
04410 ArSensorReading *son;
04411 int i;
04412
04413 for (it = myRangeDeviceList.begin(); it != myRangeDeviceList.end(); it++)
04414 {
04415 (*it)->lockDevice();
04416 (*it)->applyTransform(trans, doCumulative);
04417 (*it)->unlockDevice();
04418 }
04419
04420 for (i = 0; i < getNumSonar(); i++)
04421 {
04422 son = getSonarReading(i);
04423 if (son != NULL)
04424 son->applyTransform(trans);
04425 }
04426 }
04427
04428 const char *ArRobot::getName(void) const
04429 {
04430 return myName.c_str();
04431 }
04432
04433 void ArRobot::setName(const char * name)
04434 {
04435 std::list<ArRobot *> *robotList;
04436 std::list<ArRobot *>::iterator it;
04437 int i;
04438 char buf[1024];
04439
04440 if (name != NULL)
04441 {
04442 myName = name;
04443 }
04444 else
04445 {
04446
04447
04448
04449 robotList = Aria::getRobotList();
04450 for (i = 1, it = robotList->begin(); it != robotList->end(); it++, i++)
04451 {
04452 if (this == (*it))
04453 {
04454 if (i == 1)
04455 myName = "robot";
04456 else
04457 {
04458 sprintf(buf, "robot%d", i);
04459 myName = buf;
04460 }
04461 return;
04462 }
04463 }
04464 sprintf(buf, "robot%d", robotList->size());
04465 myName = buf;
04466 }
04467 }
04468
04479 void ArRobot::setEncoderCorrectionCallback(
04480 ArRetFunctor1<double, ArPoseWithTime> *functor)
04481 {
04482 myEncoderCorrectionCB = functor;
04483 }
04490 ArRetFunctor1<double, ArPoseWithTime> *
04491 ArRobot::getEncoderCorrectionCallback(void) const
04492 {
04493 return myEncoderCorrectionCB;
04494 }
04495
04506 void ArRobot::setDirectMotionPrecedenceTime(int mSec)
04507 {
04508 if (mSec < 0)
04509 myDirectPrecedenceTime = 0;
04510 else
04511 myDirectPrecedenceTime = mSec;
04512 }
04513
04523 unsigned int ArRobot::getDirectMotionPrecedenceTime(void) const
04524 {
04525 return myDirectPrecedenceTime;
04526 }
04527
04528
04535 void ArRobot::clearDirectMotion(void)
04536 {
04537 myTransType = TRANS_NONE;
04538 myLastTransType = TRANS_NONE;
04539 myRotType = ROT_NONE;
04540 myLastRotType = ROT_NONE;
04541 myLastActionTransVal = 0;
04542 myLastActionRotStopped = true;
04543 myLastActionRotHeading = false;
04544 }
04545
04553 void ArRobot::stopStateReflection(void)
04554 {
04555 myTransType = TRANS_IGNORE;
04556 myLastTransType = TRANS_IGNORE;
04557 myRotType = ROT_IGNORE;
04558 myLastRotType = ROT_IGNORE;
04559 }
04560
04565 bool ArRobot::isDirectMotion(void) const
04566 {
04567 if (myTransType == TRANS_NONE && myLastTransType == TRANS_NONE &&
04568 myRotType == ROT_NONE && myLastRotType == ROT_NONE)
04569 return false;
04570 else
04571 return true;
04572 }
04573
04574
04578 void ArRobot::enableMotors()
04579 {
04580 comInt(ArCommands::ENABLE, 1);
04581 }
04582
04586 void ArRobot::disableMotors()
04587 {
04588 comInt(ArCommands::ENABLE, 0);
04589 }
04590
04591
04600 void ArRobot::setStateReflectionRefreshTime(int mSec)
04601 {
04602 if (mSec < 0)
04603 myStateReflectionRefreshTime = 0;
04604 else
04605 myStateReflectionRefreshTime = mSec;
04606 }
04607
04615 int ArRobot::getStateReflectionRefreshTime(void) const
04616 {
04617 return myStateReflectionRefreshTime;
04618 }
04619
04635 void ArRobot::attachKeyHandler(ArKeyHandler *keyHandler,
04636 bool exitOnEscape,
04637 bool useExitNotShutdown)
04638 {
04639 if (myKeyHandlerCB != NULL)
04640 delete myKeyHandlerCB;
04641 myKeyHandlerCB = new ArFunctorC<ArKeyHandler>(keyHandler,
04642 &ArKeyHandler::checkKeys);
04643 addSensorInterpTask("Key Handler", 50, myKeyHandlerCB);
04644
04645 myKeyHandler = keyHandler;
04646 myKeyHandlerUseExitNotShutdown = useExitNotShutdown;
04647 if (exitOnEscape)
04648 keyHandler->addKeyHandler(ArKeyHandler::ESCAPE, &myKeyHandlerExitCB);
04649 }
04650
04651 ArKeyHandler *ArRobot::getKeyHandler(void) const
04652 {
04653 return myKeyHandler;
04654 }
04655
04656 void ArRobot::keyHandlerExit(void)
04657 {
04658 ArLog::log(ArLog::Terse, "Escape was pressed, program is exiting.");
04659
04660
04661 if (myKeyHandlerUseExitNotShutdown)
04662 Aria::exit();
04663 stopRunning();
04664 unlock();
04665 Aria::shutdown();
04666 }
04667
04668 void ArRobot::setPacketsReceivedTracking(bool packetsReceivedTracking)
04669 {
04670 myPacketsReceivedTracking = packetsReceivedTracking;
04671 myPacketsReceivedTrackingCount = 0;
04672 myPacketsReceivedTrackingStarted.setToNow();
04673 }
04674
04675 void ArRobot::ariaExitCallback(void)
04676 {
04677 mySyncLoop.stopRunIfNotConnected(false);
04678 disconnect();
04679 }
04680
04686 ArRobot::ChargeState ArRobot::getChargeState(void) const
04687 {
04688 return myChargeState;
04689 }