SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSLane.cpp
Go to the documentation of this file.
1 /****************************************************************************/
13 // Representation of a lane in the micro simulation
14 /****************************************************************************/
15 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
16 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
17 /****************************************************************************/
18 //
19 // This file is part of SUMO.
20 // SUMO is free software: you can redistribute it and/or modify
21 // it under the terms of the GNU General Public License as published by
22 // the Free Software Foundation, either version 3 of the License, or
23 // (at your option) any later version.
24 //
25 /****************************************************************************/
26 
27 
28 // ===========================================================================
29 // included modules
30 // ===========================================================================
31 #ifdef _MSC_VER
32 #include <windows_config.h>
33 #else
34 #include <config.h>
35 #endif
36 
38 #include <utils/common/StdDefs.h>
39 #include "MSVehicle.h"
40 #include "MSNet.h"
41 #include "MSVehicleType.h"
42 #include "MSEdge.h"
43 #include "MSEdgeControl.h"
44 #include "MSJunction.h"
45 #include "MSLogicJunction.h"
46 #include "MSLink.h"
47 #include "MSLane.h"
48 #include "MSVehicleTransfer.h"
49 #include "MSGlobals.h"
50 #include "MSVehicleControl.h"
51 #include "MSInsertionControl.h"
52 #include <cmath>
53 #include <bitset>
54 #include <iostream>
55 #include <cassert>
56 #include <functional>
57 #include <algorithm>
58 #include <iterator>
59 #include <exception>
60 #include <climits>
61 #include <set>
63 #include <utils/common/ToString.h>
66 #include <utils/geom/Line.h>
67 #include <utils/geom/GeomHelper.h>
68 
69 #ifdef CHECK_MEMORY_LEAKS
70 #include <foreign/nvwa/debug_new.h>
71 #endif // CHECK_MEMORY_LEAKS
72 
73 
74 // ===========================================================================
75 // static member definitions
76 // ===========================================================================
78 
79 
80 // ===========================================================================
81 // member method definitions
82 // ===========================================================================
83 MSLane::MSLane(const std::string& id, SUMOReal maxSpeed, SUMOReal length, MSEdge* const edge,
84  unsigned int numericalID, const PositionVector& shape, SUMOReal width,
85  SVCPermissions permissions) :
86  Named(id),
87  myShape(shape), myNumericalID(numericalID),
88  myVehicles(), myLength(length), myWidth(width), myEdge(edge), myMaxSpeed(maxSpeed),
89  myPermissions(permissions),
90  myLogicalPredecessorLane(0),
91  myVehicleLengthSum(0), myInlappingVehicleEnd(10000), myInlappingVehicle(0),
92  myLengthGeometryFactor(myShape.length() / myLength) {}
93 
94 
96  for (MSLinkCont::iterator i = myLinks.begin(); i != myLinks.end(); ++i) {
97  delete *i;
98  }
99 }
100 
101 
102 void
104  myLinks.push_back(link);
105 }
106 
107 
108 // ------ interaction with MSMoveReminder ------
109 void
111  myMoveReminders.push_back(rem);
112  for (VehCont::iterator veh = myVehicles.begin(); veh != myVehicles.end(); ++veh) {
113  (*veh)->addReminder(rem);
114  }
115 }
116 
117 
118 
119 // ------ Vehicle emission ------
120 void
121 MSLane::incorporateVehicle(MSVehicle* veh, SUMOReal pos, SUMOReal speed, const MSLane::VehCont::iterator& at, MSMoveReminder::Notification notification) {
122  assert(pos <= myLength);
123  bool wasInactive = myVehicles.size() == 0;
124  veh->enterLaneAtInsertion(this, pos, speed, notification);
125  if (at == myVehicles.end()) {
126  // vehicle will be the first on the lane
127  myVehicles.push_back(veh);
128  } else {
129  myVehicles.insert(at, veh);
130  }
132  if (wasInactive) {
134  }
135 }
136 
137 
138 bool
140  SUMOReal xIn = maxPos;
141  SUMOReal vIn = mspeed;
142  SUMOReal leaderDecel;
143  if (myVehicles.size() != 0) {
144  MSVehicle* leader = myVehicles.front();
145  xIn = leader->getPositionOnLane() - leader->getVehicleType().getLength() - veh.getVehicleType().getMinGap();
146  vIn = leader->getSpeed();
147  leaderDecel = leader->getCarFollowModel().getMaxDecel();
148  } else {
149  veh.getBestLanes(true, this);
150  SUMOReal brakeGap = veh.getCarFollowModel().brakeGap(mspeed);
151  std::pair<MSVehicle* const, SUMOReal> leader = getLeaderOnConsecutive(brakeGap, 0, mspeed, veh, veh.getBestLanesContinuation(this));
152  if (leader.first != 0) {
153  xIn = getLength() + leader.second;
154  vIn = leader.first->getSpeed();
155  leaderDecel = leader.first->getCarFollowModel().getMaxDecel();
156  } else {
157  incorporateVehicle(&veh, maxPos, mspeed, myVehicles.end());
158  return true;
159  }
160  }
161  const SUMOReal vHlp = 0.5 * (vIn + mspeed);
162  SUMOReal x2 = xIn;// have seen leader length already - skCar::lCar;
163  SUMOReal x1 = x2 - 100.0;
164  SUMOReal x = 0;
165  for (int i = 0; i <= 10; i++) {
166  x = 0.5 * (x1 + x2);
167  SUMOReal vSafe = veh.getCarFollowModel().followSpeed(&veh, vHlp, xIn - x, vIn, leaderDecel);
168  if (vSafe < vHlp) {
169  x2 = x;
170  } else {
171  x1 = x;
172  }
173  }
174  if (x < minPos) {
175  return false;
176  } else if (x > maxPos) {
177  x = maxPos;
178  }
179  incorporateVehicle(&veh, x, vHlp, myVehicles.begin());
180  return true;
181 }
182 
183 
184 bool
186  SUMOReal xIn = maxPos;
187  SUMOReal vIn = mspeed;
188  if (myVehicles.size() != 0) {
189  MSVehicle* leader = myVehicles.front();
190  xIn = leader->getPositionOnLane() - leader->getVehicleType().getLength() - veh.getVehicleType().getMinGap();
191  vIn = leader->getSpeed();
192  } else {
193  veh.getBestLanes(true, this);
194  SUMOReal brakeGap = veh.getCarFollowModel().brakeGap(mspeed);
195  std::pair<MSVehicle* const, SUMOReal> leader = getLeaderOnConsecutive(brakeGap, 0, mspeed, veh, veh.getBestLanesContinuation(this));
196  if (leader.first != 0) {
197  xIn = getLength() + leader.second;
198  vIn = leader.first->getSpeed();
199  } else {
200  incorporateVehicle(&veh, maxPos, mspeed, myVehicles.end());
201  return true;
202  }
203  }
204  const SUMOReal vHlp = 0.5 * (mspeed + vIn);
205  xIn = xIn - vHlp * veh.getCarFollowModel().getHeadwayTime() - veh.getVehicleType().getMinGap();
206  if (xIn < minPos) {
207  return false;
208  } else if (xIn > maxPos) {
209  xIn = maxPos;
210  }
211  incorporateVehicle(&veh, xIn, vHlp, myVehicles.begin());
212  return true;
213 }
214 
215 
216 bool
218  if (myVehicles.size() == 0) {
219  return isInsertionSuccess(&veh, mspeed, myLength / 2, true);
220  }
221  // go through the lane, look for free positions (starting after the last vehicle)
222  MSLane::VehCont::iterator predIt = myVehicles.begin();
223  SUMOReal maxSpeed = 0;
224  SUMOReal maxPos = 0;
225  MSLane::VehCont::iterator maxIt = myVehicles.begin();
226  while (predIt != myVehicles.end()) {
227  // get leader (may be zero) and follower
228  const MSVehicle* leader = predIt != myVehicles.end() - 1 ? *(predIt + 1) : getPartialOccupator();
229  const MSVehicle* follower = *predIt;
230  SUMOReal leaderRearPos = getLength();
231  SUMOReal leaderSpeed = mspeed;
232  if (leader != 0) {
233  leaderRearPos = leader->getPositionOnLane() - leader->getVehicleType().getLength();
234  if (leader == getPartialOccupator()) {
235  leaderRearPos = getPartialOccupatorEnd();
236  }
237  leaderSpeed = leader->getSpeed();
238  }
239  const SUMOReal nettoGap = leaderRearPos - follower->getPositionOnLane() - veh.getVehicleType().getLengthWithGap();
240  if (nettoGap > 0) {
241  const SUMOReal tau = veh.getCarFollowModel().getHeadwayTime();
242  const SUMOReal tauDecel = tau * veh.getCarFollowModel().getMaxDecel();
243  const SUMOReal fSpeed = follower->getSpeed();
244  const SUMOReal lhs = nettoGap / tau + tauDecel - fSpeed - fSpeed * fSpeed / (2 * tauDecel) + leaderSpeed * leaderSpeed / (2 * tauDecel);
245  if (lhs >= sqrt(tauDecel * tauDecel + leaderSpeed * leaderSpeed)) {
246  const SUMOReal frontGap = (lhs * lhs - tauDecel * tauDecel - leaderSpeed * leaderSpeed) / (2 * veh.getCarFollowModel().getMaxDecel());
247  const SUMOReal currentMaxSpeed = lhs - tauDecel;
248  if (MIN2(currentMaxSpeed, mspeed) > maxSpeed) {
249  maxSpeed = currentMaxSpeed;
250  maxPos = leaderRearPos + frontGap;
251  maxIt = predIt + 1;
252  }
253  }
254  }
255  ++predIt;
256  }
257  if (maxSpeed > 0) {
258  incorporateVehicle(&veh, maxPos, maxSpeed, maxIt);
259  return true;
260  }
261  return false;
262 }
263 
264 
265 bool
267  MSMoveReminder::Notification notification) {
268  bool adaptableSpeed = true;
269  if (myVehicles.size() == 0) {
270  if (isInsertionSuccess(&veh, mspeed, 0, adaptableSpeed, notification)) {
271  return true;
272  }
273  } else {
274  // check whether the vehicle can be put behind the last one if there is such
275  MSVehicle* leader = myVehicles.back();
276  SUMOReal leaderPos = leader->getPositionOnLane() - leader->getVehicleType().getLength();
277  SUMOReal speed = mspeed;
278  if (adaptableSpeed) {
279  speed = leader->getSpeed();
280  }
281  SUMOReal frontGapNeeded = veh.getCarFollowModel().getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()) + veh.getVehicleType().getMinGap();
282  if (leaderPos - frontGapNeeded >= 0) {
283  SUMOReal tspeed = MIN2(veh.getCarFollowModel().followSpeed(&veh, mspeed, frontGapNeeded, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()), mspeed);
284  // check whether we can insert our vehicle behind the last vehicle on the lane
285  if (isInsertionSuccess(&veh, tspeed, 0, adaptableSpeed, notification)) {
286  return true;
287  }
288  }
289  }
290  // go through the lane, look for free positions (starting after the last vehicle)
291  MSLane::VehCont::iterator predIt = myVehicles.begin();
292  while (predIt != myVehicles.end()) {
293  // get leader (may be zero) and follower
294  const MSVehicle* leader = predIt != myVehicles.end() - 1 ? *(predIt + 1) : getPartialOccupator();
295  const MSVehicle* follower = *predIt;
296 
297  // patch speed if allowed
298  SUMOReal speed = mspeed;
299  if (adaptableSpeed && leader != 0) {
300  speed = MIN2(leader->getSpeed(), mspeed);
301  }
302 
303  // compute the space needed to not collide with leader
304  SUMOReal frontMax = getLength();
305  if (leader != 0) {
306  SUMOReal leaderRearPos = leader->getPositionOnLane() - leader->getVehicleType().getLength();
307  if (leader == getPartialOccupator()) {
308  leaderRearPos = getPartialOccupatorEnd();
309  }
310  SUMOReal frontGapNeeded = veh.getCarFollowModel().getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel()) + veh.getVehicleType().getMinGap();
311  frontMax = leaderRearPos - frontGapNeeded;
312  }
313  // compute the space needed to not let the follower collide
314  const SUMOReal followPos = follower->getPositionOnLane() + follower->getVehicleType().getMinGap();
315  const SUMOReal backGapNeeded = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), veh.getSpeed(), veh.getCarFollowModel().getMaxDecel());
316  const SUMOReal backMin = followPos + backGapNeeded + veh.getVehicleType().getLength();
317 
318  // check whether there is enough room (given some extra space for rounding errors)
319  if (frontMax > 0 && backMin + POSITION_EPS < frontMax) {
320  // try to insert vehicle (should be always ok)
321  if (isInsertionSuccess(&veh, speed, backMin + POSITION_EPS, adaptableSpeed, notification)) {
322  return true;
323  }
324  }
325  ++predIt;
326  }
327  // first check at lane's begin
328  return false;
329 }
330 
331 
332 bool
334  SUMOReal pos = 0;
335  SUMOReal speed = 0;
336  bool patchSpeed = true; // whether the speed shall be adapted to infrastructure/traffic in front
337 
338  // determine the speed
339  const SUMOVehicleParameter& pars = veh.getParameter();
340  switch (pars.departSpeedProcedure) {
341  case DEPART_SPEED_GIVEN:
342  speed = pars.departSpeed;
343  patchSpeed = false;
344  break;
345  case DEPART_SPEED_RANDOM:
346  speed = RandHelper::rand(MIN2(veh.getMaxSpeed(), getVehicleMaxSpeed(&veh)));
347  patchSpeed = true; // @todo check
348  break;
349  case DEPART_SPEED_MAX:
350  speed = MIN2(veh.getMaxSpeed(), getVehicleMaxSpeed(&veh));
351  patchSpeed = true; // @todo check
352  break;
354  default:
355  // speed = 0 was set before
356  patchSpeed = false; // @todo check
357  break;
358  }
359 
360  // determine the position
361  switch (pars.departPosProcedure) {
362  case DEPART_POS_GIVEN:
363  pos = pars.departPos;
364  if (pos < 0.) {
365  pos += myLength;
366  }
367  break;
368  case DEPART_POS_RANDOM:
369  pos = RandHelper::rand(getLength());
370  break;
371  case DEPART_POS_RANDOM_FREE: {
372  for (unsigned int i = 0; i < 10; i++) {
373  // we will try some random positions ...
374  pos = RandHelper::rand(getLength());
375  if (isInsertionSuccess(&veh, speed, pos, patchSpeed)) {
376  return true;
377  }
378  }
379  // ... and if that doesn't work, we put the vehicle to the free position
380  return freeInsertion(veh, speed);
381  }
382  break;
383  case DEPART_POS_FREE:
384  return freeInsertion(veh, speed);
386  return pWagSimpleInsertion(veh, speed, getLength(), 0.0);
388  return pWagGenericInsertion(veh, speed, getLength(), 0.0);
390  return maxSpeedGapInsertion(veh, speed);
391  case DEPART_POS_BASE:
392  case DEPART_POS_DEFAULT:
393  default:
394  pos = MIN2(static_cast<SUMOReal>(veh.getVehicleType().getLength() + POSITION_EPS), myLength);
395  break;
396  }
397  // try to insert
398  return isInsertionSuccess(&veh, speed, pos, patchSpeed);
399 }
400 
401 
402 bool
404  SUMOReal speed, SUMOReal pos, bool patchSpeed,
405  MSMoveReminder::Notification notification) {
406  if (pos < 0 || pos > myLength) {
407  // we may not start there
408  WRITE_WARNING("Invalid departPos " + toString(pos) + " given for vehicle '" +
409  aVehicle->getID() + "'. Inserting at lane end instead.");
410  pos = myLength;
411  }
412  aVehicle->getBestLanes(true, this);
413  const MSCFModel& cfModel = aVehicle->getCarFollowModel();
414  const std::vector<MSLane*>& bestLaneConts = aVehicle->getBestLanesContinuation(this);
415  std::vector<MSLane*>::const_iterator ri = bestLaneConts.begin();
416  SUMOReal seen = getLength() - pos;
417  SUMOReal dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
418  const MSRoute& r = aVehicle->getRoute();
419  MSRouteIterator ce = r.begin();
420  unsigned int nRouteSuccs = 1;
421  MSLane* currentLane = this;
422  MSLane* nextLane = this;
423  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / speed);
424  while (seen < dist && ri != bestLaneConts.end()) {
425  // get the next link used...
426  MSLinkCont::const_iterator link = currentLane->succLinkSec(*aVehicle, nRouteSuccs, *currentLane, bestLaneConts);
427  if (currentLane->isLinkEnd(link)) {
428  if (&currentLane->getEdge() == r.getLastEdge()) {
429  // reached the end of the route
431  SUMOReal nspeed = cfModel.followSpeed(aVehicle, speed, seen, aVehicle->getParameter().arrivalSpeed, 0);
432  if (nspeed < speed) {
433  if (patchSpeed) {
434  speed = MIN2(nspeed, speed);
435  dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
436  } else {
437  // we may not drive with the given velocity - we cannot match the specified arrival speed
438  WRITE_ERROR("Vehicle '" + aVehicle->getID() + "' will not be able to depart using given velocity!");
440  return false;
441  }
442  }
443  }
444  } else {
445  // lane does not continue
446  SUMOReal nspeed = cfModel.followSpeed(aVehicle, speed, seen, 0, 0);
447  if (nspeed < speed) {
448  if (patchSpeed) {
449  speed = MIN2(nspeed, speed);
450  dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
451  } else {
452  // we may not drive with the given velocity - we cannot stop at the junction
453  WRITE_ERROR("Vehicle '" + aVehicle->getID() + "' will not be able to depart using given velocity!");
455  return false;
456  }
457  }
458  }
459  break;
460  }
461  if (!(*link)->opened(arrivalTime, speed, speed, aVehicle->getVehicleType().getLength())) {
462  // have to stop at junction
463  SUMOReal nspeed = cfModel.followSpeed(aVehicle, speed, seen, 0, 0);
464  if (nspeed < speed) {
465  if (patchSpeed) {
466  speed = MIN2(nspeed, speed);
467  dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
468  } else {
469  // we may not drive with the given velocity - we cannot stop at the junction in time (try again later)
470  return false;
471  }
472  }
473  break;
474  }
475  // get the next used lane (including internal)
476  nextLane = (*link)->getViaLaneOrLane();
477  // check how next lane effects the journey
478  if (nextLane != 0) {
479  arrivalTime += TIME2STEPS(nextLane->getLength() / speed);
480  SUMOReal gap = 0;
481  MSVehicle* leader = currentLane->getPartialOccupator();
482  if (leader != 0) {
483  gap = seen + currentLane->getPartialOccupatorEnd() - currentLane->getLength();
484  } else {
485  // check leader on next lane
486  leader = nextLane->getLastVehicle();
487  if (leader != 0) {
488  gap = seen + leader->getPositionOnLane() - leader->getVehicleType().getLength() - aVehicle->getVehicleType().getMinGap();
489  }
490  }
491  if (leader != 0) {
492  if (gap < 0) {
493  return false;
494  }
495  const SUMOReal nspeed = cfModel.followSpeed(aVehicle, speed, gap, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
496  if (nspeed < speed) {
497  if (patchSpeed) {
498  speed = MIN2(nspeed, speed);
499  dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
500  } else {
501  // we may not drive with the given velocity - we crash into the leader
502  return false;
503  }
504  }
505  }
506  // check next lane's maximum velocity
507  const SUMOReal nspeed = nextLane->getVehicleMaxSpeed(aVehicle);
508  if (nspeed < speed) {
509  // patch speed if needed
510  if (patchSpeed) {
511  speed = MIN2(cfModel.freeSpeed(aVehicle, speed, seen, nspeed), speed);
512  dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
513  } else {
514  // we may not drive with the given velocity - we would be too fast on the next lane
515  WRITE_ERROR("Vehicle '" + aVehicle->getID() + "' will not be able to depart using given velocity!");
517  return false;
518  }
519  }
520  // check traffic on next junction
521  // we cannot use (*link)->opened because a vehicle without priority
522  // may already be comitted to blocking the link and unable to stop
523  const SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / speed);
524  const SUMOTime leaveTime = arrivalTime + TIME2STEPS((*link)->getLength() * speed);
525  if ((*link)->hasApproachingFoe(arrivalTime, leaveTime, speed)) {
526  SUMOReal nspeed = cfModel.followSpeed(aVehicle, speed, seen, 0, 0);
527  if (nspeed < speed) {
528  if (patchSpeed) {
529  speed = MIN2(nspeed, speed);
530  dist = cfModel.brakeGap(speed) + aVehicle->getVehicleType().getMinGap();
531  } else {
532  // we may not drive with the given velocity - we crash at the junction
533  return false;
534  }
535  }
536  }
537  seen += nextLane->getLength();
538  currentLane = nextLane;
539 #ifdef HAVE_INTERNAL_LANES
540  if ((*link)->getViaLane() == 0) {
541 #else
542  if (true) {
543 #endif
544  nRouteSuccs++;
545  ++ce;
546  ++ri;
547  }
548  }
549  }
550 
551  // get the pointer to the vehicle next in front of the given position
552  MSLane::VehCont::iterator predIt = find_if(myVehicles.begin(), myVehicles.end(), bind2nd(VehPosition(), pos));
553  if (predIt != myVehicles.end()) {
554  // ok, there is one (a leader)
555  MSVehicle* leader = *predIt;
556  SUMOReal frontGapNeeded = cfModel.getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
557  SUMOReal gap = MSVehicle::gap(leader->getPositionOnLane(), leader->getVehicleType().getLength(), pos + aVehicle->getVehicleType().getMinGap());
558  if (gap < frontGapNeeded) {
559  // too close to the leader on this lane
560  return false;
561  }
562  }
563 
564  // check back vehicle
565  if (predIt != myVehicles.begin()) {
566  // there is direct follower on this lane
567  MSVehicle* follower = *(predIt - 1);
568  SUMOReal backGapNeeded = follower->getCarFollowModel().getSecureGap(follower->getSpeed(), aVehicle->getSpeed(), cfModel.getMaxDecel());
569  SUMOReal gap = MSVehicle::gap(pos, aVehicle->getVehicleType().getLength(), follower->getPositionOnLane() + follower->getVehicleType().getMinGap());
570  if (gap < backGapNeeded) {
571  // too close to the follower on this lane
572  return false;
573  }
574  } else {
575  // check approaching vehicles to prevent rear-end collisions
576  // to compute an uper bound on the look-back distance we need
577  // the chosenSpeedFactor, minGap and maxDeceleration of approaching vehicles
578  // since we do not know these we use the values from the vehicle to be inserted
579  // and add a safety factor
580  const SUMOReal dist = 2 * (aVehicle->getCarFollowModel().brakeGap(myMaxSpeed) + aVehicle->getVehicleType().getMinGap());
581  const SUMOReal backOffset = pos - aVehicle->getVehicleType().getLength();
582  const SUMOReal missingRearGap = getMissingRearGap(dist, backOffset, speed, aVehicle->getCarFollowModel().getMaxDecel());
583  if (missingRearGap > 0) {
584  // too close to a followers
585  const SUMOReal neededStartPos = pos + missingRearGap;
586  if (myVehicles.size() == 0 && notification == MSMoveReminder::NOTIFICATION_TELEPORT && neededStartPos <= myLength) {
587  // shift starting positiong as needed entering from teleport
588  pos = neededStartPos;
589  } else {
590  return false;
591  }
592  }
593  // check for in-lapping vehicle
594  MSVehicle* leader = getPartialOccupator();
595  if (leader != 0) {
596  SUMOReal frontGapNeeded = cfModel.getSecureGap(speed, leader->getSpeed(), leader->getCarFollowModel().getMaxDecel());
597  SUMOReal gap = getPartialOccupatorEnd() - pos - aVehicle->getVehicleType().getMinGap();
598  if (gap <= frontGapNeeded) {
599  // too close to the leader on this lane
600  return false;
601  }
602  }
603  }
604 
605  // may got negative while adaptation
606  if (speed < 0) {
607  return false;
608  }
609  // enter
610  incorporateVehicle(aVehicle, pos, speed, predIt, notification);
611  return true;
612 }
613 
614 
615 void
617  incorporateVehicle(veh, pos, veh->getSpeed(), find_if(myVehicles.begin(), myVehicles.end(), bind2nd(VehPosition(), pos)));
618 }
619 
620 
621 // ------ Handling vehicles lapping into lanes ------
622 SUMOReal
624  myInlappingVehicle = v;
625  if (leftVehicleLength > myLength) {
627  } else {
628  myInlappingVehicleEnd = myLength - leftVehicleLength;
629  }
630  return myLength;
631 }
632 
633 
634 void
636  if (v == myInlappingVehicle) {
637  myInlappingVehicleEnd = 10000;
638  }
639  myInlappingVehicle = 0;
640 }
641 
642 
643 std::pair<MSVehicle*, SUMOReal>
645  if (myVehicles.size() != 0) {
646  // the last vehicle is the one in scheduled by this lane
647  MSVehicle* last = *myVehicles.begin();
648  const SUMOReal pos = last->getPositionOnLane() - last->getVehicleType().getLength();
649  return std::make_pair(last, pos);
650  }
651  if (myInlappingVehicle != 0) {
652  // the last one is a vehicle extending into this lane
653  return std::make_pair(myInlappingVehicle, myInlappingVehicleEnd);
654  }
655  return std::make_pair<MSVehicle*, SUMOReal>(0, 0);
656 }
657 
658 
659 // ------ ------
660 bool
663  assert(myVehicles.size() != 0);
664  std::vector<MSVehicle*> collisions;
665  VehCont::iterator lastBeforeEnd = myVehicles.end() - 1;
666  VehCont::iterator veh;
667  // Move all next vehicles beside the first
668  for (veh = myVehicles.begin(); veh != lastBeforeEnd; ++veh) {
669  myLeftVehLength -= (*veh)->getVehicleType().getLengthWithGap();
670  VehCont::const_iterator pred(veh + 1);
671  (*veh)->move(t, this, *pred, 0, myLeftVehLength);
672  }
673  myLeftVehLength -= (*veh)->getVehicleType().getLengthWithGap();
674  (*veh)->move(t, this, 0, 0, myLeftVehLength);
675  assert((*veh)->getPositionOnLane() <= myLength);
676  assert((*veh)->getLane() == this);
677  return myVehicles.size() == 0;
678 }
679 
680 
681 void
683  if (myVehicles.size() < 2) {
684  return;
685  }
686 
687  VehCont::iterator lastVeh = myVehicles.end() - 1;
688  for (VehCont::iterator veh = myVehicles.begin(); veh != lastVeh;) {
689  VehCont::iterator pred = veh + 1;
690  SUMOReal gap = (*pred)->getPositionOnLane() - (*pred)->getVehicleType().getLength() - (*veh)->getPositionOnLane() - (*veh)->getVehicleType().getMinGap();
691  if (gap < 0) {
692  MSVehicle* vehV = *veh;
693  WRITE_WARNING("Teleporting vehicle '" + vehV->getID() + "'; collision with '"
694  + (*pred)->getID() + "', lane='" + getID() + "', gap=" + toString(gap)
695  + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
698  MSVehicleTransfer::getInstance()->addVeh(timestep, vehV);
699  veh = myVehicles.erase(veh); // remove current vehicle
700  lastVeh = myVehicles.end() - 1;
701  if (veh == myVehicles.end()) {
702  break;
703  }
704  } else {
705  ++veh;
706  }
707  }
708 }
709 
710 
711 SUMOReal
713  MSRouteIterator next = veh.getRoute().begin();
714  const MSCFModel& cfModel = veh.getCarFollowModel();
715  MSLane* currentLane = (*next)->getLanes()[0];
716  SUMOReal seen = currentLane->getLength() - pos;
717  SUMOReal dist = SPEED2DIST(speed) + cfModel.brakeGap(speed);
718  SUMOReal tspeed = speed;
719  while (seen < dist && next != veh.getRoute().end() - 1) {
720  ++next;
721  MSLane* nextLane = (*next)->getLanes()[0];
722  tspeed = MIN2(cfModel.freeSpeed(&veh, tspeed, seen, nextLane->getVehicleMaxSpeed(&veh)), nextLane->getVehicleMaxSpeed(&veh));
723  dist = SPEED2DIST(tspeed) + cfModel.brakeGap(tspeed);
724  seen += nextLane->getLength();
725  }
726  return tspeed;
727 }
728 
729 
730 bool
731 MSLane::setCritical(SUMOTime t, std::vector<MSLane*>& into) {
732  // move critical vehicles
733  for (VehCont::iterator i = myVehicles.begin(); i != myVehicles.end();) {
734  MSVehicle* veh = *i;
735  bool moved = veh->moveChecked();
736  MSLane* target = veh->getLane();
737  SUMOReal length = veh->getVehicleType().getLengthWithGap();
738  if (veh->hasArrived()) {
739  // vehicle has reached its arrival position
742  } else if (target != 0 && moved) {
743  if (target->getEdge().isVaporizing()) {
744  // vehicle has reached a vaporizing edge
747  } else {
748  // vehicle has entered a new lane
749  target->myVehBuffer.push_back(veh);
750  SUMOReal pspeed = veh->getSpeed();
751  SUMOReal oldPos = veh->getPositionOnLane() - SPEED2DIST(veh->getSpeed());
752  veh->workOnMoveReminders(oldPos, veh->getPositionOnLane(), pspeed);
753  into.push_back(target);
754  }
755  } else if (veh->isParking()) {
756  // vehicle started to park
759  } else if (veh->getPositionOnLane() > getLength()) {
760  // for any reasons the vehicle is beyond its lane... error
761  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; beyond lane (2), targetLane='" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
764  } else {
765  ++i;
766  continue;
767  }
768  myVehicleLengthSum -= length;
769  i = myVehicles.erase(i);
770  }
771  if (myVehicles.size() > 0) {
773  && !(*(myVehicles.end() - 1))->isStopped()
774  && (*(myVehicles.end() - 1))->getWaitingTime() > MSGlobals::gTimeToGridlock) {
775  MSVehicle* veh = *(myVehicles.end() - 1);
777  myVehicles.erase(myVehicles.end() - 1);
778  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; waited too long, lane='" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
781  }
782  }
783  return myVehicles.size() == 0;
784 }
785 
786 
787 bool
788 MSLane::dictionary(std::string id, MSLane* ptr) {
789  DictType::iterator it = myDict.find(id);
790  if (it == myDict.end()) {
791  // id not in myDict.
792  myDict.insert(DictType::value_type(id, ptr));
793  return true;
794  }
795  return false;
796 }
797 
798 
799 MSLane*
800 MSLane::dictionary(std::string id) {
801  DictType::iterator it = myDict.find(id);
802  if (it == myDict.end()) {
803  // id not in myDict.
804  return 0;
805  }
806  return it->second;
807 }
808 
809 
810 void
812  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
813  delete(*i).second;
814  }
815  myDict.clear();
816 }
817 
818 
819 void
820 MSLane::insertIDs(std::vector<std::string>& into) {
821  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
822  into.push_back((*i).first);
823  }
824 }
825 
826 
827 bool
830  return true;
831  }
832  MSLinkCont::const_iterator link = succLinkSec(*veh, 1, *this, veh->getBestLanesContinuation());
833  return (link != myLinks.end());
834 }
835 
836 
837 bool
839  bool wasInactive = myVehicles.size() == 0;
840  sort(myVehBuffer.begin(), myVehBuffer.end(), vehicle_position_sorter());
841  for (std::vector<MSVehicle*>::const_iterator i = myVehBuffer.begin(); i != myVehBuffer.end(); ++i) {
842  MSVehicle* veh = *i;
843  myVehicles.push_front(veh);
845  }
846  myVehBuffer.clear();
847  return wasInactive && myVehicles.size() != 0;
848 }
849 
850 
851 bool
852 MSLane::isLinkEnd(MSLinkCont::const_iterator& i) const {
853  return i == myLinks.end();
854 }
855 
856 
857 bool
858 MSLane::isLinkEnd(MSLinkCont::iterator& i) {
859  return i == myLinks.end();
860 }
861 
862 
863 MSVehicle*
865  if (myVehicles.size() == 0) {
866  return 0;
867  }
868  return *myVehicles.begin();
869 }
870 
871 
872 const MSVehicle*
874  if (myVehicles.size() == 0) {
875  return 0;
876  }
877  return *(myVehicles.end() - 1);
878 }
879 
880 
881 MSLinkCont::const_iterator
882 MSLane::succLinkSec(const SUMOVehicle& veh, unsigned int nRouteSuccs,
883  const MSLane& succLinkSource, const std::vector<MSLane*>& conts) const {
884  const MSEdge* nRouteEdge = veh.succEdge(nRouteSuccs);
885  // check whether the vehicle tried to look beyond its route
886  if (nRouteEdge == 0) {
887  // return end (no succeeding link) if so
888  return succLinkSource.myLinks.end();
889  }
890  // a link may be used if
891  // 1) there is a destination lane ((*link)->getLane()!=0)
892  // 2) the destination lane belongs to the next edge in route ((*link)->getLane()->myEdge == nRouteEdge)
893  // 3) the destination lane allows the vehicle's class ((*link)->getLane()->allowsVehicleClass(veh.getVehicleClass()))
894 
895  // at first, we'll assume we have the continuations of our route in "conts" (built in "getBestLanes")
896  // "conts" stores the best continuations of our current lane
897  MSLinkCont::const_iterator link;
898  if (nRouteSuccs < conts.size()) {
899  // we go through the links in our list and return the matching one
900  for (link = succLinkSource.myLinks.begin(); link != succLinkSource.myLinks.end(); ++link) {
901  if ((*link)->getLane() != 0 && (*link)->getLane()->myEdge == nRouteEdge && (*link)->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
902  // we should use the link if it connects us to the best lane
903  if ((*link)->getLane() == conts[nRouteSuccs]) {
904  return link;
905  }
906  }
907  }
908  }
909 
910  // ok, we were not able to use the conts for any reason
911  // we will now collect allowed links, at first
912  // collect allowed links
913  std::vector<MSLinkCont::const_iterator> valid;
914  for (link = succLinkSource.myLinks.begin(); link != succLinkSource.myLinks.end(); ++link) {
915  if ((*link)->getLane() != 0 && (*link)->getLane()->myEdge == nRouteEdge && (*link)->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
916  valid.push_back(link);
917  }
918  }
919  // if no valid link was found...
920  if (valid.size() == 0) {
921  // ... return end (no succeeding link)
922  return succLinkSource.myLinks.end();
923  }
924  // if there is only one valid link, let's use it...
925  if (valid.size() == 1) {
926  return *(valid.begin());
927  }
928  // if the next edge is the route end, then we may return an arbitary link
929  // also, if there is no allowed lane on the edge following the current one (recheck?)
930  const MSEdge* nRouteEdge2 = veh.succEdge(nRouteSuccs + 1);
931  const std::vector<MSLane*>* next_allowed = nRouteEdge->allowedLanes(*nRouteEdge2, veh.getVehicleType().getVehicleClass());
932  if (nRouteEdge2 == 0 || next_allowed == 0) {
933  return *(valid.begin());
934  }
935  // now let's determine which link is the best
936  // in fact, we do not know it, here...
937  for (std::vector<MSLinkCont::const_iterator>::iterator i = valid.begin(); i != valid.end(); ++i) {
938  if (find(next_allowed->begin(), next_allowed->end(), (**i)->getLane()) != next_allowed->end()) {
939  return *i;
940  }
941  }
942  return *(valid.begin());
943 }
944 
945 
946 
947 const MSLinkCont&
949  return myLinks;
950 }
951 
952 
953 void
956  myTmpVehicles.clear();
957 }
958 
959 
960 
961 
964  throw "Only within the gui-version";
965 }
966 
967 
968 MSVehicle*
970  for (MSLane::VehCont::iterator it = myVehicles.begin(); it < myVehicles.end(); it++) {
971  if (remVehicle == *it) {
973  myVehicles.erase(it);
975  break;
976  }
977  }
978  return remVehicle;
979 }
980 
981 
982 MSLane*
984  return myEdge->leftLane(this);
985 }
986 
987 
988 MSLane*
990  return myEdge->rightLane(this);
991 }
992 
993 
994 void
996  IncomingLaneInfo ili;
997  ili.lane = lane;
998  ili.viaLink = viaLink;
999  ili.length = lane->getLength();
1000  myIncomingLanes.push_back(ili);
1001 }
1002 
1003 
1004 void
1006  MSEdge* approachingEdge = &lane->getEdge();
1007  if (myApproachingLanes.find(approachingEdge) == myApproachingLanes.end()) {
1008  myApproachingLanes[approachingEdge] = std::vector<MSLane*>();
1009  }
1010  myApproachingLanes[approachingEdge].push_back(lane);
1011 }
1012 
1013 
1014 bool
1016  return myApproachingLanes.find(edge) != myApproachingLanes.end();
1017 }
1018 
1019 
1020 bool
1021 MSLane::isApproachedFrom(MSEdge* const edge, MSLane* const lane) {
1022  std::map<MSEdge*, std::vector<MSLane*> >::const_iterator i = myApproachingLanes.find(edge);
1023  if (i == myApproachingLanes.end()) {
1024  return false;
1025  }
1026  const std::vector<MSLane*>& lanes = (*i).second;
1027  return find(lanes.begin(), lanes.end(), lane) != lanes.end();
1028 }
1029 
1030 
1032 public:
1033  inline int operator()(const std::pair<const MSVehicle* , SUMOReal>& p1, const std::pair<const MSVehicle* , SUMOReal>& p2) const {
1034  return p1.second < p2.second;
1035  }
1036 };
1037 
1038 
1040  SUMOReal dist, SUMOReal backOffset, SUMOReal leaderSpeed, SUMOReal leaderMaxDecel) const {
1041  // this follows the same logic as getFollowerOnConsecutive. we do a tree
1042  // search until dist and check for the vehicle with the largest missing rear gap
1043  SUMOReal result = 0;
1044  std::set<MSLane*> visited;
1045  std::vector<MSLane::IncomingLaneInfo> newFound;
1046  std::vector<MSLane::IncomingLaneInfo> toExamine = myIncomingLanes;
1047  while (toExamine.size() != 0) {
1048  for (std::vector<MSLane::IncomingLaneInfo>::iterator i = toExamine.begin(); i != toExamine.end(); ++i) {
1049  MSLane* next = (*i).lane;
1050  if (next->getFirstVehicle() != 0) {
1051  MSVehicle* v = (MSVehicle*) next->getFirstVehicle();
1052  const SUMOReal agap = (*i).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
1053  const SUMOReal missingRearGap = v->getCarFollowModel().getSecureGap(
1054  v->getCarFollowModel().maxNextSpeed(v->getSpeed()), leaderSpeed, leaderMaxDecel) - agap;
1055  result = MAX2(result, missingRearGap);
1056  } else {
1057  if ((*i).length < dist) {
1058  const std::vector<MSLane::IncomingLaneInfo>& followers = next->getIncomingLanes();
1059  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = followers.begin(); j != followers.end(); ++j) {
1060  if (visited.find((*j).lane) == visited.end()) {
1061  visited.insert((*j).lane);
1063  ili.lane = (*j).lane;
1064  ili.length = (*j).length + (*i).length;
1065  ili.viaLink = (*j).viaLink;
1066  newFound.push_back(ili);
1067  }
1068  }
1069  }
1070  }
1071  }
1072  toExamine.clear();
1073  swap(newFound, toExamine);
1074  }
1075  return result;
1076 }
1077 
1078 
1079 std::pair<MSVehicle* const, SUMOReal>
1081  SUMOReal backOffset, SUMOReal predMaxDecel) const {
1082  // ok, a vehicle has not noticed the lane about itself;
1083  // iterate as long as necessary to search for an approaching one
1084  std::set<MSLane*> visited;
1085  std::vector<std::pair<MSVehicle*, SUMOReal> > possible;
1086  std::vector<MSLane::IncomingLaneInfo> newFound;
1087  std::vector<MSLane::IncomingLaneInfo> toExamine = myIncomingLanes;
1088  while (toExamine.size() != 0) {
1089  for (std::vector<MSLane::IncomingLaneInfo>::iterator i = toExamine.begin(); i != toExamine.end(); ++i) {
1090  /*
1091  if ((*i).viaLink->getState()==LINKSTATE_TL_RED) {
1092  continue;
1093  }
1094  */
1095  MSLane* next = (*i).lane;
1096  if (next->getFirstVehicle() != 0) {
1097  MSVehicle* v = (MSVehicle*) next->getFirstVehicle();
1098  SUMOReal agap = (*i).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
1099  if (agap <= v->getCarFollowModel().getSecureGap(v->getCarFollowModel().maxNextSpeed(v->getSpeed()), leaderSpeed, predMaxDecel)) {
1100  possible.push_back(std::make_pair(v, agap));
1101  }
1102  } else {
1103  if ((*i).length + seen < dist) {
1104  const std::vector<MSLane::IncomingLaneInfo>& followers = next->getIncomingLanes();
1105  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = followers.begin(); j != followers.end(); ++j) {
1106  if (visited.find((*j).lane) == visited.end()) {
1107  visited.insert((*j).lane);
1109  ili.lane = (*j).lane;
1110  ili.length = (*j).length + (*i).length;
1111  ili.viaLink = (*j).viaLink;
1112  newFound.push_back(ili);
1113  }
1114  }
1115  }
1116  }
1117  }
1118  toExamine.clear();
1119  swap(newFound, toExamine);
1120  }
1121  if (possible.size() == 0) {
1122  return std::pair<MSVehicle* const, SUMOReal>(static_cast<MSVehicle*>(0), -1);
1123  }
1124  sort(possible.begin(), possible.end(), by_second_sorter());
1125  return *(possible.begin());
1126 }
1127 
1128 
1129 std::pair<MSVehicle* const, SUMOReal>
1131  const std::vector<MSLane*>& bestLaneConts) const {
1132  if (seen > dist) {
1133  return std::pair<MSVehicle* const, SUMOReal>(static_cast<MSVehicle*>(0), -1);
1134  }
1135  unsigned int view = 1;
1136  // loop over following lanes
1137  const MSLane* targetLane = this;
1138  MSVehicle* leader = targetLane->getPartialOccupator();
1139  if (leader != 0) {
1140  return std::pair<MSVehicle* const, SUMOReal>(leader, seen - targetLane->getPartialOccupatorEnd() - veh.getVehicleType().getMinGap());
1141  }
1142  const MSLane* nextLane = targetLane;
1143  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / speed);
1144  do {
1145  // get the next link used
1146  MSLinkCont::const_iterator link = targetLane->succLinkSec(veh, view, *nextLane, bestLaneConts);
1147  if (nextLane->isLinkEnd(link) || !(*link)->opened(arrivalTime, speed, speed, veh.getVehicleType().getLength()) || (*link)->getState() == LINKSTATE_TL_RED) {
1148  break;
1149  }
1150 #ifdef HAVE_INTERNAL_LANES
1151  bool nextInternal = (*link)->getViaLane() != 0;
1152 #endif
1153  nextLane = (*link)->getViaLaneOrLane();
1154  if (nextLane == 0) {
1155  break;
1156  }
1157  arrivalTime += TIME2STEPS(nextLane->getLength() / speed);
1158  MSVehicle* leader = nextLane->getLastVehicle();
1159  if (leader != 0) {
1160  return std::pair<MSVehicle* const, SUMOReal>(leader, seen + leader->getPositionOnLane() - leader->getVehicleType().getLength() - veh.getVehicleType().getMinGap());
1161  } else {
1162  leader = nextLane->getPartialOccupator();
1163  if (leader != 0) {
1164  return std::pair<MSVehicle* const, SUMOReal>(leader, seen + nextLane->getPartialOccupatorEnd() - veh.getVehicleType().getMinGap());
1165  }
1166  }
1167  if (nextLane->getVehicleMaxSpeed(&veh) < speed) {
1168  dist = veh.getCarFollowModel().brakeGap(nextLane->getVehicleMaxSpeed(&veh));
1169  }
1170  seen += nextLane->getLength();
1171 #ifdef HAVE_INTERNAL_LANES
1172  if (!nextInternal) {
1173  view++;
1174  }
1175 #else
1176  view++;
1177 #endif
1178  } while (seen <= dist);
1179  return std::pair<MSVehicle* const, SUMOReal>(static_cast<MSVehicle*>(0), -1);
1180 }
1181 
1182 
1183 MSLane*
1185  if (myLogicalPredecessorLane != 0) {
1186  return myLogicalPredecessorLane;
1187  }
1188  if (myLogicalPredecessorLane == 0) {
1189  std::vector<MSEdge*> pred = myEdge->getIncomingEdges();
1190  // get only those edges which connect to this lane
1191  for (std::vector<MSEdge*>::iterator i = pred.begin(); i != pred.end();) {
1192  std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(*i));
1193  if (j == myIncomingLanes.end()) {
1194  i = pred.erase(i);
1195  } else {
1196  ++i;
1197  }
1198  }
1199  // get the edge with the most connections to this lane's edge
1200  if (pred.size() != 0) {
1201  std::sort(pred.begin(), pred.end(), by_connections_to_sorter(&getEdge()));
1202  MSEdge* best = *pred.begin();
1203  std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(best));
1204  myLogicalPredecessorLane = (*j).lane;
1205  }
1206  }
1207  return myLogicalPredecessorLane;
1208 }
1209 
1210 
1211 void
1214 }
1215 
1216 
1217 void
1220 }
1221 
1222 
1223 // ------------ Current state retrieval
1224 SUMOReal
1226  return myVehicleLengthSum / myLength;
1227 }
1228 
1229 
1230 SUMOReal
1232  return myVehicleLengthSum;
1233 }
1234 
1235 
1236 SUMOReal
1238  if (myVehicles.size() == 0) {
1239  return myMaxSpeed;
1240  }
1241  SUMOReal v = 0;
1242  const MSLane::VehCont& vehs = getVehiclesSecure();
1243  for (VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1244  v += (*i)->getSpeed();
1245  }
1246  SUMOReal ret = v / (SUMOReal) myVehicles.size();
1247  releaseVehicles();
1248  return ret;
1249 }
1250 
1251 
1252 SUMOReal
1254  SUMOReal ret = 0;
1255  const MSLane::VehCont& vehs = getVehiclesSecure();
1256  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1257  ret += (*i)->getHBEFA_CO2Emissions();
1258  }
1259  releaseVehicles();
1260  return ret;
1261 }
1262 
1263 
1264 SUMOReal
1266  SUMOReal ret = 0;
1267  const MSLane::VehCont& vehs = getVehiclesSecure();
1268  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1269  ret += (*i)->getHBEFA_COEmissions();
1270  }
1271  releaseVehicles();
1272  return ret;
1273 }
1274 
1275 
1276 SUMOReal
1278  SUMOReal ret = 0;
1279  const MSLane::VehCont& vehs = getVehiclesSecure();
1280  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1281  ret += (*i)->getHBEFA_PMxEmissions();
1282  }
1283  releaseVehicles();
1284  return ret;
1285 }
1286 
1287 
1288 SUMOReal
1290  SUMOReal ret = 0;
1291  const MSLane::VehCont& vehs = getVehiclesSecure();
1292  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1293  ret += (*i)->getHBEFA_NOxEmissions();
1294  }
1295  releaseVehicles();
1296  return ret;
1297 }
1298 
1299 
1300 SUMOReal
1302  SUMOReal ret = 0;
1303  const MSLane::VehCont& vehs = getVehiclesSecure();
1304  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1305  ret += (*i)->getHBEFA_HCEmissions();
1306  }
1307  releaseVehicles();
1308  return ret;
1309 }
1310 
1311 
1312 SUMOReal
1314  SUMOReal ret = 0;
1315  const MSLane::VehCont& vehs = getVehiclesSecure();
1316  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1317  ret += (*i)->getHBEFA_FuelConsumption();
1318  }
1319  releaseVehicles();
1320  return ret;
1321 }
1322 
1323 
1324 SUMOReal
1326  SUMOReal ret = 0;
1327  const MSLane::VehCont& vehs = getVehiclesSecure();
1328  if (vehs.size() == 0) {
1329  releaseVehicles();
1330  return 0;
1331  }
1332  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1333  SUMOReal sv = (*i)->getHarmonoise_NoiseEmissions();
1334  ret += (SUMOReal) pow(10., (sv / 10.));
1335  }
1336  releaseVehicles();
1337  return HelpersHarmonoise::sum(ret);
1338 }
1339 
1340 
1341 bool
1343  return cmp->getPositionOnLane() >= pos;
1344 }
1345 
1346 
1347 int
1349  return v1->getPositionOnLane() > v2->getPositionOnLane();
1350 }
1351 
1353  myEdge(e),
1354  myLaneDir(e->getLanes()[0]->getShape().getBegLine().atan2PositiveAngle())
1355 { }
1356 
1357 
1358 int
1359 MSLane::by_connections_to_sorter::operator()(const MSEdge* const e1, const MSEdge* const e2) const {
1360  const std::vector<MSLane*>* ae1 = e1->allowedLanes(*myEdge);
1361  const std::vector<MSLane*>* ae2 = e2->allowedLanes(*myEdge);
1362  SUMOReal s1 = 0;
1363  if (ae1 != 0 && ae1->size() != 0) {
1364  s1 = (SUMOReal) ae1->size() + GeomHelper::getMinAngleDiff((*ae1)[0]->getShape().getBegLine().atan2PositiveAngle(), myLaneDir) / PI / 2.;
1365  }
1366  SUMOReal s2 = 0;
1367  if (ae2 != 0 && ae2->size() != 0) {
1368  s2 = (SUMOReal) ae2->size() + GeomHelper::getMinAngleDiff((*ae2)[0]->getShape().getBegLine().atan2PositiveAngle(), myLaneDir) / PI / 2.;
1369  }
1370  return s1 < s2;
1371 }
1372 
1373 /****************************************************************************/
1374