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 "Aria.h"
00027 #include "ArExport.h"
00028 #include "ArServerHandlerMapping.h"
00029
00043 AREXPORT ArServerHandlerMapping::ArServerHandlerMapping(
00044 ArServerBase *server, ArRobot *robot, ArSick *sick,
00045 const char *baseDirectory, const char *tempDirectory,
00046 bool useReflectorValues) :
00047 myMappingStartCB(this, &ArServerHandlerMapping::serverMappingStart),
00048 myMappingEndCB(this, &ArServerHandlerMapping::serverMappingEnd),
00049 myMappingStatusCB(this, &ArServerHandlerMapping::serverMappingStatus),
00050 myPacketHandlerCB(this, &ArServerHandlerMapping::packetHandler),
00051 myLoopStartCB(this, &ArServerHandlerMapping::simpleLoopStart),
00052 myLoopEndCB(this, &ArServerHandlerMapping::simpleLoopEnd)
00053 {
00054 myServer = server;
00055 myRobot = robot;
00056 mySick = sick;
00057 myUseReflectorValues = useReflectorValues;
00058
00059 if (baseDirectory != NULL && strlen(baseDirectory) > 0)
00060 myBaseDirectory = baseDirectory;
00061 else
00062 myBaseDirectory = "";
00063 if (tempDirectory != NULL && strlen(tempDirectory) > 0)
00064 myTempDirectory = tempDirectory;
00065 else
00066 myTempDirectory = myBaseDirectory;
00067
00068 if (myServer != NULL)
00069 {
00070 myServer->addData("mappingStart", "Starts making a map",
00071 &myMappingStartCB, "string: name of map file",
00072 "byte: 0 (started mapping), 1 (already mapping), 2 (could not start map)",
00073 "Mapping", "RETURN_SINGLE");
00074 myServer->addData("mappingEnd", "Stops making a map",
00075 &myMappingEndCB, "none",
00076 "byte: 0 (ended mapping), 1 (no mapping to end), 2 (could not move temporary file to permanent file)",
00077 "Mapping", "RETURN_SINGLE");
00078 myServer->addData("mappingStatus", "Gets the status of mapping",
00079 &myMappingStatusCB, "none",
00080 "string: mapName if mapping, empty string if not mapping",
00081 "RobotInfo", "RETURN_SINGLE");
00082 myServer->addData("mappingStatusBroadcast", "Gets the status of mapping, also sent when mapping starts or ends (this is a new/better mappingStatus)",
00083 &myMappingStatusCB, "none",
00084 "string: mapName if mapping, empty string if not mapping",
00085 "RobotInfo", "RETURN_SINGLE");
00086 }
00087 mySickLogger = NULL;
00088 myMapName = "";
00089 myFileName = "";
00090 myHandlerCommands = NULL;
00091
00092 myPacketHandlerCB.setName("ArServerHandlerMapping");
00093 myRobot->addPacketHandler(&myPacketHandlerCB);
00094 }
00095
00096 AREXPORT ArServerHandlerMapping::~ArServerHandlerMapping()
00097 {
00098 delete mySickLogger;
00099 mySickLogger = NULL;
00100 }
00101
00102 AREXPORT void ArServerHandlerMapping::serverMappingStart(
00103 ArServerClient *client, ArNetPacket *packet)
00104 {
00105 ArNetPacket sendPacket;
00106 char buf[512];
00107 packet->bufToStr(buf, sizeof(buf));
00108
00109
00110 if (mySickLogger != NULL)
00111 {
00112 ArLog::log(ArLog::Normal, "MappingStart: Map already being made");
00113 sendPacket.byteToBuf(1);
00114 if (client != NULL)
00115 client->sendPacketTcp(&sendPacket);
00116 return;
00117 }
00118
00119
00120 std::list<ArFunctor *>::iterator fit;
00121 for (fit = myMappingStartCallbacks.begin();
00122 fit != myMappingStartCallbacks.end();
00123 fit++)
00124 (*fit)->invoke();
00125
00126 myRobot->lock();
00127
00128 ArUtil::lower(buf, buf, sizeof(buf));
00129 myMapName = buf;
00130
00131 myFileName = myMapName;
00132 if (strstr(myMapName.c_str(), ".2d") == NULL)
00133 myFileName += ".2d";
00134
00135 mySickLogger = new ArSickLogger(myRobot, mySick, 300, 25, myFileName.c_str(),
00136 true, Aria::getJoyHandler(),
00137 myTempDirectory.c_str(),
00138 myUseReflectorValues,
00139 Aria::getRobotJoyHandler());
00140 if (mySickLogger == NULL)
00141 {
00142 ArLog::log(ArLog::Normal, "MappingStart: mySickLogger == NULL");
00143 sendPacket.byteToBuf(2);
00144 if (client != NULL)
00145 client->sendPacketTcp(&sendPacket);
00146 myMapName = "";
00147 myFileName = "";
00148 myRobot->unlock();
00149 return;
00150 }
00151 if (!mySickLogger->wasFileOpenedSuccessfully())
00152 {
00153 ArLog::log(ArLog::Normal, "MappingStart: Cannot open map file %s",
00154 myFileName.c_str());
00155 sendPacket.byteToBuf(2);
00156 if (client != NULL)
00157 client->sendPacketTcp(&sendPacket);
00158 myMapName = "";
00159 myFileName = "";
00160 delete mySickLogger;
00161 mySickLogger = NULL;
00162 myRobot->unlock();
00163 return;
00164 }
00165
00166
00167 std::list<std::string>::iterator it;
00168
00169 for (it = myStringsForStartOfLog.begin();
00170 it != myStringsForStartOfLog.end();
00171 it++)
00172 mySickLogger->addInfoToLogPlain((*it).c_str());
00173 myRobot->unlock();
00174
00175
00176 ArLog::log(ArLog::Normal, "MappingStart: Map %s started",
00177 myFileName.c_str());
00178 sendPacket.byteToBuf(0);
00179 if (client != NULL)
00180 client->sendPacketTcp(&sendPacket);
00181
00182 ArNetPacket broadcastPacket;
00183 broadcastPacket.strToBuf(myFileName.c_str());
00184 myServer->broadcastPacketTcp(&broadcastPacket, "mappingStatusBroadcast");
00185 }
00186
00187
00188 AREXPORT void ArServerHandlerMapping::serverMappingEnd(
00189 ArServerClient *client, ArNetPacket *packet)
00190 {
00191 std::list<ArFunctor *>::iterator fit;
00192
00193 ArNetPacket sendPacket;
00194 if (mySickLogger == NULL)
00195 {
00196 ArLog::log(ArLog::Normal, "MappingEnd: No map being made");
00197 sendPacket.byteToBuf(1);
00198 if (client != NULL)
00199 client->sendPacketTcp(&sendPacket);
00200 return;
00201 }
00202
00203 myRobot->lock();
00204 delete mySickLogger;
00205 mySickLogger = NULL;
00206
00207
00208
00209
00210 if (ArUtil::strcasecmp(myBaseDirectory, myTempDirectory) != 0)
00211 {
00212 #ifndef WIN32
00213 char *mvName = "mv";
00214 #else
00215 char *mvName = "move";
00216 #endif
00217 char systemBuf[6400];
00218 char fromBuf[1024];
00219 char toBuf[1024];
00220
00221 if (myTempDirectory.size() > 0)
00222 snprintf(fromBuf, sizeof(fromBuf), "%s%s",
00223 myTempDirectory.c_str(), myFileName.c_str());
00224 else
00225 snprintf(fromBuf, sizeof(fromBuf), "%s", myFileName.c_str());
00226 ArUtil::fixSlashes(fromBuf, sizeof(fromBuf));
00227
00228 if (myTempDirectory.size() > 0)
00229 snprintf(toBuf, sizeof(toBuf), "%s%s",
00230 myBaseDirectory.c_str(), myFileName.c_str());
00231 else
00232 snprintf(toBuf, sizeof(toBuf), "%s", myFileName.c_str());
00233 ArUtil::fixSlashes(toBuf, sizeof(toBuf));
00234
00235 sprintf(systemBuf, "%s \"%s\" \"%s\"", mvName, fromBuf, toBuf);
00236 ArLog::log(ArLog::Verbose, "Moving with '%s'", systemBuf);
00237
00238 for (fit = myPreMoveCallbacks.begin();
00239 fit != myPreMoveCallbacks.end();
00240 fit++)
00241 (*fit)->invoke();
00242
00243
00244 int ret;
00245 if ((ret = system(systemBuf)) == 0)
00246 {
00247 ArLog::log(ArLog::Verbose, "ArServerHandlerMapping: Moved file %s (with %s)",
00248 myFileName.c_str(), systemBuf);
00249 sendPacket.byteToBuf(0);
00250 }
00251 else
00252 {
00253 ArLog::log(ArLog::Normal,
00254 "ArServerHandlerMapping: Couldn't move file for %s (ret of '%s' is %d) removing file",
00255 myFileName.c_str(), systemBuf, ret);
00256 unlink(fromBuf);
00257 sendPacket.uByte2ToBuf(2);
00258 }
00259
00260
00261 for (fit = myPostMoveCallbacks.begin();
00262 fit != myPostMoveCallbacks.end();
00263 fit++)
00264 (*fit)->invoke();
00265
00266 }
00267 else
00268 {
00269
00270 sendPacket.byteToBuf(0);
00271 }
00272
00273
00274 ArLog::log(ArLog::Normal, "MappingEnd: Stopped mapping %s",
00275 myFileName.c_str());
00276 myMapName = "";
00277 myFileName = "";
00278
00279 myRobot->unlock();
00280 if (client != NULL)
00281 client->sendPacketTcp(&sendPacket);
00282
00283
00284 for (fit = myMappingEndCallbacks.begin();
00285 fit != myMappingEndCallbacks.end();
00286 fit++)
00287 (*fit)->invoke();
00288
00289 ArNetPacket broadcastPacket;
00290 broadcastPacket.strToBuf(myFileName.c_str());
00291 myServer->broadcastPacketTcp(&broadcastPacket, "mappingStatusBroadcast");
00292 }
00293
00294
00295 AREXPORT void ArServerHandlerMapping::serverMappingStatus(
00296 ArServerClient *client, ArNetPacket *packet)
00297 {
00298 ArNetPacket sendPacket;
00299 sendPacket.strToBuf(myMapName.c_str());
00300 client->sendPacketTcp(&sendPacket);
00301 }
00302
00303 AREXPORT void ArServerHandlerMapping::addStringForStartOfLogs(
00304 const char *str, ArListPos::Pos position)
00305 {
00306 if (position == ArListPos::FIRST)
00307 myStringsForStartOfLog.push_front(str);
00308 else if (position == ArListPos::LAST)
00309 myStringsForStartOfLog.push_back(str);
00310 else
00311 ArLog::log(ArLog::Terse, "ArServerHandlerMapping::addStringForStartOfLogs: Invalid position.");
00312 }
00313
00314 AREXPORT void ArServerHandlerMapping::remStringForStartOfLogs(
00315 char *str)
00316 {
00317 myStringsForStartOfLog.remove(str);
00318 }
00319
00320 AREXPORT void ArServerHandlerMapping::addMappingStartCallback(
00321 ArFunctor *functor, ArListPos::Pos position)
00322 {
00323 if (position == ArListPos::FIRST)
00324 myMappingStartCallbacks.push_front(functor);
00325 else if (position == ArListPos::LAST)
00326 myMappingStartCallbacks.push_back(functor);
00327 else
00328 ArLog::log(ArLog::Terse,
00329 "ArServerHandlerMapping::addMappingStartCallback: Invalid position.");
00330 }
00331
00332 AREXPORT void ArServerHandlerMapping::remMappingStartCallback(
00333 ArFunctor *functor)
00334 {
00335 myMappingStartCallbacks.remove(functor);
00336 }
00337
00338 AREXPORT void ArServerHandlerMapping::addMappingEndCallback(
00339 ArFunctor *functor, ArListPos::Pos position)
00340 {
00341 if (position == ArListPos::FIRST)
00342 myMappingEndCallbacks.push_front(functor);
00343 else if (position == ArListPos::LAST)
00344 myMappingEndCallbacks.push_back(functor);
00345 else
00346 ArLog::log(ArLog::Terse,
00347 "ArServerHandlerMapping::addMappingEndCallback: Invalid position.");
00348 }
00349
00350 AREXPORT void ArServerHandlerMapping::remMappingEndCallback(
00351 ArFunctor *functor)
00352 {
00353 myMappingEndCallbacks.remove(functor);
00354 }
00355
00356 AREXPORT void ArServerHandlerMapping::addPreMoveCallback(
00357 ArFunctor *functor, ArListPos::Pos position)
00358 {
00359 if (position == ArListPos::FIRST)
00360 myPreMoveCallbacks.push_front(functor);
00361 else if (position == ArListPos::LAST)
00362 myPreMoveCallbacks.push_back(functor);
00363 else
00364 ArLog::log(ArLog::Terse,
00365 "ArServerHandlerMapping::addPreMoveCallback: Invalid position.");
00366 }
00367
00368 AREXPORT void ArServerHandlerMapping::remPreMoveCallback(
00369 ArFunctor *functor)
00370 {
00371 myPreMoveCallbacks.remove(functor);
00372 }
00373
00374 AREXPORT void ArServerHandlerMapping::addPostMoveCallback(
00375 ArFunctor *functor, ArListPos::Pos position)
00376 {
00377 if (position == ArListPos::FIRST)
00378 myPostMoveCallbacks.push_front(functor);
00379 else if (position == ArListPos::LAST)
00380 myPostMoveCallbacks.push_back(functor);
00381 else
00382 ArLog::log(ArLog::Terse,
00383 "ArServerHandlerMapping::addPostMoveCallback: Invalid position.");
00384 }
00385
00386 AREXPORT void ArServerHandlerMapping::remPostMoveCallback(
00387 ArFunctor *functor)
00388 {
00389 myPostMoveCallbacks.remove(functor);
00390 }
00391
00392 AREXPORT void ArServerHandlerMapping::addSimpleCommands(
00393 ArServerHandlerCommands *handlerCommands)
00394 {
00395 myHandlerCommands = handlerCommands;
00396 myHandlerCommands->addStringCommand(
00397 "mappingLoopStart",
00398 "If mapping is happening it starts a new loop with the tag of the given string",
00399 &myLoopStartCB);
00400
00401 myHandlerCommands->addStringCommand(
00402 "mappingLoopEnd",
00403 "If mapping is happening it ends a loop with the tag of the given string",
00404 &myLoopEndCB);
00405 }
00406
00407 AREXPORT void ArServerHandlerMapping::simpleLoopStart(ArArgumentBuilder *arg)
00408 {
00409 if (mySickLogger != NULL)
00410 mySickLogger->addTagToLog("loop start %s", arg->getFullString());
00411 }
00412
00413 AREXPORT void ArServerHandlerMapping::simpleLoopEnd(ArArgumentBuilder *arg)
00414 {
00415 if (mySickLogger != NULL)
00416 mySickLogger->addTagToLog("loop end %s", arg->getFullString());
00417 }
00418
00420 AREXPORT bool ArServerHandlerMapping::packetHandler(ArRobotPacket *packet)
00421 {
00422 if (packet->getID() != 0x97)
00423 return false;
00424
00425 myRobot->unlock();
00426 char argument = packet->bufToByte();
00427 if (argument == 1)
00428 {
00429
00430 if (mySickLogger != NULL)
00431 {
00432 ArLog::log(ArLog::Normal,
00433 "ArServerHandlerMapping::packetHandler: Start scan requested when already mapping");
00434 }
00435 else
00436 {
00437
00438 time_t now;
00439 struct tm nowStruct;
00440 now = time(NULL);
00441 char buf[1024];
00442
00443 if (ArUtil::localtime(&now, &nowStruct))
00444 {
00445 sprintf(buf, "%02d%02d%02d_%02d%02d%02d",
00446 (nowStruct.tm_year%100), nowStruct.tm_mon+1, nowStruct.tm_mday,
00447 nowStruct.tm_hour, nowStruct.tm_min, nowStruct.tm_sec);
00448 }
00449 else
00450 {
00451 ArLog::log(ArLog::Normal,
00452 "ArServerHandlerMapping::packetHandler: Could not make good packet name (error getting time), so just naming it \"lcd\"");
00453 sprintf(buf, "lcd");
00454 }
00455
00456 ArLog::log(ArLog::Normal, "Starting scan '%s' from LCD", buf);
00457 ArNetPacket fakePacket;
00458 fakePacket.strToBuf(buf);
00459 fakePacket.finalizePacket();
00460 serverMappingStart(NULL, &fakePacket);
00461 }
00462 }
00463 else if (argument == 0)
00464 {
00465 if (mySickLogger == NULL)
00466 {
00467 ArLog::log(ArLog::Normal,
00468 "ArServerHandlerMapping::packetHandler: Stop scan requested when not mapping");
00469 }
00470 else
00471 {
00472 ArLog::log(ArLog::Normal, "Stopping scan from LCD");
00473 serverMappingEnd(NULL, NULL);
00474 }
00475 }
00476 else
00477 {
00478 ArLog::log(ArLog::Normal, "ArServerHandlerMapping::packetHandler: Unknown scan argument %d", argument);
00479 }
00480 myRobot->lock();
00481 return true;
00482 }