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-2013 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  veh.getBestLanes(true, this);
144  if (myVehicles.size() != 0) {
145  MSVehicle* leader = myVehicles.front();
146  xIn = leader->getPositionOnLane() - leader->getVehicleType().getLength() - veh.getVehicleType().getMinGap();
147  vIn = leader->getSpeed();
148  leaderDecel = leader->getCarFollowModel().getMaxDecel();
149  } else {
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  veh.getBestLanes(true, this);
189  if (myVehicles.size() != 0) {
190  MSVehicle* leader = myVehicles.front();
191  xIn = leader->getPositionOnLane() - leader->getVehicleType().getLength() - veh.getVehicleType().getMinGap();
192  vIn = leader->getSpeed();
193  } else {
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() - aVehicle->getVehicleType().getMinGap();
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 follower
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  }
594  // may got negative while adaptation
595  if (speed < 0) {
596  return false;
597  }
598  // enter
599  incorporateVehicle(aVehicle, pos, speed, predIt, notification);
600  return true;
601 }
602 
603 
604 void
606  incorporateVehicle(veh, pos, veh->getSpeed(), find_if(myVehicles.begin(), myVehicles.end(), bind2nd(VehPosition(), pos)));
607 }
608 
609 
610 // ------ Handling vehicles lapping into lanes ------
611 SUMOReal
613  myInlappingVehicle = v;
614  if (leftVehicleLength > myLength) {
616  } else {
617  myInlappingVehicleEnd = myLength - leftVehicleLength;
618  }
619  return myLength;
620 }
621 
622 
623 void
625  if (v == myInlappingVehicle) {
626  myInlappingVehicleEnd = 10000;
627  }
628  myInlappingVehicle = 0;
629 }
630 
631 
632 std::pair<MSVehicle*, SUMOReal>
634  if (myVehicles.size() != 0) {
635  // the last vehicle is the one in scheduled by this lane
636  MSVehicle* last = *myVehicles.begin();
637  const SUMOReal pos = last->getPositionOnLane() - last->getVehicleType().getLength();
638  return std::make_pair(last, pos);
639  }
640  if (myInlappingVehicle != 0) {
641  // the last one is a vehicle extending into this lane
642  return std::make_pair(myInlappingVehicle, myInlappingVehicleEnd);
643  }
644  return std::make_pair<MSVehicle*, SUMOReal>(0, 0);
645 }
646 
647 
648 // ------ ------
649 bool
652  assert(myVehicles.size() != 0);
653  std::vector<MSVehicle*> collisions;
654  VehCont::iterator lastBeforeEnd = myVehicles.end() - 1;
655  VehCont::iterator veh;
656  // Move all next vehicles beside the first
657  for (veh = myVehicles.begin(); veh != lastBeforeEnd; ++veh) {
658  myLeftVehLength -= (*veh)->getVehicleType().getLengthWithGap();
659  VehCont::const_iterator pred(veh + 1);
660  assert((*veh)->getLane() == this);
661  (*veh)->planMove(t, *pred, 0, myLeftVehLength);
662  }
663  myLeftVehLength -= (*veh)->getVehicleType().getLengthWithGap();
664  assert((*veh)->getLane() == this);
665  (*veh)->planMove(t, 0, 0, myLeftVehLength);
666  assert((*veh)->getPositionOnLane() <= myLength);
667  assert((*veh)->getLane() == this);
668  return myVehicles.size() == 0;
669 }
670 
671 
672 void
673 MSLane::detectCollisions(SUMOTime timestep, int stage) {
674  if (myVehicles.size() < 2) {
675  return;
676  }
677 
678  VehCont::iterator lastVeh = myVehicles.end() - 1;
679  for (VehCont::iterator veh = myVehicles.begin(); veh != lastVeh;) {
680  VehCont::iterator pred = veh + 1;
681  if ((*veh)->hasInfluencer() && (*veh)->getInfluencer().isVTDControlled()) {
682  ++veh;
683  continue;
684  }
685  if ((*pred)->hasInfluencer() && (*pred)->getInfluencer().isVTDControlled()) {
686  ++veh;
687  continue;
688  }
689  SUMOReal gap = (*pred)->getPositionOnLane() - (*pred)->getVehicleType().getLength() - (*veh)->getPositionOnLane() - (*veh)->getVehicleType().getMinGap();
690  if (gap < -0.001) {
691  MSVehicle* vehV = *veh;
692  WRITE_WARNING("Teleporting vehicle '" + vehV->getID() + "'; collision with '"
693  + (*pred)->getID() + "', lane='" + getID() + "', gap=" + toString(gap)
694  + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + " stage=" + toString(stage) + ".");
697  MSVehicleTransfer::getInstance()->addVeh(timestep, vehV);
698  veh = myVehicles.erase(veh); // remove current vehicle
699  lastVeh = myVehicles.end() - 1;
700  if (veh == myVehicles.end()) {
701  break;
702  }
703  } else {
704  ++veh;
705  }
706  }
707 }
708 
709 
710 bool
711 MSLane::executeMovements(SUMOTime t, std::vector<MSLane*>& into) {
712  // move critical vehicles
713  for (VehCont::iterator i = myVehicles.begin(); i != myVehicles.end();) {
714  MSVehicle* veh = *i;
715  bool moved = veh->executeMove();
716  MSLane* target = veh->getLane();
717  SUMOReal length = veh->getVehicleType().getLengthWithGap();
718 #ifndef NO_TRACI
719  bool vtdControlled = veh->hasInfluencer() && veh->getInfluencer().isVTDControlled();
720  if (veh->hasArrived() && !vtdControlled) {
721 #else
722  if (veh->hasArrived()) {
723 #endif
724  // vehicle has reached its arrival position
727  } else if (target != 0 && moved) {
728  if (target->getEdge().isVaporizing()) {
729  // vehicle has reached a vaporizing edge
732  } else {
733  // vehicle has entered a new lane
734  target->myVehBuffer.push_back(veh);
735  SUMOReal pspeed = veh->getSpeed();
736  SUMOReal oldPos = veh->getPositionOnLane() - SPEED2DIST(veh->getSpeed());
737  veh->workOnMoveReminders(oldPos, veh->getPositionOnLane(), pspeed);
738  into.push_back(target);
739  }
740  } else if (veh->isParking()) {
741  // vehicle started to park
744  } else if (veh->getPositionOnLane() > getLength()) {
745  // for any reasons the vehicle is beyond its lane... error
746  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; beyond lane (2), targetLane='" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
749  } else {
750  ++i;
751  continue;
752  }
753  myVehicleLengthSum -= length;
754  i = myVehicles.erase(i);
755  }
756  if (myVehicles.size() > 0) {
758  && !(*(myVehicles.end() - 1))->isStopped()
759  && (*(myVehicles.end() - 1))->getWaitingTime() > MSGlobals::gTimeToGridlock) {
760  MSVehicle* veh = *(myVehicles.end() - 1);
762  myVehicles.erase(myVehicles.end() - 1);
763  WRITE_WARNING("Teleporting vehicle '" + veh->getID() + "'; waited too long, lane='" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
766  }
767  }
768  return myVehicles.size() == 0;
769 }
770 
771 
772 bool
773 MSLane::dictionary(std::string id, MSLane* ptr) {
774  DictType::iterator it = myDict.find(id);
775  if (it == myDict.end()) {
776  // id not in myDict.
777  myDict.insert(DictType::value_type(id, ptr));
778  return true;
779  }
780  return false;
781 }
782 
783 
784 MSLane*
785 MSLane::dictionary(std::string id) {
786  DictType::iterator it = myDict.find(id);
787  if (it == myDict.end()) {
788  // id not in myDict.
789  return 0;
790  }
791  return it->second;
792 }
793 
794 
795 void
797  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
798  delete(*i).second;
799  }
800  myDict.clear();
801 }
802 
803 
804 void
805 MSLane::insertIDs(std::vector<std::string>& into) {
806  for (DictType::iterator i = myDict.begin(); i != myDict.end(); ++i) {
807  into.push_back((*i).first);
808  }
809 }
810 
811 
812 bool
815  return true;
816  }
817  MSLinkCont::const_iterator link = succLinkSec(*veh, 1, *this, veh->getBestLanesContinuation());
818  return (link != myLinks.end());
819 }
820 
821 
822 bool
824  bool wasInactive = myVehicles.size() == 0;
825  sort(myVehBuffer.begin(), myVehBuffer.end(), vehicle_position_sorter());
826  for (std::vector<MSVehicle*>::const_iterator i = myVehBuffer.begin(); i != myVehBuffer.end(); ++i) {
827  MSVehicle* veh = *i;
828  myVehicles.push_front(veh);
830  }
831  myVehBuffer.clear();
832  return wasInactive && myVehicles.size() != 0;
833 }
834 
835 
836 bool
837 MSLane::isLinkEnd(MSLinkCont::const_iterator& i) const {
838  return i == myLinks.end();
839 }
840 
841 
842 bool
843 MSLane::isLinkEnd(MSLinkCont::iterator& i) {
844  return i == myLinks.end();
845 }
846 
847 
848 MSVehicle*
850  if (myVehicles.size() == 0) {
851  return 0;
852  }
853  return *myVehicles.begin();
854 }
855 
856 
857 const MSVehicle*
859  if (myVehicles.size() == 0) {
860  return 0;
861  }
862  return *(myVehicles.end() - 1);
863 }
864 
865 
866 MSLinkCont::const_iterator
867 MSLane::succLinkSec(const SUMOVehicle& veh, unsigned int nRouteSuccs,
868  const MSLane& succLinkSource, const std::vector<MSLane*>& conts) const {
869  const MSEdge* nRouteEdge = veh.succEdge(nRouteSuccs);
870  // check whether the vehicle tried to look beyond its route
871  if (nRouteEdge == 0) {
872  // return end (no succeeding link) if so
873  return succLinkSource.myLinks.end();
874  }
875  // if we are on an internal lane there should only be one link and it must be allowed
876  if (succLinkSource.getEdge().getPurpose() == MSEdge::EDGEFUNCTION_INTERNAL) {
877  assert(succLinkSource.myLinks.size() == 1);
878  assert(succLinkSource.myLinks[0]->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass()));
879  return succLinkSource.myLinks.begin();
880  }
881  // a link may be used if
882  // 1) there is a destination lane ((*link)->getLane()!=0)
883  // 2) the destination lane belongs to the next edge in route ((*link)->getLane()->myEdge == nRouteEdge)
884  // 3) the destination lane allows the vehicle's class ((*link)->getLane()->allowsVehicleClass(veh.getVehicleClass()))
885 
886  // there should be a link which leads to the next desired lane our route in "conts" (built in "getBestLanes")
887  // "conts" stores the best continuations of our current lane
888  // we should never return an arbitrary link since this may cause collisions
889  MSLinkCont::const_iterator link;
890  if (nRouteSuccs < conts.size()) {
891  // we go through the links in our list and return the matching one
892  for (link = succLinkSource.myLinks.begin(); link != succLinkSource.myLinks.end(); ++link) {
893  if ((*link)->getLane() != 0 && (*link)->getLane()->myEdge == nRouteEdge && (*link)->getLane()->allowsVehicleClass(veh.getVehicleType().getVehicleClass())) {
894  // we should use the link if it connects us to the best lane
895  if ((*link)->getLane() == conts[nRouteSuccs]) {
896  return link;
897  }
898  }
899  }
900  } else {
901  // the source lane is a dead end (no continuations exist)
902  return succLinkSource.myLinks.end();
903  }
904  // the only case where this should happen is for a disconnected route (deliberately ignored)
905  return succLinkSource.myLinks.end();
906 }
907 
908 
909 
910 const MSLinkCont&
912  return myLinks;
913 }
914 
915 
916 void
919  myTmpVehicles.clear();
920 }
921 
922 
923 
924 
927  throw "Only within the gui-version";
928 }
929 
930 
931 MSVehicle*
933  for (MSLane::VehCont::iterator it = myVehicles.begin(); it < myVehicles.end(); it++) {
934  if (remVehicle == *it) {
936  myVehicles.erase(it);
938  break;
939  }
940  }
941  return remVehicle;
942 }
943 
944 
945 MSLane*
947  return myEdge->leftLane(this);
948 }
949 
950 
951 MSLane*
953  return myEdge->rightLane(this);
954 }
955 
956 
957 void
959  IncomingLaneInfo ili;
960  ili.lane = lane;
961  ili.viaLink = viaLink;
962  ili.length = lane->getLength();
963  myIncomingLanes.push_back(ili);
964 }
965 
966 
967 void
969  MSEdge* approachingEdge = &lane->getEdge();
970  if (myApproachingLanes.find(approachingEdge) == myApproachingLanes.end()) {
971  myApproachingLanes[approachingEdge] = std::vector<MSLane*>();
972  }
973  myApproachingLanes[approachingEdge].push_back(lane);
974 }
975 
976 
977 bool
979  return myApproachingLanes.find(edge) != myApproachingLanes.end();
980 }
981 
982 
983 bool
984 MSLane::isApproachedFrom(MSEdge* const edge, MSLane* const lane) {
985  std::map<MSEdge*, std::vector<MSLane*> >::const_iterator i = myApproachingLanes.find(edge);
986  if (i == myApproachingLanes.end()) {
987  return false;
988  }
989  const std::vector<MSLane*>& lanes = (*i).second;
990  return find(lanes.begin(), lanes.end(), lane) != lanes.end();
991 }
992 
993 
995 public:
996  inline int operator()(const std::pair<const MSVehicle* , SUMOReal>& p1, const std::pair<const MSVehicle* , SUMOReal>& p2) const {
997  return p1.second < p2.second;
998  }
999 };
1000 
1001 
1003  SUMOReal dist, SUMOReal backOffset, SUMOReal leaderSpeed, SUMOReal leaderMaxDecel) const {
1004  // this follows the same logic as getFollowerOnConsecutive. we do a tree
1005  // search until dist and check for the vehicle with the largest missing rear gap
1006  SUMOReal result = 0;
1007  std::set<MSLane*> visited;
1008  std::vector<MSLane::IncomingLaneInfo> newFound;
1009  std::vector<MSLane::IncomingLaneInfo> toExamine = myIncomingLanes;
1010  while (toExamine.size() != 0) {
1011  for (std::vector<MSLane::IncomingLaneInfo>::iterator i = toExamine.begin(); i != toExamine.end(); ++i) {
1012  MSLane* next = (*i).lane;
1013  if (next->getFirstVehicle() != 0) {
1014  MSVehicle* v = (MSVehicle*) next->getFirstVehicle();
1015  const SUMOReal agap = (*i).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
1016  const SUMOReal missingRearGap = v->getCarFollowModel().getSecureGap(
1017  v->getCarFollowModel().maxNextSpeed(v->getSpeed(), v), leaderSpeed, leaderMaxDecel) - agap;
1018  result = MAX2(result, missingRearGap);
1019  } else {
1020  if ((*i).length < dist) {
1021  const std::vector<MSLane::IncomingLaneInfo>& followers = next->getIncomingLanes();
1022  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = followers.begin(); j != followers.end(); ++j) {
1023  if (visited.find((*j).lane) == visited.end()) {
1024  visited.insert((*j).lane);
1026  ili.lane = (*j).lane;
1027  ili.length = (*j).length + (*i).length;
1028  ili.viaLink = (*j).viaLink;
1029  newFound.push_back(ili);
1030  }
1031  }
1032  }
1033  }
1034  }
1035  toExamine.clear();
1036  swap(newFound, toExamine);
1037  }
1038  return result;
1039 }
1040 
1041 
1042 std::pair<MSVehicle* const, SUMOReal>
1044  SUMOReal backOffset, SUMOReal predMaxDecel) const {
1045  // ok, a vehicle has not noticed the lane about itself;
1046  // iterate as long as necessary to search for an approaching one
1047  std::set<MSLane*> visited;
1048  std::vector<std::pair<MSVehicle*, SUMOReal> > possible;
1049  std::vector<MSLane::IncomingLaneInfo> newFound;
1050  std::vector<MSLane::IncomingLaneInfo> toExamine = myIncomingLanes;
1051  while (toExamine.size() != 0) {
1052  for (std::vector<MSLane::IncomingLaneInfo>::iterator i = toExamine.begin(); i != toExamine.end(); ++i) {
1053  /*
1054  if ((*i).viaLink->getState()==LINKSTATE_TL_RED) {
1055  continue;
1056  }
1057  */
1058  MSLane* next = (*i).lane;
1059  if (next->getFirstVehicle() != 0) {
1060  MSVehicle* v = (MSVehicle*) next->getFirstVehicle();
1061  SUMOReal agap = (*i).length - v->getPositionOnLane() + backOffset - v->getVehicleType().getMinGap();
1062  if (agap <= v->getCarFollowModel().getSecureGap(v->getCarFollowModel().maxNextSpeed(v->getSpeed(), v), leaderSpeed, predMaxDecel)) {
1063  possible.push_back(std::make_pair(v, agap));
1064  }
1065  } else {
1066  if ((*i).length + seen < dist) {
1067  const std::vector<MSLane::IncomingLaneInfo>& followers = next->getIncomingLanes();
1068  for (std::vector<MSLane::IncomingLaneInfo>::const_iterator j = followers.begin(); j != followers.end(); ++j) {
1069  if (visited.find((*j).lane) == visited.end()) {
1070  visited.insert((*j).lane);
1072  ili.lane = (*j).lane;
1073  ili.length = (*j).length + (*i).length;
1074  ili.viaLink = (*j).viaLink;
1075  newFound.push_back(ili);
1076  }
1077  }
1078  }
1079  }
1080  }
1081  toExamine.clear();
1082  swap(newFound, toExamine);
1083  }
1084  if (possible.size() == 0) {
1085  return std::pair<MSVehicle* const, SUMOReal>(static_cast<MSVehicle*>(0), -1);
1086  }
1087  sort(possible.begin(), possible.end(), by_second_sorter());
1088  return *(possible.begin());
1089 }
1090 
1091 
1092 std::pair<MSVehicle* const, SUMOReal>
1094  const std::vector<MSLane*>& bestLaneConts) const {
1095  if (seen > dist) {
1096  return std::pair<MSVehicle* const, SUMOReal>(static_cast<MSVehicle*>(0), -1);
1097  }
1098  unsigned int view = 1;
1099  // loop over following lanes
1100  const MSLane* targetLane = this;
1101  MSVehicle* leader = targetLane->getPartialOccupator();
1102  if (leader != 0) {
1103  return std::pair<MSVehicle* const, SUMOReal>(leader, seen - targetLane->getPartialOccupatorEnd() - veh.getVehicleType().getMinGap());
1104  }
1105  const MSLane* nextLane = targetLane;
1106  SUMOTime arrivalTime = MSNet::getInstance()->getCurrentTimeStep() + TIME2STEPS(seen / speed);
1107  do {
1108  // get the next link used
1109  MSLinkCont::const_iterator link = targetLane->succLinkSec(veh, view, *nextLane, bestLaneConts);
1110  if (nextLane->isLinkEnd(link) || !(*link)->opened(arrivalTime, speed, speed, veh.getVehicleType().getLength()) || (*link)->getState() == LINKSTATE_TL_RED) {
1111  break;
1112  }
1113 #ifdef HAVE_INTERNAL_LANES
1114  bool nextInternal = (*link)->getViaLane() != 0;
1115 #endif
1116  nextLane = (*link)->getViaLaneOrLane();
1117  if (nextLane == 0) {
1118  break;
1119  }
1120  arrivalTime += TIME2STEPS(nextLane->getLength() / speed);
1121  MSVehicle* leader = nextLane->getLastVehicle();
1122  if (leader != 0) {
1123  return std::pair<MSVehicle* const, SUMOReal>(leader, seen + leader->getPositionOnLane() - leader->getVehicleType().getLength() - veh.getVehicleType().getMinGap());
1124  } else {
1125  leader = nextLane->getPartialOccupator();
1126  if (leader != 0) {
1127  return std::pair<MSVehicle* const, SUMOReal>(leader, seen + nextLane->getPartialOccupatorEnd() - veh.getVehicleType().getMinGap());
1128  }
1129  }
1130  if (nextLane->getVehicleMaxSpeed(&veh) < speed) {
1131  dist = veh.getCarFollowModel().brakeGap(nextLane->getVehicleMaxSpeed(&veh));
1132  }
1133  seen += nextLane->getLength();
1134 #ifdef HAVE_INTERNAL_LANES
1135  if (!nextInternal) {
1136  view++;
1137  }
1138 #else
1139  view++;
1140 #endif
1141  } while (seen <= dist);
1142  return std::pair<MSVehicle* const, SUMOReal>(static_cast<MSVehicle*>(0), -1);
1143 }
1144 
1145 
1146 MSLane*
1148  if (myLogicalPredecessorLane != 0) {
1149  return myLogicalPredecessorLane;
1150  }
1151  if (myLogicalPredecessorLane == 0) {
1152  std::vector<MSEdge*> pred = myEdge->getIncomingEdges();
1153  // get only those edges which connect to this lane
1154  for (std::vector<MSEdge*>::iterator i = pred.begin(); i != pred.end();) {
1155  std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(*i));
1156  if (j == myIncomingLanes.end()) {
1157  i = pred.erase(i);
1158  } else {
1159  ++i;
1160  }
1161  }
1162  // get the edge with the most connections to this lane's edge
1163  if (pred.size() != 0) {
1164  std::sort(pred.begin(), pred.end(), by_connections_to_sorter(&getEdge()));
1165  MSEdge* best = *pred.begin();
1166  std::vector<IncomingLaneInfo>::const_iterator j = find_if(myIncomingLanes.begin(), myIncomingLanes.end(), edge_finder(best));
1167  myLogicalPredecessorLane = (*j).lane;
1168  }
1169  }
1170  return myLogicalPredecessorLane;
1171 }
1172 
1173 
1174 void
1177 }
1178 
1179 
1180 void
1183 }
1184 
1185 
1186 // ------------ Current state retrieval
1187 SUMOReal
1189  return myVehicleLengthSum / myLength;
1190 }
1191 
1192 
1193 SUMOReal
1195  return myVehicleLengthSum;
1196 }
1197 
1198 
1199 SUMOReal
1201  if (myVehicles.size() == 0) {
1202  return myMaxSpeed;
1203  }
1204  SUMOReal v = 0;
1205  const MSLane::VehCont& vehs = getVehiclesSecure();
1206  for (VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1207  v += (*i)->getSpeed();
1208  }
1209  SUMOReal ret = v / (SUMOReal) myVehicles.size();
1210  releaseVehicles();
1211  return ret;
1212 }
1213 
1214 
1215 SUMOReal
1217  SUMOReal ret = 0;
1218  const MSLane::VehCont& vehs = getVehiclesSecure();
1219  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1220  ret += (*i)->getHBEFA_CO2Emissions();
1221  }
1222  releaseVehicles();
1223  return ret;
1224 }
1225 
1226 
1227 SUMOReal
1229  SUMOReal ret = 0;
1230  const MSLane::VehCont& vehs = getVehiclesSecure();
1231  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1232  ret += (*i)->getHBEFA_COEmissions();
1233  }
1234  releaseVehicles();
1235  return ret;
1236 }
1237 
1238 
1239 SUMOReal
1241  SUMOReal ret = 0;
1242  const MSLane::VehCont& vehs = getVehiclesSecure();
1243  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1244  ret += (*i)->getHBEFA_PMxEmissions();
1245  }
1246  releaseVehicles();
1247  return ret;
1248 }
1249 
1250 
1251 SUMOReal
1253  SUMOReal ret = 0;
1254  const MSLane::VehCont& vehs = getVehiclesSecure();
1255  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1256  ret += (*i)->getHBEFA_NOxEmissions();
1257  }
1258  releaseVehicles();
1259  return ret;
1260 }
1261 
1262 
1263 SUMOReal
1265  SUMOReal ret = 0;
1266  const MSLane::VehCont& vehs = getVehiclesSecure();
1267  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1268  ret += (*i)->getHBEFA_HCEmissions();
1269  }
1270  releaseVehicles();
1271  return ret;
1272 }
1273 
1274 
1275 SUMOReal
1277  SUMOReal ret = 0;
1278  const MSLane::VehCont& vehs = getVehiclesSecure();
1279  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1280  ret += (*i)->getHBEFA_FuelConsumption();
1281  }
1282  releaseVehicles();
1283  return ret;
1284 }
1285 
1286 
1287 SUMOReal
1289  SUMOReal ret = 0;
1290  const MSLane::VehCont& vehs = getVehiclesSecure();
1291  if (vehs.size() == 0) {
1292  releaseVehicles();
1293  return 0;
1294  }
1295  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
1296  SUMOReal sv = (*i)->getHarmonoise_NoiseEmissions();
1297  ret += (SUMOReal) pow(10., (sv / 10.));
1298  }
1299  releaseVehicles();
1300  return HelpersHarmonoise::sum(ret);
1301 }
1302 
1303 
1304 bool
1306  return cmp->getPositionOnLane() >= pos;
1307 }
1308 
1309 
1310 int
1312  return v1->getPositionOnLane() > v2->getPositionOnLane();
1313 }
1314 
1316  myEdge(e),
1317  myLaneDir(e->getLanes()[0]->getShape().getBegLine().atan2PositiveAngle())
1318 { }
1319 
1320 
1321 int
1322 MSLane::by_connections_to_sorter::operator()(const MSEdge* const e1, const MSEdge* const e2) const {
1323  const std::vector<MSLane*>* ae1 = e1->allowedLanes(*myEdge);
1324  const std::vector<MSLane*>* ae2 = e2->allowedLanes(*myEdge);
1325  SUMOReal s1 = 0;
1326  if (ae1 != 0 && ae1->size() != 0) {
1327  s1 = (SUMOReal) ae1->size() + GeomHelper::getMinAngleDiff((*ae1)[0]->getShape().getBegLine().atan2PositiveAngle(), myLaneDir) / PI / 2.;
1328  }
1329  SUMOReal s2 = 0;
1330  if (ae2 != 0 && ae2->size() != 0) {
1331  s2 = (SUMOReal) ae2->size() + GeomHelper::getMinAngleDiff((*ae2)[0]->getShape().getBegLine().atan2PositiveAngle(), myLaneDir) / PI / 2.;
1332  }
1333  return s1 < s2;
1334 }
1335 
1336 /****************************************************************************/
1337