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