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