SUMO - Simulation of Urban MObility
ROEdge.cpp
Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines