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 2001-2010 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     std::vector<SUMOVehicleClass>::const_iterator i;
00089     const std::vector<SUMOVehicleClass> &allowed = lane->getAllowedClasses();
00090     // for allowed classes
00091     for (i=allowed.begin(); i!=allowed.end(); ++i) {
00092         SUMOVehicleClass allowedC = *i;
00093         std::vector<SUMOVehicleClass>::iterator t;
00094         // add to allowed if not already in there
00095         t = find(myAllowedClasses.begin(), myAllowedClasses.end(), allowedC);
00096         if (t==myAllowedClasses.end()) {
00097             myAllowedClasses.push_back(allowedC);
00098         }
00099         // remove from disallowed if allowed on the lane
00100         t = find(myNotAllowedClasses.begin(), myNotAllowedClasses.end(), allowedC);
00101         if (t!=myNotAllowedClasses.end()) {
00102             myNotAllowedClasses.erase(t);
00103         }
00104     }
00105     // for disallowed classes
00106     const std::vector<SUMOVehicleClass> &disallowed = lane->getNotAllowedClasses();
00107     for (i=disallowed.begin(); i!=disallowed.end(); ++i) {
00108         SUMOVehicleClass disallowedC = *i;
00109         std::vector<SUMOVehicleClass>::iterator t;
00110         // add to disallowed if not already in there
00111         //  and not within allowed
00112         t = find(myAllowedClasses.begin(), myAllowedClasses.end(), disallowedC);
00113         if (t==myAllowedClasses.end()) {
00114             t = find(myNotAllowedClasses.begin(), myNotAllowedClasses.end(), disallowedC);
00115             if (t==myNotAllowedClasses.end()) {
00116                 myNotAllowedClasses.push_back(disallowedC);
00117             }
00118         }
00119     }
00120 }
00121 
00122 
00123 void
00124 ROEdge::addFollower(ROEdge *s) throw() {
00125     if (find(myFollowingEdges.begin(), myFollowingEdges.end(), s)==myFollowingEdges.end()) {
00126         myFollowingEdges.push_back(s);
00127     }
00128 }
00129 
00130 
00131 void
00132 ROEdge::addEffort(SUMOReal value, SUMOReal timeBegin, SUMOReal timeEnd) throw() {
00133     myEfforts.add(timeBegin, timeEnd, value);
00134     myUsingETimeLine = true;
00135 }
00136 
00137 
00138 void
00139 ROEdge::addTravelTime(SUMOReal value, SUMOReal timeBegin, SUMOReal timeEnd) throw() {
00140     myTravelTimes.add(timeBegin, timeEnd, value);
00141     myUsingTTTimeLine = true;
00142 }
00143 
00144 
00145 SUMOReal
00146 ROEdge::getEffort(const ROVehicle *const veh, SUMOReal time) const throw() {
00147     SUMOReal ret = 0;
00148     if (!getStoredEffort(time, ret)) {
00149         return (SUMOReal)(myLength / mySpeed);
00150     }
00151     return ret;
00152 }
00153 
00154 
00155 SUMOReal
00156 ROEdge::getTravelTime(const ROVehicle *const, SUMOReal time) const throw() {
00157     if (myUsingTTTimeLine) {
00158         if (!myHaveTTWarned && !myTravelTimes.describesTime(time)) {
00159             WRITE_WARNING("No interval matches passed time "+ toString(time)  + " in edge '" + myID + "'.\n Using edge's length / edge's speed.");
00160             myHaveTTWarned = true;
00161         }
00162         if (myInterpolate) {
00163             SUMOReal inTT = myTravelTimes.getValue(time);
00164             SUMOReal split = (SUMOReal)(myTravelTimes.getSplitTime(time, time + (SUMOTime)inTT) - time);
00165             if (split >= 0) {
00166                 return myTravelTimes.getValue(time + (SUMOTime)inTT) *((SUMOReal)1. - split / inTT) + split;
00167             }
00168         }
00169         return myTravelTimes.getValue(time);
00170     }
00171     // ok, no absolute value was found, use the normal value (without) as default
00172     return (SUMOReal)(myLength / mySpeed);
00173 }
00174 
00175 
00176 SUMOReal
00177 ROEdge::getCOEffort(const ROVehicle * const veh, SUMOReal time) const throw() {
00178     SUMOReal ret = 0;
00179     if (!getStoredEffort(time, ret)) {
00180         SUMOReal v = mySpeed;
00181         SUMOEmissionClass c = SVE_UNKNOWN;
00182         if (veh->getType()!=0) {
00183             v = MIN2(veh->getType()->maxSpeed, mySpeed);
00184             c = veh->getType()->emissionClass;
00185         }
00186         ret = HelpersHBEFA::computeCO(c, v, 0) * getTravelTime(veh, time);
00187     }
00188     return ret;
00189 }
00190 
00191 
00192 SUMOReal
00193 ROEdge::getCO2Effort(const ROVehicle * const veh, SUMOReal time) const throw() {
00194     SUMOReal ret = 0;
00195     if (!getStoredEffort(time, ret)) {
00196         SUMOReal v = mySpeed;
00197         SUMOEmissionClass c = SVE_UNKNOWN;
00198         if (veh->getType()!=0) {
00199             v = MIN2(veh->getType()->maxSpeed, mySpeed);
00200             c = veh->getType()->emissionClass;
00201         }
00202         ret = HelpersHBEFA::computeCO2(c, v, 0) * getTravelTime(veh, time);
00203     }
00204     return ret;
00205 }
00206 
00207 
00208 SUMOReal
00209 ROEdge::getPMxEffort(const ROVehicle * const veh, SUMOReal time) const throw() {
00210     SUMOReal ret = 0;
00211     if (!getStoredEffort(time, ret)) {
00212         SUMOReal v = mySpeed;
00213         SUMOEmissionClass c = SVE_UNKNOWN;
00214         if (veh->getType()!=0) {
00215             v = MIN2(veh->getType()->maxSpeed, mySpeed);
00216             c = veh->getType()->emissionClass;
00217         }
00218         ret = HelpersHBEFA::computePMx(c, v, 0) * getTravelTime(veh, time);
00219     }
00220     return ret;
00221 }
00222 
00223 
00224 SUMOReal
00225 ROEdge::getHCEffort(const ROVehicle * const veh, SUMOReal time) const throw() {
00226     SUMOReal ret = 0;
00227     if (!getStoredEffort(time, ret)) {
00228         SUMOReal v = mySpeed;
00229         SUMOEmissionClass c = SVE_UNKNOWN;
00230         if (veh->getType()!=0) {
00231             v = MIN2(veh->getType()->maxSpeed, mySpeed);
00232             c = veh->getType()->emissionClass;
00233         }
00234         ret = HelpersHBEFA::computeHC(c, v, 0) * getTravelTime(veh, time);
00235     }
00236     return ret;
00237 }
00238 
00239 
00240 SUMOReal
00241 ROEdge::getNOxEffort(const ROVehicle * const veh, SUMOReal time) const throw() {
00242     SUMOReal ret = 0;
00243     if (!getStoredEffort(time, ret)) {
00244         SUMOReal v = mySpeed;
00245         SUMOEmissionClass c = SVE_UNKNOWN;
00246         if (veh->getType()!=0) {
00247             v = MIN2(veh->getType()->maxSpeed, mySpeed);
00248             c = veh->getType()->emissionClass;
00249         }
00250         ret = HelpersHBEFA::computeNOx(c, v, 0) * getTravelTime(veh, time);
00251     }
00252     return ret;
00253 }
00254 
00255 
00256 SUMOReal
00257 ROEdge::getFuelEffort(const ROVehicle * const veh, SUMOReal time) const throw() {
00258     SUMOReal ret = 0;
00259     if (!getStoredEffort(time, ret)) {
00260         SUMOReal v = mySpeed;
00261         SUMOEmissionClass c = SVE_UNKNOWN;
00262         if (veh->getType()!=0) {
00263             v = MIN2(veh->getType()->maxSpeed, mySpeed);
00264             c = veh->getType()->emissionClass;
00265         }
00266         ret = HelpersHBEFA::computeFuel(c, v, 0) * getTravelTime(veh, time);
00267     }
00268     return ret;
00269 }
00270 
00271 
00272 SUMOReal
00273 ROEdge::getNoiseEffort(const ROVehicle * const veh, SUMOReal time) const throw() {
00274     SUMOReal ret = 0;
00275     if (!getStoredEffort(time, ret)) {
00276         SUMOReal v = mySpeed;
00277         SUMOEmissionClass c = SVE_UNKNOWN;
00278         if (veh->getType()!=0) {
00279             v = MIN2(veh->getType()->maxSpeed, mySpeed);
00280             c = veh->getType()->emissionClass;
00281         }
00282         ret = HelpersHarmonoise::computeNoise(veh->getType()->emissionClass, v, 0);
00283     }
00284     return ret;
00285 }
00286 
00287 
00288 bool
00289 ROEdge::getStoredEffort(SUMOReal time, SUMOReal &ret) const throw() {
00290     if (myUsingETimeLine) {
00291         if (!myEfforts.describesTime(time)) {
00292             if (!myHaveEWarned) {
00293                 WRITE_WARNING("No interval matches passed time "+ toString(time)  + " in edge '" + myID + "'.\n Using edge's length / edge's speed.");
00294                 myHaveEWarned = true;
00295             }
00296             return false;
00297         }
00298         if (myInterpolate) {
00299             SUMOReal inTT = myTravelTimes.getValue(time);
00300             SUMOReal ratio = (SUMOReal)(myEfforts.getSplitTime(time, time + (SUMOTime)inTT) - time) / inTT;
00301             if (ratio >= 0) {
00302                 ret = ratio * myEfforts.getValue(time) + (1-ratio)*myEfforts.getValue(time + (SUMOTime)inTT);
00303                 return true;
00304             }
00305         }
00306         ret = myEfforts.getValue(time);
00307         return true;
00308     }
00309     return false;
00310 }
00311 
00312 
00313 unsigned int
00314 ROEdge::getNoFollowing() const throw() {
00315     if (getType()==ET_SINK) {
00316         return 0;
00317     }
00318     return (unsigned int) myFollowingEdges.size();
00319 }
00320 
00321 
00322 void
00323 ROEdge::setType(ROEdge::EdgeType type) throw() {
00324     myType = type;
00325 }
00326 
00327 
00328 bool
00329 ROEdge::prohibits(const ROVehicle * const vehicle) const throw() {
00330     if (myAllowedClasses.size()==0&&myNotAllowedClasses.size()==0) {
00331         return false;
00332     }
00333     // ok, vehicles with an unknown class may be only prohibited
00334     //  if the edge is limited to a set of classes
00335     SUMOVehicleClass vclass = vehicle->getType()!=0 ? vehicle->getType()->vehicleClass : DEFAULT_VEH_CLASS;
00336     if (vclass==SVC_UNKNOWN) {
00337         return false;
00338     }
00339     // check whether it is explicitely disallowed
00340     if (find(myNotAllowedClasses.begin(), myNotAllowedClasses.end(), vclass)!=myNotAllowedClasses.end()) {
00341         return true;
00342     }
00343     // check whether it is within the allowed classes
00344     if (myAllowedClasses.size()==0||find(myAllowedClasses.begin(), myAllowedClasses.end(), vclass)!=myAllowedClasses.end()) {
00345         return false;
00346     }
00347     // ok, we have a set of allowed vehicle classes, but this vehicle's class
00348     //  is not among them
00349     return true;
00350 }
00351 
00352 
00353 void
00354 ROEdge::buildTimeLines(const std::string &measure) throw() {
00355     if (myUsingETimeLine) {
00356         SUMOReal value = (SUMOReal)(myLength / mySpeed);
00357         if (measure=="CO") {
00358             value = HelpersHBEFA::computeCO(SVE_UNKNOWN, mySpeed, 0) * value;
00359         }
00360         if (measure=="CO2") {
00361             value = HelpersHBEFA::computeCO2(SVE_UNKNOWN, mySpeed, 0) * value;
00362         }
00363         if (measure=="HC") {
00364             value = HelpersHBEFA::computeHC(SVE_UNKNOWN, mySpeed, 0) * value;
00365         }
00366         if (measure=="PMx") {
00367             value = HelpersHBEFA::computePMx(SVE_UNKNOWN, mySpeed, 0) * value;
00368         }
00369         if (measure=="NOx") {
00370             value = HelpersHBEFA::computeNOx(SVE_UNKNOWN, mySpeed, 0) * value;
00371         }
00372         if (measure=="fuel") {
00373             value = HelpersHBEFA::computeFuel(SVE_UNKNOWN, mySpeed, 0) * value;
00374         }
00375         myEfforts.fillGaps(value, myUseBoundariesOnOverrideE);
00376     }
00377     if (myUsingTTTimeLine) {
00378         SUMOReal value = (SUMOReal)(myLength / mySpeed);
00379         myTravelTimes.fillGaps(value, myUseBoundariesOnOverrideTT);
00380     }
00381 }
00382 
00383 
00384 bool
00385 ROEdge::allFollowersProhibit(const ROVehicle * const vehicle) const throw() {
00386     for (std::vector<ROEdge*>::const_iterator i=myFollowingEdges.begin(); i!=myFollowingEdges.end(); ++i) {
00387         if (!(*i)->prohibits(vehicle)) {
00388             return false;
00389         }
00390     }
00391     return true;
00392 }
00393 
00394 
00395 ROEdge*
00396 ROEdge::dictionary(size_t id) throw() {
00397     assert(myEdges.size()>id);
00398     return myEdges[id];
00399 }
00400 
00401 
00402 
00403 /****************************************************************************/
00404 

Generated on Wed May 5 00:06:36 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6