SUMO - Simulation of Urban MObility

ROEdge.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00010 // A basic edge for routing applications
00011 /****************************************************************************/
00012 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00013 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00014 /****************************************************************************/
00015 //
00016 //   This file is part of SUMO.
00017 //   SUMO is free software: you can redistribute it and/or modify
00018 //   it under the terms of the GNU General Public License as published by
00019 //   the Free Software Foundation, either version 3 of the License, or
00020 //   (at your option) any later version.
00021 //
00022 /****************************************************************************/
00023 
00024 
00025 // ===========================================================================
00026 // included modules
00027 // ===========================================================================
00028 #ifdef _MSC_VER
00029 #include <windows_config.h>
00030 #else
00031 #include <config.h>
00032 #endif
00033 
00034 #include <utils/common/MsgHandler.h>
00035 #include <utils/common/ToString.h>
00036 #include <algorithm>
00037 #include <cassert>
00038 #include <iostream>
00039 #include "ROLane.h"
00040 #include "ROEdge.h"
00041 #include "ROVehicle.h"
00042 #include <utils/common/SUMOVTypeParameter.h>
00043 #include <utils/common/HelpersHBEFA.h>
00044 #include <utils/common/HelpersHarmonoise.h>
00045 
00046 #ifdef CHECK_MEMORY_LEAKS
00047 #include <foreign/nvwa/debug_new.h>
00048 #endif // CHECK_MEMORY_LEAKS
00049 
00050 
00051 // ===========================================================================
00052 // static member definitions
00053 // ===========================================================================
00054 bool ROEdge::myHaveTTWarned = false;
00055 bool ROEdge::myHaveEWarned = false;
00056 std::vector<ROEdge*> ROEdge::myEdges;
00057 
00058 
00059 // ===========================================================================
00060 // method definitions
00061 // ===========================================================================
00062 ROEdge::ROEdge(const std::string& id, RONode* from, RONode* to, unsigned int index,
00063                bool useBoundariesOnOverride, bool interpolate)
00064     : myID(id), mySpeed(-1),
00065       myIndex(index), myLength(-1),
00066       myUsingTTTimeLine(false), myUseBoundariesOnOverrideTT(useBoundariesOnOverride),
00067       myUsingETimeLine(false), myUseBoundariesOnOverrideE(useBoundariesOnOverride),
00068       myFromNode(from), myToNode(to), myInterpolate(interpolate) {
00069     while (myEdges.size() <= index) {
00070         myEdges.push_back(0);
00071     }
00072     myEdges[index] = this;
00073 }
00074 
00075 
00076 ROEdge::~ROEdge() {
00077     for (std::vector<ROLane*>::iterator i = myLanes.begin(); i != myLanes.end(); ++i) {
00078         delete(*i);
00079     }
00080 }
00081 
00082 
00083 void
00084 ROEdge::addLane(ROLane* lane) {
00085     SUMOReal length = lane->getLength();
00086     assert(myLength == -1 || length == myLength);
00087     myLength = length;
00088     SUMOReal speed = lane->getSpeed();
00089     mySpeed = speed > mySpeed ? speed : mySpeed;
00090     myLanes.push_back(lane);
00091 
00092     // integrate new allowed classes
00093     const SUMOVehicleClasses& allowed = lane->getAllowedClasses();
00094     myAllowedClasses.insert(allowed.begin(), allowed.end());
00095     for (SUMOVehicleClasses::const_iterator it = allowed.begin(); it != allowed.end(); it++) {
00096         myNotAllowedClasses.erase(*it);
00097     }
00098     // integrate new disallowed classes
00099     const SUMOVehicleClasses& disallowed = lane->getNotAllowedClasses();
00100     for (SUMOVehicleClasses::const_iterator it = disallowed.begin(); it != disallowed.end(); it++) {
00101         // only add to myNotAllowedClasses if not explicitly allowed by other lanes
00102         if (myAllowedClasses.count(*it) == 0) {
00103             myNotAllowedClasses.insert(*it);
00104         }
00105     }
00106 }
00107 
00108 
00109 void
00110 ROEdge::addFollower(ROEdge* s) {
00111     if (find(myFollowingEdges.begin(), myFollowingEdges.end(), s) == myFollowingEdges.end()) {
00112         myFollowingEdges.push_back(s);
00113     }
00114 }
00115 
00116 
00117 void
00118 ROEdge::addEffort(SUMOReal value, SUMOReal timeBegin, SUMOReal timeEnd) {
00119     myEfforts.add(timeBegin, timeEnd, value);
00120     myUsingETimeLine = true;
00121 }
00122 
00123 
00124 void
00125 ROEdge::addTravelTime(SUMOReal value, SUMOReal timeBegin, SUMOReal timeEnd) {
00126     myTravelTimes.add(timeBegin, timeEnd, value);
00127     myUsingTTTimeLine = true;
00128 }
00129 
00130 
00131 SUMOReal
00132 ROEdge::getEffort(const ROVehicle* const veh, SUMOReal time) const {
00133     UNUSED_PARAMETER(veh);
00134     SUMOReal ret = 0;
00135     if (!getStoredEffort(time, ret)) {
00136         return (SUMOReal)(myLength / mySpeed);
00137     }
00138     return ret;
00139 }
00140 
00141 
00142 SUMOReal
00143 ROEdge::getTravelTime(const ROVehicle* const, SUMOReal time) const {
00144     if (myUsingTTTimeLine) {
00145         if (!myHaveTTWarned && !myTravelTimes.describesTime(time)) {
00146             WRITE_WARNING("No interval matches passed time " + toString(time)  + " in edge '" + myID + "'.\n Using edge's length / edge's speed.");
00147             myHaveTTWarned = true;
00148         }
00149         if (myInterpolate) {
00150             SUMOReal inTT = myTravelTimes.getValue(time);
00151             SUMOReal split = (SUMOReal)(myTravelTimes.getSplitTime(time, time + (SUMOTime)inTT) - time);
00152             if (split >= 0) {
00153                 return myTravelTimes.getValue(time + (SUMOTime)inTT) * ((SUMOReal)1. - split / inTT) + split;
00154             }
00155         }
00156         return myTravelTimes.getValue(time);
00157     }
00158     // ok, no absolute value was found, use the normal value (without) as default
00159     return (SUMOReal)(myLength / mySpeed);
00160 }
00161 
00162 
00163 SUMOReal
00164 ROEdge::getCOEffort(const ROVehicle* const veh, SUMOReal time) const {
00165     SUMOReal ret = 0;
00166     if (!getStoredEffort(time, ret)) {
00167         SUMOReal v = mySpeed;
00168         SUMOEmissionClass c = SVE_UNKNOWN;
00169         if (veh->getType() != 0) {
00170             v = MIN2(veh->getType()->maxSpeed, mySpeed);
00171             c = veh->getType()->emissionClass;
00172         }
00173         ret = HelpersHBEFA::computeCO(c, v, 0) * getTravelTime(veh, time);
00174     }
00175     return ret;
00176 }
00177 
00178 
00179 SUMOReal
00180 ROEdge::getCO2Effort(const ROVehicle* const veh, SUMOReal time) const {
00181     SUMOReal ret = 0;
00182     if (!getStoredEffort(time, ret)) {
00183         SUMOReal v = mySpeed;
00184         SUMOEmissionClass c = SVE_UNKNOWN;
00185         if (veh->getType() != 0) {
00186             v = MIN2(veh->getType()->maxSpeed, mySpeed);
00187             c = veh->getType()->emissionClass;
00188         }
00189         ret = HelpersHBEFA::computeCO2(c, v, 0) * getTravelTime(veh, time);
00190     }
00191     return ret;
00192 }
00193 
00194 
00195 SUMOReal
00196 ROEdge::getPMxEffort(const ROVehicle* const veh, SUMOReal time) const {
00197     SUMOReal ret = 0;
00198     if (!getStoredEffort(time, ret)) {
00199         SUMOReal v = mySpeed;
00200         SUMOEmissionClass c = SVE_UNKNOWN;
00201         if (veh->getType() != 0) {
00202             v = MIN2(veh->getType()->maxSpeed, mySpeed);
00203             c = veh->getType()->emissionClass;
00204         }
00205         ret = HelpersHBEFA::computePMx(c, v, 0) * getTravelTime(veh, time);
00206     }
00207     return ret;
00208 }
00209 
00210 
00211 SUMOReal
00212 ROEdge::getHCEffort(const ROVehicle* const veh, SUMOReal time) const {
00213     SUMOReal ret = 0;
00214     if (!getStoredEffort(time, ret)) {
00215         SUMOReal v = mySpeed;
00216         SUMOEmissionClass c = SVE_UNKNOWN;
00217         if (veh->getType() != 0) {
00218             v = MIN2(veh->getType()->maxSpeed, mySpeed);
00219             c = veh->getType()->emissionClass;
00220         }
00221         ret = HelpersHBEFA::computeHC(c, v, 0) * getTravelTime(veh, time);
00222     }
00223     return ret;
00224 }
00225 
00226 
00227 SUMOReal
00228 ROEdge::getNOxEffort(const ROVehicle* const veh, SUMOReal time) const {
00229     SUMOReal ret = 0;
00230     if (!getStoredEffort(time, ret)) {
00231         SUMOReal v = mySpeed;
00232         SUMOEmissionClass c = SVE_UNKNOWN;
00233         if (veh->getType() != 0) {
00234             v = MIN2(veh->getType()->maxSpeed, mySpeed);
00235             c = veh->getType()->emissionClass;
00236         }
00237         ret = HelpersHBEFA::computeNOx(c, v, 0) * getTravelTime(veh, time);
00238     }
00239     return ret;
00240 }
00241 
00242 
00243 SUMOReal
00244 ROEdge::getFuelEffort(const ROVehicle* const veh, SUMOReal time) const {
00245     SUMOReal ret = 0;
00246     if (!getStoredEffort(time, ret)) {
00247         SUMOReal v = mySpeed;
00248         SUMOEmissionClass c = SVE_UNKNOWN;
00249         if (veh->getType() != 0) {
00250             v = MIN2(veh->getType()->maxSpeed, mySpeed);
00251             c = veh->getType()->emissionClass;
00252         }
00253         ret = HelpersHBEFA::computeFuel(c, v, 0) * getTravelTime(veh, time);
00254     }
00255     return ret;
00256 }
00257 
00258 
00259 SUMOReal
00260 ROEdge::getNoiseEffort(const ROVehicle* const veh, SUMOReal time) const {
00261     SUMOReal ret = 0;
00262     if (!getStoredEffort(time, ret)) {
00263         SUMOReal v = mySpeed;
00264         SUMOEmissionClass c = SVE_UNKNOWN;
00265         if (veh->getType() != 0) {
00266             v = MIN2(veh->getType()->maxSpeed, mySpeed);
00267             c = veh->getType()->emissionClass;
00268         }
00269         ret = HelpersHarmonoise::computeNoise(veh->getType()->emissionClass, v, 0);
00270     }
00271     return ret;
00272 }
00273 
00274 
00275 bool
00276 ROEdge::getStoredEffort(SUMOReal time, SUMOReal& ret) const {
00277     if (myUsingETimeLine) {
00278         if (!myEfforts.describesTime(time)) {
00279             if (!myHaveEWarned) {
00280                 WRITE_WARNING("No interval matches passed time " + toString(time)  + " in edge '" + myID + "'.\n Using edge's length / edge's speed.");
00281                 myHaveEWarned = true;
00282             }
00283             return false;
00284         }
00285         if (myInterpolate) {
00286             SUMOReal inTT = myTravelTimes.getValue(time);
00287             SUMOReal ratio = (SUMOReal)(myEfforts.getSplitTime(time, time + (SUMOTime)inTT) - time) / inTT;
00288             if (ratio >= 0) {
00289                 ret = ratio * myEfforts.getValue(time) + (1 - ratio) * myEfforts.getValue(time + (SUMOTime)inTT);
00290                 return true;
00291             }
00292         }
00293         ret = myEfforts.getValue(time);
00294         return true;
00295     }
00296     return false;
00297 }
00298 
00299 
00300 unsigned int
00301 ROEdge::getNoFollowing() const {
00302     if (getType() == ET_SINK) {
00303         return 0;
00304     }
00305     return (unsigned int) myFollowingEdges.size();
00306 }
00307 
00308 
00309 void
00310 ROEdge::setType(ROEdge::EdgeType type) {
00311     myType = type;
00312 }
00313 
00314 
00315 bool
00316 ROEdge::prohibits(const ROVehicle* const vehicle) const {
00317     if (myAllowedClasses.size() == 0 && myNotAllowedClasses.size() == 0) {
00318         return false;
00319     }
00320     // ok, vehicles with an unknown class may be only prohibited
00321     //  if the edge is limited to a set of classes
00322     SUMOVehicleClass vclass = vehicle->getType() != 0 ? vehicle->getType()->vehicleClass : DEFAULT_VEH_CLASS;
00323     if (vclass == SVC_UNKNOWN) {
00324         return false;
00325     }
00326     // check whether it is explicitly disallowed
00327     if (find(myNotAllowedClasses.begin(), myNotAllowedClasses.end(), vclass) != myNotAllowedClasses.end()) {
00328         return true;
00329     }
00330     // check whether it is within the allowed classes
00331     if (myAllowedClasses.size() == 0 || find(myAllowedClasses.begin(), myAllowedClasses.end(), vclass) != myAllowedClasses.end()) {
00332         return false;
00333     }
00334     // ok, we have a set of allowed vehicle classes, but this vehicle's class
00335     //  is not among them
00336     return true;
00337 }
00338 
00339 
00340 void
00341 ROEdge::buildTimeLines(const std::string& measure) {
00342     if (myUsingETimeLine) {
00343         SUMOReal value = (SUMOReal)(myLength / mySpeed);
00344         if (measure == "CO") {
00345             value = HelpersHBEFA::computeCO(SVE_UNKNOWN, mySpeed, 0) * value;
00346         }
00347         if (measure == "CO2") {
00348             value = HelpersHBEFA::computeCO2(SVE_UNKNOWN, mySpeed, 0) * value;
00349         }
00350         if (measure == "HC") {
00351             value = HelpersHBEFA::computeHC(SVE_UNKNOWN, mySpeed, 0) * value;
00352         }
00353         if (measure == "PMx") {
00354             value = HelpersHBEFA::computePMx(SVE_UNKNOWN, mySpeed, 0) * value;
00355         }
00356         if (measure == "NOx") {
00357             value = HelpersHBEFA::computeNOx(SVE_UNKNOWN, mySpeed, 0) * value;
00358         }
00359         if (measure == "fuel") {
00360             value = HelpersHBEFA::computeFuel(SVE_UNKNOWN, mySpeed, 0) * value;
00361         }
00362         myEfforts.fillGaps(value, myUseBoundariesOnOverrideE);
00363     }
00364     if (myUsingTTTimeLine) {
00365         SUMOReal value = (SUMOReal)(myLength / mySpeed);
00366         myTravelTimes.fillGaps(value, myUseBoundariesOnOverrideTT);
00367     }
00368 }
00369 
00370 
00371 bool
00372 ROEdge::allFollowersProhibit(const ROVehicle* const vehicle) const {
00373     for (std::vector<ROEdge*>::const_iterator i = myFollowingEdges.begin(); i != myFollowingEdges.end(); ++i) {
00374         if (!(*i)->prohibits(vehicle)) {
00375             return false;
00376         }
00377     }
00378     return true;
00379 }
00380 
00381 
00382 ROEdge*
00383 ROEdge::dictionary(size_t id) {
00384     assert(myEdges.size() > id);
00385     return myEdges[id];
00386 }
00387 
00388 
00389 
00390 /****************************************************************************/
00391 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines