00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00053
00054
00055
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
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
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
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