|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00007 // The simulated network and simulation perfomer 00008 /****************************************************************************/ 00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00010 // Copyright (C) 2001-2011 DLR (http://www.dlr.de/) and contributors 00011 /****************************************************************************/ 00012 // 00013 // This program is free software; you can redistribute it and/or modify 00014 // it under the terms of the GNU General Public License as published by 00015 // the Free Software Foundation; either version 2 of the License, or 00016 // (at your option) any later version. 00017 // 00018 /****************************************************************************/ 00019 00020 00021 // =========================================================================== 00022 // included modules 00023 // =========================================================================== 00024 #ifdef _MSC_VER 00025 #include <windows_config.h> 00026 #else 00027 #include <config.h> 00028 #endif 00029 00030 #ifdef HAVE_VERSION_H 00031 #include <version.h> 00032 #endif 00033 00034 #include <iostream> 00035 #include <sstream> 00036 #include <typeinfo> 00037 #include <algorithm> 00038 #include <cassert> 00039 #include <vector> 00040 #include <sstream> 00041 #include <utils/common/UtilExceptions.h> 00042 #include "MSNet.h" 00043 #include "MSPersonControl.h" 00044 #include "MSEdgeControl.h" 00045 #include "MSJunctionControl.h" 00046 #include "MSInsertionControl.h" 00047 #include "MSEventControl.h" 00048 #include "MSEdge.h" 00049 #include "MSJunction.h" 00050 #include "MSJunctionLogic.h" 00051 #include "MSLane.h" 00052 #include "MSVehicleTransfer.h" 00053 #include "MSRoute.h" 00054 #include "MSRouteLoaderControl.h" 00055 #include "traffic_lights/MSTLLogicControl.h" 00056 #include "MSVehicleControl.h" 00057 #include <utils/common/MsgHandler.h> 00058 #include <utils/common/ToString.h> 00059 #include <microsim/output/MSDetectorControl.h> 00060 #include <microsim/MSVehicleTransfer.h> 00061 #include "traffic_lights/MSTrafficLightLogic.h" 00062 #include <utils/shapes/Polygon.h> 00063 #include <utils/shapes/ShapeContainer.h> 00064 #include "output/MSXMLRawOut.h" 00065 #include <utils/iodevices/OutputDevice.h> 00066 #include <utils/common/SysUtils.h> 00067 #include <utils/common/WrappingCommand.h> 00068 #include <utils/options/OptionsCont.h> 00069 #include "MSGlobals.h" 00070 #include <utils/geom/GeoConvHelper.h> 00071 #include <ctime> 00072 #include "MSPerson.h" 00073 #include "MSEdgeWeightsStorage.h" 00074 00075 00076 #ifdef _MESSAGES 00077 #include "MSMessageEmitter.h" 00078 #endif 00079 00080 #ifdef HAVE_MESOSIM 00081 #include <mesosim/MELoop.h> 00082 #include <utils/iodevices/BinaryInputDevice.h> 00083 #endif 00084 00085 #ifndef NO_TRACI 00086 #include <traci-server/TraCIServer.h> 00087 #endif 00088 00089 #ifdef CHECK_MEMORY_LEAKS 00090 #include <foreign/nvwa/debug_new.h> 00091 #endif // CHECK_MEMORY_LEAKS 00092 00093 00094 // =========================================================================== 00095 // static member definitions 00096 // =========================================================================== 00097 MSNet* MSNet::myInstance = 0; 00098 00099 00100 // =========================================================================== 00101 // member method definitions 00102 // =========================================================================== 00103 // --------------------------------------------------------------------------- 00104 // MSNet::EdgeWeightsProxi - methods 00105 // --------------------------------------------------------------------------- 00106 SUMOReal 00107 MSNet::EdgeWeightsProxi::getEffort(const MSEdge* const e, 00108 const SUMOVehicle* const v, 00109 SUMOReal t) const { 00110 SUMOReal value; 00111 if (myVehicleKnowledge.retrieveExistingEffort(e, v, t, value)) { 00112 return value; 00113 } 00114 if (myNetKnowledge.retrieveExistingEffort(e, v, t, value)) { 00115 return value; 00116 } 00117 return 0; 00118 } 00119 00120 00121 SUMOReal 00122 MSNet::EdgeWeightsProxi::getTravelTime(const MSEdge* const e, 00123 const SUMOVehicle* const v, 00124 SUMOReal t) const { 00125 SUMOReal value; 00126 if (myVehicleKnowledge.retrieveExistingTravelTime(e, v, t, value)) { 00127 return value; 00128 } 00129 if (myNetKnowledge.retrieveExistingTravelTime(e, v, t, value)) { 00130 return value; 00131 } 00132 const MSLane* const l = e->getLanes()[0]; 00133 return l->getLength() / l->getMaxSpeed(); 00134 } 00135 00136 00137 00138 // --------------------------------------------------------------------------- 00139 // MSNet - methods 00140 // --------------------------------------------------------------------------- 00141 MSNet* 00142 MSNet::getInstance(void) throw(ProcessError) { 00143 if (myInstance != 0) { 00144 return myInstance; 00145 } 00146 throw ProcessError("A network was not yet constructed."); 00147 } 00148 00149 00150 MSNet::MSNet(MSVehicleControl* vc, MSEventControl* beginOfTimestepEvents, 00151 MSEventControl* endOfTimestepEvents, MSEventControl* insertionEvents, 00152 ShapeContainer* shapeCont) throw(ProcessError) { 00153 if (myInstance!=0) { 00154 throw ProcessError("A network was already constructed."); 00155 } 00156 OptionsCont& oc = OptionsCont::getOptions(); 00157 myStep = string2time(oc.getString("begin")); 00158 myLogExecutionTime = !oc.getBool("no-duration-log"); 00159 myLogStepNumber = !oc.getBool("no-step-log"); 00160 myTooManyVehicles = oc.getInt("max-num-vehicles"); 00161 myInserter = new MSInsertionControl(*vc, string2time(oc.getString("max-depart-delay")), oc.getBool("sloppy-insert")); 00162 myVehicleControl = vc; 00163 myDetectorControl = new MSDetectorControl(); 00164 myEdges = 0; 00165 myJunctions = 0; 00166 myRouteLoaders = 0; 00167 myLogics = 0; 00168 myPersonControl = 0; 00169 myEdgeWeights = 0; 00170 myShapeContainer = shapeCont==0 ? new ShapeContainer() : shapeCont; 00171 00172 myBeginOfTimestepEvents = beginOfTimestepEvents; 00173 myEndOfTimestepEvents = endOfTimestepEvents; 00174 myInsertionEvents = insertionEvents; 00175 00176 #ifdef HAVE_MESOSIM 00177 if (MSGlobals::gUseMesoSim) { 00178 MSGlobals::gMesoNet = new MELoop(string2time(oc.getString("meso-recheck"))); 00179 } 00180 #endif 00181 myInstance = this; 00182 } 00183 00184 00185 00186 00187 void 00188 MSNet::closeBuilding(MSEdgeControl* edges, MSJunctionControl* junctions, 00189 MSRouteLoaderControl* routeLoaders, 00190 MSTLLogicControl* tlc, 00191 std::vector<SUMOTime> stateDumpTimes, 00192 std::vector<std::string> stateDumpFiles) throw() { 00193 myEdges = edges; 00194 myJunctions = junctions; 00195 myRouteLoaders = routeLoaders; 00196 myLogics = tlc; 00197 // save the time the network state shall be saved at 00198 myStateDumpTimes = stateDumpTimes; 00199 myStateDumpFiles = stateDumpFiles; 00200 00201 // set requests/responses 00202 myJunctions->postloadInitContainer(); 00203 00204 // initialise performance computation 00205 if (myLogExecutionTime) { 00206 mySimBeginMillis = SysUtils::getCurrentMillis(); 00207 } 00208 } 00209 00210 00211 MSNet::~MSNet() throw() { 00212 // delete controls 00213 delete myJunctions; 00214 delete myDetectorControl; 00215 // delete mean data 00216 delete myEdges; 00217 delete myInserter; 00218 delete myLogics; 00219 delete myRouteLoaders; 00220 delete myVehicleControl; 00221 if (myPersonControl!=0) { 00222 delete myPersonControl; 00223 } 00224 delete myShapeContainer; 00225 #ifdef _MESSAGES 00226 myMsgEmitter.clear(); 00227 msgEmitVec.clear(); 00228 #endif 00229 #ifdef HAVE_MESOSIM 00230 if (MSGlobals::gUseMesoSim) { 00231 delete MSGlobals::gMesoNet; 00232 } 00233 #endif 00234 delete myBeginOfTimestepEvents; 00235 delete myEndOfTimestepEvents; 00236 delete myInsertionEvents; 00237 delete myEdgeWeights; 00238 clearAll(); 00239 myInstance = 0; 00240 } 00241 00242 00243 int 00244 MSNet::simulate(SUMOTime start, SUMOTime stop) { 00245 // the simulation loop 00246 MSNet::SimulationState state = SIMSTATE_RUNNING; 00247 myStep = start; 00248 #ifndef NO_TRACI 00249 #ifdef HAVE_PYTHON 00250 if (OptionsCont::getOptions().isSet("python-script")) { 00251 traci::TraCIServer::runEmbedded(OptionsCont::getOptions().getString("python-script")); 00252 WRITE_MESSAGE("Simulation End: Script ended"); 00253 closeSimulation(start); 00254 return 0; 00255 } 00256 #endif 00257 #endif 00258 while (state==SIMSTATE_RUNNING) { 00259 if (myLogStepNumber) { 00260 preSimStepOutput(); 00261 } 00262 simulationStep(); 00263 if (myLogStepNumber) { 00264 postSimStepOutput(); 00265 } 00266 state = simulationState(stop); 00267 #ifndef NO_TRACI 00268 if (state!=SIMSTATE_RUNNING) { 00269 if (OptionsCont::getOptions().getInt("remote-port")!=0&&!traci::TraCIServer::wasClosed()) { 00270 state = SIMSTATE_RUNNING; 00271 } 00272 } 00273 #endif 00274 } 00275 WRITE_MESSAGE("Simulation End: " + getStateMessage(state)); 00276 // exit simulation loop 00277 closeSimulation(start); 00278 return 0; 00279 } 00280 00281 00282 void 00283 MSNet::closeSimulation(SUMOTime start) { 00284 if (myLogExecutionTime) { 00285 long duration = SysUtils::getCurrentMillis() - mySimBeginMillis; 00286 std::ostringstream msg; 00287 msg << "Performance: " << "\n" << " Duration: " << duration << " ms" << "\n"; 00288 if (duration!=0) { 00289 msg << " Real time factor: " << ((SUMOReal)(myStep-start)*1000./(SUMOReal)duration) << "\n"; 00290 msg.setf(std::ios::fixed , std::ios::floatfield); // use decimal format 00291 msg.setf(std::ios::showpoint); // print decimal point 00292 msg << " UPS: " << ((SUMOReal) myVehiclesMoved * 1000. / (SUMOReal) duration) << "\n"; 00293 } 00294 msg << "Vehicles: " << "\n" 00295 << " Emitted: " << myVehicleControl->getDepartedVehicleNo() << "\n" 00296 << " Running: " << myVehicleControl->getRunningVehicleNo() << "\n" 00297 << " Waiting: " << myInserter->getWaitingVehicleNo() << "\n"; 00298 WRITE_MESSAGE(msg.str()); 00299 } 00300 myDetectorControl->close(myStep); 00301 #ifndef NO_TRACI 00302 traci::TraCIServer::close(); 00303 #endif 00304 } 00305 00306 00307 void 00308 MSNet::simulationStep() { 00309 #ifndef NO_TRACI 00310 traci::TraCIServer::processCommandsUntilSimStep(myStep); 00311 #endif 00312 // execute beginOfTimestepEvents 00313 if (myLogExecutionTime) { 00314 mySimStepBegin = SysUtils::getCurrentMillis(); 00315 } 00316 #ifdef HAVE_MESOSIM 00317 // netstate output 00318 std::vector<SUMOTime>::iterator timeIt = find(myStateDumpTimes.begin(), myStateDumpTimes.end(), myStep); 00319 if (timeIt!=myStateDumpTimes.end()) { 00320 const int dist = distance(myStateDumpTimes.begin(), timeIt); 00321 std::ofstream strm(myStateDumpFiles[dist].c_str(), std::fstream::out|std::fstream::binary); 00322 saveState(strm); 00323 } 00324 #endif 00325 myBeginOfTimestepEvents->execute(myStep); 00326 if (MSGlobals::gCheck4Accidents) { 00327 myEdges->detectCollisions(myStep); 00328 } 00329 // check whether the tls programs need to be switched 00330 myLogics->check2Switch(myStep); 00331 // set the signals 00332 myLogics->setTrafficLightSignals(myStep); 00333 00334 #ifdef HAVE_MESOSIM 00335 if (MSGlobals::gUseMesoSim) { 00336 MSGlobals::gMesoNet->simulate(myStep); 00337 } else { 00338 #endif 00339 00340 // assure all lanes with vehicles are 'active' 00341 myEdges->patchActiveLanes(); 00342 00343 // move vehicles 00344 // precompute possible positions for vehicles that do interact with 00345 // their lane's end 00346 myEdges->moveCritical(myStep); 00347 00348 // move vehicles which do interact with their lane's end 00349 // (it is now known whether they may drive 00350 myEdges->moveFirst(myStep); 00351 if (MSGlobals::gCheck4Accidents) { 00352 myEdges->detectCollisions(myStep); 00353 } 00354 00355 // Vehicles change Lanes (maybe) 00356 myEdges->changeLanes(myStep); 00357 00358 if (MSGlobals::gCheck4Accidents) { 00359 myEdges->detectCollisions(myStep); 00360 } 00361 #ifdef HAVE_MESOSIM 00362 } 00363 #endif 00364 // load routes 00365 myRouteLoaders->loadNext(myStep); 00366 00367 // persons 00368 if (myPersonControl!=0) { 00369 myPersonControl->checkArrivedPersons(this, myStep); 00370 } 00371 // emit Vehicles 00372 myInsertionEvents->execute(myStep); 00373 myInserter->emitVehicles(myStep); 00374 if (MSGlobals::gCheck4Accidents) { 00375 myEdges->detectCollisions(myStep); 00376 } 00377 MSVehicleTransfer::getInstance()->checkInsertions(myStep); 00378 00379 // execute endOfTimestepEvents 00380 myEndOfTimestepEvents->execute(myStep); 00381 00382 // update and write (if needed) detector values 00383 writeOutput(); 00384 00385 if (myLogExecutionTime) { 00386 mySimStepEnd = SysUtils::getCurrentMillis(); 00387 mySimStepDuration = mySimStepEnd - mySimStepBegin; 00388 myVehiclesMoved += myVehicleControl->getRunningVehicleNo(); 00389 } 00390 myStep += DELTA_T; 00391 } 00392 00393 00394 MSNet::SimulationState 00395 MSNet::simulationState(SUMOTime stopTime) const throw() { 00396 if (myTooManyVehicles>0&&(int) myVehicleControl->getRunningVehicleNo()>myTooManyVehicles) { 00397 return SIMSTATE_TOO_MANY_VEHICLES; 00398 } 00399 #ifndef NO_TRACI 00400 if (traci::TraCIServer::wasClosed()) { 00401 return SIMSTATE_CONNECTION_CLOSED; 00402 } 00403 if (stopTime < 0 && OptionsCont::getOptions().getInt("remote-port") == 0) { 00404 #else 00405 if (stopTime < 0) { 00406 #endif 00407 if (myInsertionEvents->isEmpty() 00408 && (myVehicleControl->getActiveVehicleCount() == 0) 00409 && (myInserter->getPendingFlowCount() == 0) 00410 && (myPersonControl == 0 || !myPersonControl->hasPedestrians())) { 00411 if (myPersonControl) { 00412 myPersonControl->abortWaiting(); 00413 } 00414 myVehicleControl->abortWaiting(); 00415 return SIMSTATE_NO_FURTHER_VEHICLES; 00416 } 00417 } 00418 if (stopTime >= 0 && myStep >= stopTime) { 00419 return SIMSTATE_END_STEP_REACHED; 00420 } 00421 return SIMSTATE_RUNNING; 00422 } 00423 00424 00425 std::string 00426 MSNet::getStateMessage(MSNet::SimulationState state) throw() { 00427 switch (state) { 00428 case MSNet::SIMSTATE_RUNNING: 00429 return ""; 00430 case MSNet::SIMSTATE_END_STEP_REACHED: 00431 return "The final simulation step has been reached."; 00432 case MSNet::SIMSTATE_NO_FURTHER_VEHICLES: 00433 return "All vehicles have left the simulation."; 00434 case MSNet::SIMSTATE_CONNECTION_CLOSED: 00435 return "TraCI requested termination."; 00436 case MSNet::SIMSTATE_ERROR_IN_SIM: 00437 return "An error occured (see log)."; 00438 case MSNet::SIMSTATE_TOO_MANY_VEHICLES: 00439 return "Too many vehicles."; 00440 default: 00441 return "Unknown reason."; 00442 } 00443 } 00444 00445 00446 void 00447 MSNet::clearAll() { 00448 // clear container 00449 MSEdge::clear(); 00450 MSLane::clear(); 00451 MSRoute::clear(); 00452 delete MSVehicleTransfer::getInstance(); 00453 } 00454 00455 00456 SUMOTime 00457 MSNet::getCurrentTimeStep() const { 00458 return myStep; 00459 } 00460 00461 00462 void 00463 MSNet::writeOutput() { 00464 // update detector values 00465 myDetectorControl->updateDetectors(myStep); 00466 // check state dumps 00467 if (OptionsCont::getOptions().isSet("netstate-dump")) { 00468 MSXMLRawOut::write(OutputDevice::getDeviceByOption("netstate-dump"), *myEdges, myStep); 00469 } 00470 // emission output 00471 if (OptionsCont::getOptions().isSet("summary-output")) { 00472 OutputDevice& od = OutputDevice::getDeviceByOption("summary"); 00473 od << " <step time=\"" << time2string(myStep) << "\" " 00474 << "loaded=\"" << myVehicleControl->getLoadedVehicleNo() << "\" " 00475 << "emitted=\"" << myVehicleControl->getDepartedVehicleNo() << "\" " 00476 << "running=\"" << myVehicleControl->getRunningVehicleNo() << "\" " 00477 << "waiting=\"" << myInserter->getWaitingVehicleNo() << "\" " 00478 << "ended=\"" << myVehicleControl->getEndedVehicleNo() << "\" " 00479 << "meanWaitingTime=\""; 00480 myVehicleControl->printMeanWaitingTime(od); 00481 od << "\" meanTravelTime=\""; 00482 myVehicleControl->printMeanTravelTime(od); 00483 od << "\" "; 00484 if (myLogExecutionTime) { 00485 od << "duration=\"" << mySimStepDuration << "\" "; 00486 } 00487 od << "/>\n"; 00488 } 00489 // write detector values 00490 myDetectorControl->writeOutput(myStep + DELTA_T, false); 00491 } 00492 00493 00494 bool 00495 MSNet::logSimulationDuration() const throw() { 00496 return myLogExecutionTime; 00497 } 00498 00499 00500 #ifdef HAVE_MESOSIM 00501 void 00502 MSNet::saveState(std::ostream& os) throw() { 00503 FileHelpers::writeString(os, VERSION_STRING); 00504 FileHelpers::writeUInt(os, sizeof(size_t)); 00505 FileHelpers::writeUInt(os, sizeof(SUMOReal)); 00506 FileHelpers::writeUInt(os, MSEdge::dictSize()); 00507 FileHelpers::writeUInt(os, myStep); 00508 MSRoute::dict_saveState(os); 00509 myVehicleControl->saveState(os); 00510 if (MSGlobals::gUseMesoSim) { 00511 MSGlobals::gMesoNet->saveState(os); 00512 } 00513 } 00514 00515 00516 unsigned int 00517 MSNet::loadState(BinaryInputDevice& bis) throw() { 00518 std::string version; 00519 unsigned int sizeT, fpSize, numEdges, step; 00520 bis >> version; 00521 bis >> sizeT; 00522 bis >> fpSize; 00523 bis >> numEdges; 00524 bis >> step; 00525 if (version != VERSION_STRING) { 00526 WRITE_WARNING("State was written with sumo version " + version + " (present: " + VERSION_STRING +")!"); 00527 } 00528 if (sizeT != sizeof(size_t)) { 00529 WRITE_WARNING("State was written on a different platform (32bit vs. 64bit)!"); 00530 } 00531 if (fpSize != sizeof(SUMOReal)) { 00532 WRITE_WARNING("State was written with a different precision for SUMOReal!"); 00533 } 00534 if (numEdges != MSEdge::dictSize()) { 00535 WRITE_WARNING("State was written for a different net!"); 00536 } 00537 const SUMOTime offset = string2time(OptionsCont::getOptions().getString("load-state.offset")); 00538 MSRoute::dict_loadState(bis); 00539 myVehicleControl->loadState(bis, offset); 00540 if (MSGlobals::gUseMesoSim) { 00541 MSGlobals::gMesoNet->loadState(bis, *myVehicleControl, offset); 00542 } 00543 return step; 00544 } 00545 #endif 00546 00547 00548 MSPersonControl& 00549 MSNet::getPersonControl() throw() { 00550 if (myPersonControl==0) { 00551 myPersonControl = new MSPersonControl(); 00552 } 00553 return *myPersonControl; 00554 } 00555 00556 00557 MSEdgeWeightsStorage& 00558 MSNet::getWeightsStorage() throw() { 00559 if (myEdgeWeights==0) { 00560 myEdgeWeights = new MSEdgeWeightsStorage(); 00561 } 00562 return *myEdgeWeights; 00563 } 00564 00565 00566 void 00567 MSNet::preSimStepOutput() const throw() { 00568 std::cout << std::setprecision(OUTPUT_ACCURACY); 00569 std::cout << "Step #" << time2string(myStep); 00570 } 00571 00572 00573 void 00574 MSNet::postSimStepOutput() const throw() { 00575 if (myLogExecutionTime) { 00576 std::string msg; 00577 std::ostringstream oss; 00578 oss.setf(std::ios::fixed , std::ios::floatfield); // use decimal format 00579 oss.setf(std::ios::showpoint); // print decimal point 00580 oss << std::setprecision(OUTPUT_ACCURACY); 00581 if (mySimStepDuration!=0) { 00582 oss << " (" << mySimStepDuration << "ms ~= " 00583 << (1000./ (SUMOReal) mySimStepDuration) << "*RT, ~" 00584 << ((SUMOReal) myVehicleControl->getRunningVehicleNo()/(SUMOReal) mySimStepDuration*1000.); 00585 } else { 00586 oss << " (0ms ?*RT. ?"; 00587 } 00588 oss << "UPS, vehicles" 00589 << " TOT " << myVehicleControl->getDepartedVehicleNo() 00590 << " ACT " << myVehicleControl->getRunningVehicleNo() 00591 << ") "; 00592 msg = oss.str(); 00593 std::string prev = "Step #" + time2string(myStep-DELTA_T); 00594 msg = msg.substr(0, 78 - prev.length()); 00595 std::cout << msg; 00596 } 00597 std::cout << (char) 13; 00598 } 00599 00600 00601 void 00602 MSNet::addVehicleStateListener(VehicleStateListener* listener) throw() { 00603 if (find(myVehicleStateListeners.begin(), myVehicleStateListeners.end(), listener)==myVehicleStateListeners.end()) { 00604 myVehicleStateListeners.push_back(listener); 00605 } 00606 } 00607 00608 00609 void 00610 MSNet::removeVehicleStateListener(VehicleStateListener* listener) throw() { 00611 std::vector<VehicleStateListener*>::iterator i= find(myVehicleStateListeners.begin(), myVehicleStateListeners.end(), listener); 00612 if (i!=myVehicleStateListeners.end()) { 00613 myVehicleStateListeners.erase(i); 00614 } 00615 } 00616 00617 00618 void 00619 MSNet::informVehicleStateListener(const SUMOVehicle* const vehicle, VehicleState to) throw() { 00620 for (std::vector<VehicleStateListener*>::iterator i=myVehicleStateListeners.begin(); i!=myVehicleStateListeners.end(); ++i) { 00621 (*i)->vehicleStateChanged(vehicle, to); 00622 } 00623 } 00624 00625 00626 00627 // ------ Insertion and retrieval of bus stops ------ 00628 bool 00629 MSNet::addBusStop(MSBusStop* busStop) { 00630 return myBusStopDict.add(busStop->getID(), busStop); 00631 } 00632 00633 00634 MSBusStop* 00635 MSNet::getBusStop(const std::string& id) const { 00636 return myBusStopDict.get(id); 00637 } 00638 00639 00640 std::string 00641 MSNet::getBusStopID(const MSLane* lane, const SUMOReal pos) const { 00642 const std::map<std::string, MSBusStop*> &vals = myBusStopDict.getMyMap(); 00643 for (std::map<std::string, MSBusStop*>::const_iterator it = vals.begin(); it != vals.end(); ++it) { 00644 MSBusStop* stop = it->second; 00645 if (&stop->getLane() == lane && fabs(stop->getEndLanePosition() - pos) < POSITION_EPS) { 00646 return stop->getID(); 00647 } 00648 } 00649 return ""; 00650 } 00651 00652 00653 #ifdef _MESSAGES 00654 MSMessageEmitter* 00655 MSNet::getMsgEmitter(const std::string& whatemit) { 00656 msgEmitVec.clear(); 00657 msgEmitVec = myMsgEmitter.buildAndGetStaticVector(); 00658 MSMessageEmitter* msgEmitter = 0; 00659 for (int i = 0; i < msgEmitVec.size(); ++i) { 00660 if (msgEmitVec.at(i)->getEventsEnabled(whatemit)) { 00661 msgEmitter = msgEmitVec.at(i); 00662 break; 00663 } 00664 } 00665 // returns 0 if the requested MessageEmitter is not in the map 00666 return msgEmitter; 00667 } 00668 00669 00670 void 00671 MSNet::createMsgEmitter(std::string& id, 00672 std::string& file, 00673 const std::string& base, 00674 std::string& whatemit, 00675 bool reverse, 00676 bool table, 00677 bool xy, 00678 SUMOReal step) { 00679 MSMessageEmitter* msgEmitter = new MSMessageEmitter(file, base, whatemit, reverse, table, xy, step); 00680 myMsgEmitter.add(id, msgEmitter); 00681 } 00682 #endif 00683 00684 00685 /****************************************************************************/ 00686