MSMeanData.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Emission data collector for edges/lanes
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright 2001-2010 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 #include <microsim/MSEdgeControl.h>
00031 #include <microsim/MSEdge.h>
00032 #include <microsim/MSLane.h>
00033 #include <microsim/MSVehicle.h>
00034 #include <utils/common/SUMOTime.h>
00035 #include <utils/common/ToString.h>
00036 #include <utils/iodevices/OutputDevice.h>
00037 #include "MSMeanData.h"
00038 #include <limits>
00039 
00040 #ifdef HAVE_MESOSIM
00041 #include <microsim/MSGlobals.h>
00042 #include <mesosim/MELoop.h>
00043 #include <mesosim/MESegment.h>
00044 #endif
00045 
00046 #ifdef CHECK_MEMORY_LEAKS
00047 #include <foreign/nvwa/debug_new.h>
00048 #endif // CHECK_MEMORY_LEAKS
00049 
00050 
00051 // ===========================================================================
00052 // method definitions
00053 // ===========================================================================
00054 // ---------------------------------------------------------------------------
00055 // MSMeanData::MeanDataValues - methods
00056 // ---------------------------------------------------------------------------
00057 MSMeanData::MeanDataValues::MeanDataValues(MSLane * const lane, const bool doAdd, const std::set<std::string>* const vTypes) throw()
00058         : MSMoveReminder(lane, doAdd), sampleSeconds(0), travelledDistance(0), myVehicleTypes(vTypes) {}
00059 
00060 
00061 MSMeanData::MeanDataValues::~MeanDataValues() throw() {
00062 }
00063 
00064 
00065 bool
00066 MSMeanData::MeanDataValues::vehicleApplies(const SUMOVehicle& veh) const throw() {
00067     return myVehicleTypes == 0 || myVehicleTypes->empty() ||
00068            myVehicleTypes->find(veh.getVehicleType().getID()) != myVehicleTypes->end();
00069 }
00070 
00071 
00072 bool
00073 MSMeanData::MeanDataValues::isEmpty() const throw() {
00074     return sampleSeconds == 0;
00075 }
00076 
00077 
00078 void
00079 MSMeanData::MeanDataValues::update() throw() {
00080 }
00081 
00082 
00083 SUMOReal
00084 MSMeanData::MeanDataValues::getSamples() const throw() {
00085     return sampleSeconds;
00086 }
00087 
00088 
00089 // ---------------------------------------------------------------------------
00090 // MSMeanData::MeanDataValueTracker - methods
00091 // ---------------------------------------------------------------------------
00092 MSMeanData::MeanDataValueTracker::MeanDataValueTracker(MSLane * const lane,
00093         const std::set<std::string>* const vTypes,
00094         const MSMeanData* const parent) throw()
00095         : MSMeanData::MeanDataValues(lane, true, vTypes), myParent(parent) {
00096     myCurrentData.push_back(new TrackerEntry(parent->createValues(lane, false)));
00097 }
00098 
00099 
00100 MSMeanData::MeanDataValueTracker::~MeanDataValueTracker() throw() {
00101 }
00102 
00103 
00104 void
00105 MSMeanData::MeanDataValueTracker::reset() throw() {
00106     myCurrentData.push_back(new TrackerEntry(myParent->createValues(myLane, false)));
00107 }
00108 
00109 
00110 void
00111 MSMeanData::MeanDataValueTracker::addTo(MSMeanData::MeanDataValues &val) const throw() {
00112     myCurrentData.front()->myValues->addTo(val);
00113 }
00114 
00115 
00116 bool
00117 MSMeanData::MeanDataValueTracker::isStillActive(MSVehicle& veh, SUMOReal oldPos, SUMOReal newPos, SUMOReal newSpeed) throw() {
00118     if (vehicleApplies(veh)) {
00119         return myTrackedData[&veh]->myValues->isStillActive(veh, oldPos, newPos, newSpeed);
00120     }
00121     return false;
00122 }
00123 
00124 
00125 void
00126 MSMeanData::MeanDataValueTracker::notifyLeave(MSVehicle& veh, bool isArrival, bool isLaneChange) throw() {
00127     if (vehicleApplies(veh)) {
00128         myTrackedData[&veh]->myNumVehicleLeft++;
00129         myTrackedData[&veh]->myValues->notifyLeave(veh, isArrival, isLaneChange);
00130     }
00131 }
00132 
00133 
00134 bool
00135 MSMeanData::MeanDataValueTracker::notifyEnter(MSVehicle& veh, bool isEmit, bool isLaneChange) throw() {
00136     if (vehicleApplies(veh)) {
00137         myTrackedData[&veh] = myCurrentData.back();
00138         myTrackedData[&veh]->myNumVehicleEntered++;
00139         return myTrackedData[&veh]->myValues->notifyEnter(veh, isEmit, isLaneChange);
00140     }
00141     return false;
00142 }
00143 
00144 
00145 bool
00146 MSMeanData::MeanDataValueTracker::isEmpty() const throw() {
00147     return myCurrentData.front()->myValues->isEmpty();
00148 }
00149 
00150 
00151 void
00152 MSMeanData::MeanDataValueTracker::write(OutputDevice &dev, const SUMOTime period,
00153                                         const SUMOReal numLanes, const SUMOReal length, const int numVehicles) const throw(IOError) {
00154     myCurrentData.front()->myValues->write(dev, period, numLanes, length, myCurrentData.front()->myNumVehicleEntered);
00155 }
00156 
00157 
00158 size_t
00159 MSMeanData::MeanDataValueTracker::getNumReady() const throw() {
00160     size_t result = 0;
00161     for (std::list<TrackerEntry*>::const_iterator it = myCurrentData.begin(); it != myCurrentData.end(); ++it) {
00162         if ((*it)->myNumVehicleEntered == (*it)->myNumVehicleLeft) {
00163             result++;
00164         } else {
00165             break;
00166         }
00167     }
00168     return result;
00169 }
00170 
00171 
00172 void
00173 MSMeanData::MeanDataValueTracker::clearFirst() throw() {
00174     if (myCurrentData.size() == 1) {
00175         myCurrentData.front()->reset();
00176     } else {
00177         myCurrentData.pop_front();
00178     }
00179 }
00180 
00181 
00182 SUMOReal
00183 MSMeanData::MeanDataValueTracker::getSamples() const throw() {
00184     return myCurrentData.front()->myValues->getSamples();
00185 }
00186 
00187 
00188 // ---------------------------------------------------------------------------
00189 // MSMeanData - methods
00190 // ---------------------------------------------------------------------------
00191 MSMeanData::MSMeanData(const std::string &id,
00192                        const SUMOTime dumpBegin, const SUMOTime dumpEnd,
00193                        const bool useLanes, const bool withEmpty,
00194                        const bool trackVehicles,
00195                        const SUMOReal maxTravelTime, const SUMOReal minSamples,
00196                        const std::set<std::string> vTypes) throw()
00197         : myID(id), myAmEdgeBased(!useLanes), myDumpBegin(dumpBegin), myDumpEnd(dumpEnd),
00198         myDumpEmpty(withEmpty), myTrackVehicles(trackVehicles),
00199         myMaxTravelTime(maxTravelTime), myMinSamples(minSamples), myVehicleTypes(vTypes) {
00200 }
00201 
00202 
00203 void
00204 MSMeanData::init(const std::vector<MSEdge*> &edges, const bool withInternal) throw() {
00205     for (std::vector<MSEdge*>::const_iterator e = edges.begin(); e != edges.end(); ++e) {
00206         if (withInternal || (*e)->getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
00207             myEdges.push_back(*e);
00208             myMeasures.push_back(std::vector<MeanDataValues*>());
00209 #ifdef HAVE_MESOSIM
00210             if (MSGlobals::gUseMesoSim) {
00211                 MESegment *s = MSGlobals::gMesoNet->getSegmentForEdge(**e);
00212                 while (s!=0) {
00213                     myMeasures.back().push_back(createValues(0, false));
00214                     s->addDetector(myMeasures.back().back());
00215                     s = s->getNextSegment();
00216                 }
00217                 continue;
00218             }
00219 #endif
00220             if (myAmEdgeBased && myTrackVehicles) {
00221                 myMeasures.back().push_back(new MeanDataValueTracker(0, &myVehicleTypes, this));
00222             }
00223             const std::vector<MSLane*> &lanes = (*e)->getLanes();
00224             for (std::vector<MSLane*>::const_iterator lane = lanes.begin(); lane != lanes.end(); ++lane) {
00225                 if (myTrackVehicles) {
00226                     if (myAmEdgeBased) {
00227                         (*lane)->addMoveReminder(myMeasures.back().back());
00228                     } else {
00229                         myMeasures.back().push_back(new MeanDataValueTracker(*lane, &myVehicleTypes, this));
00230                     }
00231                 } else {
00232                     myMeasures.back().push_back(createValues(*lane, true));
00233                 }
00234             }
00235         }
00236     }
00237 }
00238 
00239 
00240 MSMeanData::~MSMeanData() throw() {}
00241 
00242 
00243 void
00244 MSMeanData::resetOnly(SUMOTime stopTime) throw() {
00245 #ifdef HAVE_MESOSIM
00246     if (MSGlobals::gUseMesoSim) {
00247         std::vector<MSEdge*>::iterator edge = myEdges.begin();
00248         for (std::vector<std::vector<MeanDataValues*> >::const_iterator i=myMeasures.begin(); i!=myMeasures.end(); ++i, ++edge) {
00249             MESegment *s = MSGlobals::gMesoNet->getSegmentForEdge(**edge);
00250             for (std::vector<MeanDataValues*>::const_iterator j=(*i).begin(); j!=(*i).end(); ++j) {
00251                 s->prepareMeanDataForWriting(*(*j), stopTime);
00252                 (*j)->reset();
00253                 s = s->getNextSegment();
00254             }
00255         }
00256         return;
00257     }
00258 #endif
00259     for (std::vector<std::vector<MeanDataValues*> >::const_iterator i=myMeasures.begin(); i!=myMeasures.end(); ++i) {
00260         for (std::vector<MeanDataValues*>::const_iterator j=(*i).begin(); j!=(*i).end(); ++j) {
00261             (*j)->reset();
00262         }
00263     }
00264 }
00265 
00266 
00267 void
00268 MSMeanData::writeEdge(OutputDevice &dev,
00269                       const std::vector<MeanDataValues*> &edgeValues,
00270                       MSEdge *edge, SUMOTime startTime, SUMOTime stopTime) throw(IOError) {
00271     std::vector<MeanDataValues*>::const_iterator lane;
00272     if (!myAmEdgeBased) {
00273         bool writeCheck = myDumpEmpty;
00274         if (!writeCheck) {
00275             for (lane = edgeValues.begin(); lane != edgeValues.end(); ++lane) {
00276                 if (!(*lane)->isEmpty()) {
00277                     writeCheck = true;
00278                     break;
00279                 }
00280             }
00281         }
00282         if (writeCheck) {
00283             dev.openTag("edge")<<" id=\""<<edge->getID()<<"\">\n";
00284         }
00285         for (lane = edgeValues.begin(); lane != edgeValues.end(); ++lane) {
00286             MeanDataValues& meanData = **lane;
00287             if (writePrefix(dev, meanData, "<lane id=\""+meanData.getLane()->getID())) {
00288                 meanData.write(dev, stopTime - startTime,
00289                                1.f, meanData.getLane()->getLength());
00290             }
00291             if (myTrackVehicles) {
00292                 ((MeanDataValueTracker&)meanData).clearFirst();
00293             } else {
00294                 meanData.reset();
00295             }
00296         }
00297         if (writeCheck) {
00298             dev.closeTag();
00299         }
00300     } else {
00301         if (myTrackVehicles) {
00302             MeanDataValues& meanData = **edgeValues.begin();
00303             if (writePrefix(dev, meanData, "<edge id=\""+edge->getID())) {
00304                 meanData.write(dev, stopTime - startTime,
00305                                (SUMOReal)edge->getLanes().size(), edge->getLanes()[0]->getLength());
00306             }
00307         } else {
00308             MeanDataValues* sumData = createValues(0, false);
00309             for (lane = edgeValues.begin(); lane != edgeValues.end(); ++lane) {
00310                 MeanDataValues& meanData = **lane;
00311                 meanData.addTo(*sumData);
00312                 meanData.reset();
00313             }
00314             if (writePrefix(dev, *sumData, "<edge id=\""+edge->getID())) {
00315                 sumData->write(dev, stopTime - startTime,
00316                                (SUMOReal)edge->getLanes().size(), edge->getLanes()[0]->getLength());
00317             }
00318             delete sumData;
00319         }
00320     }
00321 }
00322 
00323 
00324 bool
00325 MSMeanData::writePrefix(OutputDevice &dev, const MeanDataValues &values, const std::string prefix) const throw(IOError) {
00326     if (myDumpEmpty || !values.isEmpty()) {
00327         dev.indent() << prefix << "\" sampledSeconds=\"" << values.getSamples();
00328         return true;
00329     }
00330     return false;
00331 }
00332 
00333 
00334 void
00335 MSMeanData::writeXMLOutput(OutputDevice &dev,
00336                            SUMOTime startTime, SUMOTime stopTime) throw(IOError) {
00337     // check whether this dump shall be written for the current time
00338     size_t numReady = myDumpBegin < stopTime && myDumpEnd-DELTA_T >= startTime;
00339     if (myTrackVehicles && myDumpBegin < stopTime) {
00340         myPendingIntervals.push_back(std::make_pair(startTime, stopTime));
00341         numReady = myPendingIntervals.size();
00342         for (std::vector<std::vector<MeanDataValues*> >::const_iterator i=myMeasures.begin(); i!=myMeasures.end(); ++i) {
00343             for (std::vector<MeanDataValues*>::const_iterator j=(*i).begin(); j!=(*i).end(); ++j) {
00344                 numReady = MIN2(numReady, ((MeanDataValueTracker*)*j)->getNumReady());
00345                 if (numReady == 0) {
00346                     break;
00347                 }
00348             }
00349             if (numReady == 0) {
00350                 break;
00351             }
00352         }
00353     }
00354     if (numReady == 0) {
00355         resetOnly(stopTime);
00356     }
00357     while (numReady-- > 0) {
00358         if (!myPendingIntervals.empty()) {
00359             startTime = myPendingIntervals.front().first;
00360             stopTime = myPendingIntervals.front().second;
00361             myPendingIntervals.pop_front();
00362         }
00363         dev.openTag("interval")<<" begin=\""<<time2string(startTime)<<"\" end=\""<<
00364         time2string(stopTime)<<"\" "<<"id=\""<<myID<<"\">\n";
00365         std::vector<MSEdge*>::iterator edge = myEdges.begin();
00366         for (std::vector<std::vector<MeanDataValues*> >::const_iterator i=myMeasures.begin(); i!=myMeasures.end(); ++i, ++edge) {
00367             writeEdge(dev, (*i), *edge, startTime, stopTime);
00368         }
00369         dev.closeTag();
00370     }
00371 }
00372 
00373 
00374 void
00375 MSMeanData::writeXMLDetectorProlog(OutputDevice &dev) const throw(IOError) {
00376     dev.writeXMLHeader("netstats");
00377 }
00378 
00379 
00380 void
00381 MSMeanData::update() throw() {
00382     for (std::vector<std::vector<MeanDataValues*> >::const_iterator i=myMeasures.begin(); i!=myMeasures.end(); ++i) {
00383         const std::vector<MeanDataValues*> &lm = *i;
00384         for (std::vector<MeanDataValues*>::const_iterator j=lm.begin(); j!=lm.end(); ++j) {
00385             (*j)->update();
00386         }
00387     }
00388 }
00389 
00390 
00391 /****************************************************************************/
00392 

Generated on Wed May 5 00:06:32 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6