MSMeanData_Net.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // Network state mean 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_Net.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_Net::MSLaneMeanDataValues - methods
00056 // ---------------------------------------------------------------------------
00057 MSMeanData_Net::MSLaneMeanDataValues::MSLaneMeanDataValues(MSLane * const lane, const bool doAdd,
00058         const std::set<std::string>* const vTypes,
00059         const MSMeanData_Net *parent) throw()
00060         : MSMeanData::MeanDataValues(lane, doAdd, vTypes), myParent(parent),
00061         nVehDeparted(0), nVehArrived(0), nVehEntered(0), nVehLeft(0),
00062         nVehLaneChangeFrom(0), nVehLaneChangeTo(0), waitSeconds(0), vehLengthSum(0) {}
00063 
00064 
00065 MSMeanData_Net::MSLaneMeanDataValues::~MSLaneMeanDataValues() throw() {
00066 }
00067 
00068 
00069 void
00070 MSMeanData_Net::MSLaneMeanDataValues::reset() throw() {
00071     nVehDeparted = 0;
00072     nVehArrived = 0;
00073     nVehEntered = 0;
00074     nVehLeft = 0;
00075     nVehLaneChangeFrom = 0;
00076     nVehLaneChangeTo = 0;
00077     sampleSeconds = 0.;
00078     travelledDistance = 0;
00079     waitSeconds = 0;
00080     vehLengthSum = 0;
00081 }
00082 
00083 
00084 void
00085 MSMeanData_Net::MSLaneMeanDataValues::addTo(MSMeanData::MeanDataValues &val) const throw() {
00086     MSLaneMeanDataValues& v = (MSLaneMeanDataValues&) val;
00087     v.nVehDeparted += nVehDeparted;
00088     v.nVehArrived += nVehArrived;
00089     v.nVehEntered += nVehEntered;
00090     v.nVehLeft += nVehLeft;
00091     v.nVehLaneChangeFrom += nVehLaneChangeFrom;
00092     v.nVehLaneChangeTo += nVehLaneChangeTo;
00093     v.sampleSeconds += sampleSeconds;
00094     v.travelledDistance += travelledDistance;
00095     v.waitSeconds += waitSeconds;
00096     v.vehLengthSum += vehLengthSum;
00097 }
00098 
00099 
00100 bool
00101 MSMeanData_Net::MSLaneMeanDataValues::isStillActive(MSVehicle& veh, SUMOReal oldPos, SUMOReal newPos, SUMOReal newSpeed) throw() {
00102     if (!vehicleApplies(veh)) {
00103         return false;
00104     }
00105     bool ret = true;
00106     SUMOReal timeOnLane = (SUMOReal) DELTA_T / 1000.;
00107     if (oldPos<0&&newSpeed!=0) {
00108         timeOnLane = (oldPos+SPEED2DIST(newSpeed)) / newSpeed;
00109     }
00110     if (getLane() != 0 && oldPos+SPEED2DIST(newSpeed)>getLane()->getLength() && newSpeed != 0) {
00111         timeOnLane -= (oldPos+SPEED2DIST(newSpeed) - getLane()->getLength()) / newSpeed;
00112         ret = false;
00113     }
00114     if (timeOnLane<0) {
00115         MsgHandler::getErrorInstance()->inform("Negative vehicle step fraction on lane '" + getLane()->getID() + "'.");
00116         return false;
00117     }
00118     if (timeOnLane==0) {
00119         return false;
00120     }
00121     sampleSeconds += timeOnLane;
00122     travelledDistance += newSpeed * timeOnLane;
00123     vehLengthSum += veh.getVehicleType().getLength() * timeOnLane;
00124     if (newSpeed<myParent->myHaltSpeed) {
00125         waitSeconds += timeOnLane;
00126     }
00127     return ret;
00128 }
00129 
00130 
00131 void
00132 MSMeanData_Net::MSLaneMeanDataValues::notifyLeave(MSVehicle& veh, bool isArrival, bool isLaneChange) throw() {
00133     if (vehicleApplies(veh)) {
00134         if (isArrival) {
00135             ++nVehArrived;
00136         } else if (isLaneChange) {
00137             ++nVehLaneChangeFrom;
00138         } else {
00139             ++nVehLeft;
00140         }
00141     }
00142 }
00143 
00144 
00145 bool
00146 MSMeanData_Net::MSLaneMeanDataValues::notifyEnter(MSVehicle& veh, bool isEmit, bool isLaneChange) throw() {
00147     if (vehicleApplies(veh)) {
00148         if (isEmit) {
00149             ++nVehDeparted;
00150         } else if (isLaneChange) {
00151             ++nVehLaneChangeTo;
00152         } else {
00153             ++nVehEntered;
00154         }
00155         return true;
00156     }
00157     return false;
00158 }
00159 
00160 
00161 bool
00162 MSMeanData_Net::MSLaneMeanDataValues::isEmpty() const throw() {
00163     return sampleSeconds == 0 && nVehDeparted == 0 && nVehArrived == 0 && nVehEntered == 0 && nVehLeft == 0 && nVehLaneChangeFrom == 0 && nVehLaneChangeTo == 0;
00164 }
00165 
00166 
00167 void
00168 MSMeanData_Net::MSLaneMeanDataValues::write(OutputDevice &dev, const SUMOTime period,
00169         const SUMOReal numLanes, const SUMOReal length, const int numVehicles) const throw(IOError) {
00170     if (myParent == 0) {
00171         if (sampleSeconds > 0) {
00172             dev << "\" density=\"" << sampleSeconds / STEPS2TIME(period) *(SUMOReal) 1000 / length <<
00173             "\" occupancy=\"" << vehLengthSum / STEPS2TIME(period) / length / numLanes *(SUMOReal) 100 <<
00174             "\" waitingTime=\"" << waitSeconds <<
00175             "\" speed=\"" << travelledDistance / sampleSeconds;
00176         }
00177         dev<<"\" departed=\""<<nVehDeparted<<
00178         "\" arrived=\""<<nVehArrived<<
00179         "\" entered=\""<<nVehEntered<<
00180         "\" left=\""<<nVehLeft<<
00181         "\"/>\n";
00182         return;
00183     }
00184     if (sampleSeconds > myParent->myMinSamples) {
00185         SUMOReal traveltime = myParent->myMaxTravelTime;
00186         if (travelledDistance > 0.f) {
00187             traveltime = MIN2(traveltime, length * sampleSeconds / travelledDistance);
00188         }
00189         if (numVehicles > 0) {
00190             dev << "\" traveltime=\"" << sampleSeconds / numVehicles <<
00191             "\" waitingTime=\"" << waitSeconds <<
00192             "\" speed=\"" << travelledDistance / sampleSeconds;
00193         } else {
00194             dev << "\" traveltime=\"" << traveltime <<
00195             "\" density=\"" << sampleSeconds / STEPS2TIME(period) *(SUMOReal) 1000 / length <<
00196             "\" occupancy=\"" << vehLengthSum / STEPS2TIME(period) / length / numLanes *(SUMOReal) 100 <<
00197             "\" waitingTime=\"" << waitSeconds <<
00198             "\" speed=\"" << travelledDistance / sampleSeconds;
00199         }
00200     }
00201     dev<<"\" departed=\""<<nVehDeparted<<
00202     "\" arrived=\""<<nVehArrived<<
00203     "\" entered=\""<<nVehEntered<<
00204     "\" left=\""<<nVehLeft<<
00205     "\" laneChangedFrom=\""<<nVehLaneChangeFrom<<
00206     "\" laneChangedTo=\""<<nVehLaneChangeTo<<
00207     "\"/>\n";
00208 }
00209 
00210 
00211 #ifdef HAVE_MESOSIM
00212 void
00213 MSMeanData_Net::MSLaneMeanDataValues::addData(const MEVehicle& veh, const SUMOReal timeOnLane,
00214         const SUMOReal dist) throw() {
00215     if (vehicleApplies(veh)) {
00216         sampleSeconds += timeOnLane;
00217         travelledDistance += dist;
00218         vehLengthSum += veh.getVehicleType().getLength() * timeOnLane;
00219         if (myParent!=0&&dist/timeOnLane<myParent->myHaltSpeed) {
00220             waitSeconds += timeOnLane;
00221         }
00222     }
00223 }
00224 
00225 
00226 void
00227 MSMeanData_Net::MSLaneMeanDataValues::getLastReported(MEVehicle *v, SUMOTime &lastReportedTime, SUMOReal &lastReportedPos) throw() {
00228     std::map<MEVehicle*, std::pair<SUMOTime, SUMOReal> >::iterator j=myLastVehicleUpdateValues.find(v);
00229     if (j!=myLastVehicleUpdateValues.end()) {
00230         // the vehicle already has reported its values before; use these
00231         std::pair<SUMOTime, SUMOReal> &vals = (*j).second;
00232         lastReportedTime = vals.first;
00233         lastReportedPos = vals.second;
00234         myLastVehicleUpdateValues.erase(j);
00235     }
00236 }
00237 
00238 
00239 void
00240 MSMeanData_Net::MSLaneMeanDataValues::setLastReported(MEVehicle *v, SUMOTime lastReportedTime, SUMOReal lastReportedPos) throw() {
00241     myLastVehicleUpdateValues[v] = std::pair<SUMOTime, SUMOReal>(lastReportedTime, lastReportedPos);
00242 }
00243 #endif
00244 
00245 // ---------------------------------------------------------------------------
00246 // MSMeanData_Net - methods
00247 // ---------------------------------------------------------------------------
00248 MSMeanData_Net::MSMeanData_Net(const std::string &id,
00249                                const SUMOTime dumpBegin, const SUMOTime dumpEnd,
00250                                const bool useLanes, const bool withEmpty,
00251                                const bool trackVehicles,
00252                                const SUMOReal maxTravelTime, const SUMOReal minSamples,
00253                                const SUMOReal haltSpeed, const std::set<std::string> vTypes) throw()
00254         : MSMeanData(id, dumpBegin, dumpEnd, useLanes, withEmpty, trackVehicles, maxTravelTime, minSamples, vTypes),
00255         myHaltSpeed(haltSpeed) {
00256 }
00257 
00258 
00259 MSMeanData_Net::~MSMeanData_Net() throw() {}
00260 
00261 
00262 MSMeanData::MeanDataValues*
00263 MSMeanData_Net::createValues(MSLane * const lane, const bool doAdd) const throw(IOError) {
00264     return new MSLaneMeanDataValues(lane, doAdd, &myVehicleTypes, this);
00265 }
00266 
00267 
00268 void
00269 MSMeanData_Net::writeEdge(OutputDevice &dev,
00270                           const std::vector<MSMeanData::MeanDataValues*> &edgeValues,
00271                           MSEdge *edge, SUMOTime startTime, SUMOTime stopTime) throw(IOError) {
00272 #ifdef HAVE_MESOSIM
00273     if (MSGlobals::gUseMesoSim) {
00274         MSLaneMeanDataValues* sumData = (MSLaneMeanDataValues*)createValues(0, false);
00275         unsigned entered;
00276         bool isFirst = true;
00277         MESegment *s = MSGlobals::gMesoNet->getSegmentForEdge(*edge);
00278         std::vector<MeanDataValues*>::const_iterator data;
00279         for (data = edgeValues.begin(); data != edgeValues.end(); ++data) {
00280             MSLaneMeanDataValues& meanData = (MSLaneMeanDataValues&)**data;
00281             s->prepareMeanDataForWriting(meanData, stopTime);
00282             meanData.addTo(*sumData);
00283             if (isFirst) {
00284                 entered = meanData.nVehEntered;
00285                 isFirst = false;
00286             }
00287             sumData->nVehLeft = meanData.nVehLeft;
00288             meanData.reset();
00289             s = s->getNextSegment();
00290         }
00291         sumData->nVehEntered = entered;
00292         if (writePrefix(dev, *sumData, "<edge id=\""+edge->getID())) {
00293             sumData->write(dev, stopTime - startTime,
00294                            (SUMOReal)edge->getLanes().size(), edge->getLanes()[0]->getLength());
00295         }
00296         delete sumData;
00297         return;
00298     }
00299 #endif
00300     MSMeanData::writeEdge(dev, edgeValues, edge, startTime, stopTime);
00301 }
00302 
00303 
00304 /****************************************************************************/
00305 

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