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