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::myUseBoundariesOnOverrideTT = false; 00055 bool ROEdge::myUseBoundariesOnOverrideE = false; 00056 bool ROEdge::myInterpolate = false; 00057 bool ROEdge::myHaveTTWarned = false; 00058 bool ROEdge::myHaveEWarned = false; 00059 std::vector<ROEdge*> ROEdge::myEdges; 00060 00061 00062 // =========================================================================== 00063 // method definitions 00064 // =========================================================================== 00065 ROEdge::ROEdge(const std::string& id, RONode* from, RONode* to, unsigned int index) 00066 : myID(id), mySpeed(-1), 00067 myIndex(index), myLength(-1), 00068 myUsingTTTimeLine(false), 00069 myUsingETimeLine(false), 00070 myFromNode(from), myToNode(to) { 00071 while (myEdges.size() <= index) { 00072 myEdges.push_back(0); 00073 } 00074 myEdges[index] = this; 00075 } 00076 00077 00078 ROEdge::~ROEdge() { 00079 for (std::vector<ROLane*>::iterator i = myLanes.begin(); i != myLanes.end(); ++i) { 00080 delete(*i); 00081 } 00082 } 00083 00084 00085 void 00086 ROEdge::addLane(ROLane* lane) { 00087 SUMOReal length = lane->getLength(); 00088 assert(myLength == -1 || length == myLength); 00089 myLength = length; 00090 SUMOReal speed = lane->getSpeed(); 00091 mySpeed = speed > mySpeed ? speed : mySpeed; 00092 myLanes.push_back(lane); 00093 00094 // integrate new allowed classes 00095 myCombinedPermissions |= lane->getPermissions(); 00096 } 00097 00098 00099 void 00100 ROEdge::addFollower(ROEdge* s, std::string) { 00101 if (find(myFollowingEdges.begin(), myFollowingEdges.end(), s) == myFollowingEdges.end()) { 00102 myFollowingEdges.push_back(s); 00103 #ifdef HAVE_MESOSIM // catchall for internal stuff 00104 s->myApproachingEdges.push_back(this); 00105 #endif 00106 } 00107 } 00108 00109 00110 void 00111 ROEdge::addEffort(SUMOReal value, SUMOReal timeBegin, SUMOReal timeEnd) { 00112 myEfforts.add(timeBegin, timeEnd, value); 00113 myUsingETimeLine = true; 00114 } 00115 00116 00117 void 00118 ROEdge::addTravelTime(SUMOReal value, SUMOReal timeBegin, SUMOReal timeEnd) { 00119 myTravelTimes.add(timeBegin, timeEnd, value); 00120 myUsingTTTimeLine = true; 00121 } 00122 00123 00124 SUMOReal 00125 ROEdge::getEffort(const ROVehicle* const veh, SUMOReal time) const { 00126 SUMOReal ret = 0; 00127 if (!getStoredEffort(time, ret)) { 00128 return (SUMOReal)(myLength / MIN2(veh->getType()->maxSpeed, mySpeed)); 00129 } 00130 return ret; 00131 } 00132 00133 00134 SUMOReal 00135 ROEdge::getDistanceTo(const ROEdge* other) const { 00136 return getToNode()->getPosition().distanceTo2D(other->getFromNode()->getPosition()); 00137 } 00138 00139 00140 SUMOReal 00141 ROEdge::getTravelTime(const ROVehicle* const veh, SUMOReal time) const { 00142 if (myUsingTTTimeLine) { 00143 if (!myHaveTTWarned && !myTravelTimes.describesTime(time)) { 00144 WRITE_WARNING("No interval matches passed time " + toString(time) + " in edge '" + myID + "'.\n Using edge's length / edge's speed."); 00145 myHaveTTWarned = true; 00146 } 00147 if (myInterpolate) { 00148 SUMOReal inTT = myTravelTimes.getValue(time); 00149 SUMOReal split = (SUMOReal)(myTravelTimes.getSplitTime(time, time + (SUMOTime)inTT) - time); 00150 if (split >= 0) { 00151 return myTravelTimes.getValue(time + (SUMOTime)inTT) * ((SUMOReal)1. - split / inTT) + split; 00152 } 00153 } 00154 return myTravelTimes.getValue(time); 00155 } 00156 // ok, no absolute value was found, use the normal value (without) as default 00157 return getMinimumTravelTime(veh); 00158 } 00159 00160 00161 SUMOReal 00162 ROEdge::getMinimumTravelTime(const ROVehicle* const veh) const { 00163 return (SUMOReal)(myLength / MIN2(veh->getType()->maxSpeed, mySpeed)); 00164 } 00165 00166 00167 SUMOReal 00168 ROEdge::getCOEffort(const ROVehicle* const veh, SUMOReal time) const { 00169 SUMOReal ret = 0; 00170 if (!getStoredEffort(time, ret)) { 00171 const SUMOReal vMax = MIN2(veh->getType()->maxSpeed, mySpeed); 00172 const SUMOReal accel = veh->getType()->get(SUMO_ATTR_ACCEL, DEFAULT_VEH_ACCEL) * veh->getType()->get(SUMO_ATTR_SIGMA, DEFAULT_VEH_SIGMA) / 2.; 00173 ret = HelpersHBEFA::computeDefaultCO(veh->getType()->emissionClass, vMax, accel, 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 const SUMOReal vMax = MIN2(veh->getType()->maxSpeed, mySpeed); 00184 const SUMOReal accel = veh->getType()->get(SUMO_ATTR_ACCEL, DEFAULT_VEH_ACCEL) * veh->getType()->get(SUMO_ATTR_SIGMA, DEFAULT_VEH_SIGMA) / 2.; 00185 ret = HelpersHBEFA::computeDefaultCO2(veh->getType()->emissionClass, vMax, accel, getTravelTime(veh, time)); 00186 } 00187 return ret; 00188 } 00189 00190 00191 SUMOReal 00192 ROEdge::getPMxEffort(const ROVehicle* const veh, SUMOReal time) const { 00193 SUMOReal ret = 0; 00194 if (!getStoredEffort(time, ret)) { 00195 const SUMOReal vMax = MIN2(veh->getType()->maxSpeed, mySpeed); 00196 const SUMOReal accel = veh->getType()->get(SUMO_ATTR_ACCEL, DEFAULT_VEH_ACCEL) * veh->getType()->get(SUMO_ATTR_SIGMA, DEFAULT_VEH_SIGMA) / 2.; 00197 ret = HelpersHBEFA::computeDefaultPMx(veh->getType()->emissionClass, vMax, accel, getTravelTime(veh, time)); 00198 } 00199 return ret; 00200 } 00201 00202 00203 SUMOReal 00204 ROEdge::getHCEffort(const ROVehicle* const veh, SUMOReal time) const { 00205 SUMOReal ret = 0; 00206 if (!getStoredEffort(time, ret)) { 00207 const SUMOReal vMax = MIN2(veh->getType()->maxSpeed, mySpeed); 00208 const SUMOReal accel = veh->getType()->get(SUMO_ATTR_ACCEL, DEFAULT_VEH_ACCEL) * veh->getType()->get(SUMO_ATTR_SIGMA, DEFAULT_VEH_SIGMA) / 2.; 00209 ret = HelpersHBEFA::computeDefaultHC(veh->getType()->emissionClass, vMax, accel, getTravelTime(veh, time)); 00210 } 00211 return ret; 00212 } 00213 00214 00215 SUMOReal 00216 ROEdge::getNOxEffort(const ROVehicle* const veh, SUMOReal time) const { 00217 SUMOReal ret = 0; 00218 if (!getStoredEffort(time, ret)) { 00219 const SUMOReal vMax = MIN2(veh->getType()->maxSpeed, mySpeed); 00220 const SUMOReal accel = veh->getType()->get(SUMO_ATTR_ACCEL, DEFAULT_VEH_ACCEL) * veh->getType()->get(SUMO_ATTR_SIGMA, DEFAULT_VEH_SIGMA) / 2.; 00221 ret = HelpersHBEFA::computeDefaultNOx(veh->getType()->emissionClass, vMax, accel, getTravelTime(veh, time)); 00222 } 00223 return ret; 00224 } 00225 00226 00227 SUMOReal 00228 ROEdge::getFuelEffort(const ROVehicle* const veh, SUMOReal time) const { 00229 SUMOReal ret = 0; 00230 if (!getStoredEffort(time, ret)) { 00231 const SUMOReal vMax = MIN2(veh->getType()->maxSpeed, mySpeed); 00232 const SUMOReal accel = veh->getType()->get(SUMO_ATTR_ACCEL, DEFAULT_VEH_ACCEL) * veh->getType()->get(SUMO_ATTR_SIGMA, DEFAULT_VEH_SIGMA) / 2.; 00233 ret = HelpersHBEFA::computeDefaultFuel(veh->getType()->emissionClass, vMax, accel, getTravelTime(veh, time)); 00234 } 00235 return ret; 00236 } 00237 00238 00239 SUMOReal 00240 ROEdge::getNoiseEffort(const ROVehicle* const veh, SUMOReal time) const { 00241 SUMOReal ret = 0; 00242 if (!getStoredEffort(time, ret)) { 00243 const SUMOReal v = MIN2(veh->getType()->maxSpeed, mySpeed); 00244 ret = HelpersHarmonoise::computeNoise(veh->getType()->emissionClass, v, 0); 00245 } 00246 return ret; 00247 } 00248 00249 00250 bool 00251 ROEdge::getStoredEffort(SUMOReal time, SUMOReal& ret) const { 00252 if (myUsingETimeLine) { 00253 if (!myEfforts.describesTime(time)) { 00254 if (!myHaveEWarned) { 00255 WRITE_WARNING("No interval matches passed time " + toString(time) + " in edge '" + myID + "'.\n Using edge's length / edge's speed."); 00256 myHaveEWarned = true; 00257 } 00258 return false; 00259 } 00260 if (myInterpolate) { 00261 SUMOReal inTT = myTravelTimes.getValue(time); 00262 SUMOReal ratio = (SUMOReal)(myEfforts.getSplitTime(time, time + (SUMOTime)inTT) - time) / inTT; 00263 if (ratio >= 0) { 00264 ret = ratio * myEfforts.getValue(time) + (1 - ratio) * myEfforts.getValue(time + (SUMOTime)inTT); 00265 return true; 00266 } 00267 } 00268 ret = myEfforts.getValue(time); 00269 return true; 00270 } 00271 return false; 00272 } 00273 00274 00275 unsigned int 00276 ROEdge::getNoFollowing() const { 00277 if (getType() == ET_SINK) { 00278 return 0; 00279 } 00280 return (unsigned int) myFollowingEdges.size(); 00281 } 00282 00283 00284 #ifdef HAVE_MESOSIM // catchall for internal stuff 00285 unsigned int 00286 ROEdge::getNumApproaching() const { 00287 if (getType() == ET_SOURCE) { 00288 return 0; 00289 } 00290 return (unsigned int) myApproachingEdges.size(); 00291 } 00292 #endif 00293 00294 00295 void 00296 ROEdge::setType(ROEdge::EdgeType type) { 00297 myType = type; 00298 } 00299 00300 00301 void 00302 ROEdge::buildTimeLines(const std::string& measure) { 00303 if (myUsingETimeLine) { 00304 SUMOReal value = (SUMOReal)(myLength / mySpeed); 00305 if (measure == "CO") { 00306 value = HelpersHBEFA::computeCO(SVE_UNKNOWN, mySpeed, 0) * value; 00307 } 00308 if (measure == "CO2") { 00309 value = HelpersHBEFA::computeCO2(SVE_UNKNOWN, mySpeed, 0) * value; 00310 } 00311 if (measure == "HC") { 00312 value = HelpersHBEFA::computeHC(SVE_UNKNOWN, mySpeed, 0) * value; 00313 } 00314 if (measure == "PMx") { 00315 value = HelpersHBEFA::computePMx(SVE_UNKNOWN, mySpeed, 0) * value; 00316 } 00317 if (measure == "NOx") { 00318 value = HelpersHBEFA::computeNOx(SVE_UNKNOWN, mySpeed, 0) * value; 00319 } 00320 if (measure == "fuel") { 00321 value = HelpersHBEFA::computeFuel(SVE_UNKNOWN, mySpeed, 0) * value; 00322 } 00323 myEfforts.fillGaps(value, myUseBoundariesOnOverrideE); 00324 } 00325 if (myUsingTTTimeLine) { 00326 SUMOReal value = (SUMOReal)(myLength / mySpeed); 00327 myTravelTimes.fillGaps(value, myUseBoundariesOnOverrideTT); 00328 } 00329 } 00330 00331 00332 bool 00333 ROEdge::allFollowersProhibit(const ROVehicle* const vehicle) const { 00334 for (std::vector<ROEdge*>::const_iterator i = myFollowingEdges.begin(); i != myFollowingEdges.end(); ++i) { 00335 if (!(*i)->prohibits(vehicle)) { 00336 return false; 00337 } 00338 } 00339 return true; 00340 } 00341 00342 00343 ROEdge* 00344 ROEdge::dictionary(size_t id) { 00345 assert(myEdges.size() > id); 00346 return myEdges[id]; 00347 } 00348 00349 00350 00351 /****************************************************************************/ 00352