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