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