|
SUMO - Simulation of Urban MObility
|
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