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