00001
00031 #include "Aria.h"
00032 #include "ArNetworking.h"
00033 #include "Arnl.h"
00034
00035 #include "ArSonarLocalizationTask.h"
00036
00037 void logOptions(const char *progname)
00038 {
00039 ArLog::log(ArLog::Normal, "Usage: %s [options]\n", progname);
00040 ArLog::log(ArLog::Normal, "[options] are any program options listed below, or any ARNL configuration");
00041 ArLog::log(ArLog::Normal, "parameters as -name <value>, see params/arnl.p for list.");
00042 ArLog::log(ArLog::Normal, "For example, -map <map file>.");
00043 Aria::logOptions();
00044 }
00045
00046 bool gyroErrored = false;
00047 const char* getGyroStatusString(ArRobot* robot)
00048 {
00049 if(!robot || !robot->getOrigRobotConfig() || robot->getOrigRobotConfig()->getGyroType() < 2) return "N/A";
00050 if(robot->getFaultFlags() & ArUtil::BIT4)
00051 {
00052 gyroErrored = true;
00053 return "ERROR/OFF";
00054 }
00055 if(gyroErrored)
00056 {
00057 return "OK but error before";
00058 }
00059 return "OK";
00060 }
00061
00062 int main(int argc, char **argv)
00063 {
00064
00065 Aria::init();
00066 Arnl::init();
00067
00068
00069
00070 ArRobot robot;
00071
00072
00073 ArArgumentParser parser(&argc, argv);
00074
00075
00076
00077 ArRobotConnector robotConnector(&parser, &robot);
00078
00079
00080 if (!robotConnector.connectRobot())
00081 {
00082 ArLog::log(ArLog::Normal, "Error: Could not connect to robot... exiting");
00083 Aria::exit(3);
00084 }
00085
00086
00087
00088
00089
00090
00091 char fileDir[1024];
00092 ArUtil::addDirectories(fileDir, sizeof(fileDir), Aria::getDirectory(),
00093 "examples");
00094
00095
00096
00097
00098
00099
00100
00101 ArLog::addToConfig(Aria::getConfig());
00102
00103
00104
00105 ArAnalogGyro gyro(&robot);
00106
00107
00108 ArServerBase server;
00109
00110
00111
00112 ArServerSimpleOpener simpleOpener(&parser);
00113
00114
00115
00116
00117 parser.loadDefaultArguments();
00118
00119
00120 if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed())
00121 {
00122 logOptions(argv[0]);
00123 Aria::exit(1);
00124 }
00125
00126
00127
00128
00129 ArGlobalFunctor1<int> shutdownFunctor(&Aria::exit, 9);
00130 robot.addDisconnectOnErrorCB(&shutdownFunctor);
00131
00132
00133
00134
00135 ArSonarDevice sonarDev;
00136 robot.addRangeDevice(&sonarDev);
00137
00138
00139
00140
00141
00142 ArRobotConfig robotConfig(&robot);
00143
00144
00145 robotConfig.addAnalogGyro(&gyro);
00146
00147
00148 robot.runAsync(true);
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 ArMap map(fileDir);
00162
00163
00164 map.setIgnoreEmptyFileName(true);
00165
00166
00167
00168 map.setIgnoreCase(true);
00169
00170
00171
00172
00173
00174 ArPathPlanningTask pathTask(&robot, &sonarDev, &map);
00175
00176
00177 ArLog::log(ArLog::Normal, "Creating sonar localization task");
00178 ArSonarLocalizationTask locTask(&robot, &sonarDev, &map);
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 if (!simpleOpener.open(&server, fileDir, 240))
00191 {
00192 ArLog::log(ArLog::Normal, "Error: Could not open server.");
00193 exit(2);
00194 }
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 robot.lock();
00211 ArIRs irs;
00212 robot.addRangeDevice(&irs);
00213 pathTask.addRangeDevice(&irs, ArPathPlanningTask::CURRENT);
00214
00215
00216
00217 ArBumpers bumpers;
00218 robot.addRangeDevice(&bumpers);
00219 pathTask.addRangeDevice(&bumpers, ArPathPlanningTask::CURRENT);
00220
00221
00222
00223
00224 ArForbiddenRangeDevice forbidden(&map);
00225 robot.addRangeDevice(&forbidden);
00226 pathTask.addRangeDevice(&forbidden, ArPathPlanningTask::CURRENT);
00227
00228 robot.unlock();
00229
00230
00231
00232 ArActionSlowDownWhenNotCertain actionSlowDown(&locTask);
00233 pathTask.getPathPlanActionGroup()->addAction(&actionSlowDown, 140);
00234
00235
00236 ArActionLost actionLostPath(&locTask, &pathTask);
00237 pathTask.getPathPlanActionGroup()->addAction(&actionLostPath, 150);
00238
00239
00240
00241
00242 ArServerInfoDrawings drawings(&server);
00243 drawings.addRobotsRangeDevices(&robot);
00244
00245
00246
00247
00248 ArDrawingData drawingDataP("polyLine", ArColor(200,200,200), 1, 75);
00249 ArFunctor2C<ArPathPlanningTask, ArServerClient *, ArNetPacket *>
00250 drawingFunctorP(&pathTask, &ArPathPlanningTask::drawSearchRectangle);
00251 drawings.addDrawing(&drawingDataP, "Local Plan Area", &drawingFunctorP);
00252
00253
00254
00255
00256
00257
00258 ArServerHandlerCommands commands(&server);
00259
00260
00261
00262 ArServerInfoRobot serverInfoRobot(&server, &robot);
00263 ArServerInfoSensor serverInfoSensor(&server, &robot);
00264 ArServerInfoPath serverInfoPath(&server, &robot, &pathTask);
00265 serverInfoPath.addSearchRectangleDrawing(&drawings);
00266 serverInfoPath.addControlCommands(&commands);
00267
00268
00269
00270 ArServerInfoLocalization serverInfoLocalization(&server, &robot, &locTask);
00271 ArServerHandlerLocalization serverLocHandler(&server, &robot, &locTask);
00272
00273
00274
00275
00276
00277
00278
00279
00280 ArServerHandlerMap serverMap(&server, &map);
00281
00282
00283 ArServerSimpleComUC uCCommands(&commands, &robot);
00284 ArServerSimpleComMovementLogging loggingCommands(&commands, &robot);
00285 ArServerSimpleComLogRobotConfig configCommands(&commands, &robot);
00286
00287
00288
00289
00290
00291
00292 ArServerHandlerCommMonitor handlerCommMonitor(&server);
00293
00294
00295
00296
00297 ArServerHandlerConfig handlerConfig(&server, Aria::getConfig(),
00298 Arnl::getTypicalDefaultParamFileName(),
00299 Aria::getDirectory());
00300
00301
00302
00303
00304
00305
00306
00307
00308 ArServerModeGoto modeGoto(&server, &robot, &pathTask, &map,
00309 locTask.getRobotHome(),
00310 locTask.getRobotHomeCallback());
00311
00312
00313
00314 ArServerModeStop modeStop(&server, &robot);
00315
00316
00317
00318 ArServerModeRatioDrive modeRatioDrive(&server, &robot);
00319
00320
00321
00322
00323
00324
00325
00326
00327 ArActionLost actionLostRatioDrive(&locTask, &pathTask, &modeRatioDrive);
00328 modeRatioDrive.getActionGroup()->addAction(&actionLostRatioDrive, 110);
00329
00330
00331 modeRatioDrive.addToConfig(Aria::getConfig(), "Teleop settings");
00332 modeRatioDrive.addControlCommands(&commands);
00333
00334
00335 ArServerModeWander modeWander(&server, &robot);
00336 ArActionLost actionLostWander(&locTask, &pathTask, &modeWander);
00337 modeWander.getActionGroup()->addAction(&actionLostWander, 110);
00338
00339
00340
00341
00342
00343 ArServerInfoStrings stringInfo(&server);
00344 Aria::getInfoGroup()->addAddStringCallback(stringInfo.getAddStringFunctor());
00345
00346
00347
00348
00349 Aria::getInfoGroup()->addStringInt(
00350 "Motor Packet Count", 10,
00351 new ArConstRetFunctorC<int, ArRobot>(&robot,
00352 &ArRobot::getMotorPacCount));
00353
00354 Aria::getInfoGroup()->addStringDouble(
00355 "Sonar Localization Score", 8,
00356 new ArRetFunctorC<double, ArSonarLocalizationTask>(
00357 &locTask,
00358 &ArSonarLocalizationTask::getLocalizationScore),
00359 "%.03f");
00360 Aria::getInfoGroup()->addStringInt(
00361 "Sonar Loc Num Samples", 8,
00362 new ArRetFunctorC<int, ArSonarLocalizationTask>(
00363 &locTask, &ArSonarLocalizationTask::getCurrentNumSamples),
00364 "%4d");
00365
00366
00367
00368
00369
00370
00371 if(robot.getOrigRobotConfig() && robot.getOrigRobotConfig()->getGyroType() > 1)
00372 {
00373 Aria::getInfoGroup()->addStringString(
00374 "Gyro/IMU Status", 10,
00375 new ArGlobalRetFunctor1<const char*, ArRobot*>(&getGyroStatusString, &robot)
00376 );
00377 }
00378
00379
00380
00381
00382
00383
00384
00385 modeStop.addAsDefaultMode();
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 ArPoseStorage poseStorage(&robot);
00412 if (poseStorage.restorePose("robotPose"))
00413 serverLocHandler.setSimPose(robot.getPose());
00414 else
00415 robot.com(ArCommands::SIM_RESET);
00416
00417
00418
00419
00420
00421 #ifdef WIN32
00422
00423 ArLog::log(ArLog::Normal, "Note, file upload/download services are not implemented for Windows; not enabling them.");
00424 #else
00425
00426
00427
00428 ArServerFileLister fileLister(&server, fileDir);
00429 ArServerFileToClient fileToClient(&server, fileDir);
00430 ArServerFileFromClient fileFromClient(&server, fileDir, "/tmp");
00431 ArServerDeleteFileOnServer deleteFileOnServer(&server, fileDir);
00432
00433 #endif
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 ArHybridForwarderVideo videoForwarder(&server, "localhost", 7070);
00445
00446
00447
00448 ArPTZ *camera = NULL;
00449 ArServerHandlerCamera *handlerCamera = NULL;
00450 ArCameraCollection *cameraCollection = NULL;
00451
00452
00453 if (videoForwarder.isForwardingVideo())
00454 {
00455
00456 cameraCollection = new ArCameraCollection();
00457 cameraCollection->addCamera("Cam1", "VCC4", "Camera", "VCC4");
00458
00459 videoForwarder.setCameraName("Cam1");
00460 videoForwarder.addToCameraCollection(*cameraCollection);
00461
00462 bool invertedCamera = false;
00463 camera = new ArVCC4(&robot, invertedCamera,
00464 ArVCC4::COMM_UNKNOWN, true, true);
00465 camera->init();
00466
00467 handlerCamera = new ArServerHandlerCamera("Cam1",
00468 &server,
00469 &robot,
00470 camera,
00471 cameraCollection);
00472
00473 pathTask.addGoalFinishedCB(
00474 new ArFunctorC<ArServerHandlerCamera>(
00475 handlerCamera,
00476 &ArServerHandlerCamera::cameraModeLookAtGoalClearGoal));
00477 }
00478
00479
00480
00481
00482 if (cameraCollection != NULL) {
00483 new ArServerHandlerCameraCollection(&server, cameraCollection);
00484 }
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 Aria::getConfig()->useArgumentParser(&parser);
00496
00497
00498 ArLog::log(ArLog::Normal, "Loading config file %s into ArConfig...", Arnl::getTypicalParamFileName());
00499 if (!Aria::getConfig()->parseFile(Arnl::getTypicalParamFileName()))
00500 {
00501 ArLog::log(ArLog::Normal, "Trouble loading configuration file, exiting");
00502 Aria::exit(5);
00503 }
00504
00505
00506 if (!simpleOpener.checkAndLog() || !parser.checkHelpAndWarnUnparsed())
00507 {
00508 logOptions(argv[0]);
00509 Aria::exit(6);
00510 }
00511
00512
00513 if (map.getFileName() == NULL || strlen(map.getFileName()) <= 0)
00514 {
00515 ArLog::log(ArLog::Normal, "");
00516 ArLog::log(ArLog::Normal, "### No map file is set up, you can make a map with the following procedure");
00517 ArLog::log(ArLog::Normal, " 0) You can find this information in README.txt or docs/SonarMapping.txt");
00518 ArLog::log(ArLog::Normal, " 1) Start up Mapper3Basic");
00519 ArLog::log(ArLog::Normal, " 2) Go to File->New");
00520 ArLog::log(ArLog::Normal, " 3) Draw a line map of your area (make sure it is to scale)");
00521 ArLog::log(ArLog::Normal, " 4) Go to File->Save on Robot");
00522 ArLog::log(ArLog::Normal, " 5) In MobileEyes, go to Tools->Robot Config");
00523 ArLog::log(ArLog::Normal, " 6) Choose the Files section");
00524 ArLog::log(ArLog::Normal, " 7) Enter the path and name of your new .map file for the value of the Map parameter.");
00525 ArLog::log(ArLog::Normal, " 8) Press OK and your new map should become the map used");
00526 ArLog::log(ArLog::Normal, "");
00527 }
00528
00529
00530 ArLog::log(ArLog::Normal, "");
00531 ArLog::log(ArLog::Normal,
00532 "Directory for maps and file serving: %s", fileDir);
00533
00534 ArLog::log(ArLog::Normal, "See the ARNL README.txt for more information");
00535 ArLog::log(ArLog::Normal, "");
00536
00537
00538
00539
00540
00541
00542
00543 locTask.localizeRobotAtHomeBlocking();
00544
00545
00546
00547 server.runAsync();
00548
00549
00550
00551
00552
00553
00554
00555 ArKeyHandler *keyHandler;
00556 if ((keyHandler = Aria::getKeyHandler()) == NULL)
00557 {
00558 keyHandler = new ArKeyHandler;
00559 Aria::setKeyHandler(keyHandler);
00560 robot.lock();
00561 robot.attachKeyHandler(keyHandler);
00562 robot.unlock();
00563 puts("Server running. To exit, press escape.");
00564 }
00565
00566
00567
00568 robot.enableMotors();
00569 robot.waitForRunExit();
00570 Aria::exit(0);
00571 }
00572