00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00049
00050 bool ROEdge::myHaveTTWarned = false;
00051 bool ROEdge::myHaveEWarned = false;
00052 std::vector<ROEdge*> ROEdge::myEdges;
00053
00054
00055
00056
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
00091 for (i=allowed.begin(); i!=allowed.end(); ++i) {
00092 SUMOVehicleClass allowedC = *i;
00093 std::vector<SUMOVehicleClass>::iterator t;
00094
00095 t = find(myAllowedClasses.begin(), myAllowedClasses.end(), allowedC);
00096 if (t==myAllowedClasses.end()) {
00097 myAllowedClasses.push_back(allowedC);
00098 }
00099
00100 t = find(myNotAllowedClasses.begin(), myNotAllowedClasses.end(), allowedC);
00101 if (t!=myNotAllowedClasses.end()) {
00102 myNotAllowedClasses.erase(t);
00103 }
00104 }
00105
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
00111
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
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
00334
00335 SUMOVehicleClass vclass = vehicle->getType()!=0 ? vehicle->getType()->vehicleClass : DEFAULT_VEH_CLASS;
00336 if (vclass==SVC_UNKNOWN) {
00337 return false;
00338 }
00339
00340 if (find(myNotAllowedClasses.begin(), myNotAllowedClasses.end(), vclass)!=myNotAllowedClasses.end()) {
00341 return true;
00342 }
00343
00344 if (myAllowedClasses.size()==0||find(myAllowedClasses.begin(), myAllowedClasses.end(), vclass)!=myAllowedClasses.end()) {
00345 return false;
00346 }
00347
00348
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