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 "MSE2Collector.h"
00031
00032 #ifdef CHECK_MEMORY_LEAKS
00033 #include <foreign/nvwa/debug_new.h>
00034 #endif // CHECK_MEMORY_LEAKS
00035
00036
00037
00038
00039
00040 MSE2Collector::MSE2Collector(const std::string &id, DetectorUsage usage,
00041 MSLane * const lane, SUMOReal startPos, SUMOReal detLength,
00042 SUMOTime haltingTimeThreshold,
00043 SUMOReal haltingSpeedThreshold,
00044 SUMOReal jamDistThreshold) throw()
00045 : Named(id), MSMoveReminder(lane),
00046 myJamHaltingSpeedThreshold(haltingSpeedThreshold),
00047 myJamHaltingTimeThreshold(haltingTimeThreshold),
00048 myJamDistanceThreshold(jamDistThreshold),
00049 myStartPos(startPos), myEndPos(startPos + detLength),
00050 myUsage(usage),
00051 myCurrentOccupancy(0), myCurrentMeanSpeed(-1), myCurrentJamNo(0),
00052 myCurrentMaxJamLengthInMeters(0), myCurrentMaxJamLengthInVehicles(0),
00053 myCurrentJamLengthInMeters(0), myCurrentJamLengthInVehicles(0), myCurrentStartedHalts(0)
00054
00055 {
00056 assert(myLane != 0);
00057 assert(myStartPos >= 0 && myStartPos < myLane->getLength());
00058 assert(myEndPos - myStartPos > 0 && myEndPos <= myLane->getLength());
00059 reset();
00060 }
00061
00062
00063 MSE2Collector::~MSE2Collector() throw() {
00064 for (std::list<MSVehicle*>::iterator i=myKnownVehicles.begin(); i!=myKnownVehicles.end(); ++i) {
00065 (*i)->quitRemindedLeft(this);
00066 }
00067 myKnownVehicles.clear();
00068 }
00069
00070
00071 bool
00072 MSE2Collector::isStillActive(MSVehicle& veh, SUMOReal oldPos,
00073 SUMOReal newPos, SUMOReal) throw() {
00074 if (newPos <= myStartPos) {
00075
00076 return true;
00077 }
00078 if (oldPos <= myStartPos && newPos > myStartPos) {
00079 if (find(myKnownVehicles.begin(), myKnownVehicles.end(), &veh)==myKnownVehicles.end()) {
00080 myKnownVehicles.push_back(&veh);
00081 veh.quitRemindedEntered(this);
00082 }
00083 }
00084 if (newPos - veh.getVehicleType().getLength() > myEndPos) {
00085 veh.quitRemindedLeft(this);
00086 std::list<MSVehicle*>::iterator i = find(myKnownVehicles.begin(), myKnownVehicles.end(), &veh);
00087 if (i!=myKnownVehicles.end()) {
00088 myKnownVehicles.erase(i);
00089 }
00090 return false;
00091 }
00092 return true;
00093 }
00094
00095
00096 void
00097 MSE2Collector::notifyLeave(MSVehicle& veh, bool isArrival, bool isLaneChange) throw() {
00098 if (veh.getPositionOnLane() >= myStartPos && veh.getPositionOnLane() - veh.getVehicleType().getLength() < myEndPos) {
00099 std::list<MSVehicle*>::iterator i = find(myKnownVehicles.begin(), myKnownVehicles.end(), &veh);
00100 if (i!=myKnownVehicles.end()) {
00101 myKnownVehicles.erase(i);
00102 }
00103 veh.quitRemindedLeft(this);
00104 }
00105 }
00106
00107
00108 bool
00109 MSE2Collector::notifyEnter(MSVehicle& veh, bool, bool) throw() {
00110 if (veh.getPositionOnLane() >= myStartPos && veh.getPositionOnLane() - veh.getVehicleType().getLength() < myEndPos) {
00111
00112 veh.quitRemindedEntered(this);
00113 myKnownVehicles.push_back(&veh);
00114 return true;
00115 }
00116 if (veh.getPositionOnLane() - veh.getVehicleType().getLength() > myEndPos) {
00117
00118 return false;
00119 }
00120
00121 return true;
00122 }
00123
00124
00125 void
00126 MSE2Collector::reset() throw() {
00127 mySpeedSum = 0;
00128 myStartedHalts = 0;
00129 myJamLengthInMetersSum = 0;
00130 myJamLengthInVehiclesSum = 0;
00131 myVehicleSamples = 0;
00132 myOccupancySum = 0;
00133 myMaxOccupancy = 0;
00134 myMeanMaxJamInVehicles = 0;
00135 myMeanMaxJamInMeters = 0;
00136 myMaxJamInVehicles = 0;
00137 myMaxJamInMeters = 0;
00138 myTimeSamples = 0;
00139 myMeanVehicleNumber = 0;
00140 myMaxVehicleNumber = 0;
00141 for (std::map<MSVehicle*, SUMOReal>::iterator i=myIntervalHaltingVehicleDurations.begin(); i!=myIntervalHaltingVehicleDurations.end(); ++i) {
00142 (*i).second = 0;
00143 }
00144 myPastStandingDurations.clear();
00145 myPastIntervalStandingDurations.clear();
00146 }
00147
00148
00149
00150 void
00151 MSE2Collector::update(SUMOTime) throw() {
00152 JamInfo *currentJam = 0;
00153 std::map<MSVehicle*, SUMOReal> haltingVehicles;
00154 std::map<MSVehicle*, SUMOReal> intervalHaltingVehicles;
00155 std::vector<JamInfo*> jams;
00156
00157 SUMOReal lengthSum = 0;
00158 myCurrentMeanSpeed = 0;
00159 myCurrentMeanLength = 0;
00160 myCurrentStartedHalts = 0;
00161
00162
00163
00164 myKnownVehicles.sort(by_vehicle_position_sorter(getLane()));
00165 for (std::list<MSVehicle*>::const_iterator i=myKnownVehicles.begin(); i!=myKnownVehicles.end(); ++i) {
00166 MSVehicle *veh = *i;
00167
00168 SUMOReal length = veh->getVehicleType().getLength();
00169 if (&(veh->getLane())==getLane()) {
00170 if (veh->getPositionOnLane() - veh->getVehicleType().getLength() < myStartPos) {
00171
00172 length -= (veh->getVehicleType().getLength() - (veh->getPositionOnLane()-myStartPos));
00173 }
00174 if (veh->getPositionOnLane()>myEndPos && veh->getPositionOnLane()-veh->getVehicleType().getLength()<=myEndPos) {
00175
00176 length -= (veh->getPositionOnLane()-myEndPos);
00177 }
00178 } else {
00179
00180
00181 assert(veh->getPositionOnActiveMoveReminderLane(getLane())>0);
00182 length -= (veh->getPositionOnActiveMoveReminderLane(getLane())-myEndPos);
00183 }
00184 assert(length>=0);
00185
00186 mySpeedSum += veh->getSpeed();
00187 myCurrentMeanSpeed += veh->getSpeed();
00188 lengthSum += length;
00189 myCurrentMeanLength += length;
00190
00191
00192 bool isInJam = false;
00193
00194 if (veh->getSpeed()<myJamHaltingSpeedThreshold) {
00195
00196
00197 bool wasHalting = myHaltingVehicleDurations.find(veh)!=myHaltingVehicleDurations.end();
00198 if (wasHalting) {
00199 haltingVehicles[veh] = myHaltingVehicleDurations[veh] + 1;
00200 intervalHaltingVehicles[veh] = myIntervalHaltingVehicleDurations[veh] + 1;
00201 } else {
00202 haltingVehicles[veh] = 1;
00203 intervalHaltingVehicles[veh] = 1;
00204 myCurrentStartedHalts++;
00205 myStartedHalts++;
00206 }
00207
00208 if (haltingVehicles[veh]>myJamHaltingTimeThreshold) {
00209
00210 isInJam = true;
00211 }
00212 } else {
00213
00214 std::map<MSVehicle*, SUMOReal>::iterator v = myHaltingVehicleDurations.find(veh);
00215 if (v!=myHaltingVehicleDurations.end()) {
00216 myPastStandingDurations.push_back((*v).second);
00217 myHaltingVehicleDurations.erase(v);
00218 }
00219 v = myIntervalHaltingVehicleDurations.find(veh);
00220 if (v!=myIntervalHaltingVehicleDurations.end()) {
00221 myPastIntervalStandingDurations.push_back((*v).second);
00222 myIntervalHaltingVehicleDurations.erase(v);
00223 }
00224 }
00225
00226
00227 if (isInJam) {
00228
00229
00230 if (currentJam==0) {
00231
00232 currentJam = new JamInfo;
00233 currentJam->firstStandingVehicle = i;
00234 } else {
00235
00236
00237
00238 if (veh->getPositionOnLane()-(*currentJam->lastStandingVehicle)->getPositionOnLane()>myJamDistanceThreshold) {
00239
00240
00241 jams.push_back(currentJam);
00242 currentJam = new JamInfo;
00243 currentJam->firstStandingVehicle = i;
00244 }
00245 }
00246 currentJam->lastStandingVehicle = i;
00247 } else {
00248
00249
00250 if (currentJam!=0) {
00251 jams.push_back(currentJam);
00252 currentJam = 0;
00253 }
00254 }
00255 }
00256 if (currentJam!=0) {
00257 jams.push_back(currentJam);
00258 currentJam = 0;
00259 }
00260
00261 myCurrentMaxJamLengthInMeters = 0;
00262 myCurrentMaxJamLengthInVehicles = 0;
00263 myCurrentJamLengthInMeters = 0;
00264 myCurrentJamLengthInVehicles = 0;
00265
00266 for (std::vector<JamInfo*>::iterator i=jams.begin(); i!=jams.end(); ++i) {
00267
00268 SUMOReal jamLengthInMeters =
00269 (*(*i)->firstStandingVehicle)->getPositionOnActiveMoveReminderLane(getLane())
00270 - (*(*i)->lastStandingVehicle)->getPositionOnActiveMoveReminderLane(getLane())
00271 + (*(*i)->lastStandingVehicle)->getVehicleType().getLength();
00272 unsigned jamLengthInVehicles = (unsigned) distance((*i)->firstStandingVehicle, (*i)->lastStandingVehicle) + 1;
00273
00274 myCurrentMaxJamLengthInMeters = MAX2(myCurrentMaxJamLengthInMeters, jamLengthInMeters);
00275 myCurrentMaxJamLengthInVehicles = MAX2(myCurrentMaxJamLengthInVehicles, jamLengthInVehicles);
00276 myJamLengthInMetersSum += jamLengthInMeters;
00277 myJamLengthInVehiclesSum += jamLengthInVehicles;
00278 myCurrentJamLengthInMeters += jamLengthInMeters;
00279 myCurrentJamLengthInVehicles += jamLengthInVehicles;
00280 }
00281 myCurrentJamNo = (unsigned) jams.size();
00282
00283 unsigned noVehicles = (unsigned) myKnownVehicles.size();
00284 myVehicleSamples += noVehicles;
00285 myTimeSamples += 1;
00286
00287 SUMOReal currentOccupancy = lengthSum / (myEndPos-myStartPos) * (SUMOReal) 100.;
00288 myCurrentOccupancy = currentOccupancy;
00289 myOccupancySum += currentOccupancy;
00290 myMaxOccupancy = MAX2(myMaxOccupancy, currentOccupancy);
00291
00292 myMeanMaxJamInVehicles += myCurrentMaxJamLengthInVehicles;
00293 myMeanMaxJamInMeters += myCurrentMaxJamLengthInMeters;
00294 myMaxJamInVehicles = MAX2(myMaxJamInVehicles, myCurrentMaxJamLengthInVehicles);
00295 myMaxJamInMeters = MAX2(myMaxJamInMeters, myCurrentMaxJamLengthInMeters);
00296
00297 myHaltingVehicleDurations = haltingVehicles;
00298 myIntervalHaltingVehicleDurations = intervalHaltingVehicles;
00299
00300 myMeanVehicleNumber += (unsigned) myKnownVehicles.size();
00301 myMaxVehicleNumber = MAX2((unsigned) myKnownVehicles.size(), myMaxVehicleNumber);
00302
00303 myCurrentMeanSpeed = noVehicles!=0 ? myCurrentMeanSpeed / (SUMOReal) noVehicles : -1;
00304 myCurrentMeanLength = noVehicles!=0 ? myCurrentMeanLength / (SUMOReal) noVehicles : -1;
00305
00306
00307 for (std::vector<JamInfo*>::iterator i=jams.begin(); i!=jams.end(); ++i) {
00308 delete *i;
00309 }
00310 jams.clear();
00311 }
00312
00313
00314
00315 void
00316 MSE2Collector::writeXMLOutput(OutputDevice &dev, SUMOTime startTime, SUMOTime stopTime) throw(IOError) {
00317 dev<<" <interval begin=\""<<time2string(startTime)<<"\" end=\""<< time2string(stopTime)<<"\" "<<"id=\""<<getID()<<"\" ";
00318
00319 SUMOReal meanSpeed = myVehicleSamples!=0 ? mySpeedSum / (SUMOReal) myVehicleSamples : -1;
00320 SUMOReal meanOccupancy = myTimeSamples!=0 ? myOccupancySum / (SUMOReal) myTimeSamples : 0;
00321 SUMOReal meanJamLengthInMeters = myTimeSamples!=0 ? myMeanMaxJamInMeters / (SUMOReal) myTimeSamples : 0;
00322 SUMOReal meanJamLengthInVehicles = myTimeSamples!=0 ? myMeanMaxJamInVehicles / (SUMOReal) myTimeSamples : 0;
00323 SUMOReal meanVehicleNumber = myTimeSamples!=0 ? (SUMOReal) myMeanVehicleNumber / (SUMOReal) myTimeSamples : 0;
00324
00325 SUMOReal haltingDurationSum = 0;
00326 SUMOReal maxHaltingDuration = 0;
00327 SUMOReal haltingNo = 0;
00328 for (std::vector<SUMOReal>::iterator i=myPastStandingDurations.begin(); i!=myPastStandingDurations.end(); ++i) {
00329 haltingDurationSum += (*i);
00330 maxHaltingDuration = MAX2(maxHaltingDuration, (*i));
00331 haltingNo = haltingNo + 1;
00332 }
00333 for (std::map<MSVehicle*, SUMOReal> ::iterator i=myHaltingVehicleDurations.begin(); i!=myHaltingVehicleDurations.end(); ++i) {
00334 haltingDurationSum += (*i).second;
00335 maxHaltingDuration = MAX2(maxHaltingDuration, (*i).second);
00336 haltingNo = haltingNo + 1;
00337 }
00338 SUMOReal meanHaltingDuration = haltingNo!=0 ? haltingDurationSum / (SUMOReal) haltingNo : 0;
00339
00340 SUMOReal intervalHaltingDurationSum = 0;
00341 SUMOReal intervalMaxHaltingDuration = 0;
00342 SUMOReal intervalHaltingNo = 0;
00343 for (std::vector<SUMOReal>::iterator i=myPastIntervalStandingDurations.begin(); i!=myPastIntervalStandingDurations.end(); ++i) {
00344 intervalHaltingDurationSum += (*i);
00345 intervalMaxHaltingDuration = MAX2(intervalMaxHaltingDuration, (*i));
00346 intervalHaltingNo = intervalHaltingNo + 1;
00347 }
00348 for (std::map<MSVehicle*, SUMOReal> ::iterator i=myIntervalHaltingVehicleDurations.begin(); i!=myIntervalHaltingVehicleDurations.end(); ++i) {
00349 intervalHaltingDurationSum += (*i).second;
00350 intervalMaxHaltingDuration = MAX2(intervalMaxHaltingDuration, (*i).second);
00351 intervalHaltingNo = intervalHaltingNo + 1;
00352 }
00353 SUMOReal intervalMeanHaltingDuration = intervalHaltingNo!=0 ? intervalHaltingDurationSum / (SUMOReal) intervalHaltingNo : 0;
00354
00355 dev << "nSamples=\"" << myVehicleSamples << "\" "
00356 << "meanSpeed=\"" << meanSpeed << "\" "
00357 << "meanOccupancy=\"" << meanOccupancy << "\" "
00358 << "maxOccupancy=\"" << myMaxOccupancy << "\" "
00359 << "meanMaxJamLengthInVehicles=\"" << meanJamLengthInVehicles << "\" "
00360 << "meanMaxJamLengthInMeters=\"" << meanJamLengthInMeters << "\" "
00361 << "maxJamLengthInVehicles=\"" << myMaxJamInVehicles << "\" "
00362 << "maxJamLengthInMeters=\"" << myMaxJamInMeters << "\" "
00363 << "jamLengthInVehiclesSum=\"" << myJamLengthInVehiclesSum << "\" "
00364 << "jamLengthInMetersSum=\"" << myJamLengthInMetersSum << "\" "
00365 << "meanHaltingDuration=\"" << meanHaltingDuration << "\" "
00366 << "maxHaltingDuration=\"" << maxHaltingDuration << "\" "
00367 << "haltingDurationSum=\"" << haltingDurationSum << "\" "
00368 << "meanIntervalHaltingDuration=\"" << intervalMeanHaltingDuration << "\" "
00369 << "maxIntervalHaltingDuration=\"" << intervalMaxHaltingDuration << "\" "
00370 << "intervalHaltingDurationSum=\"" << intervalHaltingDurationSum << "\" "
00371 << "startedHalts=\"" << myStartedHalts << "\" "
00372 << "meanVehicleNumber=\"" << meanVehicleNumber << "\" "
00373 << "maxVehicleNumber=\"" << myMaxVehicleNumber << "\" "
00374 << "/>\n";
00375 reset();
00376 }
00377
00378
00379 void
00380 MSE2Collector::writeXMLDetectorProlog(OutputDevice &dev) const throw(IOError) {
00381 dev.writeXMLHeader("detector");
00382 }
00383
00384
00385 unsigned
00386 MSE2Collector::getCurrentVehicleNumber() const throw() {
00387 return (unsigned) myKnownVehicles.size();
00388 }
00389
00390
00391 SUMOReal
00392 MSE2Collector::getCurrentOccupancy() const throw() {
00393 return myCurrentOccupancy *(SUMOReal) 100.;
00394 }
00395
00396
00397 SUMOReal
00398 MSE2Collector::getCurrentMeanSpeed() const throw() {
00399 return myCurrentMeanSpeed;
00400 }
00401
00402
00403 SUMOReal
00404 MSE2Collector::getCurrentMeanLength() const throw() {
00405 return myCurrentMeanLength;
00406 }
00407
00408
00409 unsigned
00410 MSE2Collector::getCurrentJamNumber() const throw() {
00411 return myCurrentJamNo;
00412 }
00413
00414
00415 unsigned
00416 MSE2Collector::getCurrentMaxJamLengthInVehicles() const throw() {
00417 return myCurrentMaxJamLengthInVehicles;
00418 }
00419
00420
00421 SUMOReal
00422 MSE2Collector::getCurrentMaxJamLengthInMeters() const throw() {
00423 return myCurrentMaxJamLengthInMeters;
00424 }
00425
00426
00427 unsigned
00428 MSE2Collector::getCurrentJamLengthInVehicles() const throw() {
00429 return myCurrentJamLengthInVehicles;
00430 }
00431
00432
00433 SUMOReal
00434 MSE2Collector::getCurrentJamLengthInMeters() const throw() {
00435 return myCurrentJamLengthInMeters;
00436 }
00437
00438
00439 unsigned
00440 MSE2Collector::getCurrentStartedHalts() const throw() {
00441 return myCurrentStartedHalts;
00442 }
00443
00444
00445 void
00446 MSE2Collector::removeOnTripEnd(MSVehicle *veh) throw() {
00447 myKnownVehicles.erase(find(myKnownVehicles.begin(), myKnownVehicles.end(), veh));
00448 }
00449
00450
00451
00452