Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2002-2024 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 : /****************************************************************************/
14 : /// @file MSLaneChanger.cpp
15 : /// @author Christian Roessel
16 : /// @author Daniel Krajzewicz
17 : /// @author Laura Bieker
18 : /// @author Michael Behrisch
19 : /// @author Friedemann Wesner
20 : /// @author Jakob Erdmann
21 : /// @date Fri, 01 Feb 2002
22 : ///
23 : // Performs lane changing of vehicles
24 : /****************************************************************************/
25 : #include <config.h>
26 :
27 : #include "MSLaneChanger.h"
28 : #include "MSNet.h"
29 : #include "MSLink.h"
30 : #include "MSVehicle.h"
31 : #include "MSVehicleType.h"
32 : #include "MSVehicleTransfer.h"
33 : #include "MSStop.h"
34 : #include "MSGlobals.h"
35 : #include <cassert>
36 : #include <iterator>
37 : #include <cstdlib>
38 : #include <cmath>
39 : #include <microsim/lcmodels/MSAbstractLaneChangeModel.h>
40 : #include <microsim/transportables/MSTransportableControl.h>
41 : #include <microsim/transportables/MSPModel.h>
42 : #include <utils/common/MsgHandler.h>
43 :
44 : #define OPPOSITE_OVERTAKING_SAFE_TIMEGAP 0.0
45 : #define OPPOSITE_OVERTAKING_SAFETYGAP_HEADWAY_FACTOR 0.0
46 : #define OPPOSITE_OVERTAKING_SAFETY_FACTOR 1.2
47 : // XXX maxLookAhead should be higher if all leaders are stopped and lower when they are jammed/queued
48 : #define OPPOSITE_OVERTAKING_MAX_LOOKAHEAD 150.0 // just a guess
49 : #define OPPOSITE_OVERTAKING_MAX_LOOKAHEAD_EMERGENCY 1000.0 // just a guess
50 : // this is used for finding oncoming vehicles while driving in the opposite direction
51 : #define OPPOSITE_OVERTAKING_ONCOMING_LOOKAHEAD 1000.0 // just a guess
52 : // do not attempt overtaking maneuvers that would exceed this distance
53 : #define OPPOSITE_OVERTAKING_MAX_SPACE_TO_OVERTAKE 1000.0 // just a guess
54 : #define OPPOSITE_OVERTAKING_HILLTOP_THRESHOHOLD 5 // (m)
55 :
56 : // halting time to signal yielding in deadlock
57 : #define OPPOSITE_OVERTAKING_DEADLOCK_WAIT 1 // (s)
58 :
59 : // ===========================================================================
60 : // debug defines
61 : // ===========================================================================
62 :
63 : //#define DEBUG_CONTINUE_CHANGE
64 : //#define DEBUG_CHECK_CHANGE
65 : //#define DEBUG_SURROUNDING_VEHICLES // debug getRealFollower() and getRealLeader()
66 : //#define DEBUG_CHANGE_OPPOSITE
67 : //#define DEBUG_CHANGE_OPPOSITE_OVERTAKINGTIME
68 : //#define DEBUG_CHANGE_OPPOSITE_DEADLOCK
69 : //#define DEBUG_ACTIONSTEPS
70 : //#define DEBUG_STATE
71 : //#define DEBUG_CANDIDATE
72 : //#define DEBUG_COND (vehicle->getLaneChangeModel().debugVehicle())
73 : #define DEBUG_COND (vehicle->isSelected())
74 : //#define DEBUG_COND (true)
75 :
76 :
77 :
78 : // ===========================================================================
79 : // ChangeElem member method definitions
80 : // ===========================================================================
81 867291 : MSLaneChanger::ChangeElem::ChangeElem(MSLane* _lane) :
82 867291 : lead(nullptr),
83 867291 : lane(_lane),
84 867291 : hoppedVeh(nullptr),
85 867291 : lastBlocked(nullptr),
86 867291 : firstBlocked(nullptr),
87 867291 : lastStopped(nullptr),
88 867291 : ahead(_lane->getWidth()),
89 867291 : aheadNext(_lane->getWidth(), nullptr, 0.) {
90 867291 : }
91 :
92 : void
93 1157305 : MSLaneChanger::ChangeElem::registerHop(MSVehicle* vehicle) {
94 : //std::cout << SIMTIME << " registerHop lane=" << lane->getID() << " veh=" << vehicle->getID() << "\n";
95 1157305 : lane->myTmpVehicles.insert(lane->myTmpVehicles.begin(), vehicle);
96 1157305 : dens += vehicle->getVehicleType().getLengthWithGap();
97 1157305 : hoppedVeh = vehicle;
98 1157305 : }
99 :
100 :
101 : // ===========================================================================
102 : // member method definitions
103 : // ===========================================================================
104 445548 : MSLaneChanger::MSLaneChanger(const std::vector<MSLane*>* lanes, bool allowChanging) :
105 445548 : myAllowsChanging(allowChanging),
106 445548 : myChangeToOpposite(lanes->front()->getEdge().canChangeToOpposite()) {
107 :
108 : // Fill the changer with the lane-data.
109 445548 : myChanger.reserve(lanes->size());
110 1312839 : for (std::vector<MSLane*>::const_iterator lane = lanes->begin(); lane != lanes->end(); ++lane) {
111 1734582 : myChanger.push_back(ChangeElem(*lane));
112 867291 : myChanger.back().mayChangeRight = lane != lanes->begin();
113 867291 : myChanger.back().mayChangeLeft = (lane + 1) != lanes->end();
114 867291 : if ((*lane)->isInternal()) {
115 : // avoid changing on internal sibling lane
116 283444 : if (myChanger.back().mayChangeRight && (*lane)->getLogicalPredecessorLane() == (*(lane - 1))->getLogicalPredecessorLane()) {
117 49713 : myChanger.back().mayChangeRight = false;
118 : }
119 283444 : if (myChanger.back().mayChangeLeft && (*lane)->getLogicalPredecessorLane() == (*(lane + 1))->getLogicalPredecessorLane()) {
120 49713 : myChanger.back().mayChangeLeft = false;
121 : }
122 : // avoid changing if lanes have different lengths
123 283444 : if (myChanger.back().mayChangeRight && (*lane)->getLength() != (*(lane - 1))->getLength()) {
124 : //std::cout << " cannot change right from lane=" << (*lane)->getID() << " len=" << (*lane)->getLength() << " to=" << (*(lane - 1))->getID() << " len2=" << (*(lane - 1))->getLength() << "\n";
125 13990 : myChanger.back().mayChangeRight = false;
126 : }
127 283444 : if (myChanger.back().mayChangeLeft && (*lane)->getLength() != (*(lane + 1))->getLength()) {
128 : //std::cout << " cannot change left from lane=" << (*lane)->getID() << " len=" << (*lane)->getLength() << " to=" << (*(lane + 1))->getID() << " len2=" << (*(lane + 1))->getLength() << "\n";
129 13990 : myChanger.back().mayChangeLeft = false;
130 : }
131 : }
132 : }
133 445548 : }
134 :
135 :
136 665301 : MSLaneChanger::~MSLaneChanger() {
137 665301 : }
138 :
139 :
140 : void
141 35839107 : MSLaneChanger::laneChange(SUMOTime t) {
142 : // This is what happens in one timestep. After initialization of the
143 : // changer, each vehicle will try to change. After that the changer
144 : // needs an update to prevent multiple changes of one vehicle.
145 : // Finally, the change-result has to be given back to the lanes.
146 35839107 : initChanger();
147 : try {
148 383568087 : while (vehInChanger()) {
149 311889873 : const bool haveChanged = change();
150 311889873 : updateChanger(haveChanged);
151 : }
152 35839107 : updateLanes(t);
153 0 : } catch (const ProcessError&) {
154 : // clean up locks or the gui may hang
155 0 : for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
156 0 : ce->lane->releaseVehicles();
157 : }
158 0 : throw;
159 0 : }
160 35839107 : }
161 :
162 :
163 : void
164 35839107 : MSLaneChanger::initChanger() {
165 : // Prepare myChanger with a safe state.
166 105712334 : for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
167 69873227 : ce->lead = nullptr;
168 69873227 : ce->hoppedVeh = nullptr;
169 69873227 : ce->lastBlocked = nullptr;
170 69873227 : ce->firstBlocked = nullptr;
171 69873227 : ce->lastStopped = nullptr;
172 69873227 : ce->dens = 0;
173 69873227 : ce->lane->getVehiclesSecure();
174 :
175 : //std::cout << SIMTIME << " initChanger lane=" << ce->lane->getID() << " vehicles=" << toString(ce->lane->myVehicles) << "\n";
176 : }
177 35839107 : }
178 :
179 :
180 : void
181 311889873 : MSLaneChanger::updateChanger(bool vehHasChanged) {
182 : assert(veh(myCandi) != 0);
183 :
184 : // "Push" the vehicles to the back, i.e. follower becomes vehicle,
185 : // vehicle becomes leader, and leader becomes predecessor of vehicle,
186 : // if it exists.
187 311889873 : if (!vehHasChanged) {
188 : //std::cout << SIMTIME << " updateChanger: lane=" << myCandi->lane->getID() << " has new lead=" << veh(myCandi)->getID() << "\n";
189 310914292 : myCandi->lead = veh(myCandi);
190 : }
191 :
192 311889873 : MSLane::VehCont& vehicles = myCandi->lane->myVehicles;
193 : vehicles.pop_back();
194 : //std::cout << SIMTIME << " updateChanger lane=" << myCandi->lane->getID() << " vehicles=" << toString(myCandi->lane->myVehicles) << "\n";
195 311889873 : }
196 :
197 :
198 : void
199 35839107 : MSLaneChanger::updateLanes(SUMOTime t) {
200 :
201 : // Update the lane's vehicle-container.
202 : // First: it is bad style to change other classes members, but for
203 : // this release, other attempts were too time-consuming. In a next
204 : // release we will change from this lane-centered design to a vehicle-
205 : // centered. This will solve many problems.
206 : // Second: this swap would be faster if vehicle-containers would have
207 : // been pointers, but then I had to change too much of the MSLane code.
208 105712334 : for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
209 : //std::cout << SIMTIME << " updateLanes lane=" << ce->lane->getID() << " myVehicles=" << toString(ce->lane->myVehicles) << " myTmpVehicles=" << toString(ce->lane->myTmpVehicles) << "\n";
210 69873227 : ce->lane->swapAfterLaneChange(t);
211 69873227 : ce->lane->releaseVehicles();
212 : }
213 35839107 : }
214 :
215 :
216 : MSLaneChanger::ChangerIt
217 311889873 : MSLaneChanger::findCandidate() {
218 : // Find the vehicle in myChanger with the largest position. If there
219 : // is no vehicle in myChanger (shouldn't happen) , return myChanger.end().
220 : ChangerIt max = myChanger.end();
221 : #ifdef DEBUG_CANDIDATE
222 : std::cout << SIMTIME << " findCandidate() on edge " << myChanger.begin()->lane->getEdge().getID() << std::endl;
223 : #endif
224 :
225 953364550 : for (ChangerIt ce = myChanger.begin(); ce != myChanger.end(); ++ce) {
226 560904658 : if (veh(ce) == nullptr) {
227 80570019 : continue;
228 : }
229 : #ifdef DEBUG_CANDIDATE
230 : std::cout << " lane = " << ce->lane->getID() << "\n";
231 : std::cout << " check vehicle=" << veh(ce)->getID() << " pos=" << veh(ce)->getPositionOnLane() << " lane=" << ce->lane->getID() << " isFrontOnLane=" << veh(ce)->isFrontOnLane(ce->lane) << "\n";
232 : #endif
233 560904658 : if (max == myChanger.end()) {
234 : #ifdef DEBUG_CANDIDATE
235 : std::cout << " new max vehicle=" << veh(ce)->getID() << " pos=" << veh(ce)->getPositionOnLane() << " lane=" << ce->lane->getID() << " isFrontOnLane=" << veh(ce)->isFrontOnLane(ce->lane) << "\n";
236 : #endif
237 : max = ce;
238 311889873 : continue;
239 : }
240 : assert(veh(ce) != 0);
241 : assert(veh(max) != 0);
242 498029570 : if (veh(max)->getPositionOnLane() < veh(ce)->getPositionOnLane()) {
243 : #ifdef DEBUG_CANDIDATE
244 : std::cout << " new max vehicle=" << veh(ce)->getID() << " pos=" << veh(ce)->getPositionOnLane() << " lane=" << ce->lane->getID() << " isFrontOnLane=" << veh(ce)->isFrontOnLane(ce->lane) << " oldMaxPos=" << veh(max)->getPositionOnLane() << "\n";
245 : #endif
246 : max = ce;
247 : }
248 : }
249 : assert(max != myChanger.end());
250 : assert(veh(max) != 0);
251 311889873 : return max;
252 : }
253 :
254 :
255 : bool
256 1075005702 : MSLaneChanger::mayChange(int direction) const {
257 1075005702 : if (direction == 0) {
258 : return true;
259 : }
260 998838744 : if (!myAllowsChanging) {
261 : return false;
262 : }
263 997239241 : SUMOVehicleClass svc = veh(myCandi)->getVClass();
264 997239241 : if (direction == -1) {
265 507481692 : return myCandi->mayChangeRight && (myCandi - 1)->lane->allowsVehicleClass(svc) && myCandi->lane->allowsChangingRight(svc);
266 489757549 : } else if (direction == 1) {
267 489757549 : return myCandi->mayChangeLeft && (myCandi + 1)->lane->allowsVehicleClass(svc) && myCandi->lane->allowsChangingLeft(svc);
268 : } else {
269 : return false;
270 : }
271 : }
272 :
273 :
274 : bool
275 216887278 : MSLaneChanger::change() {
276 : // Find change-candidate. If it is on an allowed lane, try to change
277 : // to the right (there is a rule in Germany that you have to change
278 : // to the right, unless you are overtaking). If change to the right
279 : // isn't possible, check if there is a possibility to overtake (on the
280 : // left.
281 : // If candidate isn't on an allowed lane, changing to an allowed has
282 : // priority.
283 :
284 : #ifdef DEBUG_ACTIONSTEPS
285 : // std::cout<< "\nCHANGE" << std::endl;
286 : #endif
287 :
288 :
289 216887278 : myCandi = findCandidate();
290 : MSVehicle* vehicle = veh(myCandi);
291 216887278 : vehicle->getLaneChangeModel().clearNeighbors();
292 :
293 216887278 : if (vehicle->getLaneChangeModel().isChangingLanes() && !vehicle->getLaneChangeModel().alreadyChanged()) {
294 529506 : return continueChange(vehicle, myCandi);
295 : }
296 216357772 : if (!myAllowsChanging || vehicle->getLaneChangeModel().alreadyChanged() || vehicle->isStoppedOnLane()) {
297 1435872 : registerUnchanged(vehicle);
298 1435872 : if (vehicle->isStoppedOnLane()) {
299 1246997 : myCandi->lastStopped = vehicle;
300 : }
301 1435872 : return false;
302 : }
303 :
304 214921900 : if (!vehicle->isActive()) {
305 : #ifdef DEBUG_ACTIONSTEPS
306 : if (DEBUG_COND) {
307 : std::cout << SIMTIME << " veh '" << vehicle->getID() << "' skips regular change checks." << std::endl;
308 : }
309 : #endif
310 : bool changed = false;
311 20828061 : const int oldstate = vehicle->getLaneChangeModel().getOwnState();
312 : // let TraCI influence the wish to change lanes during non-actionsteps
313 20828061 : checkTraCICommands(vehicle);
314 20828061 : if (oldstate != vehicle->getLaneChangeModel().getOwnState()) {
315 5 : changed = applyTraCICommands(vehicle);
316 : }
317 5 : if (!changed) {
318 20828056 : registerUnchanged(vehicle);
319 : }
320 20828061 : return changed;
321 : }
322 :
323 : // Check for changes to the opposite lane if vehicle is active
324 194093839 : std::pair<MSVehicle* const, double> leader = getRealLeader(myCandi);
325 194093839 : if (myChanger.size() == 1 || vehicle->getLaneChangeModel().isOpposite() || (!mayChange(-1) && !mayChange(1))) {
326 23316102 : if (changeOpposite(vehicle, leader, myCandi->lastStopped)) {
327 : return true;
328 : }
329 23277389 : registerUnchanged(vehicle);
330 23277389 : return false;
331 : }
332 :
333 170777737 : vehicle->updateBestLanes(); // needed?
334 577071479 : for (int i = 0; i < (int) myChanger.size(); ++i) {
335 406293742 : vehicle->adaptBestLanesOccupation(i, myChanger[i].dens);
336 : }
337 :
338 170777737 : const std::vector<MSVehicle::LaneQ>& preb = vehicle->getBestLanes();
339 : // check whether the vehicle wants and is able to change to right lane
340 : int stateRight = 0;
341 170777737 : if (mayChange(-1)) {
342 90539922 : stateRight = checkChangeWithinEdge(-1, leader, preb);
343 : // change if the vehicle wants to and is allowed to change
344 90539922 : if ((stateRight & LCA_RIGHT) != 0 && (stateRight & LCA_BLOCKED) == 0) {
345 273664 : vehicle->getLaneChangeModel().setOwnState(stateRight);
346 273664 : return startChange(vehicle, myCandi, -1);
347 : }
348 90266258 : if ((stateRight & LCA_RIGHT) != 0 && (stateRight & LCA_URGENT) != 0) {
349 2250676 : (myCandi - 1)->lastBlocked = vehicle;
350 2250676 : if ((myCandi - 1)->firstBlocked == nullptr) {
351 419140 : (myCandi - 1)->firstBlocked = vehicle;
352 : }
353 : }
354 : }
355 :
356 : // check whether the vehicle wants and is able to change to left lane
357 : int stateLeft = 0;
358 170504073 : if (mayChange(1)) {
359 100011667 : stateLeft = checkChangeWithinEdge(1, leader, preb);
360 : // change if the vehicle wants to and is allowed to change
361 100011667 : if ((stateLeft & LCA_LEFT) != 0 && (stateLeft & LCA_BLOCKED) == 0) {
362 354136 : vehicle->getLaneChangeModel().setOwnState(stateLeft);
363 354136 : return startChange(vehicle, myCandi, 1);
364 : }
365 99657531 : if ((stateLeft & LCA_LEFT) != 0 && (stateLeft & LCA_URGENT) != 0) {
366 1426166 : (myCandi + 1)->lastBlocked = vehicle;
367 1426166 : if ((myCandi + 1)->firstBlocked == nullptr) {
368 374705 : (myCandi + 1)->firstBlocked = vehicle;
369 : }
370 : }
371 : }
372 :
373 170149937 : if ((stateRight & LCA_URGENT) != 0 && (stateLeft & LCA_URGENT) != 0) {
374 : // ... wants to go to the left AND to the right
375 : // just let them go to the right lane...
376 : stateLeft = 0;
377 : }
378 170149937 : vehicle->getLaneChangeModel().setOwnState(stateRight | stateLeft);
379 :
380 : // only emergency vehicles should change to the opposite side on a
381 : // multi-lane road (or vehicles that need to stop on the opposite side)
382 170149937 : if ((vehicle->getVehicleType().getVehicleClass() == SVC_EMERGENCY
383 170145203 : || hasOppositeStop(vehicle))
384 170149992 : && changeOpposite(vehicle, leader, myCandi->lastStopped)) {
385 35 : return true;
386 : }
387 :
388 170149902 : registerUnchanged(vehicle);
389 : return false;
390 : }
391 :
392 :
393 : void
394 310351084 : MSLaneChanger::registerUnchanged(MSVehicle* vehicle) {
395 : //std::cout << SIMTIME << " registerUnchanged lane=" << myCandi->lane->getID() << " veh=" << vehicle->getID() << "\n";
396 620702168 : myCandi->lane->myTmpVehicles.insert(myCandi->lane->myTmpVehicles.begin(), veh(myCandi));
397 310351084 : myCandi->dens += vehicle->getVehicleType().getLengthWithGap();
398 310351084 : vehicle->getLaneChangeModel().unchanged();
399 310351084 : }
400 :
401 :
402 :
403 : void
404 41739800 : MSLaneChanger::checkTraCICommands(MSVehicle* vehicle) {
405 : #ifdef DEBUG_STATE
406 : const int oldstate = vehicle->getLaneChangeModel().getOwnState();
407 : #endif
408 41739800 : vehicle->getLaneChangeModel().checkTraCICommands();
409 : #ifdef DEBUG_STATE
410 : if (DEBUG_COND) {
411 : const int newstate = vehicle->getLaneChangeModel().getOwnState();
412 : std::cout << SIMTIME
413 : << " veh=" << vehicle->getID()
414 : << " oldState=" << toString((LaneChangeAction) oldstate)
415 : << " newState=" << toString((LaneChangeAction) newstate)
416 : << ((newstate & LCA_BLOCKED) != 0 ? " (blocked)" : "")
417 : << ((newstate & LCA_OVERLAPPING) != 0 ? " (overlap)" : "")
418 : << "\n";
419 : }
420 : #endif
421 41739800 : }
422 :
423 :
424 : bool
425 5 : MSLaneChanger::applyTraCICommands(MSVehicle* vehicle) {
426 : // Execute request if not blocked
427 : bool changed = false;
428 5 : const int state = vehicle->getLaneChangeModel().getOwnState();
429 5 : const int dir = (state & LCA_RIGHT) != 0 ? -1 : ((state & LCA_LEFT) != 0 ? 1 : 0);
430 5 : const bool execute = dir != 0 && ((state & LCA_BLOCKED) == 0);
431 : if (execute) {
432 : ChangerIt to = myCandi + dir;
433 5 : bool continuous = vehicle->getLaneChangeModel().startLaneChangeManeuver(myCandi->lane, to->lane, dir);
434 5 : if (continuous) {
435 0 : changed = continueChange(vehicle, myCandi);
436 : } else {
437 : // insert vehicle into target lane
438 5 : to->registerHop(vehicle);
439 : changed = true;
440 : }
441 : }
442 5 : return changed;
443 : }
444 :
445 :
446 : bool
447 627800 : MSLaneChanger::startChange(MSVehicle* vehicle, ChangerIt& from, int direction) {
448 627800 : if (vehicle->isRemoteControlled()) {
449 47 : registerUnchanged(vehicle);
450 47 : return false;
451 : }
452 : ChangerIt to = from + direction;
453 : // @todo delay entering the target lane until the vehicle intersects it
454 : // physically (considering lane width and vehicle width)
455 : //if (to->lane->getID() == "beg_1") std::cout << SIMTIME << " startChange to lane=" << to->lane->getID() << " myTmpVehiclesBefore=" << toString(to->lane->myTmpVehicles) << "\n";
456 627753 : const bool continuous = vehicle->getLaneChangeModel().startLaneChangeManeuver(from->lane, to->lane, direction);
457 627753 : if (continuous) {
458 33733 : return continueChange(vehicle, myCandi);
459 : } else {
460 594020 : to->registerHop(vehicle);
461 594020 : to->lane->requireCollisionCheck();
462 594020 : return true;
463 : }
464 : }
465 :
466 : bool
467 565871 : MSLaneChanger::continueChange(MSVehicle* vehicle, ChangerIt& from) {
468 565871 : MSAbstractLaneChangeModel& lcm = vehicle->getLaneChangeModel();
469 565871 : const int direction = lcm.isOpposite() ? -lcm.getLaneChangeDirection() : lcm.getLaneChangeDirection();
470 565871 : const bool pastMidpoint = lcm.updateCompletion(); // computes lcm.mySpeedLat as a side effect
471 565871 : const double speedLat = lcm.isOpposite() ? -lcm.getSpeedLat() : lcm.getSpeedLat();
472 565871 : vehicle->myState.myPosLat += SPEED2DIST(speedLat);
473 565871 : vehicle->myCachedPosition = Position::INVALID;
474 : //std::cout << SIMTIME << " veh=" << vehicle->getID() << " dir=" << direction << " pm=" << pastMidpoint << " speedLat=" << speedLat << " posLat=" << vehicle->myState.myPosLat << "\n";
475 565871 : if (pastMidpoint) {
476 36149 : MSLane* source = myCandi->lane;
477 36149 : MSLane* target = source->getParallelLane(direction);
478 36149 : vehicle->myState.myPosLat -= direction * 0.5 * (source->getWidth() + target->getWidth());
479 36149 : lcm.primaryLaneChanged(source, target, direction);
480 36149 : if (&source->getEdge() == &target->getEdge()) {
481 : ChangerIt to = from + direction;
482 33558 : to->registerHop(vehicle);
483 : }
484 : target->requireCollisionCheck();
485 : } else {
486 529722 : from->registerHop(vehicle);
487 529722 : from->lane->requireCollisionCheck();
488 : }
489 565871 : if (!lcm.isChangingLanes()) {
490 33101 : vehicle->myState.myPosLat = 0;
491 33101 : lcm.endLaneChangeManeuver();
492 : }
493 565871 : lcm.updateShadowLane();
494 565871 : if (lcm.getShadowLane() != nullptr && &lcm.getShadowLane()->getEdge() == &vehicle->getLane()->getEdge()) {
495 : // set as hoppedVeh on the shadow lane so it is found as leader on both lanes
496 401375 : myChanger[lcm.getShadowLane()->getIndex()].hoppedVeh = vehicle;
497 : lcm.getShadowLane()->requireCollisionCheck();
498 : }
499 565871 : vehicle->myAngle = vehicle->computeAngle();
500 565871 : if (lcm.isOpposite()) {
501 19238 : vehicle->myAngle += M_PI;
502 : }
503 :
504 : #ifdef DEBUG_CONTINUE_CHANGE
505 : if (DEBUG_COND) {
506 : std::cout << SIMTIME
507 : << " continueChange veh=" << vehicle->getID()
508 : << " from=" << Named::getIDSecure(from->lane)
509 : << " dir=" << direction
510 : << " speedLat=" << speedLat
511 : << " pastMidpoint=" << pastMidpoint
512 : << " posLat=" << vehicle->getLateralPositionOnLane()
513 : << " completion=" << lcm.getLaneChangeCompletion()
514 : << " shadowLane=" << Named::getIDSecure(lcm.getShadowLane())
515 : //<< " shadowHopped=" << Named::getIDSecure(shadow->lane)
516 : << "\n";
517 : }
518 : #endif
519 565871 : return pastMidpoint && lcm.getShadowLane() == nullptr;
520 : }
521 :
522 :
523 : std::pair<MSVehicle* const, double>
524 384645428 : MSLaneChanger::getRealLeader(const ChangerIt& target) const {
525 : assert(veh(myCandi) != 0);
526 : MSVehicle* vehicle = veh(myCandi);
527 : #ifdef DEBUG_SURROUNDING_VEHICLES
528 : if (DEBUG_COND) {
529 : std::cout << SIMTIME << " veh '" << vehicle->getID() << "' looks for leader on lc-target lane '" << target->lane->getID() << "'." << std::endl;
530 : }
531 : #endif
532 : // get the leading vehicle on the lane to change to
533 384645428 : MSVehicle* neighLead = target->lead;
534 :
535 : #ifdef DEBUG_SURROUNDING_VEHICLES
536 : if (DEBUG_COND) {
537 : if (neighLead != 0) {
538 : std::cout << "Considering '" << neighLead->getID() << "' at position " << neighLead->getPositionOnLane() << std::endl;
539 : }
540 : }
541 : #endif
542 :
543 : // check whether the hopped vehicle became the leader
544 384645428 : if (target->hoppedVeh != nullptr) {
545 6163351 : double hoppedPos = target->hoppedVeh->getPositionOnLane();
546 : #ifdef DEBUG_SURROUNDING_VEHICLES
547 : if (DEBUG_COND) {
548 : std::cout << "Considering hopped vehicle '" << target->hoppedVeh->getID() << "' at position " << hoppedPos << std::endl;
549 : }
550 : #endif
551 6163351 : if (hoppedPos > vehicle->getPositionOnLane() && (neighLead == nullptr || neighLead->getPositionOnLane() > hoppedPos)) {
552 937005 : neighLead = target->hoppedVeh;
553 : //if (vehicle->getID() == "flow.21") std::cout << SIMTIME << " neighLead=" << Named::getIDSecure(neighLead) << " (422)\n";
554 : }
555 : }
556 : // extra check for shared lane
557 384645428 : const bool checkBidi = target->lane->getBidiLane() != nullptr && target->lane->getBidiLane()->getVehicleNumberWithPartials() > 0;
558 384645428 : if (neighLead == nullptr || checkBidi) {
559 : #ifdef DEBUG_SURROUNDING_VEHICLES
560 : if (DEBUG_COND) {
561 : std::cout << "Looking for leader on consecutive lanes." << std::endl;
562 : }
563 : #endif
564 : // There's no leader on the target lane. Look for leaders on consecutive lanes.
565 : // (there might also be partial leaders due to continuous lane changing or bidiLane)
566 59123997 : MSLane* targetLane = target->lane;
567 : const double egoBack = vehicle->getBackPositionOnLane();
568 : double leaderBack = targetLane->getLength();
569 59123997 : if (neighLead != nullptr) {
570 236760 : leaderBack = neighLead->getBackPositionOnLane(targetLane);
571 : }
572 63768667 : for (MSVehicle* pl : targetLane->myPartialVehicles) {
573 4644670 : double plBack = pl->getBackPositionOnLane(targetLane);
574 4644670 : if (pl->isBidiOn(targetLane)) {
575 427167 : plBack -= pl->getVehicleType().getLengthWithGap();
576 : }
577 4644670 : const double plPos = plBack + pl->getVehicleType().getLength();
578 : #ifdef DEBUG_SURROUNDING_VEHICLES
579 : if (DEBUG_COND) {
580 : std::cout << " partial=" << pl->getID() << " plBack=" << plBack << " plPos=" << plPos << " leaderBack=" << leaderBack << " egoBack=" << egoBack << "\n";
581 : }
582 : #endif
583 4644670 : if (plBack < leaderBack && plPos + pl->getVehicleType().getMinGap() >= egoBack) {
584 : neighLead = pl;
585 : leaderBack = plBack;
586 : }
587 : }
588 59123997 : if (neighLead != nullptr) {
589 : #ifdef DEBUG_SURROUNDING_VEHICLES
590 : if (DEBUG_COND) {
591 : std::cout << " found leader=" << neighLead->getID() << " (partial)\n";
592 : }
593 : #endif
594 3908739 : const double gap = leaderBack - vehicle->getPositionOnLane() - vehicle->getVehicleType().getMinGap();
595 3908739 : return std::pair<MSVehicle*, double>(neighLead, gap);
596 : }
597 55215258 : double seen = myCandi->lane->getLength() - vehicle->getPositionOnLane();
598 55215258 : double speed = vehicle->getSpeed();
599 55215258 : double dist = vehicle->getCarFollowModel().brakeGap(speed) + vehicle->getVehicleType().getMinGap();
600 55215258 : if (target->lane->getBidiLane() != nullptr) {
601 371013 : dist += target->lane->getBidiLane()->getMaximumBrakeDist();
602 : }
603 : // always check for link leaders while on an internal lane
604 55215258 : if (seen > dist && !myCandi->lane->isInternal()) {
605 : #ifdef DEBUG_SURROUNDING_VEHICLES
606 : if (DEBUG_COND) {
607 : std::cout << " found no leader within dist=" << dist << "\n";
608 : }
609 : #endif
610 28677016 : return std::pair<MSVehicle* const, double>(static_cast<MSVehicle*>(nullptr), -1);
611 : }
612 26538242 : const std::vector<MSLane*>& bestLaneConts = vehicle->getBestLanesContinuation(targetLane);
613 :
614 26538242 : std::pair<MSVehicle* const, double> result = target->lane->getLeaderOnConsecutive(dist, seen, speed, *vehicle, bestLaneConts);
615 : #ifdef DEBUG_SURROUNDING_VEHICLES
616 : if (DEBUG_COND) {
617 : std::cout << " found consecutiveLeader=" << Named::getIDSecure(result.first) << "\n";
618 : }
619 : #endif
620 26538242 : return result;
621 : } else {
622 : #ifdef DEBUG_SURROUNDING_VEHICLES
623 : if (DEBUG_COND) {
624 : std::cout << " found leader=" << neighLead->getID() << "\n";
625 : }
626 : #endif
627 325521431 : return std::pair<MSVehicle* const, double>(neighLead, neighLead->getBackPositionOnLane(target->lane) - vehicle->getPositionOnLane() - vehicle->getVehicleType().getMinGap());
628 : }
629 : }
630 :
631 :
632 : std::pair<MSVehicle* const, double>
633 381103178 : MSLaneChanger::getRealFollower(const ChangerIt& target) const {
634 : assert(veh(myCandi) != 0);
635 : MSVehicle* vehicle = veh(myCandi);
636 : #ifdef DEBUG_SURROUNDING_VEHICLES
637 : if (DEBUG_COND) {
638 : std::cout << SIMTIME << " veh '" << vehicle->getID() << "' looks for follower on lc-target lane '" << target->lane->getID() << "'." << std::endl;
639 : }
640 : #endif
641 381103178 : const double candiPos = vehicle->getPositionOnLane();
642 : MSVehicle* neighFollow = nullptr;
643 381103178 : if (target != myCandi) {
644 : neighFollow = veh(target);
645 : } else {
646 : // veh(target) would return the ego vehicle so we use its predecessor instead
647 190551589 : if (target->lane->myVehicles.size() > 1) {
648 169816218 : neighFollow = target->lane->myVehicles[target->lane->myVehicles.size() - 2];
649 : }
650 : }
651 :
652 : #ifdef DEBUG_SURROUNDING_VEHICLES
653 : if (DEBUG_COND) {
654 : if (neighFollow != 0) {
655 : std::cout << "veh(target) returns '" << neighFollow->getID() << "' at position " << neighFollow->getPositionOnLane() << std::endl;
656 : } else {
657 : std::cout << "veh(target) returns none." << std::endl;
658 : }
659 : }
660 : #endif
661 :
662 :
663 : #ifdef DEBUG_SURROUNDING_VEHICLES
664 : if (DEBUG_COND) {
665 : if (getCloserFollower(candiPos, neighFollow, target->hoppedVeh) != neighFollow) {
666 : std::cout << "Hopped vehicle '" << target->hoppedVeh->getID() << "' at position " << target->hoppedVeh->getPositionOnLane() << " is closer." << std::endl;
667 : }
668 : }
669 : #endif
670 :
671 : // check whether the hopped vehicle became the follower
672 381103178 : neighFollow = getCloserFollower(candiPos, neighFollow, target->hoppedVeh);
673 :
674 :
675 : #ifdef DEBUG_SURROUNDING_VEHICLES
676 : if (DEBUG_COND) {
677 : MSVehicle* partialBehind = getCloserFollower(candiPos, neighFollow, target->lane->getPartialBehind(vehicle));
678 : if (partialBehind != 0 && partialBehind != neighFollow) {
679 : std::cout << "'Partial behind'-vehicle '" << target->lane->getPartialBehind(vehicle)->getID() << "' at position " << partialBehind->getPositionOnLane() << " is closer." << std::endl;
680 : }
681 : }
682 : #endif
683 : // or a follower which is partially lapping into the target lane
684 381103178 : neighFollow = getCloserFollower(candiPos, neighFollow, target->lane->getPartialBehind(vehicle));
685 :
686 381103178 : if (neighFollow == nullptr) {
687 52162031 : CLeaderDist consecutiveFollower = target->lane->getFollowersOnConsecutive(vehicle, vehicle->getBackPositionOnLane(), true)[0];
688 : #ifdef DEBUG_SURROUNDING_VEHICLES
689 : if (DEBUG_COND) {
690 : if (consecutiveFollower.first == 0) {
691 : std::cout << "no follower found." << std::endl;
692 : } else {
693 : std::cout << "found follower '" << consecutiveFollower.first->getID() << "' on consecutive lanes." << std::endl;
694 : }
695 : }
696 : #endif
697 52162031 : return std::make_pair(const_cast<MSVehicle*>(consecutiveFollower.first), consecutiveFollower.second);
698 : } else {
699 : #ifdef DEBUG_SURROUNDING_VEHICLES
700 : if (DEBUG_COND) {
701 : std::cout << "found follower '" << neighFollow->getID() << "'." << std::endl;
702 : }
703 : #endif
704 : return std::pair<MSVehicle* const, double>(neighFollow,
705 328941147 : vehicle->getPositionOnLane() - vehicle->getVehicleType().getLength() - neighFollow->getPositionOnLane() - neighFollow->getVehicleType().getMinGap());
706 : }
707 : }
708 :
709 :
710 : MSVehicle*
711 762206356 : MSLaneChanger::getCloserFollower(const double maxPos, MSVehicle* follow1, MSVehicle* follow2) {
712 762206356 : if (follow1 == nullptr || follow1->getPositionOnLane() > maxPos) {
713 104639648 : return follow2;
714 657566708 : } else if (follow2 == nullptr || follow2->getPositionOnLane() > maxPos) {
715 656047836 : return follow1;
716 : } else {
717 1518872 : if (follow1->getPositionOnLane() > follow2->getPositionOnLane()) {
718 : return follow1;
719 : } else {
720 : return follow2;
721 : }
722 : }
723 : }
724 :
725 : int
726 190551589 : MSLaneChanger::checkChangeWithinEdge(
727 : int laneOffset,
728 : const std::pair<MSVehicle* const, double>& leader,
729 : const std::vector<MSVehicle::LaneQ>& preb) const {
730 :
731 190551589 : std::pair<MSVehicle*, double> follower = getRealFollower(myCandi);
732 190551589 : std::pair<MSVehicle* const, double> neighLead = getRealLeader(myCandi + laneOffset);
733 190551589 : std::pair<MSVehicle*, double> neighFollow = getRealFollower(myCandi + laneOffset);
734 190551589 : if (neighLead.first != nullptr && neighLead.first == neighFollow.first) {
735 : // vehicles should not be leader and follower at the same time to avoid
736 : // contradictory behavior
737 : neighFollow.first = 0;
738 : }
739 : ChangerIt target = myCandi + laneOffset;
740 190551589 : return checkChange(laneOffset, target->lane, leader, follower, neighLead, neighFollow, preb);
741 : }
742 :
743 : int
744 191005197 : MSLaneChanger::checkChange(
745 : int laneOffset,
746 : const MSLane* targetLane,
747 : const std::pair<MSVehicle* const, double>& leader,
748 : const std::pair<MSVehicle* const, double>& follower,
749 : const std::pair<MSVehicle* const, double>& neighLead,
750 : const std::pair<MSVehicle* const, double>& neighFollow,
751 : const std::vector<MSVehicle::LaneQ>& preb) const {
752 :
753 : MSVehicle* vehicle = veh(myCandi);
754 :
755 : #ifdef DEBUG_CHECK_CHANGE
756 : if (DEBUG_COND) {
757 : std::cout
758 : << "\n" << SIMTIME << " checkChange() for vehicle '" << vehicle->getID() << "'"
759 : << std::endl;
760 : }
761 : #endif
762 :
763 : int blocked = 0;
764 191005197 : int blockedByLeader = (laneOffset == -1 ? LCA_BLOCKED_BY_RIGHT_LEADER : LCA_BLOCKED_BY_LEFT_LEADER);
765 : int blockedByFollower = (laneOffset == -1 ? LCA_BLOCKED_BY_RIGHT_FOLLOWER : LCA_BLOCKED_BY_LEFT_FOLLOWER);
766 : // overlap
767 191005197 : if (neighFollow.first != nullptr && neighFollow.second < 0) {
768 54234039 : blocked |= (blockedByFollower | LCA_OVERLAPPING);
769 :
770 : // Debug (Leo)
771 : #ifdef DEBUG_CHECK_CHANGE
772 : if (DEBUG_COND) {
773 : std::cout << SIMTIME
774 : << " overlapping with follower..."
775 : << std::endl;
776 : }
777 : #endif
778 :
779 : }
780 191005197 : if (neighLead.first != nullptr && neighLead.second < 0) {
781 55151894 : blocked |= (blockedByLeader | LCA_OVERLAPPING);
782 :
783 : #ifdef DEBUG_CHECK_CHANGE
784 : if (DEBUG_COND) {
785 : std::cout << SIMTIME
786 : << " overlapping with leader..."
787 : << std::endl;
788 : }
789 : #endif
790 :
791 : }
792 191005197 : double secureFrontGap = MSAbstractLaneChangeModel::NO_NEIGHBOR;
793 : double secureBackGap = MSAbstractLaneChangeModel::NO_NEIGHBOR;
794 : double secureOrigFrontGap = MSAbstractLaneChangeModel::NO_NEIGHBOR;
795 :
796 191005197 : const double tauRemainder = vehicle->getActionStepLength() == DELTA_T ? 0 : MAX2(vehicle->getCarFollowModel().getHeadwayTime() - TS, 0.);
797 : // safe back gap
798 191005197 : if ((blocked & blockedByFollower) == 0 && neighFollow.first != nullptr) {
799 : // Calculate secure gap conservatively with vNextFollower / vNextLeader as
800 : // extrapolated speeds after the driver's expected reaction time (tau).
801 : // NOTE: there exists a possible source for collisions if the follower and the leader
802 : // have desynchronized action steps as the extrapolated speeds can be exceeded in this case
803 :
804 : // Expected reaction time (tau) for the follower-vehicle.
805 : // (subtracted TS since at this point the vehicles' states are already updated)
806 111462788 : const double vNextFollower = neighFollow.first->getSpeed() + MAX2(0., tauRemainder * neighFollow.first->getAcceleration());
807 111462788 : const double vNextLeader = vehicle->getSpeed() + MIN2(0., tauRemainder * vehicle->getAcceleration());
808 : // !!! eigentlich: vsafe braucht die Max. Geschwindigkeit beider Spuren
809 111462788 : secureBackGap = neighFollow.first->getCarFollowModel().getSecureGap(neighFollow.first, vehicle, vNextFollower,
810 : vNextLeader, vehicle->getCarFollowModel().getMaxDecel());
811 : #ifdef DEBUG_CHECK_CHANGE
812 : if (DEBUG_COND) {
813 : std::cout << SIMTIME
814 : << " follower=" << neighFollow.first->getID()
815 : << " backGap=" << neighFollow.second
816 : << " vNextFollower=" << vNextFollower
817 : << " vNextEgo=" << vNextLeader
818 : << " secureGap=" << secureBackGap
819 : << " safetyFactor=" << vehicle->getLaneChangeModel().getSafetyFactor()
820 : << " blocked=" << (neighFollow.second < secureBackGap * vehicle->getLaneChangeModel().getSafetyFactor())
821 : << "\n";
822 : }
823 : #endif
824 111462788 : if (neighFollow.second < secureBackGap * vehicle->getLaneChangeModel().getSafetyFactor()) {
825 66284622 : if (vehicle->getLaneChangeModel().isOpposite()
826 66284622 : && neighFollow.first->getLaneChangeModel().getLastLaneChangeOffset() == laneOffset) {
827 : // during opposite direction driving, the vehicle are handled in
828 : // downstream rather than upstream order, the neighFollower may have
829 : // been the actual follower in this simulation step and should not
830 : // block changing in this case
831 : #ifdef DEBUG_CHECK_CHANGE
832 : if (DEBUG_COND) {
833 : std::cout << " ignoring opposite follower who changed in this step\n";
834 : }
835 : #endif
836 : } else {
837 66284537 : blocked |= blockedByFollower;
838 : }
839 : }
840 : }
841 :
842 : // safe front gap
843 191005197 : if ((blocked & blockedByLeader) == 0 && neighLead.first != nullptr) {
844 : // Calculate secure gap conservatively with vNextFollower / vNextLeader as
845 : // extrapolated speeds after the driver's expected reaction time (tau).
846 : // NOTE: there exists a possible source for collisions if the follower and the leader
847 : // have desynchronized action steps as the extrapolated speeds can be exceeded in this case
848 :
849 : // Expected reaction time (tau) for the follower-vehicle.
850 : // (subtracted TS since at this point the vehicles' states are already updated)
851 110281339 : const double vNextFollower = vehicle->getSpeed() + MAX2(0., tauRemainder * vehicle->getAcceleration());
852 218791997 : const double vNextLeader = neighLead.first->getSpeed() + MIN2(0., tauRemainder * neighLead.first->getAcceleration());
853 : // !!! eigentlich: vsafe braucht die Max. Geschwindigkeit beider Spuren
854 110281339 : secureFrontGap = vehicle->getCarFollowModel().getSecureGap(vehicle, neighLead.first, vNextFollower,
855 110281339 : vNextLeader, neighLead.first->getCarFollowModel().getMaxDecel());
856 : #ifdef DEBUG_CHECK_CHANGE
857 : if (DEBUG_COND) {
858 : std::cout << SIMTIME
859 : << " leader=" << neighLead.first->getID()
860 : << " frontGap=" << neighLead.second
861 : << " vNextEgo=" << vNextFollower
862 : << " vNextLeader=" << vNextLeader
863 : << " secureGap=" << secureFrontGap
864 : << " safetyFactor=" << vehicle->getLaneChangeModel().getSafetyFactor()
865 : << " blocked=" << (neighLead.second < secureFrontGap * vehicle->getLaneChangeModel().getSafetyFactor())
866 : << "\n";
867 : }
868 : #endif
869 110281339 : if (neighLead.second < secureFrontGap * vehicle->getLaneChangeModel().getSafetyFactor()) {
870 59941999 : blocked |= blockedByLeader;
871 : }
872 : }
873 135853303 : if (blocked == 0 && targetLane->hasPedestrians()) {
874 99686 : PersonDist nextLeader = targetLane->nextBlocking(vehicle->getBackPositionOnLane(),
875 49843 : vehicle->getRightSideOnLane(), vehicle->getRightSideOnLane() + vehicle->getVehicleType().getWidth(),
876 49843 : ceil(vehicle->getSpeed() / vehicle->getCarFollowModel().getMaxDecel()));
877 49843 : if (nextLeader.first != 0) {
878 2715 : const double brakeGap = vehicle->getCarFollowModel().brakeGap(vehicle->getSpeed());
879 : // returned gap value is relative to backPosition
880 2715 : const double gap = nextLeader.second - vehicle->getVehicleType().getLengthWithGap();
881 : #ifdef DEBUG_CHECK_CHANGE
882 : if (DEBUG_COND) {
883 : std::cout << SIMTIME << " pedestrian on road " + leader.first->getID() << " gap=" << gap << " brakeGap=" << brakeGap << "\n";
884 : }
885 : #endif
886 2715 : if (brakeGap > gap) {
887 2227 : blocked |= blockedByLeader;
888 : #ifdef DEBUG_CHECK_CHANGE
889 : if (DEBUG_COND) {
890 : std::cout << SIMTIME << " blocked by pedestrian " + leader.first->getID() << "\n";
891 : }
892 : #endif
893 : }
894 : }
895 : }
896 :
897 191005197 : if (leader.first != nullptr) {
898 177776260 : secureOrigFrontGap = vehicle->getCarFollowModel().getSecureGap(vehicle, leader.first, vehicle->getSpeed(), leader.first->getSpeed(), leader.first->getCarFollowModel().getMaxDecel());
899 : }
900 :
901 191005197 : MSAbstractLaneChangeModel::MSLCMessager msg(leader.first, neighLead.first, neighFollow.first);
902 191005197 : int state = blocked | vehicle->getLaneChangeModel().wantsChange(
903 191005197 : laneOffset, msg, blocked, leader, follower, neighLead, neighFollow, *targetLane, preb, &(myCandi->lastBlocked), &(myCandi->firstBlocked));
904 :
905 191005197 : if (blocked == 0 && (state & LCA_WANTS_LANECHANGE) != 0 && neighLead.first != nullptr) {
906 : // do a more careful (but expensive) check to ensure that a
907 : // safety-critical leader is not being overlooked
908 : // while changing on an intersection, it is not sufficient to abort the
909 : // search with a leader on the current lane because all linkLeaders must
910 : // be considered as well
911 524006 : const double seen = myCandi->lane->getLength() - vehicle->getPositionOnLane();
912 524006 : const double speed = vehicle->getSpeed();
913 524006 : const double dist = vehicle->getCarFollowModel().brakeGap(speed) + vehicle->getVehicleType().getMinGap();
914 524006 : if (seen < dist || myCandi->lane->isInternal()) {
915 84434 : std::pair<MSVehicle* const, double> neighLead2 = targetLane->getCriticalLeader(dist, seen, speed, *vehicle);
916 84434 : if (neighLead2.first != nullptr && neighLead2.first != neighLead.first) {
917 12066 : const double secureGap = vehicle->getCarFollowModel().getSecureGap(vehicle, neighLead2.first, vehicle->getSpeed(),
918 12066 : neighLead2.first->getSpeed(), neighLead2.first->getCarFollowModel().getMaxDecel());
919 12066 : const double secureGap2 = secureGap * vehicle->getLaneChangeModel().getSafetyFactor();
920 : #ifdef DEBUG_SURROUNDING_VEHICLES
921 : if (DEBUG_COND) {
922 : std::cout << SIMTIME << " found critical leader=" << neighLead2.first->getID()
923 : << " gap=" << neighLead2.second << " secGap=" << secureGap << " secGap2=" << secureGap2 << "\n";
924 : }
925 : #endif
926 12066 : if (neighLead2.second < secureGap2) {
927 417 : state |= blockedByLeader;
928 : }
929 : }
930 : }
931 : }
932 38851669 : if (blocked == 0 && (state & LCA_WANTS_LANECHANGE)) {
933 : // ensure that merging is safe for any upcoming zipper links after changing
934 724710 : if (vehicle->unsafeLinkAhead(targetLane)) {
935 744 : state |= blockedByLeader;
936 : }
937 : }
938 :
939 191005197 : if ((state & LCA_BLOCKED) == 0 && (state & LCA_WANTS_LANECHANGE) != 0 && MSGlobals::gLaneChangeDuration > DELTA_T) {
940 : // Ensure that a continuous lane change manoeuvre can be completed before the next turning movement.
941 : // Assume lateral position == 0. (If this should change in the future add + laneOffset*vehicle->getLateralPositionOnLane() to distToNeighLane)
942 93257 : const double distToNeighLane = 0.5 * (vehicle->getLane()->getWidth() + targetLane->getWidth());
943 : // Extrapolate the LC duration if operating with speed dependent lateral speed.
944 93257 : const MSAbstractLaneChangeModel& lcm = vehicle->getLaneChangeModel();
945 93257 : const double assumedDecel = lcm.getAssumedDecelForLaneChangeDuration();
946 93257 : const double estimatedLCDuration = lcm.estimateLCDuration(vehicle->getSpeed(), distToNeighLane, assumedDecel, (state & LCA_URGENT) != 0);
947 93257 : if (estimatedLCDuration == -1) {
948 : // Can't guarantee that LC will succeed if vehicle is braking -> assert(lcm.myMaxSpeedLatStanding==0)
949 : #ifdef DEBUG_CHECK_CHANGE
950 : if (DEBUG_COND) {
951 : std::cout << SIMTIME << " checkChange() too slow to guarantee completion of continuous lane change."
952 : << "\nestimatedLCDuration=" << estimatedLCDuration
953 : << "\ndistToNeighLane=" << distToNeighLane
954 : << std::endl;
955 : }
956 : #endif
957 45940 : state |= LCA_INSUFFICIENT_SPEED;
958 : } else {
959 : // Compute covered distance, when braking for the whole lc duration
960 47317 : const double decel = vehicle->getCarFollowModel().getMaxDecel() * estimatedLCDuration;
961 : const double avgSpeed = 0.5 * (
962 47317 : MAX2(0., vehicle->getSpeed() - ACCEL2SPEED(vehicle->getCarFollowModel().getMaxDecel())) +
963 47317 : MAX2(0., vehicle->getSpeed() - decel));
964 : // Distance required for lane change.
965 47317 : const double space2change = avgSpeed * estimatedLCDuration;
966 : // Available distance for LC maneuver (distance till next turn)
967 47317 : double seen = myCandi->lane->getLength() - vehicle->getPositionOnLane();
968 : #ifdef DEBUG_CHECK_CHANGE
969 : if (DEBUG_COND) {
970 : std::cout << SIMTIME << " checkChange() checking continuous lane change..."
971 : << "\ndistToNeighLane=" << distToNeighLane
972 : << " estimatedLCDuration=" << estimatedLCDuration
973 : << " space2change=" << space2change
974 : << " avgSpeed=" << avgSpeed
975 : << std::endl;
976 : }
977 : #endif
978 :
979 : // for finding turns it doesn't matter whether we look along the current lane or the target lane
980 47317 : const std::vector<MSLane*>& bestLaneConts = vehicle->getBestLanesContinuation();
981 : int view = 1;
982 47317 : const MSLane* nextLane = vehicle->getLane();
983 47317 : std::vector<MSLink*>::const_iterator link = MSLane::succLinkSec(*vehicle, view, *nextLane, bestLaneConts);
984 51265 : while (!nextLane->isLinkEnd(link) && seen <= space2change) {
985 3964 : if ((*link)->getDirection() == LinkDirection::LEFT || (*link)->getDirection() == LinkDirection::RIGHT
986 : // the lanes after an internal junction are on different
987 : // edges and do not allow lane-changing
988 7928 : || (nextLane->getEdge().isInternal() && (*link)->getViaLaneOrLane()->getEdge().isInternal())
989 : ) {
990 16 : state |= LCA_INSUFFICIENT_SPACE;
991 16 : break;
992 : }
993 3948 : if ((*link)->getViaLane() == nullptr) {
994 3932 : view++;
995 : }
996 : nextLane = (*link)->getViaLaneOrLane();
997 3948 : seen += nextLane->getLength();
998 : // get the next link used
999 3948 : link = MSLane::succLinkSec(*vehicle, view, *nextLane, bestLaneConts);
1000 : }
1001 : #ifdef DEBUG_CHECK_CHANGE
1002 : if (DEBUG_COND) {
1003 : std::cout << " available distance=" << seen << std::endl;
1004 : }
1005 : #endif
1006 47317 : if (nextLane->isLinkEnd(link) && seen < space2change) {
1007 : #ifdef DEBUG_CHECK_CHANGE
1008 : if (DEBUG_COND) {
1009 : std::cout << SIMTIME << " checkChange insufficientSpace: seen=" << seen << " space2change=" << space2change << "\n";
1010 : }
1011 : #endif
1012 10872 : state |= LCA_INSUFFICIENT_SPACE;
1013 : }
1014 :
1015 47317 : if ((state & LCA_BLOCKED) == 0) {
1016 : // check for dangerous leaders in case the target lane changes laterally between
1017 : // now and the lane-changing midpoint
1018 36429 : const double speed = vehicle->getSpeed();
1019 36429 : seen = myCandi->lane->getLength() - vehicle->getPositionOnLane();
1020 36429 : nextLane = vehicle->getLane();
1021 : view = 1;
1022 36429 : const double dist = vehicle->getCarFollowModel().brakeGap(speed) + vehicle->getVehicleType().getMinGap();
1023 36429 : std::vector<MSLink*>::const_iterator nextLink = MSLane::succLinkSec(*vehicle, view, *nextLane, bestLaneConts);
1024 40293 : while (!nextLane->isLinkEnd(nextLink) && seen <= space2change && seen <= dist) {
1025 3928 : nextLane = (*nextLink)->getViaLaneOrLane();
1026 3928 : const MSLane* const parallelLane = nextLane->getParallelLane(laneOffset);
1027 3928 : if (parallelLane == nullptr) {
1028 0 : state |= LCA_INSUFFICIENT_SPACE;
1029 0 : break;
1030 : } else {
1031 3928 : std::pair<MSVehicle* const, double> neighLead2 = parallelLane->getLeader(vehicle, -seen, std::vector<MSLane*>());
1032 2231 : if (neighLead2.first != nullptr && neighLead2.first != neighLead.first
1033 4854 : && (neighLead2.second < vehicle->getCarFollowModel().getSecureGap(vehicle, neighLead2.first,
1034 463 : vehicle->getSpeed(), neighLead2.first->getSpeed(), neighLead2.first->getCarFollowModel().getMaxDecel()))) {
1035 64 : state |= blockedByLeader;
1036 64 : break;
1037 : }
1038 : }
1039 3864 : if ((*nextLink)->getViaLane() == nullptr) {
1040 3856 : view++;
1041 : }
1042 3864 : seen += nextLane->getLength();
1043 : // get the next link used
1044 3864 : nextLink = MSLane::succLinkSec(*vehicle, view, *nextLane, bestLaneConts);
1045 : }
1046 : }
1047 : }
1048 : }
1049 : const int oldstate = state;
1050 : // let TraCI influence the wish to change lanes and the security to take
1051 191005197 : state = vehicle->influenceChangeDecision(state);
1052 191005197 : blocked = state & LCA_BLOCKED;
1053 : #ifdef DEBUG_CHECK_CHANGE
1054 : if (DEBUG_COND) {
1055 : std::cout << SIMTIME
1056 : << " veh=" << vehicle->getID()
1057 : << " oldState=" << toString((LaneChangeAction)oldstate)
1058 : << " newState=" << toString((LaneChangeAction)state)
1059 : << ((blocked & LCA_BLOCKED) ? " (blocked)" : "")
1060 : << ((blocked & LCA_OVERLAPPING) ? " (overlap)" : "")
1061 : << "\n";
1062 : }
1063 : #endif
1064 :
1065 191005197 : if (state & LCA_WANTS_LANECHANGE && blocked == 0) {
1066 666590 : blocked = vehicle->getLaneChangeModel().checkChangeBeforeCommitting(vehicle, state);
1067 666590 : state |= blocked;
1068 : }
1069 191005197 : vehicle->getLaneChangeModel().saveLCState(laneOffset, oldstate, state);
1070 191005197 : if (blocked == 0 && (state & LCA_WANTS_LANECHANGE)) {
1071 : // this lane change will be executed, save gaps
1072 666590 : vehicle->getLaneChangeModel().setFollowerGaps(neighFollow, secureBackGap);
1073 666590 : vehicle->getLaneChangeModel().setLeaderGaps(neighLead, secureFrontGap);
1074 666590 : vehicle->getLaneChangeModel().setOrigLeaderGaps(leader, secureOrigFrontGap);
1075 : }
1076 191005197 : if (laneOffset != 0) {
1077 191005197 : vehicle->getLaneChangeModel().saveNeighbors(laneOffset, neighFollow, neighLead);
1078 : }
1079 191005197 : return state;
1080 : }
1081 :
1082 : bool
1083 251449761 : MSLaneChanger::hasOppositeStop(MSVehicle* vehicle) {
1084 251449761 : if (vehicle->hasStops()) {
1085 3023593 : const MSStop& stop = vehicle->getNextStop();
1086 3023593 : if (stop.isOpposite && vehicle->nextStopDist() < OPPOSITE_OVERTAKING_MAX_LOOKAHEAD) {
1087 : return true;
1088 : }
1089 : }
1090 : return false;
1091 : }
1092 :
1093 :
1094 : bool
1095 1426 : MSLaneChanger::checkOppositeStop(MSVehicle* vehicle, const MSLane* oncomingLane, const MSLane* opposite, std::pair<MSVehicle*, double> leader) {
1096 1426 : const bool isOpposite = vehicle->getLaneChangeModel().isOpposite();
1097 1426 : double vMax = vehicle->getLane()->getVehicleMaxSpeed(vehicle);
1098 : std::pair<MSVehicle*, double> neighLead(nullptr, -1);
1099 1426 : std::pair<MSVehicle*, double> oncoming(nullptr, -1);
1100 1426 : const std::vector<MSVehicle::LaneQ> preb = getBestLanesOpposite(vehicle, vehicle->getNextStop().lane, -1);
1101 1426 : const int laneIndex = vehicle->getLaneChangeModel().getNormalizedLaneIndex();
1102 1426 : const int bestOffset = preb[laneIndex].bestLaneOffset;
1103 : //std::cout << SIMTIME << " veh=" << vehicle->getID() << " laneIndex=" << laneIndex << " bestOffset=" << bestOffset << " target=" << target->getID() << "\n";
1104 :
1105 : // compute safety constraints (assume vehicle is safe once stop is reached)
1106 : const double spaceToStop = vehicle->nextStopDist();
1107 1426 : const double timeToStopForward = spaceToStop / MAX2(vehicle->getSpeed(), vehicle->getCarFollowModel().getMaxAccel());
1108 1426 : const double timeToStopLateral = (MSGlobals::gLaneChangeDuration > 0
1109 1426 : ? STEPS2TIME(MSGlobals::gLaneChangeDuration) * bestOffset
1110 1256 : : (MSGlobals::gLateralResolution > 0
1111 1256 : ? bestOffset * SUMO_const_laneWidth / vehicle->getVehicleType().getMaxSpeedLat()
1112 : : 0.));
1113 : const double timeToStop = MAX2(timeToStopForward, timeToStopLateral);
1114 1426 : if (!isOpposite) {
1115 : // we keep neighLead distinct from oncoming because it determines blocking on the neigh lane
1116 : // but also look for an oncoming leader to compute safety constraint
1117 636 : const double searchDist = timeToStop * oncomingLane->getSpeedLimit() * 2 + spaceToStop;
1118 636 : neighLead = oncomingLane->getOppositeLeader(vehicle, searchDist, true);
1119 636 : oncoming = getOncomingVehicle(oncomingLane, neighLead, searchDist, vMax);
1120 : } else {
1121 : double searchDist = OPPOSITE_OVERTAKING_ONCOMING_LOOKAHEAD;
1122 790 : oncoming = oncomingLane->getOppositeLeader(vehicle, searchDist, true);
1123 790 : oncoming = getOncomingVehicle(oncomingLane, oncoming, searchDist, vMax);
1124 : }
1125 : double oncomingSpeed;
1126 1426 : const double surplusGap = computeSurplusGap(vehicle, opposite, oncoming, timeToStop, spaceToStop, oncomingSpeed);
1127 1426 : if (!isOpposite && surplusGap < 0) {
1128 : #ifdef DEBUG_CHANGE_OPPOSITE
1129 : if (DEBUG_COND) {
1130 : std::cout << " cannot changeOppositeStop due to dangerous oncoming spaceToStop=" << spaceToStop
1131 : << " timeToStopForward=" << timeToStopForward << " timeToStopLateral=" << timeToStopLateral << " surplusGap=" << surplusGap << "\n";
1132 : }
1133 : #endif
1134 : return false;
1135 : }
1136 :
1137 1072 : if (bestOffset > 0) {
1138 532 : MSLane* const target = preb[laneIndex + 1].lane;
1139 532 : neighLead = target->getOppositeLeader(vehicle, OPPOSITE_OVERTAKING_MAX_LOOKAHEAD, true);
1140 532 : std::pair<MSVehicle* const, double> neighFollow = target->getOppositeFollower(vehicle);
1141 532 : return checkChangeOpposite(vehicle, 1, target, leader, neighLead, neighFollow, preb);
1142 : } else {
1143 : // return prematurely (due to foe?)
1144 : //return checkChangeOpposite(vehicle, -1, target, leader, neighLead, neighFollow, preb);
1145 : return false;
1146 : }
1147 1426 : }
1148 :
1149 :
1150 : std::vector<MSVehicle::LaneQ>
1151 623471 : MSLaneChanger::getBestLanesOpposite(MSVehicle* vehicle, const MSLane* stopLane, double oppositeLength) {
1152 623471 : const bool isOpposite = vehicle->getLaneChangeModel().isOpposite();
1153 623471 : const MSEdge* forward = isOpposite ? vehicle->getLane()->getEdge().getOppositeEdge()->getNormalSuccessor() : vehicle->getLane()->getEdge().getNormalSuccessor();
1154 623471 : const MSEdge* opposite = forward->getOppositeEdge();
1155 : const int numForward = forward->getNumLanes();
1156 : const int numOpposite = opposite->getNumLanes();
1157 : const std::vector<MSLane*>& oLanes = opposite->getLanes();
1158 623471 : std::vector<MSVehicle::LaneQ> preb = vehicle->getBestLanes();
1159 1297251 : for (int i = 0; i < numOpposite; i++) {
1160 673780 : preb.push_back(preb.back());
1161 673780 : preb.back().lane = oLanes[numOpposite - 1 - i];
1162 673780 : preb.back().length = oppositeLength;
1163 673780 : if (isOpposite) {
1164 413149 : preb.back().bestLaneOffset = -1 - i;
1165 : //std::cout << " oi=" << i << " bestOffset =" << preb.back().bestLaneOffset << "\n";
1166 : }
1167 : }
1168 623471 : if (stopLane != nullptr) {
1169 1426 : const int stopIndex = numForward + numOpposite - stopLane->getIndex() - 1;
1170 6064 : for (int i = 0; i < (int)preb.size(); i++) {
1171 4638 : preb[i].bestLaneOffset = stopIndex - i;
1172 4638 : preb[i].length = vehicle->getLaneChangeModel().getForwardPos() + vehicle->nextStopDist();
1173 : //std::cout << " oi2=" << i << " stopIndex=" << stopIndex << " bestOffset =" << preb[i].bestLaneOffset << " stopDist=" << vehicle->nextStopDist() << " length=" << preb[i].length << "\n";
1174 : }
1175 : }
1176 : #ifdef DEBUG_CHANGE_OPPOSITE
1177 : if (DEBUG_COND) {
1178 : std::cout << SIMTIME << " getBestLanesOpposite " << vehicle->getID() << " isOpposite=" << isOpposite << "\n";
1179 : for (int i = 0; i < (int)preb.size(); i++) {
1180 : std::cout << " i=" << i << " lane=" << preb[i].lane->getID() << " bestOffset=" << preb[i].bestLaneOffset << " length=" << preb[i].length << "\n";
1181 : }
1182 : }
1183 : #endif
1184 623471 : return preb;
1185 0 : }
1186 :
1187 :
1188 : bool
1189 24672179 : MSLaneChanger::changeOpposite(MSVehicle* vehicle, std::pair<MSVehicle*, double> leader, MSVehicle* lastStopped) {
1190 : // Evaluate lane-changing between opposite direction lanes
1191 24672179 : if (!myChangeToOpposite) {
1192 : return false;
1193 : }
1194 7771776 : const bool isOpposite = vehicle->getLaneChangeModel().isOpposite();
1195 : MSLane* source = vehicle->getMutableLane();
1196 7771776 : MSLane* opposite = isOpposite ? source->getParallelLane(1) : source->getOpposite();
1197 :
1198 : #ifdef DEBUG_CHANGE_OPPOSITE
1199 : gDebugFlag5 = DEBUG_COND;
1200 : if (DEBUG_COND) {
1201 : std::cout << SIMTIME << " veh=" << vehicle->getID() << " considerChangeOpposite source=" << source->getID()
1202 : << " opposite=" << Named::getIDSecure(opposite) << " lead=" << Named::getIDSecure(leader.first) << " isOpposite=" << isOpposite << "\n";
1203 : }
1204 : #endif
1205 : //There is no lane for opposite driving
1206 7771776 : if (opposite == nullptr) {
1207 : return false;
1208 : }
1209 7735266 : if (vehicle->isStopped()) {
1210 : // stopped vehicles obviously should not change lanes. Usually this is
1211 : // prevent by appropriate bestLane distances
1212 : return false;
1213 : }
1214 : int ret = 0;
1215 7735266 : ret = vehicle->influenceChangeDecision(ret);
1216 : bool oppositeChangeByTraci = false;
1217 : // Check whether a lane change to the opposite direction was requested via TraCI
1218 7735266 : if ((ret & (LCA_TRACI)) != 0) {
1219 121 : if (isOpposite && (ret & LCA_LEFT) != 0) {
1220 : // stay on the opposite side
1221 : return false;
1222 : }
1223 : oppositeChangeByTraci = true;
1224 : }
1225 7735216 : if (!isOpposite && !oppositeChangeByTraci && !source->allowsChangingLeft(vehicle->getVClass())) {
1226 : // lane changing explicitly forbidden from this lane
1227 : #ifdef DEBUG_CHANGE_OPPOSITE
1228 : if (DEBUG_COND) {
1229 : std::cout << " not overtaking due to changeLeft restriction\n";
1230 : }
1231 : #endif
1232 : return false;
1233 : }
1234 :
1235 : //lane for opposite driving is not permitted
1236 7733959 : if (!opposite->allowsVehicleClass(vehicle->getVClass())) {
1237 : return false;
1238 : }
1239 :
1240 7732702 : const MSLane* oncomingLane = isOpposite ? source : opposite;
1241 : //const MSLane* forwardLane = isOpposite ? opposite : source;
1242 : // changing into the opposite direction is always to the left (XXX except for left-hand networkds)
1243 : int direction = isOpposite ? -1 : 1;
1244 : std::pair<MSVehicle*, double> neighLead(nullptr, -1);
1245 :
1246 : // distance that can safely be driven on the opposite side
1247 : double surplusGap = std::numeric_limits<double>::max();
1248 :
1249 : // we need to find two vehicles:
1250 : // 1) the leader that shall be overtaken (not necessarily the current leader but one of its leaders that has enough space in front)
1251 : // 2) the oncoming vehicle (we need to look past vehicles that are currently overtaking through the opposite direction themselves)
1252 : //
1253 : // if the vehicle is driving normally, then the search for 1) starts on the current lane and 2) on the opposite lane
1254 : // if the vehicle is driving on the opposite side then 1) is found on the neighboring lane and 2) on the current lane
1255 :
1256 : std::pair<MSVehicle*, double> overtaken(nullptr, -1);
1257 : // oncoming vehicle that is driving in the "correct" direction
1258 : std::pair<MSVehicle*, double> oncoming(nullptr, -1);
1259 : // oncoming vehicle that is driving against the flow
1260 : std::pair<MSVehicle*, double> oncomingOpposite(nullptr, -1);
1261 : // the maximum speed while overtaking (may be lowered if slow vehicles are
1262 : // currently overtaking ahead of vehicle)
1263 7732702 : double vMax = vehicle->getLane()->getVehicleMaxSpeed(vehicle);
1264 7732702 : double oncomingSpeed = oncomingLane->getSpeedLimit();
1265 :
1266 : // check for opposite direction stop
1267 7732702 : if (!oppositeChangeByTraci && hasOppositeStop(vehicle)) {
1268 1426 : return checkOppositeStop(vehicle, oncomingLane, opposite, leader);
1269 : }
1270 :
1271 7731276 : if (!isOpposite && leader.first == nullptr && !oppositeChangeByTraci) {
1272 : // no reason to change unless there is a leader
1273 : // or we are changing back to the propper direction
1274 : // XXX also check whether the leader is so far away as to be irrelevant
1275 : return false;
1276 : }
1277 : if (!isOpposite && !oppositeChangeByTraci
1278 6988409 : && vehicle->getVClass() != SVC_EMERGENCY
1279 14336770 : && leader.first != nullptr) {
1280 12852867 : if (leader.first->signalSet(MSGlobals::gLefthand
1281 : ? MSVehicle::VEH_SIGNAL_BLINKER_RIGHT : MSVehicle::VEH_SIGNAL_BLINKER_LEFT)) {
1282 : // do not try to overtake a vehicle that is about to turn left or wants
1283 : // to change left itself
1284 : #ifdef DEBUG_CHANGE_OPPOSITE
1285 : if (DEBUG_COND) {
1286 : std::cout << " not overtaking leader " << leader.first->getID() << " that has blinker set\n";
1287 : }
1288 : #endif
1289 203665 : if (lastStopped != nullptr && vehicle->getWaitingSeconds() >= OPPOSITE_OVERTAKING_DEADLOCK_WAIT) {
1290 1499 : neighLead = oncomingLane->getOppositeLeader(vehicle, OPPOSITE_OVERTAKING_ONCOMING_LOOKAHEAD, true, MSLane::MinorLinkMode::FOLLOW_ONCOMING);
1291 1499 : const double lastStoppedGap = lastStopped->getBackPositionOnLane() - vehicle->getPositionOnLane() - vehicle->getVehicleType().getMinGap();
1292 1499 : resolveDeadlock(vehicle, leader, neighLead, std::make_pair(lastStopped, lastStoppedGap));
1293 : }
1294 187865 : return false;
1295 6773187 : } else if (leader.second < 0) {
1296 : // leaders is either a junction leader (that cannot be overtaken) or something else is wrong
1297 : #ifdef DEBUG_CHANGE_OPPOSITE
1298 : if (DEBUG_COND) {
1299 : std::cout << " not overtaking leader " << leader.first->getID() << " with gap " << leader.second << "\n";
1300 : }
1301 : #endif
1302 : return false;
1303 : }
1304 : }
1305 :
1306 : // checks for overtaking space
1307 6886082 : double timeToOvertake = std::numeric_limits<double>::max();
1308 6886082 : double spaceToOvertake = std::numeric_limits<double>::max();
1309 6886082 : double maxSpaceToOvertake = 0;
1310 :
1311 6886082 : if (oppositeChangeByTraci) {
1312 71 : timeToOvertake = STEPS2TIME(vehicle->getInfluencer().getLaneTimeLineDuration());//todo discuss concept
1313 71 : spaceToOvertake = timeToOvertake * vehicle->getLane()->getVehicleMaxSpeed(vehicle);
1314 : } else {
1315 6886011 : if (isOpposite) {
1316 : // -1 will use getMaximumBrakeDist() as look-ahead distance
1317 387238 : neighLead = opposite->getOppositeLeader(vehicle, -1, false);
1318 : // make sure that overlapping vehicles on the neighboring lane are found by starting search at the back position
1319 774476 : overtaken = opposite->getLeader(vehicle, opposite->getOppositePos(vehicle->getBackPositionOnLane()), vehicle->getBestLanesContinuation(opposite));
1320 387238 : overtaken.second -= vehicle->getVehicleType().getLength();
1321 387238 : if (overtaken.first == nullptr && neighLead.first != nullptr) {
1322 : overtaken = neighLead;
1323 : }
1324 387238 : if (overtaken.first != nullptr) {
1325 381189 : overtaken = getColumnleader(maxSpaceToOvertake, vehicle, overtaken);
1326 : }
1327 : #ifdef DEBUG_CHANGE_OPPOSITE
1328 : if (DEBUG_COND) {
1329 : std::cout << " leaderOnSource=" << Named::getIDSecure(oncoming.first) << " gap=" << oncoming.second << "\n";
1330 : std::cout << " leaderOnTarget=" << Named::getIDSecure(neighLead.first) << " gap=" << neighLead.second << "\n";
1331 : std::cout << " overtaken=" << Named::getIDSecure(overtaken.first) << " gap=" << overtaken.second << "\n";
1332 : }
1333 : #endif
1334 : } else {
1335 6498773 : overtaken = getColumnleader(maxSpaceToOvertake, vehicle, leader);
1336 : }
1337 :
1338 6886011 : if (overtaken.first == 0) {
1339 2625738 : if (!isOpposite) {
1340 : // no reason to change to the opposite side
1341 : #ifdef DEBUG_CHANGE_OPPOSITE
1342 : if (DEBUG_COND) {
1343 : std::cout << " no leader found\n";
1344 : }
1345 : #endif
1346 2584384 : if (vehicle->getWaitingSeconds() >= OPPOSITE_OVERTAKING_DEADLOCK_WAIT) {
1347 785547 : neighLead = oncomingLane->getOppositeLeader(vehicle, OPPOSITE_OVERTAKING_ONCOMING_LOOKAHEAD, true, MSLane::MinorLinkMode::FOLLOW_ONCOMING);
1348 785547 : resolveDeadlock(vehicle, leader, neighLead, std::make_pair(nullptr, leader.second));
1349 : }
1350 2584384 : return false;
1351 : }
1352 : } else {
1353 : #ifdef DEBUG_CHANGE_OPPOSITE
1354 : if (DEBUG_COND) {
1355 : std::cout << " compute time/space to overtake for columnLeader=" << overtaken.first->getID() << " egoGap=" << overtaken.second << "\n";
1356 : }
1357 : #endif
1358 : // if we have limited space to overtake, we may have to limit our maximum maneuver speed
1359 4260273 : vMax = MIN2(vMax, getMaxOvertakingSpeed(vehicle, maxSpaceToOvertake));
1360 : // there might be leader vehicles on the opposite side that also drive
1361 : // against the flow which are slower than ego (must be factored into
1362 : // overtaking time)
1363 4260273 : computeOvertakingTime(vehicle, vMax, overtaken.first, overtaken.second, timeToOvertake, spaceToOvertake);
1364 : #ifdef DEBUG_CHANGE_OPPOSITE
1365 : if (DEBUG_COND) {
1366 : std::cout << SIMTIME
1367 : << " veh=" << vehicle->getID()
1368 : << " changeOpposite opposite=" << opposite->getID()
1369 : << " lead=" << Named::getIDSecure(leader.first)
1370 : << " maxSpaceToOvertake=" << maxSpaceToOvertake
1371 : << " vMax=" << vMax
1372 : << " timeToOvertake=" << timeToOvertake
1373 : << " spaceToOvertake=" << spaceToOvertake
1374 : << "\n";
1375 : }
1376 : #endif
1377 :
1378 4260273 : if (!isOpposite && spaceToOvertake > OPPOSITE_OVERTAKING_MAX_SPACE_TO_OVERTAKE) {
1379 : #ifdef DEBUG_CHANGE_OPPOSITE
1380 : if (DEBUG_COND) {
1381 : std::cout << " cannot changeOpposite (cannot overtake fast leader " << Named::getIDSecure(overtaken.first) << " v=" << overtaken.first->getSpeed() << ")\n";
1382 : }
1383 : #endif
1384 1559812 : neighLead = oncomingLane->getOppositeLeader(vehicle, OPPOSITE_OVERTAKING_ONCOMING_LOOKAHEAD, true, MSLane::MinorLinkMode::FOLLOW_ONCOMING);
1385 : bool wait = false;
1386 1559812 : if (vehicle->getWaitingSeconds() >= OPPOSITE_OVERTAKING_DEADLOCK_WAIT) {
1387 85140 : wait = resolveDeadlock(vehicle, leader, neighLead, overtaken);
1388 : }
1389 1559812 : if (!wait && lastStopped != nullptr) {
1390 156760 : const double lastStoppedGap = lastStopped->getBackPositionOnLane() - vehicle->getPositionOnLane() - vehicle->getVehicleType().getMinGap();
1391 : #ifdef DEBUG_CHANGE_OPPOSITE
1392 : if (DEBUG_COND) {
1393 : std::cout << " lastStopped=" << Named::getIDSecure(lastStopped) << " gap=" << lastStoppedGap << "\n";
1394 : }
1395 : #endif
1396 156760 : avoidDeadlock(vehicle, neighLead, std::make_pair(lastStopped, lastStoppedGap), leader);
1397 : }
1398 1559812 : return false;
1399 : }
1400 : }
1401 :
1402 : // if we have a leader vehicle that is driving in the opposite
1403 : // direction, it may slow us down (update vMax)
1404 : if (!isOpposite) {
1405 : assert(timeToOvertake != std::numeric_limits<double>::max());
1406 : assert(spaceToOvertake != std::numeric_limits<double>::max());
1407 : // we keep neighLead distinct from oncoming because it determines blocking on the neigh lane
1408 : // but also look for an oncoming leader to compute safety constraint
1409 2354577 : double searchDist = timeToOvertake * oncomingLane->getSpeedLimit() * 2 + spaceToOvertake;
1410 2354577 : neighLead = oncomingLane->getOppositeLeader(vehicle, searchDist, true, MSLane::MinorLinkMode::FOLLOW_ONCOMING);
1411 2354577 : oncoming = getOncomingVehicle(oncomingLane, neighLead, searchDist, vMax, overtaken.first, MSLane::MinorLinkMode::FOLLOW_ONCOMING);
1412 2354577 : oncomingOpposite = getOncomingOppositeVehicle(vehicle, overtaken, searchDist);
1413 : } else {
1414 : double searchDist = OPPOSITE_OVERTAKING_ONCOMING_LOOKAHEAD;
1415 387238 : oncoming = oncomingLane->getOppositeLeader(vehicle, searchDist, true);
1416 387238 : oncoming = getOncomingVehicle(oncomingLane, oncoming, searchDist, vMax, overtaken.first);
1417 387238 : oncomingOpposite = getOncomingOppositeVehicle(vehicle, overtaken, searchDist);
1418 : }
1419 2741815 : if (oncoming.first != nullptr && (oncoming.first->isStopped()
1420 1559917 : || oncoming.first->getWaitingSeconds() >= OPPOSITE_OVERTAKING_DEADLOCK_WAIT)) {
1421 : // finish overtaking within the available space
1422 969129 : const double oncomingGap = oncoming.second - oncoming.first->getVehicleType().getMinGap();
1423 969129 : if (oncomingGap > 0) {
1424 835158 : vMax = MIN2(vMax, getMaxOvertakingSpeed(vehicle, oncomingGap));
1425 : }
1426 : #ifdef DEBUG_CHANGE_OPPOSITE
1427 : if (DEBUG_COND) {
1428 : std::cout << " oncoming=" << oncoming.first->getID() << " stopped=" << oncoming.first->isStopped()
1429 : << " halting=" << oncoming.first->getWaitingSeconds()
1430 : << " oncomingGap=" << oncomingGap
1431 : << " vMaxGap=" << getMaxOvertakingSpeed(vehicle, oncomingGap)
1432 : << " vMax=" << vMax << "\n";
1433 : }
1434 : #endif
1435 : }
1436 :
1437 2741815 : if (overtaken.first != nullptr && vMax != vehicle->getLane()->getVehicleMaxSpeed(vehicle)) {
1438 : // recompute overtaking time with slow opposite leader
1439 1057049 : computeOvertakingTime(vehicle, vMax, overtaken.first, overtaken.second, timeToOvertake, spaceToOvertake);
1440 : #ifdef DEBUG_CHANGE_OPPOSITE
1441 : if (DEBUG_COND) {
1442 : std::cout << " recomputed overtaking time with vMax=" << vMax
1443 : << " timeToOvertake=" << timeToOvertake
1444 : << " spaceToOvertake=" << spaceToOvertake
1445 : << "\n";
1446 : }
1447 : #endif
1448 : }
1449 2741815 : if (!isOpposite) {
1450 2354577 : if (spaceToOvertake > OPPOSITE_OVERTAKING_MAX_SPACE_TO_OVERTAKE) {
1451 : #ifdef DEBUG_CHANGE_OPPOSITE
1452 : if (DEBUG_COND) {
1453 : std::cout << " cannot changeOpposite (check2: cannot overtake fast leader " << Named::getIDSecure(overtaken.first) << " v=" << overtaken.first->getSpeed() << ")\n";
1454 : }
1455 : #endif
1456 324404 : resolveDeadlock(vehicle, leader, neighLead, overtaken);
1457 324404 : return false;
1458 : }
1459 : // check for upcoming stops
1460 2030173 : if (vehicle->nextStopDist() < spaceToOvertake) {
1461 : #ifdef DEBUG_CHANGE_OPPOSITE
1462 : if (DEBUG_COND) {
1463 : std::cout << " cannot changeOpposite due to upcoming stop (dist=" << vehicle->nextStopDist() << " spaceToOvertake=" << spaceToOvertake << ")\n";
1464 : }
1465 : #endif
1466 : return false;
1467 : }
1468 : assert(timeToOvertake != std::numeric_limits<double>::max());
1469 : assert(spaceToOvertake != std::numeric_limits<double>::max());
1470 : }
1471 :
1472 : // check for dangerous oncoming leader
1473 2349170 : surplusGap = computeSurplusGap(vehicle, opposite, oncoming, timeToOvertake, spaceToOvertake, oncomingSpeed);
1474 2349170 : if (oncomingOpposite.first != nullptr) {
1475 : double oncomingSpeed2;
1476 414663 : const double conservativeTime = ceil(timeToOvertake / TS) * TS;
1477 414663 : const double conservativeSpace = conservativeTime * vehicle->getLane()->getVehicleMaxSpeed(vehicle);
1478 414663 : const double surplusGap2 = computeSurplusGap(vehicle, opposite, oncomingOpposite, conservativeTime, conservativeSpace, oncomingSpeed2, true);
1479 : #ifdef DEBUG_CHANGE_OPPOSITE
1480 : if (DEBUG_COND) {
1481 : std::cout << " oncomingOpposite=" << oncomingOpposite.first->getID() << " speed=" << oncomingSpeed2 << " gap=" << oncomingOpposite.second << " surplusGap2=" << surplusGap2 << "\n";
1482 : }
1483 : #endif
1484 : surplusGap = MIN2(surplusGap, surplusGap2);
1485 414663 : oncomingSpeed = MAX2(oncomingSpeed, oncomingSpeed2);
1486 346578 : if (!isOpposite && surplusGap >= 0 && oncoming.first != nullptr && oncoming.first->isStopped()
1487 415456 : && oncomingOpposite.second > oncoming.second) {
1488 : // even if ego can change back and forth successfully, we have to
1489 : // make sure that the oncoming vehicle can also finish its lane
1490 : // change in time
1491 782 : const double oSpeed = MAX2(oncomingOpposite.first->getSpeed(), NUMERICAL_EPS);
1492 : // conservative estimate
1493 782 : const double closingSpeed = (vehicle->getLane()->getVehicleMaxSpeed(vehicle)
1494 782 : + oncomingOpposite.first->getLane()->getVehicleMaxSpeed(oncomingOpposite.first));
1495 782 : const double ooSTO = oncomingOpposite.second - oncoming.second + oncomingOpposite.first->getVehicleType().getLengthWithGap();
1496 782 : double ooTTO = ooSTO / oSpeed;
1497 : // round to multiples of step length (TS)
1498 782 : ooTTO = ceil(ooTTO / TS) * TS;
1499 782 : const double surplusGap3 = oncomingOpposite.second - ooTTO * closingSpeed;
1500 : #ifdef DEBUG_CHANGE_OPPOSITE
1501 : if (DEBUG_COND) {
1502 : std::cout << " oSpeed=" << oSpeed << " ooSTO=" << ooSTO << " ooTTO=" << ooTTO << " surplusGap3=" << surplusGap3 << "\n";
1503 : }
1504 : #endif
1505 : surplusGap = MIN2(surplusGap, surplusGap3);
1506 : }
1507 : }
1508 2349170 : if (!isOpposite && surplusGap < 0) {
1509 : #ifdef DEBUG_CHANGE_OPPOSITE
1510 : if (DEBUG_COND) {
1511 : std::cout << " cannot changeOpposite due to dangerous oncoming (surplusGap=" << surplusGap << ")\n";
1512 : }
1513 : #endif
1514 :
1515 : #ifdef DEBUG_CHANGE_OPPOSITE
1516 : if (DEBUG_COND) {
1517 : if (oncoming.first->getLaneChangeModel().isOpposite()) {
1518 : std::cout << SIMTIME << " ego=" << vehicle->getID() << " does not changeOpposite due to dangerous oncoming " << oncoming.first->getID() << " (but the leader is also opposite)\n";
1519 : }
1520 : }
1521 : #endif
1522 1402054 : avoidDeadlock(vehicle, neighLead, overtaken, leader);
1523 1402054 : return false;
1524 : }
1525 : }
1526 : // compute remaining space on the opposite side
1527 : // 1. the part that remains on the current lane
1528 947187 : double usableDist = isOpposite ? vehicle->getPositionOnLane() : source->getLength() - vehicle->getPositionOnLane();
1529 :
1530 947187 : if (usableDist < spaceToOvertake) {
1531 : // look forward along the next lanes
1532 362078 : const std::vector<MSLane*>& bestLaneConts = vehicle->getBestLanesContinuation();
1533 : assert(bestLaneConts.size() >= 1);
1534 : std::vector<MSLane*>::const_iterator it = bestLaneConts.begin() + 1;
1535 489901 : while (usableDist < spaceToOvertake && it != bestLaneConts.end()) {
1536 : #ifdef DEBUG_CHANGE_OPPOSITE
1537 : if (DEBUG_COND) {
1538 : std::cout << " usableDist=" << usableDist << " opposite=" << Named::getIDSecure((*it)->getOpposite()) << "\n";
1539 : }
1540 : #endif
1541 260387 : if ((*it)->getOpposite() == nullptr || !(*it)->getOpposite()->allowsVehicleClass(vehicle->getVClass())) {
1542 : // opposite lane ends
1543 : break;
1544 : }
1545 : // do not overtake past a minor link or turn
1546 149788 : const MSLane* const prev = *(it - 1);
1547 149788 : if (prev != nullptr) {
1548 145986 : const MSLink* link = prev->getLinkTo(*it);
1549 145986 : if (link == nullptr || link->getState() == LINKSTATE_ZIPPER
1550 145986 : || (link->getDirection() != LinkDirection::STRAIGHT && vehicle->getVehicleType().getVehicleClass() != SVC_EMERGENCY)
1551 271691 : || (!link->havePriority()
1552 : // consider traci-influence
1553 7797 : && (!vehicle->hasInfluencer() || vehicle->getInfluencer().getRespectJunctionPriority())
1554 : // consider junction model parameters
1555 560 : && ((!link->haveRed() && !link->haveYellow()) || !vehicle->ignoreRed(link, true)))) {
1556 : #ifdef DEBUG_CHANGE_OPPOSITE
1557 : if (DEBUG_COND) {
1558 : std::cout << " stop lookahead at link=" << (link == 0 ? "NULL" : link->getViaLaneOrLane()->getID()) << " state=" << (link == 0 ? "?" : toString(link->getState())) << " ignoreRed=" << vehicle->ignoreRed(link, true) << "\n";
1559 : }
1560 : #endif
1561 : break;
1562 : }
1563 : }
1564 127823 : usableDist += (*it)->getLength();
1565 : ++it;
1566 : }
1567 : }
1568 947187 : if (!isOpposite && usableDist < spaceToOvertake) {
1569 : #ifdef DEBUG_CHANGE_OPPOSITE
1570 : if (DEBUG_COND) {
1571 : std::cout << " cannot changeOpposite due to insufficient space (seen=" << usableDist << " spaceToOvertake=" << spaceToOvertake << ")\n";
1572 : }
1573 : #endif
1574 : return false;
1575 : }
1576 383173 : if (!isOpposite && MSNet::getInstance()->hasElevation() && !overtaken.first->isStopped()) {
1577 : // do not overtake before the top of a hill
1578 127046 : double searchDist = timeToOvertake * oncomingLane->getSpeedLimit() * 1.5 * vehicle->getLaneChangeModel().getOppositeSafetyFactor() + spaceToOvertake;
1579 127046 : int view = vehicle->getLane()->isInternal() ? 1 : 0;
1580 127046 : bool foundHill = vehicle->getSlope() > 0;
1581 127046 : if (foundHilltop(vehicle, foundHill, searchDist, vehicle->getBestLanesContinuation(), view, vehicle->getPositionOnLane(), vehicle->getPosition().z(), OPPOSITE_OVERTAKING_HILLTOP_THRESHOHOLD)) {
1582 : return false;
1583 : }
1584 : }
1585 : #ifdef DEBUG_CHANGE_OPPOSITE
1586 : if (DEBUG_COND) {
1587 : std::cout << " usableDist=" << usableDist << " spaceToOvertake=" << spaceToOvertake << " timeToOvertake=" << timeToOvertake << "\n";
1588 : }
1589 : #endif
1590 : // compute wish to change
1591 670500 : std::pair<MSVehicle* const, double> neighFollow = opposite->getOppositeFollower(vehicle);
1592 670500 : double oppositeLength = vehicle->getBestLanes().back().length;
1593 670500 : if (isOpposite) {
1594 387258 : const bool canOvertake = spaceToOvertake <= OPPOSITE_OVERTAKING_MAX_SPACE_TO_OVERTAKE;
1595 387258 : oppositeLength = computeSafeOppositeLength(vehicle, oppositeLength, source, usableDist, oncoming, vMax, oncomingSpeed, neighLead, overtaken, neighFollow, surplusGap, opposite, canOvertake);
1596 : leader.first = nullptr;
1597 387258 : if (neighLead.first != nullptr && neighLead.first->getLaneChangeModel().isOpposite()) {
1598 : // ignore oncoming vehicle on the target lane (it might even change back in this step)
1599 : neighLead.first = nullptr;
1600 : }
1601 : } else {
1602 524376 : if (leader.first != nullptr && neighLead.first != nullptr && leader.first->getWaitingSeconds() >= OPPOSITE_OVERTAKING_DEADLOCK_WAIT
1603 323779 : && vehicle->getVehicleType().getVehicleClass() != SVC_EMERGENCY) {
1604 : #ifdef DEBUG_CHANGE_OPPOSITE
1605 : if (DEBUG_COND) {
1606 : std::cout << " not changing to avoid deadlock\n";
1607 : }
1608 : #endif
1609 : return false;
1610 : }
1611 243125 : if (neighLead.first != nullptr && neighLead.first->isStopped()) {
1612 : // do not start overtaking if the opposite side has been waitin for longer
1613 8894 : if (yieldToOppositeWaiting(vehicle, neighLead.first, 10)) {
1614 : return false;
1615 : }
1616 : }
1617 236724 : if (oncoming.first != nullptr && oncoming.first != neighLead.first && oncoming.first->isStopped()) {
1618 : // only abort the current column of overtaking vehicles if the opposite side has been waiting long enough
1619 15131 : if (yieldToOppositeWaiting(vehicle, oncoming.first, 10, TIME2STEPS(60))) {
1620 : return false;
1621 : }
1622 : }
1623 : }
1624 621878 : std::vector<MSVehicle::LaneQ> preb = getBestLanesOpposite(vehicle, nullptr, oppositeLength);
1625 621878 : return checkChangeOpposite(vehicle, direction, opposite, leader, neighLead, neighFollow, preb);
1626 621878 : }
1627 :
1628 :
1629 : bool
1630 1558814 : MSLaneChanger::avoidDeadlock(MSVehicle* vehicle,
1631 : std::pair<MSVehicle*, double> neighLead,
1632 : std::pair<MSVehicle*, double> overtaken,
1633 : std::pair<MSVehicle*, double> leader) {
1634 : assert(!vehicle->getLaneChangeModel().isOpposite());
1635 : #ifdef DEBUG_CHANGE_OPPOSITE_DEADLOCK
1636 : if (DEBUG_COND) {
1637 : std::cout << SIMTIME << " veh=" << vehicle->getID() << " avoidDeadlock"
1638 : << " neighLead=" << Named::getIDSecure(neighLead.first)
1639 : << " overtaken=" << Named::getIDSecure(overtaken.first)
1640 : << " leader=" << Named::getIDSecure(leader.first)
1641 : << "\n";
1642 : }
1643 : #endif
1644 1558814 : if (leader.first == nullptr || neighLead.first == nullptr || overtaken.first == nullptr) {
1645 : return false;
1646 1558429 : } else if (!neighLead.first->isStopped()
1647 2699558 : && vehicle->getWaitingSeconds() >= OPPOSITE_OVERTAKING_DEADLOCK_WAIT) {
1648 : // possibly there is an oncoming vehicle before the stoppled leader that
1649 : // could drive due to our yielding
1650 419416 : auto neighLeadFollow = neighLead.first->getFollower(overtaken.second);
1651 419416 : neighLead.second += neighLead.first->getVehicleType().getLengthWithGap() + neighLeadFollow.second;
1652 419416 : neighLead.first = const_cast<MSVehicle*>(neighLeadFollow.first);
1653 : #ifdef DEBUG_CHANGE_OPPOSITE_DEADLOCK
1654 : if (DEBUG_COND) {
1655 : std::cout << " neighLead follower=" << Named::getIDSecure(neighLeadFollow.first) << "\n";
1656 : }
1657 : #endif
1658 419416 : if (neighLead.first == nullptr) {
1659 6342 : return false;
1660 : }
1661 : }
1662 :
1663 1552087 : const bool yield = (yieldToDeadlockOncoming(vehicle, neighLead.first, overtaken.second)
1664 2429874 : || leader.first->getWaitingSeconds() >= OPPOSITE_OVERTAKING_DEADLOCK_WAIT);
1665 1552087 : if (neighLead.first->isStopped()
1666 1552087 : && (overtaken.first->isStopped()
1667 33305 : || leader.first->getLaneChangeModel().isOpposite()
1668 32667 : || yield)) {
1669 :
1670 : // estimate required gap
1671 448594 : double requiredGap = MAX2(vehicle->getVehicleType().getLengthWithGap(), neighLead.first->getVehicleType().getLengthWithGap());
1672 448594 : requiredGap = MAX2(requiredGap, overtaken.first->getVehicleType().getLengthWithGap());
1673 448594 : requiredGap = MAX2(requiredGap, leader.first->getVehicleType().getLengthWithGap());
1674 448594 : requiredGap += 1;
1675 448594 : const double distToStop = neighLead.second - requiredGap;
1676 :
1677 : // find the next non-stopped vehicle behind neighLead
1678 448594 : double neighStoppedBack = vehicle->getVehicleType().getMinGap();
1679 1185580 : while (neighLead.first != nullptr && neighLead.first->isStopped()) {
1680 783747 : const double nextGap = neighLead.second + neighLead.first->getVehicleType().getLengthWithGap();
1681 783747 : if (neighStoppedBack + nextGap > overtaken.second) {
1682 : break;
1683 : }
1684 : neighStoppedBack += nextGap;
1685 736986 : auto neighLeadFollow = neighLead.first->getFollower();
1686 736986 : neighLead.second = neighLeadFollow.second;
1687 736986 : neighLead.first = const_cast<MSVehicle*>(neighLeadFollow.first);
1688 : #ifdef DEBUG_CHANGE_OPPOSITE_DEADLOCK
1689 : if (DEBUG_COND) {
1690 : std::cout << " neighLeadFollower=" << Named::getIDSecure(neighLead.first) << "\n";
1691 : }
1692 : #endif
1693 : if (neighStoppedBack > overtaken.second) {
1694 : break;
1695 : }
1696 : }
1697 :
1698 448594 : const double leaderBGap = leader.first->getBrakeGap();
1699 448594 : const double leaderFGap = leader.first->getLane()->getLeader(leader.first, leader.first->getPositionOnLane(), vehicle->getBestLanesContinuation(), overtaken.second, true).second;
1700 : const double extraGap = MAX2(leaderBGap, leaderFGap);
1701 448594 : const double gapWithEgo = leader.second + extraGap - neighStoppedBack - vehicle->getVehicleType().getLengthWithGap();
1702 : #ifdef DEBUG_CHANGE_OPPOSITE_DEADLOCK
1703 : if (DEBUG_COND) {
1704 : std::cout << SIMTIME << " veh=" << vehicle->getID() << " avoidDeadlock"
1705 : << " neighLeadGap=" << neighLead.second
1706 : << " leaderGap=" << leader.second
1707 : << " bGap=" << leaderBGap
1708 : << " fGap=" << leaderFGap
1709 : << " eGap=" << extraGap
1710 : << " neighStoppedBack=" << neighStoppedBack
1711 : << " neighStoppedBackPos=" << vehicle->getPositionOnLane() + neighStoppedBack
1712 : << " requiredGap=" << requiredGap
1713 : << " gapWithEgo=" << gapWithEgo
1714 : << " yield=" << yield
1715 : << "\n";
1716 : }
1717 : #endif
1718 : // vehicle must fit behind leader and still leave required gap
1719 448594 : if (leader.first->getLaneChangeModel().isOpposite() || yield || gapWithEgo < requiredGap) {
1720 426033 : const std::vector<MSVehicle::LaneQ>& preb = vehicle->getBestLanes();
1721 426033 : const double currentDist = preb[vehicle->getLane()->getIndex()].length;
1722 426033 : const double stopPos = vehicle->getPositionOnLane() + distToStop;
1723 : #ifdef DEBUG_CHANGE_OPPOSITE_DEADLOCK
1724 : if (DEBUG_COND) {
1725 : std::cout << " currentDist=" << currentDist << " stopPos=" << stopPos << " lGap+eGap=" << leader.second + extraGap << " distToStop=" << distToStop << "\n";
1726 : }
1727 : #endif
1728 426033 : if (leader.second + leaderBGap + leader.first->getLength() > distToStop) {
1729 168256 : const double blockerLength = currentDist - stopPos;
1730 168256 : const bool reserved = vehicle->getLaneChangeModel().saveBlockerLength(blockerLength, -1);
1731 : #ifdef DEBUG_CHANGE_OPPOSITE_DEADLOCK
1732 : if (DEBUG_COND) {
1733 : std::cout << SIMTIME << " veh=" << vehicle->getID() << " avoidDeadlock"
1734 : << " blockerLength=" << blockerLength
1735 : << " reserved=" << reserved
1736 : << "\n";
1737 : }
1738 : #endif
1739 168256 : return reserved;
1740 : }
1741 : }
1742 : }
1743 : return false;
1744 : }
1745 :
1746 :
1747 : bool
1748 1552777 : MSLaneChanger::yieldToDeadlockOncoming(const MSVehicle* vehicle, const MSVehicle* stoppedNeigh, double dist) {
1749 1552777 : if (vehicle->getWaitingSeconds() >= OPPOSITE_OVERTAKING_DEADLOCK_WAIT && stoppedNeigh != nullptr) {
1750 : // is there a vehicle waiting behind stoppedNeigh that is encouraged by
1751 : // halting ego? Due to edge-ordering it might change-opposite this step
1752 : // and not be visible as leader
1753 774535 : std::pair<const MSVehicle*, double> follower = stoppedNeigh->getFollower(dist);
1754 774535 : double followerGap = stoppedNeigh->getVehicleType().getLengthWithGap();
1755 1147418 : while (follower.first != nullptr && followerGap < dist && follower.first->isStopped()) {
1756 372883 : followerGap += follower.second + follower.first->getVehicleType().getLengthWithGap();
1757 372883 : follower = follower.first->getFollower(dist);
1758 : };
1759 774535 : if (follower.first != nullptr) {
1760 754488 : followerGap += follower.second;
1761 : }
1762 : #ifdef DEBUG_CHANGE_OPPOSITE_DEADLOCK
1763 : if (DEBUG_COND) {
1764 : std::cout << SIMTIME << " veh=" << vehicle->getID() << " yieldToDeadlockOncoming"
1765 : << " dist=" << dist << " follower=" << Named::getIDSecure(follower.first) << " fGap=" << followerGap
1766 : << "\n";
1767 : }
1768 : #endif
1769 774535 : return follower.first != nullptr && followerGap < dist && !follower.first->isStopped();
1770 : }
1771 : return false;
1772 : }
1773 :
1774 :
1775 : bool
1776 32316 : MSLaneChanger::yieldToOppositeWaiting(const MSVehicle* vehicle, const MSVehicle* stoppedNeigh, double dist, SUMOTime deltaWait) {
1777 32316 : std::pair<const MSVehicle*, double> follower = stoppedNeigh->getFollower(dist);
1778 85961 : while (follower.first != nullptr && follower.second < dist && follower.first->isStopped()) {
1779 53645 : follower = follower.first->getFollower(dist);
1780 : };
1781 : #ifdef DEBUG_CHANGE_OPPOSITE_DEADLOCK
1782 : if (DEBUG_COND && follower.first != nullptr) {
1783 : std::cout << SIMTIME << " yieldToOppositeWaiting veh=" << vehicle->getID() << " stoppedNeigh=" << stoppedNeigh->getID()
1784 : << " oncoming=" << follower.first->getID()
1785 : << " wait=" << follower.first->getWaitingSeconds()
1786 : << " vehWait=" << vehicle->getWaitingSeconds()
1787 : << " deltaWait=" << STEPS2TIME(deltaWait)
1788 : << "\n";
1789 : }
1790 : #endif
1791 32316 : if (follower.first != nullptr && follower.second < dist && follower.first->getWaitingTime() > vehicle->getWaitingTime() + deltaWait) {
1792 : return true;
1793 : }
1794 : return false;
1795 : }
1796 :
1797 :
1798 : bool
1799 1196590 : MSLaneChanger::resolveDeadlock(MSVehicle* vehicle,
1800 : std::pair<MSVehicle* const, double> leader,
1801 : std::pair<MSVehicle*, double> neighLead,
1802 : std::pair<MSVehicle*, double> overtaken) {
1803 1196590 : const double deadLockZone = overtaken.second;
1804 : #ifdef DEBUG_CHANGE_OPPOSITE_DEADLOCK
1805 : if (DEBUG_COND) {
1806 : std::cout << SIMTIME << " veh=" << vehicle->getID() << " resolveDeadlock waiting=" << vehicle->getWaitingSeconds()
1807 : << " leader=" << Named::getIDSecure(leader.first)
1808 : << " gap=" << leader.second
1809 : << "\n";
1810 : }
1811 : #endif
1812 : if (vehicle->getWaitingSeconds() >= OPPOSITE_OVERTAKING_DEADLOCK_WAIT
1813 1196590 : && leader.first != nullptr && leader.second > vehicle->getVehicleType().getLengthWithGap()) {
1814 : // assume vehicle is halting to avoid deadlock (since there is enough
1815 : // space to drive further)
1816 : // keep halting as long as there is an oncoming vehicle
1817 7166 : std::pair<MSVehicle* const, double> oncomingOpposite = getOncomingOppositeVehicle(vehicle, std::make_pair(nullptr, -1), leader.second);
1818 : #ifdef DEBUG_CHANGE_OPPOSITE_DEADLOCK
1819 : if (DEBUG_COND) {
1820 : std::cout << SIMTIME << " veh=" << vehicle->getID() << " resolveDeadlock"
1821 : << " leader=" << leader.first->getID()
1822 : << " leaderGap=" << leader.second
1823 : << " neighLead=" << Named::getIDSecure(neighLead.first)
1824 : << " deadLockZone=" << deadLockZone
1825 : << "\n";
1826 : }
1827 : #endif
1828 7166 : if (neighLead.first != nullptr && !neighLead.first->isStopped()) {
1829 : // possibly there is an oncoming vehicle before the stoppled leader that
1830 : // could drive due to our yielding
1831 6185 : auto neighLeadFollow = neighLead.first->getFollower(deadLockZone);
1832 6185 : neighLead.second += neighLead.first->getVehicleType().getLengthWithGap() + neighLeadFollow.second;
1833 6185 : neighLead.first = const_cast<MSVehicle*>(neighLeadFollow.first);
1834 : #ifdef DEBUG_CHANGE_OPPOSITE_DEADLOCK
1835 : if (DEBUG_COND) {
1836 : std::cout << " neighLead follower=" << Named::getIDSecure(neighLeadFollow.first) << "\n";
1837 : }
1838 : #endif
1839 : }
1840 :
1841 7166 : if (oncomingOpposite.first != nullptr ||
1842 5545 : (neighLead.first != nullptr && neighLead.first->isStopped()
1843 690 : && yieldToDeadlockOncoming(vehicle, neighLead.first, deadLockZone))) {
1844 1283 : const std::vector<MSVehicle::LaneQ>& preb = vehicle->getBestLanes();
1845 1283 : const double currentDist = preb[vehicle->getLane()->getIndex()].length;
1846 : // mirror code in patchSpeed
1847 1283 : const double blockerLength = currentDist - vehicle->getPositionOnLane() - 1 - vehicle->getVehicleType().getMinGap() - NUMERICAL_EPS;
1848 1283 : const bool reserved = vehicle->getLaneChangeModel().saveBlockerLength(blockerLength, -1);
1849 : #ifdef DEBUG_CHANGE_OPPOSITE_DEADLOCK
1850 : if (DEBUG_COND) {
1851 : std::cout << SIMTIME << " veh=" << vehicle->getID() << " resolveDeadlock"
1852 : << " leader=" << leader.first->getID()
1853 : << " leaderGap=" << leader.second
1854 : << " oncoming=" << Named::getIDSecure(oncomingOpposite.first)
1855 : << " currentDist=" << currentDist
1856 : << " blockerLength=" << blockerLength
1857 : << " reserved=" << reserved
1858 : << "\n";
1859 : }
1860 : #else
1861 : UNUSED_PARAMETER(reserved);
1862 : #endif
1863 1283 : return true;
1864 : }
1865 : }
1866 : return false;
1867 : }
1868 :
1869 :
1870 : double
1871 387258 : MSLaneChanger::computeSafeOppositeLength(MSVehicle* vehicle, double oppositeLength, const MSLane* source, double usableDist,
1872 : std::pair<MSVehicle*, double> oncoming, double vMax, double oncomingSpeed,
1873 : std::pair<MSVehicle*, double> neighLead,
1874 : std::pair<MSVehicle*, double> overtaken,
1875 : std::pair<MSVehicle*, double> neighFollow,
1876 : double surplusGap, const MSLane* opposite,
1877 : bool canOvertake) {
1878 : // compute the remaining distance that can be driven on the opposite side
1879 : // this value will put into oppositeLength of the opposite lanes
1880 : // @note: length counts from the start of the current lane
1881 : // @note: see MSLaneChangeModel::LC2013::_wantsChange @1092 (isOpposite()
1882 : // position on the target lane
1883 387258 : const double forwardPos = source->getOppositePos(vehicle->getPositionOnLane());
1884 :
1885 : // consider usableDist (due to minor links or end of opposite lanes)
1886 387258 : oppositeLength = MIN2(oppositeLength, usableDist + forwardPos);
1887 : // consider upcoming stops
1888 387258 : oppositeLength = MIN2(oppositeLength, vehicle->nextStopDist() + forwardPos);
1889 : #ifdef DEBUG_CHANGE_OPPOSITE
1890 : if (DEBUG_COND) {
1891 : std::cout << " laneQLength=" << oppositeLength << " usableDist=" << usableDist << " forwardPos=" << forwardPos << " stopDist=" << vehicle->nextStopDist() << "\n";
1892 : }
1893 : #endif
1894 : // consider oncoming leaders
1895 387258 : const MSVehicle* oncomingVeh = oncoming.first;
1896 387258 : if (oncomingVeh != 0) {
1897 276037 : if (!oncomingVeh->getLaneChangeModel().isOpposite() && oncomingVeh->getLaneChangeModel().getShadowLane() != source) {
1898 : double egoSpeedFraction = 0.5;
1899 273044 : if (oncomingSpeed > 0) {
1900 181745 : egoSpeedFraction = MIN2(egoSpeedFraction, vMax / (vMax + oncomingSpeed));
1901 : }
1902 273044 : oppositeLength = MIN2(oppositeLength, forwardPos + oncoming.second * egoSpeedFraction);
1903 : #ifdef DEBUG_CHANGE_OPPOSITE
1904 : if (DEBUG_COND) {
1905 : std::cout << SIMTIME << " found oncoming leader=" << oncomingVeh->getID() << " gap=" << oncoming.second
1906 : << " egoSpeedFraction=" << egoSpeedFraction << " newDist=" << oppositeLength << "\n";
1907 : }
1908 : #endif
1909 : } else {
1910 : #ifdef DEBUG_CHANGE_OPPOSITE
1911 : if (DEBUG_COND) {
1912 : std::cout << SIMTIME << " opposite leader=" << oncomingVeh->getID() << " gap=" << oncoming.second << " is driving against the flow\n";
1913 : }
1914 : #endif
1915 : }
1916 276037 : if (neighLead.first != nullptr) {
1917 265831 : if (overtaken.first == nullptr) {
1918 : #ifdef DEBUG_CHANGE_OPPOSITE
1919 : if (DEBUG_COND) {
1920 : std::cout << SIMTIME << " ego=" << vehicle->getID() << " did not find columnleader to overtake\n";
1921 : }
1922 : #endif
1923 238247 : } else if (oncomingVeh != nullptr && oncomingVeh->isStopped()
1924 76279 : && neighLead.second > 0
1925 37726 : && neighFollow.second > 0
1926 8291 : && yieldToOppositeWaiting(vehicle, oncomingVeh, 10, TIME2STEPS(60))) {
1927 : // merge back into the forward lane
1928 196 : oppositeLength = forwardPos + neighLead.second;
1929 : } else {
1930 238051 : if (surplusGap > 0) {
1931 : // exaggerate remaining dist so that the vehicle continues
1932 : // overtaking (otherwise the lane change model might abort prematurely)
1933 137198 : oppositeLength += 1000;
1934 : } else {
1935 : // return from the opposite side ahead of the unpassable column (unless overlapping)
1936 100853 : if (overtaken.second > 0) {
1937 98282 : oppositeLength = MIN2(oppositeLength, forwardPos + overtaken.second);
1938 : }
1939 : // (don't set the distance so low as to imply emergency braking)
1940 201706 : oppositeLength = MAX2(oppositeLength, forwardPos + vehicle->getCarFollowModel().brakeGap(vehicle->getSpeed()));
1941 : }
1942 : #ifdef DEBUG_CHANGE_OPPOSITE
1943 : if (DEBUG_COND) {
1944 : std::cout << SIMTIME << " ego=" << vehicle->getID() << " is overtaking " << overtaken.first->getID()
1945 : << " surplusGap=" << surplusGap
1946 : << " final laneQLength=" << oppositeLength
1947 : << "\n";
1948 : }
1949 : #endif
1950 : }
1951 : }
1952 : } else {
1953 111221 : if (overtaken.first == nullptr || !canOvertake) {
1954 : // there is no reason to stay on the opposite side
1955 30326 : std::pair<MSVehicle* const, double> oppFollow = opposite->getOppositeFollower(vehicle);
1956 30326 : if (oppFollow.first == nullptr) {
1957 : oppositeLength = forwardPos;
1958 : } else {
1959 58244 : const double secureGap = oppFollow.first->getCarFollowModel().getSecureGap(
1960 29122 : oppFollow.first, vehicle, oppFollow.first->getSpeed(), vehicle->getSpeed(), vehicle->getCarFollowModel().getMaxDecel());
1961 : #ifdef DEBUG_CHANGE_OPPOSITE
1962 : if (DEBUG_COND) {
1963 : std::cout << SIMTIME << " ego=" << vehicle->getID() << " neighFollow=" << oppFollow.first->getID() << " gap=" << oppFollow.second << " secureGap=" << secureGap << "\n";
1964 : }
1965 : #endif
1966 29122 : if (oppFollow.second > secureGap) {
1967 : // back gap is safe for immidiate return
1968 : oppositeLength = forwardPos;
1969 : }
1970 : }
1971 : }
1972 : }
1973 : #ifdef DEBUG_CHANGE_OPPOSITE
1974 : if (DEBUG_COND) {
1975 : std::cout << SIMTIME << " veh=" << vehicle->getID() << " remaining dist=" << oppositeLength - forwardPos << " forwardPos=" << forwardPos << " oppositeLength=" << oppositeLength << "\n";
1976 : }
1977 : #endif
1978 387258 : return oppositeLength;
1979 : }
1980 :
1981 :
1982 : std::pair<MSVehicle* const, double>
1983 2743241 : MSLaneChanger::getOncomingVehicle(const MSLane* opposite, std::pair<MSVehicle*, double> oncoming,
1984 : double searchDist, double& vMax, const MSVehicle* overtaken, MSLane::MinorLinkMode mLinkMode) {
1985 : double gap = oncoming.second;
1986 4676147 : while (oncoming.first != nullptr && (oncoming.first->getLaneChangeModel().isOpposite() || oncoming.first->getLaneChangeModel().getShadowLane() == opposite)) {
1987 1991994 : searchDist -= (oncoming.first->getVehicleType().getLengthWithGap() + MAX2(0.0, oncoming.second));
1988 : // leader is itself overtaking through the opposite side. find real oncoming vehicle
1989 1991994 : gap += oncoming.first->getVehicleType().getLengthWithGap();
1990 1991994 : if (oncoming.first != overtaken) {
1991 3003206 : vMax = MIN2(vMax, oncoming.first->getSpeed());
1992 : } // else: might be the case if we are overtaking a vehicle that is stopped on the opposite side
1993 : #ifdef DEBUG_CHANGE_OPPOSITE
1994 : if (gDebugFlag5) {
1995 : std::cout << SIMTIME << " oncoming=" << oncoming.first->getID() << " isOpposite gap=" << oncoming.second
1996 : << " totalGap=" << gap << " searchDist=" << searchDist << " vMax=" << vMax << "\n";
1997 : }
1998 : #endif
1999 1991994 : if (searchDist < 0) {
2000 : break;
2001 : }
2002 : // getOppositeLeader resets the search postion by ego length and may thus create cycles
2003 1932906 : if (oncoming.first->getLaneChangeModel().getShadowLane() != opposite) {
2004 1858373 : opposite = oncoming.first->getLane();
2005 : }
2006 1932906 : oncoming = opposite->getFollower(oncoming.first, oncoming.first->getPositionOnLane(opposite), searchDist, mLinkMode);
2007 1932906 : if (oncoming.first != nullptr) {
2008 1692131 : gap += oncoming.second + oncoming.first->getVehicleType().getLength();
2009 : #ifdef DEBUG_CHANGE_OPPOSITE
2010 : if (gDebugFlag5) {
2011 : std::cout << SIMTIME << " oncoming=" << oncoming.first->getID() << " gap=" << oncoming.second << " totalGap=" << gap << "\n";
2012 : }
2013 : #endif
2014 : }
2015 : }
2016 : oncoming.second = gap;
2017 2743241 : return oncoming;
2018 : }
2019 :
2020 :
2021 : std::pair<MSVehicle* const, double>
2022 2748981 : MSLaneChanger::getOncomingOppositeVehicle(const MSVehicle* vehicle, std::pair<MSVehicle*, double> overtaken, double searchDist) {
2023 : double gap = 0;
2024 : const MSVehicle* front = nullptr;
2025 2748981 : if (overtaken.first != nullptr) {
2026 2700461 : gap += overtaken.second + overtaken.first->getVehicleType().getLengthWithGap();
2027 : front = overtaken.first;
2028 : } else {
2029 : // only for special situations (i.e. traci-triggered)
2030 : front = vehicle;
2031 : }
2032 : // we only need to look for the next leader: If it's driving in the forward
2033 : // direction, it "protects" from oncoming opposite vehicles.
2034 : // all leader vehicles on the current laneChanger edge are already moved into MSLane::myTmpVehicles
2035 2748981 : const bool checkTmpVehicles = front->getLane() == vehicle->getLane();
2036 2748981 : std::vector<MSLane*> conts = vehicle->getBestLanesContinuation();
2037 3021341 : while (conts.size() > 0 && conts.front() != front->getLane()) {
2038 : conts.erase(conts.begin());
2039 : }
2040 2748981 : std::pair<MSVehicle* const, double> oncoming = front->getLane()->getLeader(front, front->getPositionOnLane(), conts, searchDist, checkTmpVehicles);
2041 2748981 : if (oncoming.first != nullptr) {
2042 2036682 : const bool isOpposite = oncoming.first->getLaneChangeModel().isOpposite();
2043 2036682 : const MSLane* shadowLane = oncoming.first->getLaneChangeModel().getShadowLane();
2044 : #ifdef DEBUG_CHANGE_OPPOSITE
2045 : if (gDebugFlag5) {
2046 : std::cout << SIMTIME
2047 : << " front=" << front->getID() << " searchDist=" << searchDist
2048 : << " oncomingOpposite=" << oncoming.first->getID()
2049 : << " gap=" << oncoming.second
2050 : << " isOpposite=" << isOpposite
2051 : << " shadowLane=" << Named::getIDSecure(shadowLane)
2052 : << "\n";
2053 : }
2054 : #endif
2055 2036682 : if (isOpposite && shadowLane != front->getLane()) {
2056 : // distance was to back position (but the vehicle is oncoming)
2057 485021 : oncoming.second -= oncoming.first->getVehicleType().getLength();
2058 485021 : oncoming.second += gap;
2059 485021 : return oncoming;
2060 : }
2061 : }
2062 2263960 : return std::make_pair(nullptr, -1);
2063 2748981 : }
2064 :
2065 :
2066 : double
2067 2765259 : MSLaneChanger::computeSurplusGap(const MSVehicle* vehicle, const MSLane* opposite, std::pair<MSVehicle*, double> oncoming,
2068 : double timeToOvertake, double spaceToOvertake, double& oncomingSpeed, bool oncomingOpposite) {
2069 : double surplusGap = std::numeric_limits<double>::max();
2070 2765259 : const MSVehicle* oncomingVeh = oncoming.first;
2071 2765259 : if (oncomingVeh != 0 && (oncomingOpposite
2072 1935686 : || (!oncomingVeh->getLaneChangeModel().isOpposite()
2073 1902382 : && oncomingVeh->getLaneChangeModel().getShadowLane() != opposite))) {
2074 : // conservative: assume that the oncoming vehicle accelerates to its maximum speed
2075 : // unless it has been standing (then assume it is trying to let us pass
2076 : // to avoid deadlock)
2077 4085975 : oncomingSpeed = (oncomingVeh->isStopped() || oncomingVeh->getWaitingSeconds() >= OPPOSITE_OVERTAKING_DEADLOCK_WAIT
2078 3549558 : ? 0 : oncomingVeh->getLane()->getVehicleMaxSpeed(oncomingVeh));
2079 2315754 : const double safetyGap = ((oncomingSpeed + vehicle->getLane()->getVehicleMaxSpeed(vehicle))
2080 2315754 : * vehicle->getCarFollowModel().getHeadwayTime()
2081 2315754 : * OPPOSITE_OVERTAKING_SAFETYGAP_HEADWAY_FACTOR);
2082 2315754 : surplusGap = oncoming.second - spaceToOvertake - timeToOvertake * oncomingSpeed - safetyGap;
2083 : #ifdef DEBUG_CHANGE_OPPOSITE
2084 : if (DEBUG_COND) {
2085 : std::cout << SIMTIME
2086 : << " oncoming=" << oncomingVeh->getID()
2087 : << " oGap=" << oncoming.second
2088 : << " oSpeed=" << oncomingSpeed
2089 : << " sto=" << spaceToOvertake
2090 : << " tto=" << timeToOvertake
2091 : << " safetyGap=" << safetyGap
2092 : << " surplusGap=" << surplusGap
2093 : << "\n";
2094 : }
2095 : #endif
2096 : }
2097 2765259 : return surplusGap;
2098 : }
2099 :
2100 : bool
2101 149475 : MSLaneChanger::foundHilltop(MSVehicle* vehicle, bool foundHill, double searchDist, const std::vector<MSLane*>& bestLanes, int view, double pos, double lastMax, double hilltopThreshold) {
2102 149475 : if (view >= (int)bestLanes.size()) {
2103 : return false;
2104 : }
2105 146463 : MSLane* lane = bestLanes[view];
2106 : double laneDist = 0;
2107 : const PositionVector& shape = lane->getShape();
2108 : double lastZ = lastMax;
2109 3953012 : for (int i = 1; i < (int)shape.size(); i++) {
2110 3930583 : const double dist = lane->interpolateGeometryPosToLanePos(shape[i - 1].distanceTo(shape[i]));
2111 3930583 : laneDist += dist;
2112 3930583 : if (laneDist > pos) {
2113 2118615 : const double z = shape[i].z();
2114 2118615 : if (z > lastMax) {
2115 : lastMax = z;
2116 : }
2117 2118615 : if (z > lastZ) {
2118 : foundHill = true;
2119 : }
2120 : lastZ = z;
2121 : #ifdef DEBUG_CHANGE_OPPOSITE
2122 : if (DEBUG_COND) {
2123 : std::cout << SIMTIME << " foundHill=" << foundHill << " searchDist=" << searchDist << " lastMax=" << lastMax << " lane=" << lane->getID() << " laneDist=" << laneDist << " z=" << z << "\n";
2124 : }
2125 : #endif
2126 2118615 : if (foundHill && z < lastMax) {
2127 1647938 : const double drop = lastMax - z;
2128 : //std::cout << SIMTIME << " searchDist=" << searchDist << " hillDrop=" << drop << " lastMax=" << lastMax << " lane=" << lane->getID() << " laneDist=" << laneDist << " z=" << z << "\n";
2129 1647938 : if (drop > hilltopThreshold) {
2130 : #ifdef DEBUG_CHANGE_OPPOSITE
2131 : if (DEBUG_COND) {
2132 : std::cout << " cannot changeOpposite before the top of a hill searchDist=" << searchDist << " hillDrop=" << drop
2133 : << " lastMax=" << lastMax << " lane=" << lane->getID() << " laneDist=" << laneDist << " z=" << z << "\n";
2134 : }
2135 : #endif
2136 : return true;
2137 : }
2138 : }
2139 2018684 : if (pos == 0) {
2140 1891640 : searchDist -= dist;
2141 : } else {
2142 127044 : searchDist -= laneDist - pos;
2143 : pos = 0;
2144 : }
2145 2018684 : if (searchDist <= 0) {
2146 : return false;
2147 : }
2148 : }
2149 : }
2150 22429 : return foundHilltop(vehicle, foundHill, searchDist, bestLanes, view + 1, 0, lastMax, hilltopThreshold);
2151 : }
2152 :
2153 :
2154 : bool
2155 453608 : MSLaneChanger::checkChangeOpposite(
2156 : MSVehicle* vehicle,
2157 : int laneOffset,
2158 : MSLane* targetLane,
2159 : const std::pair<MSVehicle* const, double>& leader,
2160 : const std::pair<MSVehicle* const, double>& neighLead,
2161 : const std::pair<MSVehicle* const, double>& neighFollow,
2162 : const std::vector<MSVehicle::LaneQ>& preb) {
2163 453608 : const bool isOpposite = vehicle->getLaneChangeModel().isOpposite();
2164 : MSLane* source = vehicle->getMutableLane();
2165 453608 : const std::pair<MSVehicle* const, double> follower(nullptr, -1);
2166 453608 : int state = checkChange(laneOffset, targetLane, leader, follower, neighLead, neighFollow, preb);
2167 453608 : vehicle->getLaneChangeModel().setOwnState(state);
2168 453608 : bool changingAllowed = (state & LCA_BLOCKED) == 0;
2169 : // change if the vehicle wants to and is allowed to change
2170 453608 : if ((state & LCA_WANTS_LANECHANGE) != 0 && changingAllowed
2171 : // do not change to the opposite direction for cooperative reasons
2172 38760 : && (isOpposite || (state & LCA_COOPERATIVE) == 0)) {
2173 38748 : const bool continuous = vehicle->getLaneChangeModel().startLaneChangeManeuver(source, targetLane, laneOffset);
2174 : #ifdef DEBUG_CHANGE_OPPOSITE
2175 : if (DEBUG_COND) {
2176 : std::cout << SIMTIME << " changing to opposite veh=" << vehicle->getID() << " dir=" << laneOffset << " opposite=" << Named::getIDSecure(targetLane)
2177 : << " state=" << toString((LaneChangeAction)state) << "\n";
2178 : }
2179 : #endif
2180 38748 : if (continuous) {
2181 2632 : continueChange(vehicle, myCandi);
2182 : }
2183 38748 : return true;
2184 : }
2185 : #ifdef DEBUG_CHANGE_OPPOSITE
2186 : if (DEBUG_COND) {
2187 : std::cout << SIMTIME << " not changing to opposite veh=" << vehicle->getID() << " dir=" << laneOffset
2188 : << " opposite=" << Named::getIDSecure(targetLane) << " state=" << toString((LaneChangeAction)state) << "\n";
2189 : }
2190 : #endif
2191 : return false;
2192 : }
2193 :
2194 :
2195 : void
2196 5317322 : MSLaneChanger::computeOvertakingTime(const MSVehicle* vehicle, double vMax, const MSVehicle* leader, double gap, double& timeToOvertake, double& spaceToOvertake) {
2197 : // Assumptions:
2198 : // - leader maintains the current speed
2199 : // - vehicle merges with maxSpeed ahead of leader
2200 : // XXX affected by ticket #860 (the formula is invalid for the current position update rule)
2201 :
2202 : // first compute these values for the case where vehicle is accelerating
2203 : // without upper bound on speed
2204 5317322 : const double v = vehicle->getSpeed();
2205 5317322 : const double u = leader->getAcceleration() > 0 ? leader->getLane()->getVehicleMaxSpeed(leader) : leader->getSpeed();
2206 : const double a = vehicle->getCarFollowModel().getMaxAccel();
2207 : const double d = vehicle->getCarFollowModel().getMaxDecel();
2208 5317322 : const double g = MAX2(0.0, (
2209 : // drive up to the rear of leader
2210 5317322 : gap + vehicle->getVehicleType().getMinGap()
2211 : // drive head-to-head with the leader
2212 5317322 : + leader->getVehicleType().getLengthWithGap()
2213 : // drive past the leader
2214 5317322 : + vehicle->getVehicleType().getLength()
2215 : // allow for safe gap between leader and vehicle
2216 5317322 : + leader->getCarFollowModel().getSecureGap(leader, vehicle, u, vMax, d))
2217 : // time to move between lanes
2218 5317322 : + (MSGlobals::gSublane ? vMax * vehicle->getLane()->getWidth() / vehicle->getVehicleType().getMaxSpeedLat() : 0));
2219 : const double sign = -1; // XXX recheck
2220 : // v*t + t*t*a*0.5 = g + u*t
2221 : // solve t
2222 : // t = ((u - v - (((((2.0*(u - v))**2.0) + (8.0*a*g))**(1.0/2.0))*sign/2.0))/a)
2223 5317322 : double t = (u - v - sqrt(4 * (u - v) * (u - v) + 8 * a * g) * sign * 0.5) / a;
2224 : #ifdef DEBUG_CHANGE_OPPOSITE_OVERTAKINGTIME
2225 : if (DEBUG_COND) {
2226 : std::cout << " computeOvertakingTime v=" << v << " vMax=" << vMax << " u=" << u << " a=" << a << " d=" << d << " gap=" << gap << " g=" << g << " t=" << t
2227 : << " distEgo=" << v* t + t* t* a * 0.5 << " distLead=" << g + u* t
2228 : << "\n";
2229 : }
2230 : #endif
2231 : assert(t >= 0);
2232 5317322 : if (vMax <= u) {
2233 : // do not try to overtake faster leader
2234 1368329 : timeToOvertake = std::numeric_limits<double>::max();
2235 1368329 : spaceToOvertake = std::numeric_limits<double>::max();
2236 1368329 : return;
2237 : }
2238 :
2239 : // allow for a safety time gap
2240 3948993 : t += OPPOSITE_OVERTAKING_SAFE_TIMEGAP;
2241 : // round to multiples of step length (TS)
2242 3948993 : if (u > 0) {
2243 2314285 : t = ceil(t / TS) * TS;
2244 : }
2245 :
2246 : /// XXX ignore speed limit when overtaking through the opposite lane?
2247 3948993 : const double timeToMaxSpeed = (vMax - v) / a;
2248 :
2249 : #ifdef DEBUG_CHANGE_OPPOSITE_OVERTAKINGTIME
2250 : if (DEBUG_COND) {
2251 : std::cout << " t=" << t << " tvMax=" << timeToMaxSpeed << "\n";
2252 : }
2253 : #endif
2254 3948993 : if (t <= timeToMaxSpeed) {
2255 181279 : timeToOvertake = t;
2256 181279 : spaceToOvertake = v * t + t * t * a * 0.5;
2257 : #ifdef DEBUG_CHANGE_OPPOSITE_OVERTAKINGTIME
2258 : if (DEBUG_COND) {
2259 : std::cout << " sto=" << spaceToOvertake << "\n";
2260 : }
2261 : #endif
2262 : } else {
2263 : // space until max speed is reached
2264 3767714 : const double s = v * timeToMaxSpeed + timeToMaxSpeed * timeToMaxSpeed * a * 0.5;
2265 : const double m = timeToMaxSpeed;
2266 : // s + (t-m) * vMax = g + u*t
2267 : // solve t
2268 3767714 : t = (g - s + m * vMax) / (vMax - u);
2269 3767714 : if (t < 0) {
2270 : // cannot overtake in time
2271 : #ifdef DEBUG_CHANGE_OPPOSITE_OVERTAKINGTIME
2272 : if (DEBUG_COND) {
2273 : std::cout << " t2=" << t << "\n";
2274 : }
2275 : #endif
2276 0 : timeToOvertake = std::numeric_limits<double>::max();
2277 0 : spaceToOvertake = std::numeric_limits<double>::max();
2278 0 : return;
2279 : } else {
2280 : // allow for a safety time gap
2281 3767714 : t += OPPOSITE_OVERTAKING_SAFE_TIMEGAP;
2282 : // round to multiples of step length (TS)
2283 3767714 : if (u > 0) {
2284 2293403 : t = ceil(t / TS) * TS;
2285 : }
2286 3767714 : timeToOvertake = t;
2287 3767714 : spaceToOvertake = s + (t - m) * vMax;
2288 : #ifdef DEBUG_CHANGE_OPPOSITE_OVERTAKINGTIME
2289 : if (DEBUG_COND) {
2290 : std::cout << " t2=" << t << " s=" << s << " sto=" << spaceToOvertake << " m=" << m << "\n";
2291 : }
2292 : #endif
2293 : }
2294 : }
2295 3948993 : const double safetyFactor = OPPOSITE_OVERTAKING_SAFETY_FACTOR * vehicle->getLaneChangeModel().getOppositeSafetyFactor();
2296 3948993 : timeToOvertake *= safetyFactor;
2297 3948993 : if (STEPS2TIME(leader->getStopDuration()) < timeToOvertake) {
2298 2515334 : spaceToOvertake *= safetyFactor;
2299 : }
2300 3948993 : double frac = fmod(timeToOvertake, TS);
2301 3948993 : if (frac > 0) {
2302 : // round to full sim step
2303 3630466 : timeToOvertake += TS - frac;
2304 : }
2305 : #ifdef DEBUG_CHANGE_OPPOSITE_OVERTAKINGTIME
2306 : if (DEBUG_COND) {
2307 : if (safetyFactor != 1) {
2308 : std::cout << " applying safetyFactor=" << safetyFactor
2309 : << " leaderStopTime=" << STEPS2TIME(leader->getStopDuration())
2310 : << " tto=" << timeToOvertake << " sto=" << spaceToOvertake << "\n";
2311 : }
2312 : }
2313 : #endif
2314 : }
2315 :
2316 :
2317 :
2318 : std::pair<MSVehicle*, double>
2319 6885025 : MSLaneChanger::getColumnleader(double& maxSpace, MSVehicle* vehicle, std::pair<MSVehicle*, double> leader, double maxLookAhead) {
2320 : assert(leader.first != 0);
2321 6885025 : const MSLane* source = vehicle->getLane();
2322 : // find a leader vehicle with sufficient space ahead for merging back
2323 6885025 : const double overtakingSpeed = source->getVehicleMaxSpeed(vehicle); // just a guess
2324 : const double mergeBrakeGap = vehicle->getCarFollowModel().brakeGap(overtakingSpeed);
2325 : std::pair<MSVehicle*, double> columnLeader = leader;
2326 : double egoGap = leader.second;
2327 : bool foundSpaceAhead = false;
2328 6885025 : double seen = leader.second + leader.first->getVehicleType().getLengthWithGap();
2329 6885025 : std::vector<MSLane*> conts = vehicle->getBestLanesContinuation();
2330 6885025 : if (maxLookAhead == std::numeric_limits<double>::max()) {
2331 6879962 : maxLookAhead = (vehicle->getVehicleType().getVehicleClass() == SVC_EMERGENCY
2332 6879962 : ? OPPOSITE_OVERTAKING_MAX_LOOKAHEAD_EMERGENCY
2333 : : OPPOSITE_OVERTAKING_MAX_LOOKAHEAD);
2334 6879962 : maxLookAhead = MAX2(maxLookAhead, mergeBrakeGap + 10
2335 6879962 : + vehicle->getVehicleType().getLengthWithGap()
2336 6879962 : + leader.first->getVehicleType().getLengthWithGap());
2337 : }
2338 : #ifdef DEBUG_CHANGE_OPPOSITE
2339 : if (DEBUG_COND) {
2340 : std::cout << " getColumnleader vehicle=" << vehicle->getID() << " leader=" << leader.first->getID() << " gap=" << leader.second << " maxLookAhead=" << maxLookAhead << "\n";
2341 : }
2342 : #endif
2343 6885025 : const double safetyFactor = OPPOSITE_OVERTAKING_SAFETY_FACTOR * vehicle->getLaneChangeModel().getOppositeSafetyFactor();
2344 43647583 : while (!foundSpaceAhead) {
2345 39387310 : const double requiredSpaceAfterLeader = (columnLeader.first->getCarFollowModel().getSecureGap(
2346 : columnLeader.first, vehicle,
2347 39387310 : columnLeader.first->getSpeed(), overtakingSpeed, vehicle->getCarFollowModel().getMaxDecel())
2348 39387310 : + columnLeader.first->getVehicleType().getMinGap()
2349 39387310 : + vehicle->getVehicleType().getLengthWithGap());
2350 :
2351 :
2352 : // all leader vehicles on the current laneChanger edge are already moved into MSLane::myTmpVehicles
2353 39387310 : const bool checkTmpVehicles = (&columnLeader.first->getLane()->getEdge() == &source->getEdge());
2354 39387310 : double searchStart = columnLeader.first->getPositionOnLane();
2355 39387310 : std::pair<MSVehicle*, double> leadLead = columnLeader.first->getLane()->getLeader(
2356 : columnLeader.first, searchStart, conts, requiredSpaceAfterLeader + mergeBrakeGap,
2357 : checkTmpVehicles);
2358 : std::set<MSVehicle*> seenLeaders;
2359 40174167 : while (leadLead.first != nullptr && leadLead.first->getLaneChangeModel().isOpposite()) {
2360 : #ifdef DEBUG_CHANGE_OPPOSITE
2361 : if (DEBUG_COND) {
2362 : std::cout << " skipping opposite leadLead=" << leadLead.first->getID() << " gap=" << leadLead.second << "\n";
2363 : }
2364 : #endif
2365 1022152 : if (leadLead.second + seen > maxLookAhead || seenLeaders.count(leadLead.first) > 0) {
2366 235295 : leadLead.first = nullptr;
2367 235295 : break;
2368 : }
2369 : seenLeaders.insert(leadLead.first);
2370 : // found via shadow lane, skip it
2371 786857 : const double searchStart2 = searchStart + MAX2(0.0, leadLead.second) + leadLead.first->getVehicleType().getLengthWithGap();
2372 786857 : leadLead = columnLeader.first->getLane()->getLeader(
2373 : columnLeader.first, searchStart2, conts, requiredSpaceAfterLeader + mergeBrakeGap,
2374 : checkTmpVehicles);
2375 786857 : leadLead.second += (searchStart2 - searchStart);
2376 : }
2377 39387310 : if (leadLead.first == nullptr) {
2378 1796416 : double availableSpace = columnLeader.first->getLane()->getLength() - columnLeader.first->getPositionOnLane();
2379 1796416 : double requiredSpace = safetyFactor * requiredSpaceAfterLeader;
2380 1796416 : if (!columnLeader.first->isStopped()) {
2381 : // if the leader is stopped we can trade space for time
2382 842821 : requiredSpace += safetyFactor * mergeBrakeGap;
2383 : }
2384 : #ifdef DEBUG_CHANGE_OPPOSITE
2385 : if (DEBUG_COND) {
2386 : std::cout << " no direct leader found after columnLeader " << columnLeader.first->getID()
2387 : << " availableSpace=" << availableSpace
2388 : << " reqAfterLeader=" << requiredSpaceAfterLeader
2389 : << " ovSpeed=" << overtakingSpeed
2390 : << " reqBGap=" << mergeBrakeGap
2391 : << " reqMin=" << requiredSpace / safetyFactor
2392 : << " req=" << requiredSpace
2393 : << "\n";
2394 : }
2395 : #endif
2396 1796416 : if (availableSpace > requiredSpace) {
2397 : foundSpaceAhead = true;
2398 : } else {
2399 : // maybe the columnleader is stopped before a junction or takes a different turn.
2400 : // try to find another columnleader on successive lanes
2401 390976 : const bool allowMinor = vehicle->getVehicleType().getVehicleClass() == SVC_EMERGENCY;
2402 390976 : bool contsEnd = false;
2403 390976 : const MSLane* next = getLaneAfter(columnLeader.first->getLane(), conts, allowMinor, contsEnd);
2404 : #ifdef DEBUG_CHANGE_OPPOSITE
2405 : if (DEBUG_COND) {
2406 : std::cout << " look for another leader on lane " << Named::getIDSecure(next) << "\n";
2407 : }
2408 : #endif
2409 424001 : while (next != nullptr && seen < maxLookAhead) {
2410 102079 : seen += next->getLength();
2411 102079 : MSVehicle* cand = next->getLastAnyVehicle();
2412 102079 : if (cand == nullptr) {
2413 80275 : availableSpace += next->getLength();
2414 80275 : if (availableSpace > requiredSpace) {
2415 : foundSpaceAhead = true;
2416 : break;
2417 : }
2418 33025 : next = getLaneAfter(next, conts, allowMinor, contsEnd);
2419 : } else {
2420 21804 : availableSpace += cand->getBackPositionOnLane();
2421 21804 : if (availableSpace > requiredSpace) {
2422 : foundSpaceAhead = true;
2423 : break;
2424 : } else {
2425 5063 : return getColumnleader(maxSpace, vehicle, std::make_pair(cand, availableSpace + cand->getPositionOnLane()), maxLookAhead - seen);
2426 : }
2427 : }
2428 : }
2429 : #ifdef DEBUG_CHANGE_OPPOSITE
2430 : if (DEBUG_COND) {
2431 : std::cout << " foundSpaceAhead=" << foundSpaceAhead << " availableSpace=" << availableSpace << " next=" << Named::getIDSecure(next) << " contsEnd=" << contsEnd << " conts=" << toString(conts) << "\n";
2432 : }
2433 : #endif
2434 385913 : if (!foundSpaceAhead && contsEnd) {
2435 : foundSpaceAhead = true;
2436 : availableSpace = requiredSpace;
2437 : }
2438 385913 : if (!foundSpaceAhead) {
2439 88393 : return std::make_pair(nullptr, -1);
2440 : }
2441 : }
2442 1702960 : maxSpace = egoGap + columnLeader.first->getVehicleType().getLength() + availableSpace;
2443 : } else {
2444 37590894 : const double sGap = vehicle->getCarFollowModel().getSecureGap(vehicle, leadLead.first,
2445 37590894 : overtakingSpeed, leadLead.first->getSpeed(), leadLead.first->getCarFollowModel().getMaxDecel());
2446 37590894 : double requiredSpace = safetyFactor * requiredSpaceAfterLeader;
2447 37590894 : if (!columnLeader.first->isStopped()) {
2448 : // if the leader is stopped we can trade space for time
2449 34500454 : requiredSpace += safetyFactor * sGap;
2450 : }
2451 : #ifdef DEBUG_CHANGE_OPPOSITE
2452 : if (DEBUG_COND) {
2453 : std::cout << " leader's leader " << leadLead.first->getID() << " space=" << leadLead.second
2454 : << " reqAfterLeader=" << requiredSpaceAfterLeader
2455 : << " ovSpeed=" << overtakingSpeed
2456 : << " reqSGap=" << sGap
2457 : << " reqMin=" << requiredSpace / safetyFactor
2458 : << " req=" << requiredSpace
2459 : << "\n";
2460 : }
2461 : #endif
2462 37590894 : if (leadLead.second > requiredSpace) {
2463 : foundSpaceAhead = true;
2464 2557313 : maxSpace = egoGap + columnLeader.first->getVehicleType().getLength() + leadLead.second;
2465 : } else {
2466 :
2467 35033581 : if (leadLead.second < 0) {
2468 : // must be a junction leader or some other dangerous situation
2469 : #ifdef DEBUG_CHANGE_OPPOSITE
2470 : if (DEBUG_COND) {
2471 : std::cout << " leader's leader " << leadLead.first->getID() << " gap=" << leadLead.second << " is junction leader (aborting)\n";
2472 : }
2473 : #endif
2474 124650 : return std::make_pair(nullptr, -1);
2475 : }
2476 :
2477 : #ifdef DEBUG_CHANGE_OPPOSITE
2478 : if (DEBUG_COND) {
2479 : std::cout << " not enough space after columnLeader=" << columnLeader.first->getID() << " required=" << requiredSpace << "\n";
2480 : }
2481 : #endif
2482 34908931 : seen += MAX2(0., leadLead.second) + leadLead.first->getVehicleType().getLengthWithGap();
2483 34908931 : if (seen > maxLookAhead) {
2484 : #ifdef DEBUG_CHANGE_OPPOSITE
2485 : if (DEBUG_COND) {
2486 : std::cout << " cannot changeOpposite due to insufficient free space after columnLeader (seen=" << seen << " columnLeader=" << columnLeader.first->getID() << ")\n";
2487 : }
2488 : #endif
2489 2406646 : return std::make_pair(nullptr, -1);
2490 : }
2491 : // see if merging after leadLead is possible
2492 32502285 : egoGap += columnLeader.first->getVehicleType().getLengthWithGap() + leadLead.second;
2493 : columnLeader = leadLead;
2494 : #ifdef DEBUG_CHANGE_OPPOSITE
2495 : if (DEBUG_COND) {
2496 : std::cout << " new columnLeader=" << columnLeader.first->getID() << "\n";
2497 : }
2498 : #endif
2499 : }
2500 : }
2501 : }
2502 : columnLeader.second = egoGap;
2503 4260273 : return columnLeader;
2504 6885025 : }
2505 :
2506 :
2507 : const MSLane*
2508 424001 : MSLaneChanger::getLaneAfter(const MSLane* lane, const std::vector<MSLane*>& conts, bool allowMinor, bool& contsEnd) {
2509 552608 : for (auto it = conts.begin(); it != conts.end(); ++it) {
2510 532668 : if (*it == lane) {
2511 404061 : if (it + 1 != conts.end()) {
2512 : // abort on minor link
2513 170532 : const MSLane* next = *(it + 1);
2514 170532 : const MSLink* link = lane->getLinkTo(next);
2515 170532 : if (link == nullptr || (!allowMinor && !link->havePriority())) {
2516 : return nullptr;
2517 : }
2518 : return next;
2519 : } else {
2520 233529 : contsEnd = true;
2521 233529 : return nullptr;
2522 : }
2523 : }
2524 : }
2525 : return nullptr;
2526 : }
2527 :
2528 : double
2529 4833283 : MSLaneChanger::getMaxOvertakingSpeed(const MSVehicle* vehicle, double maxSpaceToOvertake) {
2530 : // v*v/2*a + v*v/2*d = maxSpaceToOvertake
2531 : const double a = vehicle->getCarFollowModel().getMaxAccel();
2532 : const double d = vehicle->getCarFollowModel().getMaxDecel();
2533 4833283 : const double v = sqrt(2 * maxSpaceToOvertake * a * d / (a + d));
2534 4833283 : return v;
2535 : }
2536 :
2537 : /****************************************************************************/
|