00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "Aria.h"
00042 #include "ArNetworking.h"
00043
00044
00045
00046
00047
00048
00049
00050
00051 class InputHandler
00052 {
00053 public:
00058 InputHandler(ArClientBase *client, ArKeyHandler *keyHandler);
00059 virtual ~InputHandler(void);
00060
00062 void up(void);
00063
00065 void down(void);
00066
00068 void left(void);
00069
00071 void right(void);
00072
00074 void sendInput(void);
00075
00077 void safeDrive();
00078
00080 void unsafeDrive();
00081
00082 void listData();
00083
00084 void logTrackingTerse();
00085 void logTrackingVerbose();
00086 void resetTracking();
00087 protected:
00088 ArClientBase *myClient;
00089 ArKeyHandler *myKeyHandler;
00090
00092 bool myPrinting;
00093
00095 double myTransRatio;
00096
00098 double myRotRatio;
00099
00102
00103 ArFunctorC<InputHandler> myUpCB;
00104 ArFunctorC<InputHandler> myDownCB;
00105 ArFunctorC<InputHandler> myLeftCB;
00106 ArFunctorC<InputHandler> myRightCB;
00107 ArFunctorC<InputHandler> mySafeDriveCB;
00108 ArFunctorC<InputHandler> myUnsafeDriveCB;
00109 ArFunctorC<InputHandler> myListDataCB;
00110 ArFunctorC<InputHandler> myLogTrackingTerseCB;
00111 ArFunctorC<InputHandler> myLogTrackingVerboseCB;
00112 ArFunctorC<InputHandler> myResetTrackingCB;
00114 };
00115
00116 InputHandler::InputHandler(ArClientBase *client, ArKeyHandler *keyHandler) :
00117 myClient(client), myKeyHandler(keyHandler),
00118 myPrinting(false), myTransRatio(0.0), myRotRatio(0.0) ,
00119
00120
00121 myUpCB(this, &InputHandler::up),
00122 myDownCB(this, &InputHandler::down),
00123 myLeftCB(this, &InputHandler::left),
00124 myRightCB(this, &InputHandler::right),
00125 mySafeDriveCB(this, &InputHandler::safeDrive),
00126 myUnsafeDriveCB(this, &InputHandler::unsafeDrive),
00127 myListDataCB(this, &InputHandler::listData),
00128 myLogTrackingTerseCB(this, &InputHandler::logTrackingTerse),
00129 myLogTrackingVerboseCB(this, &InputHandler::logTrackingVerbose),
00130 myResetTrackingCB(this, &InputHandler::resetTracking)
00131 {
00132
00133
00134
00135 myKeyHandler->addKeyHandler(ArKeyHandler::UP, &myUpCB);
00136 myKeyHandler->addKeyHandler(ArKeyHandler::DOWN, &myDownCB);
00137 myKeyHandler->addKeyHandler(ArKeyHandler::LEFT, &myLeftCB);
00138 myKeyHandler->addKeyHandler(ArKeyHandler::RIGHT, &myRightCB);
00139 myKeyHandler->addKeyHandler('s', &mySafeDriveCB);
00140 myKeyHandler->addKeyHandler('u', &myUnsafeDriveCB);
00141 myKeyHandler->addKeyHandler('l', &myListDataCB);
00142 myKeyHandler->addKeyHandler('t', &myLogTrackingTerseCB);
00143 myKeyHandler->addKeyHandler('v', &myLogTrackingVerboseCB);
00144 myKeyHandler->addKeyHandler('r', &myResetTrackingCB);
00145 }
00146
00147 InputHandler::~InputHandler(void)
00148 {
00149
00150 }
00151
00152 void InputHandler::up(void)
00153 {
00154 if (myPrinting)
00155 printf("Forwards\n");
00156 myTransRatio = 100;
00157 }
00158
00159 void InputHandler::down(void)
00160 {
00161 if (myPrinting)
00162 printf("Backwards\n");
00163 myTransRatio = -100;
00164 }
00165
00166 void InputHandler::left(void)
00167 {
00168 if (myPrinting)
00169 printf("Left\n");
00170 myRotRatio = 100;
00171 }
00172
00173 void InputHandler::right(void)
00174 {
00175 if (myPrinting)
00176 printf("Right\n");
00177 myRotRatio = -100;
00178 }
00179
00180 void InputHandler::safeDrive()
00181 {
00182
00183
00184 ArNetPacket p;
00185 p.byteToBuf(1);
00186
00187
00188 if(myPrinting)
00189 printf("Sending setSafeDrive 1.\n");
00190 myClient->requestOnce("setSafeDrive",&p);
00191 if(myPrinting)
00192 printf("\nSent enable safe drive.\n");
00193 }
00194
00195 void InputHandler::unsafeDrive()
00196 {
00197
00198
00199 ArNetPacket p;
00200 p.byteToBuf(0);
00201
00202
00203 if(myPrinting)
00204 printf("Sending setSafeDrive 0.\n");
00205 myClient->requestOnce("setSafeDrive",&p);
00206 if(myPrinting)
00207 printf("\nSent disable safe drive command. Your robot WILL run over things if you're not careful.\n");
00208 }
00209
00210 void InputHandler::listData()
00211 {
00212 myClient->logDataList();
00213 }
00214
00215 void InputHandler::logTrackingTerse()
00216 {
00217 myClient->logTracking(true);
00218 }
00219
00220 void InputHandler::logTrackingVerbose()
00221 {
00222 myClient->logTracking(false);
00223 }
00224
00225 void InputHandler::resetTracking()
00226 {
00227 myClient->resetTracking();
00228 }
00229
00230
00231 void InputHandler::sendInput(void)
00232 {
00233
00234
00235
00236 if(!myClient->dataExists("ratioDrive")) return;
00237
00238
00239
00240
00241 ArNetPacket packet;
00242 packet.doubleToBuf(myTransRatio);
00243 packet.doubleToBuf(myRotRatio);
00244 packet.doubleToBuf(50);
00245 if (myPrinting)
00246 printf("Sending\n");
00247 myClient->requestOnce("ratioDrive", &packet);
00248 myTransRatio = 0;
00249 myRotRatio = 0;
00250 }
00251
00252
00256 class OutputHandler
00257 {
00258 public:
00259 OutputHandler(ArClientBase *client);
00260 virtual ~OutputHandler(void);
00261
00263 void handleOutput(ArNetPacket *packet);
00264
00266 void handleBatteryInfo(ArNetPacket *packet);
00268 void handlePhysicalInfo(ArNetPacket *packet);
00269
00270 protected:
00271
00273
00274 double myX;
00275 double myY;
00276 double myTh;
00277 double myVel;
00278 double myRotVel;
00279 double myVoltage;
00280 char myStatus[256];
00281 char myMode[32];
00283 ArClientBase *myClient;
00284
00289 ArFunctor1C<OutputHandler, ArNetPacket *> myHandleOutputCB;
00290 ArFunctor1C<OutputHandler, ArNetPacket *> myHandleBatteryInfoCB;
00291 ArFunctor1C<OutputHandler, ArNetPacket *> myHandlePhysicalInfoCB;
00293
00295 bool myNeedToPrintHeader;
00297 bool myGotBatteryInfo;
00298 };
00299
00300 OutputHandler::OutputHandler(ArClientBase *client) :
00301 myClient(client),
00302 myHandleOutputCB(this, &OutputHandler::handleOutput),
00303 myHandleBatteryInfoCB(this, &OutputHandler::handleBatteryInfo),
00304 myHandlePhysicalInfoCB(this, &OutputHandler::handlePhysicalInfo),
00305 myNeedToPrintHeader(false),
00306 myGotBatteryInfo(false)
00307 {
00308
00309 myClient->addHandler("physicalInfo", &myHandlePhysicalInfoCB);
00310 myClient->requestOnce("physicalInfo");
00311
00312
00313
00314 myClient->addHandler("batteryInfo", &myHandleBatteryInfoCB);
00315 myClient->requestOnce("batteryInfo");
00316
00317
00318 myClient->addHandler("update", &myHandleOutputCB);
00319 myClient->request("update", 100);
00320 }
00321
00322 OutputHandler::~OutputHandler(void)
00323 {
00324
00325 myClient->requestStop("update");
00326 }
00327
00328 void OutputHandler::handleOutput(ArNetPacket *packet)
00329 {
00330
00331
00332
00333
00334
00335
00336 memset(myStatus, 0, sizeof(myStatus));
00337 memset(myMode, 0, sizeof(myMode));
00338 packet->bufToStr(myStatus, sizeof(myStatus));
00339 packet->bufToStr(myMode, sizeof(myMode));
00340 myVoltage = ( (double) packet->bufToByte2() )/10.0;
00341 myX = (double) packet->bufToByte4();
00342 myY = (double) packet->bufToByte4();
00343 myTh = (double) packet->bufToByte2();
00344 myVel = (double) packet->bufToByte2();
00345 myRotVel = (double) packet->bufToByte2();
00346
00347 if(myNeedToPrintHeader)
00348 {
00349 printf("\n%6s|%6s|%6s|%6s|%6s|%6s|%15s|%20s|\n",
00350 "x","y","theta", "vel", "rotVel", "volts", "mode","status");
00351 fflush(stdout);
00352 myNeedToPrintHeader = false;
00353 }
00354 if (myGotBatteryInfo)
00355 printf("%6.0f|%6.0f|%6.1f|%6.1f|%6.1f|%6.1f|%15s|%20s|\r",
00356 myX, myY, myTh, myVel, myRotVel, myVoltage, myMode, myStatus);
00357
00358 fflush(stdout);
00359 }
00360
00361 void OutputHandler::handleBatteryInfo(ArNetPacket *packet)
00362 {
00363
00364
00365
00366 double lowBattery = packet->bufToDouble();
00367 double shutdown = packet->bufToDouble();
00368 printf("Low battery voltage: %6g Shutdown battery voltage: %6g\n", lowBattery, shutdown);
00369 fflush(stdout);
00370 myNeedToPrintHeader = true;
00371 myGotBatteryInfo = true;
00372 }
00373
00374
00375 void OutputHandler::handlePhysicalInfo(ArNetPacket *packet)
00376 {
00377
00378 char robotType[512];
00379 char robotSubtype[512];
00380 int width;
00381 int lengthFront;
00382 int lengthRear;
00383
00384 packet->bufToStr(robotType, sizeof(robotType));
00385 packet->bufToStr(robotSubtype, sizeof(robotSubtype));
00386 width = packet->bufToByte2();
00387 lengthFront = packet->bufToByte2();
00388 lengthRear = packet->bufToByte2();
00389
00390 printf("Type: %s Subtype: %s Width %d: LengthFront: %d LengthRear: %d\n",
00391 robotType, robotSubtype, width, lengthFront, lengthRear);
00392 fflush(stdout);
00393 }
00394
00395
00396
00397 void escape(void)
00398 {
00399 printf("esc pressed, shutting down aria\n");
00400 Aria::shutdown();
00401 }
00402
00403 int main(int argc, char **argv)
00404 {
00405
00406 Aria::init();
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 ArClientBase client;
00420
00421
00422 ArArgumentParser parser(&argc, argv);
00423
00424
00425
00426
00427
00428 ArClientSimpleConnector clientConnector(&parser);
00429
00430 parser.loadDefaultArguments();
00431
00432
00433 if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed())
00434 {
00435 Aria::logOptions();
00436 exit(0);
00437 }
00438
00439
00440
00441 if (!clientConnector.connectClient(&client))
00442 {
00443 if (client.wasRejected())
00444 printf("Server '%s' rejected connection, exiting\n", client.getHost());
00445 else
00446 printf("Could not connect to server '%s', exiting\n", client.getHost());
00447 exit(1);
00448 }
00449
00450 printf("Connected to server.\n");
00451
00452
00453
00454 ArKeyHandler keyHandler;
00455 Aria::setKeyHandler(&keyHandler);
00456
00457
00458 ArGlobalFunctor escapeCB(&escape);
00459 keyHandler.addKeyHandler(ArKeyHandler::ESCAPE, &escapeCB);
00460
00461
00462
00463
00464
00465
00466 client.runAsync();
00467
00468
00469 InputHandler inputHandler(&client, &keyHandler);
00470 inputHandler.safeDrive();
00471
00472
00473
00474 if(!client.dataExists("ratioDrive") )
00475 printf("Warning: server does not have ratioDrive command, can not use drive commands!\n");
00476 else
00477 printf("Keys are:\nUP: Forward\nDOWN: Backward\nLEFT: Turn Left\nRIGHT: Turn Right\n");
00478 printf("s: Enable safe drive mode (if supported).\nu: Disable safe drive mode (if supported).\nl: list all data requests on server\n\nDrive commands use 'ratioDrive'.\nt: logs the network tracking tersely\nv: logs the network tracking verbosely\nr: resets the network tracking\n\n");
00479
00480
00481
00482
00483 OutputHandler outputHandler(&client);
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 while (client.getRunningWithLock())
00496 {
00497 keyHandler.checkKeys();
00498 inputHandler.sendInput();
00499 ArUtil::sleep(100);
00500 }
00501
00502
00503
00504 Aria::shutdown();
00505 return 0;
00506 }