#include "Aria.h"
#include "ArNetworking.h"
#include "Arnl.h"
#include "ArSonarLocalizationTask.h"
void logOptions(const char *progname)
{
ArLog::log(ArLog::Normal, "Usage: %s [options]\n", progname);
ArLog::log(ArLog::Normal, "[options] are any program options listed below, or any ARNL configuration");
ArLog::log(ArLog::Normal, "parameters as -name <value>, see params/arnl.p for list.");
ArLog::log(ArLog::Normal, "For example, -map <map file>.");
Aria::logOptions();
}
bool gyroErrored = false;
const char* getGyroStatusString(ArRobot* robot)
{
if(!robot || !robot->getOrigRobotConfig() || robot->getOrigRobotConfig()->getGyroType() < 2) return "N/A";
if(robot->getFaultFlags() & ArUtil::BIT4)
{
gyroErrored = true;
return "ERROR/OFF";
}
if(gyroErrored)
{
return "OK but error before";
}
return "OK";
}
int main(int argc, char **argv)
{
Aria::init();
Arnl::init();
ArRobot robot;
ArArgumentParser parser(&argc, argv);
ArRobotConnector robotConnector(&parser, &robot);
if (!robotConnector.connectRobot())
{
ArLog::log(ArLog::Normal, "Error: Could not connect to robot... exiting");
Aria::exit(3);
}
char fileDir[1024];
ArUtil::addDirectories(fileDir, sizeof(fileDir), Aria::getDirectory(),
"examples");
ArLog::addToConfig(Aria::getConfig());
ArAnalogGyro gyro(&robot);
ArServerBase server;
ArServerSimpleOpener simpleOpener(&parser);
parser.loadDefaultArguments();
if (!Aria::parseArgs() || !parser.checkHelpAndWarnUnparsed())
{
logOptions(argv[0]);
Aria::exit(1);
}
ArGlobalFunctor1<int> shutdownFunctor(&Aria::exit, 9);
robot.addDisconnectOnErrorCB(&shutdownFunctor);
ArSonarDevice sonarDev;
robot.addRangeDevice(&sonarDev);
ArRobotConfig robotConfig(&robot);
robotConfig.addAnalogGyro(&gyro);
robot.runAsync(true);
ArMap map(fileDir);
map.setIgnoreEmptyFileName(true);
map.setIgnoreCase(true);
ArPathPlanningTask pathTask(&robot, &sonarDev, &map);
ArLog::log(ArLog::Normal, "Creating sonar localization task");
ArSonarLocalizationTask locTask(&robot, &sonarDev, &map);
if (!simpleOpener.open(&server, fileDir, 240))
{
ArLog::log(ArLog::Normal, "Error: Could not open server.");
exit(2);
}
robot.lock();
ArIRs irs;
robot.addRangeDevice(&irs);
pathTask.addRangeDevice(&irs, ArPathPlanningTask::CURRENT);
ArBumpers bumpers;
robot.addRangeDevice(&bumpers);
pathTask.addRangeDevice(&bumpers, ArPathPlanningTask::CURRENT);
ArForbiddenRangeDevice forbidden(&map);
robot.addRangeDevice(&forbidden);
pathTask.addRangeDevice(&forbidden, ArPathPlanningTask::CURRENT);
robot.unlock();
ArActionSlowDownWhenNotCertain actionSlowDown(&locTask);
pathTask.getPathPlanActionGroup()->addAction(&actionSlowDown, 140);
ArActionLost actionLostPath(&locTask, &pathTask);
pathTask.getPathPlanActionGroup()->addAction(&actionLostPath, 150);
ArServerInfoDrawings drawings(&server);
drawings.addRobotsRangeDevices(&robot);
ArDrawingData drawingDataP("polyLine", ArColor(200,200,200), 1, 75);
ArFunctor2C<ArPathPlanningTask, ArServerClient *, ArNetPacket *>
drawingFunctorP(&pathTask, &ArPathPlanningTask::drawSearchRectangle);
drawings.addDrawing(&drawingDataP, "Local Plan Area", &drawingFunctorP);
ArServerHandlerCommands commands(&server);
ArServerInfoRobot serverInfoRobot(&server, &robot);
ArServerInfoSensor serverInfoSensor(&server, &robot);
ArServerInfoPath serverInfoPath(&server, &robot, &pathTask);
serverInfoPath.addSearchRectangleDrawing(&drawings);
serverInfoPath.addControlCommands(&commands);
ArServerInfoLocalization serverInfoLocalization(&server, &robot, &locTask);
ArServerHandlerLocalization serverLocHandler(&server, &robot, &locTask);
ArServerHandlerMap serverMap(&server, &map);
ArServerSimpleComUC uCCommands(&commands, &robot);
ArServerSimpleComMovementLogging loggingCommands(&commands, &robot);
ArServerSimpleComLogRobotConfig configCommands(&commands, &robot);
ArServerHandlerCommMonitor handlerCommMonitor(&server);
ArServerHandlerConfig handlerConfig(&server, Aria::getConfig(),
Arnl::getTypicalDefaultParamFileName(),
Aria::getDirectory());
ArServerModeGoto modeGoto(&server, &robot, &pathTask, &map,
locTask.getRobotHome(),
locTask.getRobotHomeCallback());
ArServerModeStop modeStop(&server, &robot);
ArServerModeRatioDrive modeRatioDrive(&server, &robot);
ArActionLost actionLostRatioDrive(&locTask, &pathTask, &modeRatioDrive);
modeRatioDrive.getActionGroup()->addAction(&actionLostRatioDrive, 110);
modeRatioDrive.addToConfig(Aria::getConfig(), "Teleop settings");
modeRatioDrive.addControlCommands(&commands);
ArServerModeWander modeWander(&server, &robot);
ArActionLost actionLostWander(&locTask, &pathTask, &modeWander);
modeWander.getActionGroup()->addAction(&actionLostWander, 110);
ArServerInfoStrings stringInfo(&server);
Aria::getInfoGroup()->addAddStringCallback(stringInfo.getAddStringFunctor());
Aria::getInfoGroup()->addStringInt(
"Motor Packet Count", 10,
new ArConstRetFunctorC<int, ArRobot>(&robot,
&ArRobot::getMotorPacCount));
Aria::getInfoGroup()->addStringDouble(
"Sonar Localization Score", 8,
new ArRetFunctorC<double, ArSonarLocalizationTask>(
&locTask,
&ArSonarLocalizationTask::getLocalizationScore),
"%.03f");
Aria::getInfoGroup()->addStringInt(
"Sonar Loc Num Samples", 8,
new ArRetFunctorC<int, ArSonarLocalizationTask>(
&locTask, &ArSonarLocalizationTask::getCurrentNumSamples),
"%4d");
if(robot.getOrigRobotConfig() && robot.getOrigRobotConfig()->getGyroType() > 1)
{
Aria::getInfoGroup()->addStringString(
"Gyro/IMU Status", 10,
new ArGlobalRetFunctor1<const char*, ArRobot*>(&getGyroStatusString, &robot)
);
}
modeStop.addAsDefaultMode();
ArPoseStorage poseStorage(&robot);
if (poseStorage.restorePose("robotPose"))
serverLocHandler.setSimPose(robot.getPose());
else
robot.com(ArCommands::SIM_RESET);
#ifdef WIN32
ArLog::log(ArLog::Normal, "Note, file upload/download services are not implemented for Windows; not enabling them.");
#else
ArServerFileLister fileLister(&server, fileDir);
ArServerFileToClient fileToClient(&server, fileDir);
ArServerFileFromClient fileFromClient(&server, fileDir, "/tmp");
ArServerDeleteFileOnServer deleteFileOnServer(&server, fileDir);
#endif
ArHybridForwarderVideo videoForwarder(&server, "localhost", 7070);
ArPTZ *camera = NULL;
ArServerHandlerCamera *handlerCamera = NULL;
ArCameraCollection *cameraCollection = NULL;
if (videoForwarder.isForwardingVideo())
{
cameraCollection = new ArCameraCollection();
cameraCollection->addCamera("Cam1", "VCC4", "Camera", "VCC4");
videoForwarder.setCameraName("Cam1");
videoForwarder.addToCameraCollection(*cameraCollection);
bool invertedCamera = false;
camera = new ArVCC4(&robot, invertedCamera,
ArVCC4::COMM_UNKNOWN, true, true);
camera->init();
handlerCamera = new ArServerHandlerCamera("Cam1",
&server,
&robot,
camera,
cameraCollection);
pathTask.addGoalFinishedCB(
new ArFunctorC<ArServerHandlerCamera>(
handlerCamera,
&ArServerHandlerCamera::cameraModeLookAtGoalClearGoal));
}
if (cameraCollection != NULL) {
new ArServerHandlerCameraCollection(&server, cameraCollection);
}
Aria::getConfig()->useArgumentParser(&parser);
ArLog::log(ArLog::Normal, "Loading config file %s into ArConfig...", Arnl::getTypicalParamFileName());
if (!Aria::getConfig()->parseFile(Arnl::getTypicalParamFileName()))
{
ArLog::log(ArLog::Normal, "Trouble loading configuration file, exiting");
Aria::exit(5);
}
if (!simpleOpener.checkAndLog() || !parser.checkHelpAndWarnUnparsed())
{
logOptions(argv[0]);
Aria::exit(6);
}
if (map.getFileName() == NULL || strlen(map.getFileName()) <= 0)
{
ArLog::log(ArLog::Normal, "");
ArLog::log(ArLog::Normal, "### No map file is set up, you can make a map with the following procedure");
ArLog::log(ArLog::Normal, " 0) You can find this information in README.txt or docs/SonarMapping.txt");
ArLog::log(ArLog::Normal, " 1) Start up Mapper3Basic");
ArLog::log(ArLog::Normal, " 2) Go to File->New");
ArLog::log(ArLog::Normal, " 3) Draw a line map of your area (make sure it is to scale)");
ArLog::log(ArLog::Normal, " 4) Go to File->Save on Robot");
ArLog::log(ArLog::Normal, " 5) In MobileEyes, go to Tools->Robot Config");
ArLog::log(ArLog::Normal, " 6) Choose the Files section");
ArLog::log(ArLog::Normal, " 7) Enter the path and name of your new .map file for the value of the Map parameter.");
ArLog::log(ArLog::Normal, " 8) Press OK and your new map should become the map used");
ArLog::log(ArLog::Normal, "");
}
ArLog::log(ArLog::Normal, "");
ArLog::log(ArLog::Normal,
"Directory for maps and file serving: %s", fileDir);
ArLog::log(ArLog::Normal, "See the ARNL README.txt for more information");
ArLog::log(ArLog::Normal, "");
locTask.localizeRobotAtHomeBlocking();
server.runAsync();
ArKeyHandler *keyHandler;
if ((keyHandler = Aria::getKeyHandler()) == NULL)
{
keyHandler = new ArKeyHandler;
Aria::setKeyHandler(keyHandler);
robot.lock();
robot.attachKeyHandler(keyHandler);
robot.unlock();
puts("Server running. To exit, press escape.");
}
robot.enableMotors();
robot.waitForRunExit();
Aria::exit(0);
}