Eclipse SUMO - Simulation of Urban MObility
MSLCHelper.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2013-2022 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // Common functions for lane change models
19 /****************************************************************************/
20 
21 #include <microsim/MSEdge.h>
22 #include <microsim/MSLane.h>
23 #include <microsim/MSLink.h>
24 #include <microsim/MSVehicle.h>
26 #include "MSLCHelper.h"
27 
28 // ===========================================================================
29 // Debug flags
30 // ===========================================================================
31 //#define DEBUG_WANTS_CHANGE
32 
33 
34 // ===========================================================================
35 // member method definitions
36 // ===========================================================================
37 
38 double
40  double bonusParam,
41  const MSVehicle::LaneQ& curr,
42  const MSVehicle::LaneQ& neigh,
43  const MSVehicle::LaneQ& best) {
44  if (veh.getLaneChangeModel().isOpposite()) {
45  return 0;
46  }
47  const MSVehicle::LaneQ& inner = neigh.lane->getIndex() > curr.lane->getIndex() ? neigh : curr;
48 #ifdef DEBUG_WANTS_CHANGE
49  const bool debugVehicle = veh.getLaneChangeModel().debugVehicle();
50  if (debugVehicle) {
51  std::cout << SIMTIME << " veh=" << veh.getID() << " getRoundaboutDistBonus bonusParam=" << bonusParam
52  << " curr=" << curr.lane->getID()
53  << " neigh=" << neigh.lane->getID()
54  << " inner=" << inner.lane->getID()
55  << " best=" << best.lane->getID()
56  << "\n innerCont=" << toString(inner.bestContinuations)
57  << "\n bestCont=" << toString(best.bestContinuations)
58  << "\n";
59  }
60 #endif
61 
62  int roundaboutJunctionsAhead = 0;
63  bool enteredRoundabout = false;
64  double seen = -veh.getPositionOnLane();
65 
66  // first check using only normal lanes
67  for (int i = 0; i < (int)best.bestContinuations.size(); i++) {
68  const MSLane* lane = best.bestContinuations[i];
69  if (lane == nullptr) {
70  lane = veh.getLane();
71  }
72  if ((!enteredRoundabout || lane->getEdge().isRoundabout()) && i >= (int)inner.bestContinuations.size()) {
73  // no bonus if we cannot continue on the inner lane until leaving the roundabout
74 #ifdef DEBUG_WANTS_CHANGE
75  if (debugVehicle) {
76  std::cout << " noBonus: inner does not continue (lane=" << lane->getID() << ")\n";
77  }
78 #endif
79  return 0;
80  }
81  if (seen > 300) {
82  // avoid long look-ahead
83 #ifdef DEBUG_WANTS_CHANGE
84  if (debugVehicle) {
85  std::cout << " noBonus: seen=" << seen << " (lane=" << lane->getID() << ")\n";
86  }
87 #endif
88  return 0;
89  }
90  const MSJunction* junction = lane->getEdge().getToJunction();
91  if (lane->getEdge().isRoundabout()) {
92  enteredRoundabout = true;
93  if (junction->getIncoming().size() + junction->getOutgoing().size() > 2) {
94  roundaboutJunctionsAhead++;
95  }
96  } else if (enteredRoundabout) {
97  // only check the first roundabout
98  break;
99  }
100  seen += lane->getLength();
101  }
102  // no bonus if we want to take the next exit
103  if (roundaboutJunctionsAhead < 2) {
104  return 0;
105  }
106 
107  // compute bonus value based on jamming and exact distances (taking into
108  // account internal lanes)
109  double occupancyOuter = 0;
110  double occupancyInner = 0;
111  double distanceInRoundabout = 0;
112  MSLane* prevNormal = nullptr;
113  MSLane* prevInner = nullptr;
114  enteredRoundabout = false;
115  for (int i = 0; i < (int)best.bestContinuations.size(); i++) {
116  MSLane* lane = best.bestContinuations[i];
117  if (lane == nullptr) {
118  continue;
119  }
120  if (lane->getEdge().isRoundabout()) {
121  enteredRoundabout = true;
122  } else if (enteredRoundabout) {
123  // only check the first roundabout
124  break;
125  }
126  MSLane* via = nullptr;
127  if (prevNormal != nullptr) {
128  for (MSLink* link : prevNormal->getLinkCont()) {
129  if (link->getLane() == lane) {
130  via = link->getViaLane();
131  }
132  }
133  }
134  if (enteredRoundabout) {
135  distanceInRoundabout += lane->getLength();
136  if (via != nullptr) {
137  distanceInRoundabout += via->getLength();
138  }
139  }
140  // discount vehicles that are upstream from ego
141  const double upstreamDiscount = &lane->getEdge() == &veh.getLane()->getEdge()
142  ? (lane->getLength() - veh.getPositionOnLane()) / lane->getLength() : 1;
143  prevNormal = lane;
144  occupancyOuter += upstreamDiscount * lane->getBruttoVehLenSum();
145 #ifdef DEBUG_WANTS_CHANGE
146  if (debugVehicle) {
147  std::cout << " lane=" << lane->getID() << " occ=" << lane->getBruttoVehLenSum() << " discount=" << upstreamDiscount << " outer=" << occupancyOuter << "\n";
148  }
149 #endif
150  if (via != nullptr) {
151  occupancyOuter += via->getBruttoVehLenSum();
152 #ifdef DEBUG_WANTS_CHANGE
153  if (debugVehicle) {
154  std::cout << " via=" << via->getID() << " occ=" << via->getBruttoVehLenSum() << " outer=" << occupancyOuter << "\n";
155  }
156 #endif
157  }
158  if (i < (int)inner.bestContinuations.size()) {
159  MSLane* innerLane = inner.bestContinuations[i];
160  occupancyInner += upstreamDiscount * innerLane->getBruttoVehLenSum();
161 #ifdef DEBUG_WANTS_CHANGE
162  if (debugVehicle) {
163  std::cout << " inner=" << innerLane->getID() << " occ=" << innerLane->getBruttoVehLenSum() << " discount=" << upstreamDiscount << " inner=" << occupancyInner << "\n";
164  }
165 #endif
166  if (prevInner != nullptr) {
167  for (MSLink* link : prevInner->getLinkCont()) {
168  if (link->getLane() == innerLane && link->getViaLane() != nullptr) {
169  occupancyInner += link->getViaLane()->getBruttoVehLenSum();
170 #ifdef DEBUG_WANTS_CHANGE
171  if (debugVehicle) {
172  std::cout << " innerVia=" << link->getViaLane()->getID() << " occ=" << link->getViaLane()->getBruttoVehLenSum() << " inner=" << occupancyInner << "\n";
173  }
174 #endif
175  }
176  }
177  }
178  prevInner = innerLane;
179  }
180  }
181 
182 #ifdef DEBUG_WANTS_CHANGE
183  if (debugVehicle) {
184  std::cout << " distanceInRoundabout=" << distanceInRoundabout
185  << " roundaboutJunctionsAhead=" << roundaboutJunctionsAhead
186  << " occupancyInner=" << occupancyInner
187  << " occupancyOuter=" << occupancyOuter
188  << "\n";
189  }
190 #endif
191 
192  const double maxOccupancy = MAX2(occupancyInner, occupancyOuter);
193  if (maxOccupancy == 0) {
194  // no bonues if the roundabout is empty
195  return 0;
196  }
197  // give some bonus for using the inside lane at equal occupancy
198  const double bonus = roundaboutJunctionsAhead * 7.5;
199  const double relativeJam = (occupancyOuter - occupancyInner + bonus) / (maxOccupancy + bonus);
200  // no bonus if the inner lane or the left lane entering the roundabout is jammed
201  const double jamFactor = MAX2(0.0, relativeJam);
202  const double result = distanceInRoundabout * jamFactor * bonusParam * 9; // the 9 is abitrary and only there for backward compatibility
203 #ifdef DEBUG_WANTS_CHANGE
204  if (debugVehicle) {
205  std::cout << " relativeJam=" << relativeJam
206  << " jamFactor=" << jamFactor
207  << " distanceBonus=" << result
208  << "\n";
209  }
210 #endif
211  return result;
212 }
213 
214 
215 
216 /****************************************************************************/
#define SIMTIME
Definition: SUMOTime.h:60
T MAX2(T a, T b)
Definition: StdDefs.h:80
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
virtual bool debugVehicle() const
whether the current vehicles shall be debugged
bool isRoundabout() const
Definition: MSEdge.h:685
const MSJunction * getToJunction() const
Definition: MSEdge.h:401
The base class for an intersection.
Definition: MSJunction.h:58
const ConstMSEdgeVector & getIncoming() const
Definition: MSJunction.h:105
const ConstMSEdgeVector & getOutgoing() const
Definition: MSJunction.h:111
static double getRoundaboutDistBonus(const MSVehicle &veh, double bonusParam, const MSVehicle::LaneQ &curr, const MSVehicle::LaneQ &neigh, const MSVehicle::LaneQ &best)
Computes the artificial bonus distance for roundabout lanes this additional distance reduces the sens...
Definition: MSLCHelper.cpp:39
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
const std::vector< MSLink * > & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.h:641
double getBruttoVehLenSum() const
Returns the sum of lengths of vehicles, including their minGaps, which were on the lane during the la...
Definition: MSLane.h:1031
double getLength() const
Returns the lane's length.
Definition: MSLane.h:541
int getIndex() const
Returns the lane's index.
Definition: MSLane.h:563
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:674
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:75
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:5051
double getPositionOnLane() const
Get the vehicle's position along the lane.
Definition: MSVehicle.h:372
const MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:552
const std::string & getID() const
Returns the id.
Definition: Named.h:74
A structure representing the best lanes for continuing the current route starting at 'lane'.
Definition: MSVehicle.h:811
std::vector< MSLane * > bestContinuations
Definition: MSVehicle.h:831
MSLane * lane
The described lane.
Definition: MSVehicle.h:813