SUMO - Simulation of Urban MObility

ROEdge.cpp

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