Eclipse SUMO - Simulation of Urban MObility
MSVehicle.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
27 // Representation of a vehicle in the micro simulation
28 /****************************************************************************/
29 
30 // ===========================================================================
31 // included modules
32 // ===========================================================================
33 #include <config.h>
34 
35 #include <iostream>
36 #include <cassert>
37 #include <cmath>
38 #include <cstdlib>
39 #include <algorithm>
40 #include <map>
41 #include <memory>
42 #include <utils/common/ToString.h>
49 #include <utils/common/StdDefs.h>
50 #include <utils/geom/GeomHelper.h>
65 #include "MSEdgeControl.h"
66 #include "MSVehicleControl.h"
67 #include "MSVehicleTransfer.h"
68 #include "MSGlobals.h"
69 #include "MSJunctionLogic.h"
70 #include "MSStoppingPlace.h"
71 #include "MSParkingArea.h"
73 #include "MSEdgeWeightsStorage.h"
75 #include "MSMoveReminder.h"
76 #include "MSTransportableControl.h"
77 #include "MSLane.h"
78 #include "MSJunction.h"
79 #include "MSVehicle.h"
80 #include "MSEdge.h"
81 #include "MSVehicleType.h"
82 #include "MSNet.h"
83 #include "MSRoute.h"
84 #include "MSLinkCont.h"
85 #include "MSLeaderInfo.h"
86 #include "MSDriverState.h"
87 
88 //#define DEBUG_PLAN_MOVE
89 //#define DEBUG_PLAN_MOVE_LEADERINFO
90 //#define DEBUG_CHECKREWINDLINKLANES
91 //#define DEBUG_EXEC_MOVE
92 //#define DEBUG_FURTHER
93 //#define DEBUG_SETFURTHER
94 //#define DEBUG_TARGET_LANE
95 //#define DEBUG_STOPS
96 //#define DEBUG_BESTLANES
97 //#define DEBUG_IGNORE_RED
98 //#define DEBUG_ACTIONSTEPS
99 //#define DEBUG_NEXT_TURN
100 //#define DEBUG_TRACI
101 //#define DEBUG_REVERSE_BIDI
102 //#define DEBUG_REPLACE_ROUTE
103 //#define DEBUG_COND (getID() == "follower")
104 //#define DEBUG_COND (true)
105 #define DEBUG_COND (isSelected())
106 //#define DEBUG_COND2(obj) (obj->getID() == "follower")
107 #define DEBUG_COND2(obj) (obj->isSelected())
108 
109 
110 #define STOPPING_PLACE_OFFSET 0.5
111 
112 #define CRLL_LOOK_AHEAD 5
113 
114 #define JUNCTION_BLOCKAGE_TIME 5 // s
115 
116 // @todo Calibrate with real-world values / make configurable
117 #define DIST_TO_STOPLINE_EXPECT_PRIORITY 1.0
118 
119 #define NUMERICAL_EPS_SPEED (0.1 * NUMERICAL_EPS * TS)
120 
121 // ===========================================================================
122 // static value definitions
123 // ===========================================================================
124 std::vector<MSLane*> MSVehicle::myEmptyLaneVector;
125 
126 
127 // ===========================================================================
128 // method definitions
129 // ===========================================================================
130 /* -------------------------------------------------------------------------
131  * methods of MSVehicle::State
132  * ----------------------------------------------------------------------- */
134  myPos = state.myPos;
135  mySpeed = state.mySpeed;
136  myPosLat = state.myPosLat;
137  myBackPos = state.myBackPos;
140 }
141 
142 
145  myPos = state.myPos;
146  mySpeed = state.mySpeed;
147  myPosLat = state.myPosLat;
148  myBackPos = state.myBackPos;
149  myPreviousSpeed = state.myPreviousSpeed;
150  myLastCoveredDist = state.myLastCoveredDist;
151  return *this;
152 }
153 
154 
155 bool
157  return (myPos != state.myPos ||
158  mySpeed != state.mySpeed ||
159  myPosLat != state.myPosLat ||
160  myLastCoveredDist != state.myLastCoveredDist ||
161  myPreviousSpeed != state.myPreviousSpeed ||
162  myBackPos != state.myBackPos);
163 }
164 
165 
166 MSVehicle::State::State(double pos, double speed, double posLat, double backPos) :
167  myPos(pos), mySpeed(speed), myPosLat(posLat), myBackPos(backPos), myPreviousSpeed(speed), myLastCoveredDist(SPEED2DIST(speed)) {}
168 
169 
170 
171 /* -------------------------------------------------------------------------
172  * methods of MSVehicle::WaitingTimeCollector
173  * ----------------------------------------------------------------------- */
174 
176 
177 MSVehicle::WaitingTimeCollector::WaitingTimeCollector(const WaitingTimeCollector& wt) : myMemorySize(wt.getMemorySize()), myWaitingIntervals(wt.getWaitingIntervals()) {}
178 
181  myMemorySize = wt.getMemorySize();
182  myWaitingIntervals = wt.getWaitingIntervals();
183  return *this;
184 }
185 
188  myWaitingIntervals.clear();
189  passTime(t, true);
190  return *this;
191 }
192 
193 SUMOTime
195  assert(memorySpan <= myMemorySize);
196  if (memorySpan == -1) {
197  memorySpan = myMemorySize;
198  }
199  SUMOTime totalWaitingTime = 0;
200  for (waitingIntervalList::const_iterator i = myWaitingIntervals.begin(); i != myWaitingIntervals.end(); i++) {
201  if (i->second >= memorySpan) {
202  if (i->first >= memorySpan) {
203  break;
204  } else {
205  totalWaitingTime += memorySpan - i->first;
206  }
207  } else {
208  totalWaitingTime += i->second - i->first;
209  }
210  }
211  return totalWaitingTime;
212 }
213 
214 void
216  waitingIntervalList::iterator i = myWaitingIntervals.begin();
217  waitingIntervalList::iterator end = myWaitingIntervals.end();
218  bool startNewInterval = i == end || (i->first != 0);
219  while (i != end) {
220  i->first += dt;
221  if (i->first >= myMemorySize) {
222  break;
223  }
224  i->second += dt;
225  i++;
226  }
227 
228  // remove intervals beyond memorySize
229  waitingIntervalList::iterator::difference_type d = std::distance(i, end);
230  while (d > 0) {
231  myWaitingIntervals.pop_back();
232  d--;
233  }
234 
235  if (!waiting) {
236  return;
237  } else if (!startNewInterval) {
238  myWaitingIntervals.begin()->first = 0;
239  } else {
240  myWaitingIntervals.push_front(std::make_pair(0, dt));
241  }
242  return;
243 }
244 
245 
246 
247 
248 /* -------------------------------------------------------------------------
249  * methods of MSVehicle::Influencer::GapControlState
250  * ----------------------------------------------------------------------- */
251 void
253 // std::cout << "GapControlVehStateListener::vehicleStateChanged() vehicle=" << vehicle->getID() << ", to=" << to << std::endl;
254  switch (to) {
258  // Vehicle left road
259 // Look up reference vehicle in refVehMap and in case deactivate corresponding gap control
260  const MSVehicle* msVeh = static_cast<const MSVehicle*>(vehicle);
261 // std::cout << "GapControlVehStateListener::vehicleStateChanged() vehicle=" << vehicle->getID() << " left the road." << std::endl;
262  if (GapControlState::refVehMap.find(msVeh) != end(GapControlState::refVehMap)) {
263 // std::cout << "GapControlVehStateListener::deactivating ref vehicle=" << vehicle->getID() << std::endl;
264  GapControlState::refVehMap[msVeh]->deactivate();
265  }
266  }
267  break;
268  default:
269  {};
270  // do nothing, vehicle still on road
271  }
272 }
273 
274 std::map<const MSVehicle*, MSVehicle::Influencer::GapControlState*>
276 
279 
281  tauOriginal(-1), tauCurrent(-1), tauTarget(-1), addGapCurrent(-1), addGapTarget(-1),
282  remainingDuration(-1), changeRate(-1), maxDecel(-1), referenceVeh(nullptr), active(false), gapAttained(false), prevLeader(nullptr),
283  lastUpdate(-1), timeHeadwayIncrement(0.0), spaceHeadwayIncrement(0.0) {}
284 
285 
287  deactivate();
288 }
289 
290 void
292 // std::cout << "GapControlState::init()" << std::endl;
293  if (MSNet::hasInstance()) {
294  MSNet::VehicleStateListener* vsl = dynamic_cast<MSNet::VehicleStateListener*>(&vehStateListener);
296  } else {
297  WRITE_ERROR("MSVehicle::Influencer::GapControlState::init(): No MSNet instance found!")
298  }
299 }
300 
301 void
303  MSNet::VehicleStateListener* vsl = dynamic_cast<MSNet::VehicleStateListener*>(&vehStateListener);
305 }
306 
307 void
308 MSVehicle::Influencer::GapControlState::activate(double tauOrig, double tauNew, double additionalGap, double dur, double rate, double decel, const MSVehicle* refVeh) {
310  WRITE_ERROR("No gap control available for meso.")
311  } else {
312  // always deactivate control before activating (triggers clean-up of refVehMap)
313 // std::cout << "activate gap control with refVeh=" << (refVeh==nullptr? "NULL" : refVeh->getID()) << std::endl;
314  tauOriginal = tauOrig;
315  tauCurrent = tauOrig;
316  tauTarget = tauNew;
317  addGapCurrent = 0.0;
318  addGapTarget = additionalGap;
319  remainingDuration = dur;
320  changeRate = rate;
321  maxDecel = decel;
322  referenceVeh = refVeh;
323  active = true;
324  gapAttained = false;
325  prevLeader = nullptr;
326  lastUpdate = SIMSTEP - DELTA_T;
327  timeHeadwayIncrement = changeRate * TS * (tauTarget - tauOriginal);
328  spaceHeadwayIncrement = changeRate * TS * addGapTarget;
329 
330  if (referenceVeh != nullptr) {
331  // Add refVeh to refVehMap
332  GapControlState::refVehMap[referenceVeh] = this;
333  }
334  }
335 }
336 
337 void
339  active = false;
340  if (referenceVeh != nullptr) {
341  // Remove corresponding refVehMapEntry if appropriate
342  GapControlState::refVehMap.erase(referenceVeh);
343  referenceVeh = nullptr;
344  }
345 }
346 
347 
348 /* -------------------------------------------------------------------------
349  * methods of MSVehicle::Influencer
350  * ----------------------------------------------------------------------- */
352  myGapControlState(nullptr),
353  myOriginalSpeed(-1),
354  myLatDist(0),
368  myTraCISignals(-1),
369  myRoutingMode(0)
370 {}
371 
372 
374 
375 void
377  GapControlState::init();
378 }
379 
380 void
382  GapControlState::cleanup();
383 }
384 
385 void
386 MSVehicle::Influencer::setSpeedTimeLine(const std::vector<std::pair<SUMOTime, double> >& speedTimeLine) {
387  mySpeedAdaptationStarted = true;
388  mySpeedTimeLine = speedTimeLine;
389 }
390 
391 void
392 MSVehicle::Influencer::activateGapController(double originalTau, double newTimeHeadway, double newSpaceHeadway, double duration, double changeRate, double maxDecel, MSVehicle* refVeh) {
393  if (myGapControlState == nullptr) {
394  myGapControlState = std::make_shared<GapControlState>();
395  }
396  myGapControlState->activate(originalTau, newTimeHeadway, newSpaceHeadway, duration, changeRate, maxDecel, refVeh);
397 }
398 
399 void
401  if (myGapControlState != nullptr && myGapControlState->active) {
402  myGapControlState->deactivate();
403  }
404 }
405 
406 void
407 MSVehicle::Influencer::setLaneTimeLine(const std::vector<std::pair<SUMOTime, int> >& laneTimeLine) {
408  myLaneTimeLine = laneTimeLine;
409 }
410 
411 
412 void
414  for (auto& item : myLaneTimeLine) {
415  item.second += indexShift;
416  }
417 }
418 
419 
420 void
422  myLatDist = latDist;
423 }
424 
425 int
427  return (1 * myConsiderSafeVelocity +
428  2 * myConsiderMaxAcceleration +
429  4 * myConsiderMaxDeceleration +
430  8 * myRespectJunctionPriority +
431  16 * myEmergencyBrakeRedLight);
432 }
433 
434 
435 int
437  return (1 * myStrategicLC +
438  4 * myCooperativeLC +
439  16 * mySpeedGainLC +
440  64 * myRightDriveLC +
441  256 * myTraciLaneChangePriority +
442  1024 * mySublaneLC);
443 }
444 
445 SUMOTime
447  SUMOTime duration = -1;
448  for (std::vector<std::pair<SUMOTime, int>>::iterator i = myLaneTimeLine.begin(); i != myLaneTimeLine.end(); ++i) {
449  if (duration < 0) {
450  duration = i->first;
451  } else {
452  duration -= i->first;
453  }
454  }
455  return -duration;
456 }
457 
458 SUMOTime
460  if (!myLaneTimeLine.empty()) {
461  return myLaneTimeLine.back().first;
462  } else {
463  return -1;
464  }
465 }
466 
467 
468 double
469 MSVehicle::Influencer::influenceSpeed(SUMOTime currentTime, double speed, double vSafe, double vMin, double vMax) {
470  // keep original speed
471  myOriginalSpeed = speed;
472 
473  // remove leading commands which are no longer valid
474  while (mySpeedTimeLine.size() == 1 || (mySpeedTimeLine.size() > 1 && currentTime > mySpeedTimeLine[1].first)) {
475  mySpeedTimeLine.erase(mySpeedTimeLine.begin());
476  }
477 
478  if (!(mySpeedTimeLine.size() < 2 || currentTime < mySpeedTimeLine[0].first)) {
479  // Speed advice is active -> compute new speed according to speedTimeLine
480  if (!mySpeedAdaptationStarted) {
481  mySpeedTimeLine[0].second = speed;
482  mySpeedAdaptationStarted = true;
483  }
484  currentTime += DELTA_T;
485  const double td = STEPS2TIME(currentTime - mySpeedTimeLine[0].first) / STEPS2TIME(mySpeedTimeLine[1].first + DELTA_T - mySpeedTimeLine[0].first);
486  speed = mySpeedTimeLine[0].second - (mySpeedTimeLine[0].second - mySpeedTimeLine[1].second) * td;
487  if (myConsiderSafeVelocity) {
488  speed = MIN2(speed, vSafe);
489  }
490  if (myConsiderMaxAcceleration) {
491  speed = MIN2(speed, vMax);
492  }
493  if (myConsiderMaxDeceleration) {
494  speed = MAX2(speed, vMin);
495  }
496  }
497  return speed;
498 }
499 
500 double
501 MSVehicle::Influencer::gapControlSpeed(SUMOTime currentTime, const SUMOVehicle* veh, double speed, double vSafe, double vMin, double vMax) {
502 #ifdef DEBUG_TRACI
503  if DEBUG_COND2(veh) {
504  std::cout << currentTime << " Influencer::gapControlSpeed(): speed=" << speed
505  << ", vSafe=" << vSafe
506  << ", vMin=" << vMin
507  << ", vMax=" << vMax
508  << std::endl;
509  }
510 #endif
511  double gapControlSpeed = speed;
512  if (myGapControlState != nullptr && myGapControlState->active) {
513  // Determine leader and the speed that would be chosen by the gap controller
514  const double currentSpeed = veh->getSpeed();
515  const MSVehicle* msVeh = dynamic_cast<const MSVehicle*>(veh);
516  assert(msVeh != nullptr);
517  const double desiredTargetTimeSpacing = myGapControlState->tauTarget * currentSpeed;
518  std::pair<const MSVehicle*, double> leaderInfo;
519  if (myGapControlState->referenceVeh == nullptr) {
520  // No reference vehicle specified -> use current leader as reference
521  leaderInfo = msVeh->getLeader(MAX2(desiredTargetTimeSpacing, myGapControlState->addGapCurrent) + 20.);
522  } else {
523  // Control gap wrt reference vehicle
524  const MSVehicle* leader = myGapControlState->referenceVeh;
525  double dist = msVeh->getDistanceToPosition(leader->getPositionOnLane(), leader->getEdge()) - leader->getLength();
526  if (dist > 100000) {
527  // Reference vehicle was not found downstream the ego's route
528  // Maybe, it is behind the ego vehicle
529  dist = - leader->getDistanceToPosition(msVeh->getPositionOnLane(), msVeh->getEdge()) - leader->getLength();
530 #ifdef DEBUG_TRACI
531  if DEBUG_COND2(veh) {
532  if (dist < -100000) {
533  // also the ego vehicle is not ahead of the reference vehicle -> no CF-relation
534  std::cout << " Ego and reference vehicle are not in CF relation..." << std::endl;
535  } else {
536  std::cout << " Reference vehicle is behind ego..." << std::endl;
537  }
538  }
539 #endif
540  }
541  leaderInfo = std::make_pair(leader, dist - msVeh->getVehicleType().getMinGap());
542  }
543  const double fakeDist = MAX2(0.0, leaderInfo.second - myGapControlState->addGapCurrent);
544 #ifdef DEBUG_TRACI
545  if DEBUG_COND2(veh) {
546  const double desiredCurrentSpacing = myGapControlState->tauCurrent * currentSpeed;
547  std::cout << " Gap control active:"
548  << " currentSpeed=" << currentSpeed
549  << ", desiredTargetTimeSpacing=" << desiredTargetTimeSpacing
550  << ", desiredCurrentSpacing=" << desiredCurrentSpacing
551  << ", leader=" << (leaderInfo.first == nullptr ? "NULL" : leaderInfo.first->getID())
552  << ", dist=" << leaderInfo.second
553  << ", fakeDist=" << fakeDist
554  << ",\n tauOriginal=" << myGapControlState->tauOriginal
555  << ", tauTarget=" << myGapControlState->tauTarget
556  << ", tauCurrent=" << myGapControlState->tauCurrent
557  << std::endl;
558  }
559 #endif
560  if (leaderInfo.first != nullptr) {
561  if (myGapControlState->prevLeader != nullptr && myGapControlState->prevLeader != leaderInfo.first) {
562  // TODO: The leader changed. What to do?
563  }
564  // Remember leader
565  myGapControlState->prevLeader = leaderInfo.first;
566 
567  // Calculate desired following speed assuming the alternative headway time
568  MSCFModel* cfm = (MSCFModel*) & (msVeh->getVehicleType().getCarFollowModel());
569  const double origTau = cfm->getHeadwayTime();
570  cfm->setHeadwayTime(myGapControlState->tauCurrent);
571  gapControlSpeed = MIN2(gapControlSpeed,
572  cfm->followSpeed(msVeh, currentSpeed, fakeDist, leaderInfo.first->getSpeed(), leaderInfo.first->getCurrentApparentDecel(), leaderInfo.first));
573  cfm->setHeadwayTime(origTau);
574 #ifdef DEBUG_TRACI
575  if DEBUG_COND2(veh) {
576  std::cout << " -> gapControlSpeed=" << gapControlSpeed;
577  if (myGapControlState->maxDecel > 0) {
578  std::cout << ", with maxDecel bound: " << MAX2(gapControlSpeed, currentSpeed - TS * myGapControlState->maxDecel);
579  }
580  std::cout << std::endl;
581  }
582 #endif
583  if (myGapControlState->maxDecel > 0) {
584  gapControlSpeed = MAX2(gapControlSpeed, currentSpeed - TS * myGapControlState->maxDecel);
585  }
586  }
587 
588  // Update gap controller
589  // Check (1) if the gap control has established the desired gap,
590  // and (2) if it has maintained active for the given duration afterwards
591  if (myGapControlState->lastUpdate < currentTime) {
592 #ifdef DEBUG_TRACI
593  if DEBUG_COND2(veh) {
594  std::cout << " Updating GapControlState." << std::endl;
595  }
596 #endif
597  if (myGapControlState->tauCurrent == myGapControlState->tauTarget && myGapControlState->addGapCurrent == myGapControlState->addGapTarget) {
598  if (!myGapControlState->gapAttained) {
599  // Check if the desired gap was established (add the POSITIONAL_EPS to avoid infinite asymptotic behavior without having established the gap)
600  myGapControlState->gapAttained = leaderInfo.first == nullptr || leaderInfo.second > MAX2(desiredTargetTimeSpacing, myGapControlState->addGapTarget) - POSITION_EPS;
601 #ifdef DEBUG_TRACI
602  if DEBUG_COND2(veh) {
603  if (myGapControlState->gapAttained) {
604  std::cout << " Target gap was established." << std::endl;
605  }
606  }
607 #endif
608  } else {
609  // Count down remaining time if desired gap was established
610  myGapControlState->remainingDuration -= TS;
611 #ifdef DEBUG_TRACI
612  if DEBUG_COND2(veh) {
613  std::cout << " Gap control remaining duration: " << myGapControlState->remainingDuration << std::endl;
614  }
615 #endif
616  if (myGapControlState->remainingDuration <= 0) {
617 #ifdef DEBUG_TRACI
618  if DEBUG_COND2(veh) {
619  std::cout << " Gap control duration expired, deactivating control." << std::endl;
620  }
621 #endif
622  // switch off gap control
623  myGapControlState->deactivate();
624  }
625  }
626  } else {
627  // Adjust current headway values
628  myGapControlState->tauCurrent = MIN2(myGapControlState->tauCurrent + myGapControlState->timeHeadwayIncrement, myGapControlState->tauTarget);
629  myGapControlState->addGapCurrent = MIN2(myGapControlState->addGapCurrent + myGapControlState->spaceHeadwayIncrement, myGapControlState->addGapTarget);
630  }
631  }
632  if (myConsiderSafeVelocity) {
633  gapControlSpeed = MIN2(gapControlSpeed, vSafe);
634  }
635  if (myConsiderMaxAcceleration) {
636  gapControlSpeed = MIN2(gapControlSpeed, vMax);
637  }
638  if (myConsiderMaxDeceleration) {
639  gapControlSpeed = MAX2(gapControlSpeed, vMin);
640  }
641  return MIN2(speed, gapControlSpeed);
642  } else {
643  return speed;
644  }
645 }
646 
647 double
649  return mySpeedTimeLine.empty() ? -1 : myOriginalSpeed;
650 }
651 
652 
653 int
654 MSVehicle::Influencer::influenceChangeDecision(const SUMOTime currentTime, const MSEdge& currentEdge, const int currentLaneIndex, int state) {
655  // remove leading commands which are no longer valid
656  while (myLaneTimeLine.size() == 1 || (myLaneTimeLine.size() > 1 && currentTime > myLaneTimeLine[1].first)) {
657  myLaneTimeLine.erase(myLaneTimeLine.begin());
658  }
659  ChangeRequest changeRequest = REQUEST_NONE;
660  // do nothing if the time line does not apply for the current time
661  if (myLaneTimeLine.size() >= 2 && currentTime >= myLaneTimeLine[0].first) {
662  const int destinationLaneIndex = myLaneTimeLine[1].second;
663  if (destinationLaneIndex < (int)currentEdge.getLanes().size()) {
664  if (currentLaneIndex > destinationLaneIndex) {
665  changeRequest = REQUEST_RIGHT;
666  } else if (currentLaneIndex < destinationLaneIndex) {
667  changeRequest = REQUEST_LEFT;
668  } else {
669  changeRequest = REQUEST_HOLD;
670  }
671  } else if (currentEdge.getLanes().back()->getOpposite() != nullptr) { // change to opposite direction driving
672  changeRequest = REQUEST_LEFT;
673  state = state | LCA_TRACI;
674  }
675  }
676  // check whether the current reason shall be canceled / overridden
677  if ((state & LCA_WANTS_LANECHANGE_OR_STAY) != 0) {
678  // flags for the current reason
679  LaneChangeMode mode = LC_NEVER;
680  if ((state & LCA_TRACI) != 0 && myLatDist != 0) {
681  // security checks
682  if ((myTraciLaneChangePriority == LCP_ALWAYS)
683  || (myTraciLaneChangePriority == LCP_NOOVERLAP && (state & LCA_OVERLAPPING) == 0)) {
684  state &= ~(LCA_BLOCKED | LCA_OVERLAPPING);
685  }
686  // continue sublane change manoeuvre
687  return state;
688  } else if ((state & LCA_STRATEGIC) != 0) {
689  mode = myStrategicLC;
690  } else if ((state & LCA_COOPERATIVE) != 0) {
691  mode = myCooperativeLC;
692  } else if ((state & LCA_SPEEDGAIN) != 0) {
693  mode = mySpeedGainLC;
694  } else if ((state & LCA_KEEPRIGHT) != 0) {
695  mode = myRightDriveLC;
696  } else if ((state & LCA_SUBLANE) != 0) {
697  mode = mySublaneLC;
698  } else if ((state & LCA_TRACI) != 0) {
699  mode = LC_NEVER;
700  } else {
701  WRITE_WARNING("Lane change model did not provide a reason for changing (state=" + toString(state) + ", time=" + time2string(currentTime) + "\n");
702  }
703  if (mode == LC_NEVER) {
704  // cancel all lcModel requests
706  state &= ~LCA_URGENT;
707  } else if (mode == LC_NOCONFLICT && changeRequest != REQUEST_NONE) {
708  if (
709  ((state & LCA_LEFT) != 0 && changeRequest != REQUEST_LEFT) ||
710  ((state & LCA_RIGHT) != 0 && changeRequest != REQUEST_RIGHT) ||
711  ((state & LCA_STAY) != 0 && changeRequest != REQUEST_HOLD)) {
712  // cancel conflicting lcModel request
714  state &= ~LCA_URGENT;
715  }
716  } else if (mode == LC_ALWAYS) {
717  // ignore any TraCI requests
718  return state;
719  }
720  }
721  // apply traci requests
722  if (changeRequest == REQUEST_NONE) {
723  return state;
724  } else {
725  state |= LCA_TRACI;
726  // security checks
727  if ((myTraciLaneChangePriority == LCP_ALWAYS)
728  || (myTraciLaneChangePriority == LCP_NOOVERLAP && (state & LCA_OVERLAPPING) == 0)) {
729  state &= ~(LCA_BLOCKED | LCA_OVERLAPPING);
730  }
731  if (changeRequest != REQUEST_HOLD && myTraciLaneChangePriority != LCP_OPPORTUNISTIC) {
732  state |= LCA_URGENT;
733  }
734  switch (changeRequest) {
735  case REQUEST_HOLD:
736  return state | LCA_STAY;
737  case REQUEST_LEFT:
738  return state | LCA_LEFT;
739  case REQUEST_RIGHT:
740  return state | LCA_RIGHT;
741  default:
742  throw ProcessError("should not happen");
743  }
744  }
745 }
746 
747 
748 double
750  assert(myLaneTimeLine.size() >= 2);
751  assert(currentTime >= myLaneTimeLine[0].first);
752  return STEPS2TIME(myLaneTimeLine[1].first - currentTime);
753 }
754 
755 
756 void
758  myConsiderSafeVelocity = ((speedMode & 1) != 0);
759  myConsiderMaxAcceleration = ((speedMode & 2) != 0);
760  myConsiderMaxDeceleration = ((speedMode & 4) != 0);
761  myRespectJunctionPriority = ((speedMode & 8) != 0);
762  myEmergencyBrakeRedLight = ((speedMode & 16) != 0);
763 }
764 
765 
766 void
768  myStrategicLC = (LaneChangeMode)(value & (1 + 2));
769  myCooperativeLC = (LaneChangeMode)((value & (4 + 8)) >> 2);
770  mySpeedGainLC = (LaneChangeMode)((value & (16 + 32)) >> 4);
771  myRightDriveLC = (LaneChangeMode)((value & (64 + 128)) >> 6);
772  myTraciLaneChangePriority = (TraciLaneChangePriority)((value & (256 + 512)) >> 8);
773  mySublaneLC = (LaneChangeMode)((value & (1024 + 2048)) >> 10);
774 }
775 
776 
777 void
778 MSVehicle::Influencer::setRemoteControlled(Position xyPos, MSLane* l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector& route, SUMOTime t) {
779  myRemoteXYPos = xyPos;
780  myRemoteLane = l;
781  myRemotePos = pos;
782  myRemotePosLat = posLat;
783  myRemoteAngle = angle;
784  myRemoteEdgeOffset = edgeOffset;
785  myRemoteRoute = route;
786  myLastRemoteAccess = t;
787 }
788 
789 
790 bool
792  return myLastRemoteAccess == MSNet::getInstance()->getCurrentTimeStep();
793 }
794 
795 
796 bool
798  return myLastRemoteAccess >= t - TIME2STEPS(10);
799 }
800 
801 void
803  const bool wasOnRoad = v->isOnRoad();
804  const bool keepLane = v->getLane() == myRemoteLane;
805  if (v->isOnRoad() && !keepLane) {
808  }
809  if (myRemoteRoute.size() != 0) {
810  v->replaceRouteEdges(myRemoteRoute, -1, 0, "traci:moveToXY", true);
811  }
812  v->myCurrEdge = v->getRoute().begin() + myRemoteEdgeOffset;
813  if (myRemoteLane != nullptr && myRemotePos > myRemoteLane->getLength()) {
814  myRemotePos = myRemoteLane->getLength();
815  }
816  if (myRemoteLane != nullptr && fabs(myRemotePosLat) < 0.5 * (myRemoteLane->getWidth() + v->getVehicleType().getWidth())) {
817  if (keepLane) {
818  v->myState.myPos = myRemotePos;
819  v->myState.myPosLat = myRemotePosLat;
820  } else {
824  myRemoteLane->forceVehicleInsertion(v, myRemotePos, notify, myRemotePosLat);
825  v->updateBestLanes();
826  }
827  if (!wasOnRoad) {
828  v->drawOutsideNetwork(false);
829  }
830  //std::cout << "on road network p=" << myRemoteXYPos << " a=" << myRemoteAngle << " l=" << Named::getIDSecure(myRemoteLane) << " pos=" << myRemotePos << " posLat=" << myRemotePosLat << "\n";
831  } else {
832  if (v->getDeparture() == NOT_YET_DEPARTED) {
833  v->onDepart();
834  }
835  v->drawOutsideNetwork(true);
836  // see updateState
837  double vNext = v->processTraCISpeedControl(
838  v->getVehicleType().getMaxSpeed(), v->getSpeed());
839  v->setBrakingSignals(vNext);
840  v->updateWaitingTime(vNext);
841  v->myState.myPreviousSpeed = v->getSpeed();
842  v->myAcceleration = SPEED2ACCEL(vNext - v->getSpeed());
843  v->myState.mySpeed = vNext;
844  //std::cout << "outside network p=" << myRemoteXYPos << " a=" << myRemoteAngle << " l=" << Named::getIDSecure(myRemoteLane) << "\n";
845  }
846  // ensure that the position is correct (i.e. when the lanePosition is ambiguous at corners)
847  v->setRemoteState(myRemoteXYPos);
848  v->setAngle(GeomHelper::fromNaviDegree(myRemoteAngle));
849 }
850 
851 
852 double
854  if (veh->getPosition() == Position::INVALID) {
855  return oldSpeed;
856  }
857  double dist = veh->getPosition().distanceTo2D(myRemoteXYPos);
858  if (myRemoteLane != nullptr) {
859  // if the vehicles is frequently placed on a new edge, the route may
860  // consist only of a single edge. In this case the new edge may not be
861  // on the route so distAlongRoute will be double::max.
862  // In this case we still want a sensible speed value
863  const double distAlongRoute = veh->getDistanceToPosition(myRemotePos, &myRemoteLane->getEdge());
864  if (distAlongRoute != std::numeric_limits<double>::max()) {
865  dist = distAlongRoute;
866  }
867  }
868  //std::cout << SIMTIME << " veh=" << veh->getID() << " oldPos=" << veh->getPosition() << " traciPos=" << myRemoteXYPos << " dist=" << dist << "\n";
869  const double minSpeed = myConsiderMaxDeceleration ?
870  veh->getCarFollowModel().minNextSpeedEmergency(oldSpeed, veh) : 0;
871  const double maxSpeed = (myRemoteLane != nullptr
872  ? myRemoteLane->getVehicleMaxSpeed(veh)
873  : (veh->getLane() != nullptr
874  ? veh->getLane()->getVehicleMaxSpeed(veh)
875  : veh->getVehicleType().getMaxSpeed()));
876  return MIN2(maxSpeed, MAX2(minSpeed, DIST2SPEED(dist)));
877 }
878 
879 double
881  double dist = 0;
882  if (myRemoteLane == nullptr) {
883  dist = veh->getPosition().distanceTo2D(myRemoteXYPos);
884  } else {
885  // if the vehicles is frequently placed on a new edge, the route may
886  // consist only of a single edge. In this case the new edge may not be
887  // on the route so getDistanceToPosition will return double::max.
888  // In this case we would rather not move the vehicle in executeMove
889  // (updateState) as it would result in emergency braking
890  dist = veh->getDistanceToPosition(myRemotePos, &myRemoteLane->getEdge());
891  }
892  if (DIST2SPEED(dist) > veh->getMaxSpeed()) {
893  return 0;
894  } else {
895  return dist;
896  }
897 }
898 
899 
901 MSVehicle::Influencer::getRouterTT(const int rngIndex) const {
902  if (myRoutingMode == 1) {
903  return MSRoutingEngine::getRouterTT(rngIndex);
904  } else {
905  return MSNet::getInstance()->getRouterTT(rngIndex);
906  }
907 }
908 
909 
910 /* -------------------------------------------------------------------------
911  * Stop-methods
912  * ----------------------------------------------------------------------- */
913 double
915  if (busstop != nullptr) {
916  return busstop->getLastFreePos(veh);
917  } else if (containerstop != nullptr) {
918  return containerstop->getLastFreePos(veh);
919  } else if (parkingarea != nullptr) {
920  return parkingarea->getLastFreePos(veh);
921  } else if (chargingStation != nullptr) {
922  return chargingStation->getLastFreePos(veh);
923  }
924  return pars.endPos;
925 }
926 
927 
928 std::string
930  if (parkingarea != nullptr) {
931  return "parkingArea:" + parkingarea->getID();
932  } else if (containerstop != nullptr) {
933  return "containerStop:" + containerstop->getID();
934  } else if (busstop != nullptr) {
935  return "busStop:" + busstop->getID();
936  } else if (chargingStation != nullptr) {
937  return "chargingStation:" + chargingStation->getID();
938  } else {
939  return "lane:" + lane->getID() + " pos:" + toString(pars.endPos);
940  }
941 }
942 
943 
944 void
946  // lots of duplication with SUMOVehicleParameter::Stop::write()
947  dev.openTag(SUMO_TAG_STOP);
948  if (busstop != nullptr) {
949  dev.writeAttr(SUMO_ATTR_BUS_STOP, busstop->getID());
950  }
951  if (containerstop != nullptr) {
952  dev.writeAttr(SUMO_ATTR_CONTAINER_STOP, containerstop->getID());
953  }
954  if (busstop == nullptr && containerstop == nullptr) {
955  dev.writeAttr(SUMO_ATTR_LANE, lane->getID());
956  dev.writeAttr(SUMO_ATTR_STARTPOS, pars.startPos);
957  dev.writeAttr(SUMO_ATTR_ENDPOS, pars.endPos);
958  }
959  if (duration >= 0) {
960  dev.writeAttr(SUMO_ATTR_DURATION, time2string(duration));
961  }
962  if (pars.until >= 0) {
963  dev.writeAttr(SUMO_ATTR_UNTIL, time2string(pars.until));
964  }
965  if (pars.triggered) {
966  dev.writeAttr(SUMO_ATTR_TRIGGERED, pars.triggered);
967  }
968  if (pars.containerTriggered) {
969  dev.writeAttr(SUMO_ATTR_CONTAINER_TRIGGERED, pars.containerTriggered);
970  }
971  if (pars.parking) {
972  dev.writeAttr(SUMO_ATTR_PARKING, pars.parking);
973  }
974  if (pars.awaitedPersons.size() > 0) {
975  dev.writeAttr(SUMO_ATTR_EXPECTED, joinToString(pars.awaitedPersons, " "));
976  }
977  if (pars.awaitedContainers.size() > 0) {
978  dev.writeAttr(SUMO_ATTR_EXPECTED_CONTAINERS, joinToString(pars.awaitedContainers, " "));
979  }
980  dev.closeTag();
981 }
982 
983 
984 /* -------------------------------------------------------------------------
985  * MSVehicle-methods
986  * ----------------------------------------------------------------------- */
988  MSVehicleType* type, const double speedFactor) :
989  MSBaseVehicle(pars, route, type, speedFactor),
990  myWaitingTime(0),
992  myTimeLoss(0),
993  myState(0, 0, 0, 0),
994  myDriverState(nullptr),
995  myActionStep(true),
996  myLastActionTime(0),
997  myLane(nullptr),
998  myLastBestLanesEdge(nullptr),
1000  myAcceleration(0),
1002  mySignals(0),
1003  myAmOnNet(false),
1006  myHaveToWaitOnNextLink(false),
1007  myAngle(0),
1008  myStopDist(std::numeric_limits<double>::max()),
1009  myCollisionImmunity(-1),
1014  myEdgeWeights(nullptr),
1015  myInfluencer(nullptr) {
1016  if (!(*myCurrEdge)->isTazConnector()) {
1017  if (pars->departLaneProcedure == DEPART_LANE_GIVEN) {
1018  if ((*myCurrEdge)->getDepartLane(*this) == nullptr) {
1019  throw ProcessError("Invalid departlane definition for vehicle '" + pars->id + "'.");
1020  }
1021  } else {
1022  if ((*myCurrEdge)->allowedLanes(type->getVehicleClass()) == nullptr) {
1023  throw ProcessError("Vehicle '" + pars->id + "' is not allowed to depart on any lane of its first edge.");
1024  }
1025  }
1026  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > type->getMaxSpeed()) {
1027  throw ProcessError("Departure speed for vehicle '" + pars->id +
1028  "' is too high for the vehicle type '" + type->getID() + "'.");
1029  }
1030  }
1034  myNextDriveItem = myLFLinkLanes.begin();
1035 }
1036 
1037 
1039  delete myEdgeWeights;
1040  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
1041  (*i)->resetPartialOccupation(this);
1042  }
1046  // still needed when calling resetPartialOccupation (getShadowLane) and when removing
1047  // approach information from parallel links
1048  delete myLaneChangeModel;
1049  myFurtherLanes.clear();
1050  myFurtherLanesPosLat.clear();
1051  //
1052  if (myType->isVehicleSpecific()) {
1054  }
1055  delete myInfluencer;
1056 }
1057 
1058 
1059 void
1061 #ifdef DEBUG_ACTIONSTEPS
1062  if (DEBUG_COND) {
1063  std::cout << SIMTIME << " Removing vehicle '" << getID() << "' (reason: " << toString(reason) << ")" << std::endl;
1064  }
1065 #endif
1068  leaveLane(reason);
1069 }
1070 
1071 
1072 // ------------ interaction with the route
1073 bool
1075  return (myCurrEdge == myRoute->end() - 1
1076  && (myStops.empty() || myStops.front().edge != myCurrEdge)
1078  && !isRemoteControlled());
1079 }
1080 
1081 
1082 bool
1083 MSVehicle::replaceRoute(const MSRoute* newRoute, const std::string& info, bool onInit, int offset, bool addRouteStops, bool removeStops) {
1084  const ConstMSEdgeVector& edges = newRoute->getEdges();
1085  // assert the vehicle may continue (must not be "teleported" or whatever to another position)
1086  if (!onInit && !newRoute->contains(*myCurrEdge)) {
1087  return false;
1088  }
1089 
1090  // rebuild in-vehicle route information
1091  if (onInit) {
1092  myCurrEdge = newRoute->begin();
1093  } else {
1094  MSRouteIterator newCurrEdge = std::find(edges.begin() + offset, edges.end(), *myCurrEdge);
1095  if (myLane->getEdge().isInternal() && (
1096  (newCurrEdge + 1) == edges.end() || (*(newCurrEdge + 1)) != &(myLane->getOutgoingViaLanes().front().first->getEdge()))) {
1097  return false;
1098  }
1099  myCurrEdge = newCurrEdge;
1100  }
1101  const bool stopsFromScratch = onInit && myRoute->getStops().empty();
1102  // check whether the old route may be deleted (is not used by anyone else)
1103  newRoute->addReference();
1104  myRoute->release();
1105  // assign new route
1106  myRoute = newRoute;
1107  // update arrival definition
1109  // save information that the vehicle was rerouted
1110  myNumberReroutes++;
1112  // if we did not drive yet it may be best to simply reassign the stops from scratch
1113  if (stopsFromScratch) {
1114  myStops.clear();
1116  } else {
1117  // recheck old stops
1118  MSRouteIterator searchStart = myCurrEdge;
1119  double lastPos = getPositionOnLane();
1120  if (myLane != nullptr && myLane->isInternal()
1121  && myStops.size() > 0 && !myStops.front().lane->isInternal()) {
1122  // searchStart is still incoming to the intersection so lastPos
1123  // relative to that edge must be adapted
1124  lastPos += (*myCurrEdge)->getLength();
1125  }
1126 #ifdef DEBUG_REPLACE_ROUTE
1127  if (DEBUG_COND) {
1128  std::cout << " replaceRoute on " << (*myCurrEdge)->getID() << " lane=" << myLane->getID() << "\n";
1129  }
1130 #endif
1131  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end();) {
1132  double endPos = iter->getEndPos(*this);
1133 #ifdef DEBUG_REPLACE_ROUTE
1134  if (DEBUG_COND) {
1135  std::cout << " stopEdge=" << iter->lane->getEdge().getID() << " start=" << (searchStart - myCurrEdge) << " endPos=" << endPos << " lastPos=" << lastPos << "\n";
1136  }
1137 #endif
1138  if (*searchStart != &iter->lane->getEdge()
1139  || endPos < lastPos) {
1140  if (searchStart != edges.end() && !iter->reached) {
1141  searchStart++;
1142  }
1143  }
1144  lastPos = endPos;
1145 
1146  iter->edge = std::find(searchStart, edges.end(), &iter->lane->getEdge());
1147 #ifdef DEBUG_REPLACE_ROUTE
1148  if (DEBUG_COND) {
1149  std::cout << " foundIndex=" << (iter->edge - myCurrEdge) << " end=" << (edges.end() - myCurrEdge) << "\n";
1150  }
1151 #endif
1152  if (iter->edge == edges.end()) {
1153  if (removeStops) {
1154  iter = myStops.erase(iter);
1155  continue;
1156  } else {
1157  assert(false);
1158  }
1159  } else {
1160  searchStart = iter->edge;
1161  }
1162  ++iter;
1163  }
1164  // add new stops
1165  if (addRouteStops) {
1166  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator i = newRoute->getStops().begin(); i != newRoute->getStops().end(); ++i) {
1167  std::string error;
1168  addStop(*i, error);
1169  if (error != "") {
1170  WRITE_WARNING(error);
1171  }
1172  }
1173  }
1174  }
1175  // update best lanes (after stops were added)
1176  myLastBestLanesEdge = nullptr;
1177  myLastBestLanesInternalLane = nullptr;
1178  updateBestLanes(true, onInit ? (*myCurrEdge)->getLanes().front() : 0);
1179  assert(!removeStops || haveValidStopEdges());
1180  return true;
1181 }
1182 
1183 
1184 const MSEdgeWeightsStorage&
1186  return _getWeightsStorage();
1187 }
1188 
1189 
1192  return _getWeightsStorage();
1193 }
1194 
1195 
1198  if (myEdgeWeights == nullptr) {
1200  }
1201  return *myEdgeWeights;
1202 }
1203 
1204 
1205 // ------------ Interaction with move reminders
1206 void
1207 MSVehicle::workOnMoveReminders(double oldPos, double newPos, double newSpeed) {
1208  // This erasure-idiom works for all stl-sequence-containers
1209  // See Meyers: Effective STL, Item 9
1210  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
1211  // XXX: calling notifyMove with newSpeed seems not the best choice. For the ballistic update, the average speed is calculated and used
1212  // although a higher order quadrature-formula might be more adequate.
1213  // For the euler case (where the speed is considered constant for each time step) it is conceivable that
1214  // the current calculations may lead to systematic errors for large time steps (compared to reality). Refs. #2579
1215  if (!rem->first->notifyMove(*this, oldPos + rem->second, newPos + rem->second, MAX2(0., newSpeed))) {
1216 #ifdef _DEBUG
1217  if (myTraceMoveReminders) {
1218  traceMoveReminder("notifyMove", rem->first, rem->second, false);
1219  }
1220 #endif
1221  rem = myMoveReminders.erase(rem);
1222  } else {
1223 #ifdef _DEBUG
1224  if (myTraceMoveReminders) {
1225  traceMoveReminder("notifyMove", rem->first, rem->second, true);
1226  }
1227 #endif
1228  ++rem;
1229  }
1230  }
1231 }
1232 
1233 
1234 // XXX: consider renaming...
1235 void
1237  // save the old work reminders, patching the position information
1238  // add the information about the new offset to the old lane reminders
1239  const double oldLaneLength = myLane->getLength();
1240  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end(); ++rem) {
1241  rem->second += oldLaneLength;
1242 #ifdef _DEBUG
1243 // if (rem->first==0) std::cout << "Null reminder (?!)" << std::endl;
1244 // std::cout << "Adapted MoveReminder on lane " << ((rem->first->getLane()==0) ? "NULL" : rem->first->getLane()->getID()) <<" position to " << rem->second << std::endl;
1245  if (myTraceMoveReminders) {
1246  traceMoveReminder("adaptedPos", rem->first, rem->second, true);
1247  }
1248 #endif
1249  }
1250  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane.getMoveReminders().begin(); rem != enteredLane.getMoveReminders().end(); ++rem) {
1251  addReminder(*rem);
1252  }
1253 }
1254 
1255 
1256 // ------------ Other getter methods
1257 double
1259  if (myLane == nullptr) {
1260  return 0;
1261  }
1262  const double lp = getPositionOnLane();
1263  const double gp = myLane->interpolateLanePosToGeometryPos(lp);
1264  return myLane->getShape().slopeDegreeAtOffset(gp);
1265 }
1266 
1267 
1268 Position
1269 MSVehicle::getPosition(const double offset) const {
1270  if (myLane == nullptr) {
1271  // when called in the context of GUI-Drawing, the simulation step is already incremented
1273  return myCachedPosition;
1274  } else {
1275  return Position::INVALID;
1276  }
1277  }
1278  if (isParking()) {
1279  if (myStops.begin()->parkingarea != nullptr) {
1280  return myStops.begin()->parkingarea->getVehiclePosition(*this);
1281  } else {
1282  // position beside the road
1283  PositionVector shp = myLane->getEdge().getLanes()[0]->getShape();
1284  shp.move2side(SUMO_const_laneWidth * (MSNet::getInstance()->lefthand() ? -1 : 1));
1286  }
1287  }
1288  const bool changingLanes = getLaneChangeModel().isChangingLanes();
1289  const double posLat = (MSNet::getInstance()->lefthand() ? 1 : -1) * getLateralPositionOnLane();
1290  if (offset == 0. && !changingLanes) {
1293  }
1294  return myCachedPosition;
1295  }
1296  Position result = validatePosition(myLane->geometryPositionAtOffset(getPositionOnLane() + offset, posLat), offset);
1297  return result;
1298 }
1299 
1300 
1301 Position
1304  const std::vector<MSLane*>& bestLanes = getBestLanesContinuation();
1305  auto nextBestLane = bestLanes.begin();
1306  const bool opposite = getLaneChangeModel().isOpposite();
1307  double pos = opposite ? myLane->getLength() - myState.myPos : myState.myPos;
1308  const MSLane* lane = opposite ? myLane->getOpposite() : getLane();
1309  assert(lane != 0);
1310  bool success = true;
1311 
1312  while (offset > 0) {
1313  // take into account lengths along internal lanes
1314  while (lane->isInternal() && offset > 0) {
1315  if (offset > lane->getLength() - pos) {
1316  offset -= lane->getLength() - pos;
1317  lane = lane->getLinkCont()[0]->getViaLaneOrLane();
1318  pos = 0.;
1319  if (lane == nullptr) {
1320  success = false;
1321  offset = 0.;
1322  }
1323  } else {
1324  pos += offset;
1325  offset = 0;
1326  }
1327  }
1328  // set nextBestLane to next non-internal lane
1329  while (nextBestLane != bestLanes.end() && *nextBestLane == nullptr) {
1330  ++nextBestLane;
1331  }
1332  if (offset > 0) {
1333  assert(!lane->isInternal());
1334  assert(lane == *nextBestLane);
1335  if (offset > lane->getLength() - pos) {
1336  offset -= lane->getLength() - pos;
1337  ++nextBestLane;
1338  assert(nextBestLane == bestLanes.end() || *nextBestLane != 0);
1339  if (nextBestLane == bestLanes.end()) {
1340  success = false;
1341  offset = 0.;
1342  } else {
1343  MSLink* link = lane->getLinkTo(*nextBestLane);
1344  assert(link != 0);
1345  lane = link->getViaLaneOrLane();
1346  pos = 0.;
1347  }
1348  } else {
1349  pos += offset;
1350  offset = 0;
1351  }
1352  }
1353 
1354  }
1355 
1356  if (success) {
1357  return lane->geometryPositionAtOffset(pos, -getLateralPositionOnLane());
1358  } else {
1359  return Position::INVALID;
1360  }
1361 }
1362 
1363 
1364 Position
1365 MSVehicle::validatePosition(Position result, double offset) const {
1366  int furtherIndex = 0;
1367  double lastLength = getPositionOnLane();
1368  while (result == Position::INVALID) {
1369  if (furtherIndex >= (int)myFurtherLanes.size()) {
1370  //WRITE_WARNING("Could not compute position for vehicle '" + getID() + "', time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
1371  break;
1372  }
1373  //std::cout << SIMTIME << " veh=" << getID() << " lane=" << myLane->getID() << " pos=" << getPositionOnLane() << " posLat=" << getLateralPositionOnLane() << " offset=" << offset << " result=" << result << " i=" << furtherIndex << " further=" << myFurtherLanes.size() << "\n";
1374  MSLane* further = myFurtherLanes[furtherIndex];
1375  offset += lastLength;
1376  result = further->geometryPositionAtOffset(further->getLength() + offset, -getLateralPositionOnLane());
1377  lastLength = further->getLength();
1378  furtherIndex++;
1379  //std::cout << SIMTIME << " newResult=" << result << "\n";
1380  }
1381  return result;
1382 }
1383 
1384 
1385 const MSEdge*
1387  // too close to the next junction, so avoid an emergency brake here
1388  if (myLane != nullptr && (myCurrEdge + 1) != myRoute->end() &&
1389  myState.myPos > myLane->getLength() - getCarFollowModel().brakeGap(myState.mySpeed, getCarFollowModel().getMaxDecel(), 0.)) {
1390  return *(myCurrEdge + 1);
1391  }
1392  if (myLane != nullptr) {
1393  return myLane->getNextNormal();
1394  }
1395  return *myCurrEdge;
1396 }
1397 
1398 void
1399 MSVehicle::setAngle(double angle, bool straightenFurther) {
1400 #ifdef DEBUG_FURTHER
1401  if (DEBUG_COND) {
1402  std::cout << SIMTIME << " veh '" << getID() << " setAngle(" << angle << ") straightenFurther=" << straightenFurther << std::endl;
1403  }
1404 #endif
1405  myAngle = angle;
1406  MSLane* next = myLane;
1407  if (straightenFurther && myFurtherLanesPosLat.size() > 0) {
1408  for (int i = 0; i < (int)myFurtherLanes.size(); i++) {
1409  MSLane* further = myFurtherLanes[i];
1410  if (further->getLinkTo(next) != nullptr) {
1412  next = further;
1413  } else {
1414  break;
1415  }
1416  }
1417  }
1418 }
1419 
1420 
1421 void
1422 MSVehicle::setActionStepLength(double actionStepLength, bool resetOffset) {
1423  SUMOTime actionStepLengthMillisecs = SUMOVehicleParserHelper::processActionStepLength(actionStepLength);
1424  SUMOTime previousActionStepLength = getActionStepLength();
1425  const bool newActionStepLength = actionStepLengthMillisecs != previousActionStepLength;
1426  if (newActionStepLength) {
1427  getSingularType().setActionStepLength(actionStepLengthMillisecs, resetOffset);
1428  if (!resetOffset) {
1429  updateActionOffset(previousActionStepLength, actionStepLengthMillisecs);
1430  }
1431  }
1432  if (resetOffset) {
1434  }
1435 }
1436 
1437 
1438 double
1440  Position p1;
1441  const double posLat = -myState.myPosLat; // @todo get rid of the '-'
1442  if (isParking()) {
1443  if (myStops.begin()->parkingarea != nullptr) {
1444  return myStops.begin()->parkingarea->getVehicleAngle(*this);
1445  } else {
1447  }
1448  }
1449  if (getLaneChangeModel().isChangingLanes()) {
1450  // cannot use getPosition() because it already includes the offset to the side and thus messes up the angle
1452  } else {
1453  p1 = getPosition();
1454  }
1455 
1456  Position p2 = getBackPosition();
1457  if (p2 == Position::INVALID) {
1458  // Handle special case of vehicle's back reaching out of the network
1459  if (myFurtherLanes.size() > 0) {
1460  p2 = myFurtherLanes.back()->geometryPositionAtOffset(0, -myFurtherLanesPosLat.back());
1461  if (p2 == Position::INVALID) {
1462  // unsuitable lane geometry
1463  p2 = myLane->geometryPositionAtOffset(0, posLat);
1464  }
1465  } else {
1466  p2 = myLane->geometryPositionAtOffset(0, posLat);
1467  }
1468  }
1469  double result = (p1 != p2 ? p2.angleTo2D(p1) :
1472  result += DEG2RAD(getLaneChangeModel().getAngleOffset());
1473  }
1474 #ifdef DEBUG_FURTHER
1475  if (DEBUG_COND) {
1476  std::cout << SIMTIME << " computeAngle veh=" << getID() << " p1=" << p1 << " p2=" << p2 << " angle=" << RAD2DEG(result) << " naviDegree=" << GeomHelper::naviDegree(result) << "\n";
1477  }
1478 #endif
1479  return result;
1480 }
1481 
1482 
1483 const Position
1485  const double posLat = MSNet::getInstance()->lefthand() ? myState.myPosLat : -myState.myPosLat;
1486  if (myState.myPos >= myType->getLength()) {
1487  // vehicle is fully on the new lane
1489  } else {
1490  if (getLaneChangeModel().isChangingLanes() && myFurtherLanes.size() > 0 && getLaneChangeModel().getShadowLane(myFurtherLanes.back()) == nullptr) {
1491  // special case where the target lane has no predecessor
1492 #ifdef DEBUG_FURTHER
1493  if (DEBUG_COND) {
1494  std::cout << " getBackPosition veh=" << getID() << " specialCase using myLane=" << myLane->getID() << " pos=0 posLat=" << myState.myPosLat << " result=" << myLane->geometryPositionAtOffset(0, posLat) << "\n";
1495  }
1496 #endif
1497  return myLane->geometryPositionAtOffset(0, posLat);
1498  } else {
1499 #ifdef DEBUG_FURTHER
1500  if (DEBUG_COND) {
1501  std::cout << " getBackPosition veh=" << getID() << " myLane=" << myLane->getID() << " further=" << toString(myFurtherLanes) << " myFurtherLanesPosLat=" << toString(myFurtherLanesPosLat) << "\n";
1502  }
1503 #endif
1504  return myFurtherLanes.size() > 0 && !getLaneChangeModel().isChangingLanes()
1505  ? myFurtherLanes.back()->geometryPositionAtOffset(getBackPositionOnLane(myFurtherLanes.back()), -myFurtherLanesPosLat.back() * (MSNet::getInstance()->lefthand() ? -1 : 1))
1506  : myLane->geometryPositionAtOffset(0, posLat);
1507  }
1508  }
1509 }
1510 
1511 // ------------
1512 bool
1513 MSVehicle::addStop(const SUMOVehicleParameter::Stop& stopPar, std::string& errorMsg, SUMOTime untilOffset, bool collision,
1514  MSRouteIterator* searchStart) {
1515  Stop stop(stopPar);
1516  stop.lane = MSLane::dictionary(stopPar.lane);
1517  if (!stop.lane->allowsVehicleClass(myType->getVehicleClass())) {
1518  errorMsg = "Vehicle '" + myParameter->id + "' is not allowed to stop on lane '" + stopPar.lane + "'.";
1519  return false;
1520  }
1525  stop.duration = stopPar.duration;
1526  stop.triggered = stopPar.triggered;
1527  stop.containerTriggered = stopPar.containerTriggered;
1528  if (stopPar.until != -1) {
1529  // !!! it would be much cleaner to invent a constructor for stops which takes "until" as an argument
1530  const_cast<SUMOVehicleParameter::Stop&>(stop.pars).until += untilOffset;
1531  }
1532  stop.collision = collision;
1533  stop.numExpectedPerson = (int)stopPar.awaitedPersons.size();
1534  stop.numExpectedContainer = (int)stopPar.awaitedContainers.size();
1535  std::string stopType = "stop";
1536  std::string stopID = "";
1537  if (stop.busstop != nullptr) {
1538  stopType = "busStop";
1539  stopID = stop.busstop->getID();
1540  } else if (stop.containerstop != nullptr) {
1541  stopType = "containerStop";
1542  stopID = stop.containerstop->getID();
1543  } else if (stop.chargingStation != nullptr) {
1544  stopType = "chargingStation";
1545  stopID = stop.chargingStation->getID();
1546  } else if (stop.parkingarea != nullptr) {
1547  stopType = "parkingArea";
1548  stopID = stop.parkingarea->getID();
1549  }
1550  const std::string errorMsgStart = stopID == "" ? stopType : stopType + " '" + stopID + "'";
1551 
1552  if (stop.pars.startPos < 0 || stop.pars.endPos > stop.lane->getLength()) {
1553  errorMsg = errorMsgStart + " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' has an invalid position.";
1554  return false;
1555  }
1556  if (stopType != "stop" && stopType != "parkingArea" && myType->getLength() / 2. > stop.pars.endPos - stop.pars.startPos
1557  && MSNet::getInstance()->warnOnce(stopType + ":" + stopID)) {
1558  errorMsg = errorMsgStart + " on lane '" + stopPar.lane + "' is too short for vehicle '" + myParameter->id + "'.";
1559  }
1560  // if stop is on an internal edge the normal edge before the intersection is used
1561  const MSEdge* stopEdge = stop.lane->getEdge().getNormalBefore();
1562  if (searchStart == nullptr) {
1563  searchStart = &myCurrEdge;
1564  }
1565  stop.edge = std::find(*searchStart, myRoute->end(), stopEdge);
1566  MSRouteIterator prevStopEdge = myCurrEdge;
1567  MSEdge* prevEdge = nullptr;
1568  double prevStopPos = myState.myPos;
1569  // where to insert the stop
1570  std::list<Stop>::iterator iter = myStops.begin();
1571  if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(myStops.size())) {
1572  if (myStops.size() > 0) {
1573  prevStopEdge = myStops.back().edge;
1574  prevEdge = &myStops.back().lane->getEdge();
1575  prevStopPos = myStops.back().pars.endPos;
1576  iter = myStops.end();
1577  stop.edge = std::find(prevStopEdge, myRoute->end(), stopEdge);
1578  if (prevStopEdge == stop.edge // laneEdge check is insufficient for looped routes
1579  && prevEdge == &stop.lane->getEdge() // route iterator check insufficient for internal lane stops
1580  && prevStopPos > stop.pars.endPos) {
1581  stop.edge = std::find(prevStopEdge + 1, myRoute->end(), stopEdge);
1582  }
1583  }
1584  } else {
1585  if (stopPar.index == STOP_INDEX_FIT) {
1586  while (iter != myStops.end() && (iter->edge < stop.edge ||
1587  (iter->pars.endPos < stop.pars.endPos && iter->edge == stop.edge))) {
1588  prevStopEdge = iter->edge;
1589  prevStopPos = iter->pars.endPos;
1590  ++iter;
1591  }
1592  } else {
1593  int index = stopPar.index;
1594  while (index > 0) {
1595  prevStopEdge = iter->edge;
1596  prevStopPos = iter->pars.endPos;
1597  ++iter;
1598  --index;
1599  }
1600  stop.edge = std::find(prevStopEdge, myRoute->end(), stopEdge);
1601  }
1602  }
1603  const bool sameEdgeAsLastStop = prevStopEdge == stop.edge && prevEdge == &stop.lane->getEdge();
1604  if (stop.edge == myRoute->end() || prevStopEdge > stop.edge ||
1605  (sameEdgeAsLastStop && prevStopPos > stop.pars.endPos && !collision)
1606  || (stop.lane->getEdge().isInternal() && stop.lane->getNextNormal() != *(stop.edge + 1))) {
1607  if (stop.edge != myRoute->end()) {
1608  // check if the edge occurs again later in the route
1609  MSRouteIterator next = stop.edge + 1;
1610  return addStop(stopPar, errorMsg, untilOffset, collision, &next);
1611  }
1612  errorMsg = errorMsgStart + " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is not downstream the current route.";
1613  //std::cout << " could not add stop " << errorMsgStart << " prevStops=" << myStops.size() << " searchStart=" << (*searchStart - myRoute->begin()) << " route=" << toString(myRoute->getEdges()) << "\n";
1614  return false;
1615  }
1616  // David.C:
1617  //if (!stop.parking && (myCurrEdge == stop.edge && myState.myPos > stop.endPos - getCarFollowModel().brakeGap(myState.mySpeed))) {
1618  const double endPosOffset = stop.lane->getEdge().isInternal() ? (*stop.edge)->getLength() : 0;
1619  const double distToStop = stop.pars.endPos + endPosOffset - myState.myPos;
1620  if (myCurrEdge == stop.edge && distToStop < getCarFollowModel().brakeGap(myState.mySpeed)) {
1621  if (collision) {
1622  if (distToStop < getCarFollowModel().brakeGap(myState.mySpeed, getCarFollowModel().getEmergencyDecel(), 0)) {
1623  double vNew = getCarFollowModel().maximumSafeStopSpeed(distToStop, getSpeed(), false, 0);
1624  //std::cout << SIMTIME << " veh=" << getID() << " v=" << myState.mySpeed << " distToStop=" << distToStop
1625  // << " vMinNex=" << getCarFollowModel().minNextSpeed(getSpeed(), this)
1626  // << " bg1=" << getCarFollowModel().brakeGap(myState.mySpeed)
1627  // << " bg2=" << getCarFollowModel().brakeGap(myState.mySpeed, getCarFollowModel().getEmergencyDecel(), 0)
1628  // << " vNew=" << vNew
1629  // << "\n";
1630  myState.mySpeed = MIN2(myState.mySpeed, vNew + ACCEL2SPEED(getCarFollowModel().getEmergencyDecel()));
1633  }
1634  } else {
1635  errorMsg = errorMsgStart + " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is too close to break.";
1636  return false;
1637  }
1638  }
1639  if (!hasDeparted() && myCurrEdge == stop.edge) {
1640  double pos = -1;
1642  pos = myParameter->departPos;
1643  if (pos < 0.) {
1644  pos += (*myCurrEdge)->getLength();
1645  }
1646  }
1648  pos = MIN2(stop.pars.endPos + endPosOffset, basePos(*myCurrEdge));
1649  }
1650  if (pos > stop.pars.endPos + endPosOffset) {
1651  if (stop.edge != myRoute->end()) {
1652  // check if the edge occurs again later in the route
1653  MSRouteIterator next = stop.edge + 1;
1654  return addStop(stopPar, errorMsg, untilOffset, collision, &next);
1655  }
1656  errorMsg = errorMsgStart + " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' is before departPos.";
1657  return false;
1658  }
1659  }
1660  if (iter != myStops.begin()) {
1661  std::list<Stop>::iterator iter2 = iter;
1662  iter2--;
1663  if (stop.pars.until >= 0 && iter2->pars.until > stop.pars.until) {
1664  errorMsg = errorMsgStart + " for vehicle '" + myParameter->id + "' on lane '" + stopPar.lane + "' ends earlier than previous stop.";
1665  }
1666  }
1667  myStops.insert(iter, stop);
1668  //std::cout << " added stop " << errorMsgStart << " totalStops=" << myStops.size() << " searchStart=" << (*searchStart - myRoute->begin())
1669  // << " routeIndex=" << (stop.edge - myRoute->begin())
1670  // << " route=" << toString(myRoute->getEdges()) << "\n";
1671  return true;
1672 }
1673 
1674 
1675 bool
1676 MSVehicle::replaceParkingArea(MSParkingArea* parkingArea, std::string& errorMsg) {
1677  // Check if there is a parking area to be replaced
1678  if (parkingArea == 0) {
1679  errorMsg = "new parkingArea is NULL";
1680  return false;
1681  }
1682  if (myStops.size() == 0) {
1683  errorMsg = "vehicle has no stops";
1684  return false;
1685  }
1686  if (myStops.front().parkingarea == 0) {
1687  errorMsg = "first stop is not at parkingArea";
1688  return false;
1689  }
1690  Stop& first = myStops.front();
1691  SUMOVehicleParameter::Stop& stopPar = const_cast<SUMOVehicleParameter::Stop&>(first.pars);
1692  // merge subsequent duplicate stops equals to parking area
1693  for (std::list<Stop>::iterator iter = ++myStops.begin(); iter != myStops.end();) {
1694  if (iter->parkingarea == parkingArea) {
1695  stopPar.duration += iter->duration;
1696  myStops.erase(iter++);
1697  } else {
1698  break;
1699  }
1700  }
1701  stopPar.lane = parkingArea->getLane().getID();
1702  stopPar.parkingarea = parkingArea->getID();
1703  stopPar.startPos = parkingArea->getBeginLanePosition();
1704  stopPar.endPos = parkingArea->getEndLanePosition();
1705  first.edge = myRoute->end(); // will be patched in replaceRoute
1706  first.lane = &parkingArea->getLane();
1707  first.parkingarea = parkingArea;
1708  return true;
1709 }
1710 
1711 
1714  MSParkingArea* nextParkingArea = nullptr;
1715  if (!myStops.empty()) {
1717  Stop stop = myStops.front();
1718  if (!stop.reached && stop.parkingarea != nullptr) {
1719  nextParkingArea = stop.parkingarea;
1720  }
1721  }
1722  return nextParkingArea;
1723 }
1724 
1725 
1728  MSParkingArea* currentParkingArea = nullptr;
1729  if (isParking()) {
1730  currentParkingArea = myStops.begin()->parkingarea;
1731  }
1732  return currentParkingArea;
1733 }
1734 
1735 
1736 bool
1738  return !myStops.empty() && myStops.begin()->reached /*&& myState.mySpeed < SUMO_const_haltingSpeed @todo #1864#*/;
1739 }
1740 
1741 
1742 bool
1744  return !isStopped() && !myStops.empty() && myLane != nullptr && &myStops.front().lane->getEdge() == &myLane->getEdge();
1745 }
1746 
1747 bool
1749  return isStopped() && myStops.front().lane == myLane;
1750 }
1751 
1752 bool
1753 MSVehicle::keepStopping(bool afterProcessing) const {
1754  if (isStopped()) {
1755  // after calling processNextStop, DELTA_T has already been subtracted from the duration
1756  return (myStops.front().duration + (afterProcessing ? DELTA_T : 0) > 0 || isStoppedTriggered() || myStops.front().collision
1757  || (myStops.front().pars.speed > 0 && myState.myPos < myStops.front().pars.endPos));
1758  } else {
1759  return false;
1760  }
1761 }
1762 
1763 
1764 SUMOTime
1766  if (isStopped()) {
1767  return myStops.front().duration;
1768  }
1769  return 0;
1770 }
1771 
1772 
1773 SUMOTime
1775  return (myStops.empty() || !myStops.front().collision) ? myCollisionImmunity : MAX2((SUMOTime)0, myStops.front().duration);
1776 }
1777 
1778 
1779 bool
1781  return isStopped() && myStops.begin()->pars.parking && (
1782  myStops.begin()->parkingarea == nullptr || !myStops.begin()->parkingarea->parkOnRoad());
1783 }
1784 
1785 
1786 bool
1788  return isStopped() && (myStops.begin()->triggered || myStops.begin()->containerTriggered);
1789 }
1790 
1791 
1792 bool
1793 MSVehicle::isStoppedInRange(const double pos, const double tolerance) const {
1794  if (isStopped()) {
1795  const Stop& stop = myStops.front();
1796  if (stop.pars.endPos - stop.pars.startPos <= MIN_STOP_LENGTH) {
1797  return stop.pars.startPos - tolerance <= pos && stop.pars.endPos + tolerance >= pos;
1798  }
1799  return stop.pars.startPos <= pos && stop.pars.endPos >= pos;
1800  }
1801  return false;
1802 }
1803 
1804 
1805 double
1806 MSVehicle::processNextStop(double currentVelocity) {
1807  if (myStops.empty()) {
1808  // no stops; pass
1809  return currentVelocity;
1810  }
1811 
1812 #ifdef DEBUG_STOPS
1813  if (DEBUG_COND) {
1814  std::cout << "\nPROCESS_NEXT_STOP\n" << SIMTIME << " vehicle '" << getID() << "'" << std::endl;
1815  }
1816 #endif
1817 
1818  Stop& stop = myStops.front();
1820  if (stop.reached) {
1821 
1822 #ifdef DEBUG_STOPS
1823  if (DEBUG_COND) {
1824  std::cout << SIMTIME << " vehicle '" << getID() << "' reached stop.\n"
1825  << "Remaining duration: " << STEPS2TIME(stop.duration) << std::endl;
1826  }
1827 #endif
1828  // ok, we have already reached the next stop
1829  // any waiting persons may board now
1830  MSNet* const net = MSNet::getInstance();
1831  const bool boarded = (time <= stop.endBoarding
1832  && net->hasPersons()
1833  && net->getPersonControl().boardAnyWaiting(&myLane->getEdge(), this, stop.pars, stop.timeToBoardNextPerson, stop.duration)
1834  && stop.numExpectedPerson == 0);
1835  // load containers
1836  const bool loaded = (time <= stop.endBoarding
1837  && net->hasContainers()
1839  && stop.numExpectedContainer == 0);
1840  if (time > stop.endBoarding) {
1841  stop.triggered = false;
1842  stop.containerTriggered = false;
1843  }
1844  if (boarded) {
1845  if (stop.busstop != nullptr) {
1846  const std::vector<MSTransportable*>& persons = myPersonDevice->getTransportables();
1847  for (std::vector<MSTransportable*>::const_iterator i = persons.begin(); i != persons.end(); ++i) {
1848  stop.busstop->removeTransportable(*i);
1849  }
1850  }
1851  // the triggering condition has been fulfilled. Maybe we want to wait a bit longer for additional riders (car pooling)
1852  stop.triggered = false;
1856 #ifdef DEBUG_STOPS
1857  if (DEBUG_COND) {
1858  std::cout << SIMTIME << " vehicle '" << getID() << "' unregisters as waiting for person." << std::endl;
1859  }
1860 #endif
1861  }
1862  }
1863  if (loaded) {
1864  if (stop.containerstop != nullptr) {
1865  const std::vector<MSTransportable*>& containers = myContainerDevice->getTransportables();
1866  for (std::vector<MSTransportable*>::const_iterator i = containers.begin(); i != containers.end(); ++i) {
1868  }
1869  }
1870  // the triggering condition has been fulfilled
1871  stop.containerTriggered = false;
1875 #ifdef DEBUG_STOPS
1876  if (DEBUG_COND) {
1877  std::cout << SIMTIME << " vehicle '" << getID() << "' unregisters as waiting for container." << std::endl;
1878  }
1879 #endif
1880  }
1881  }
1882  if (!keepStopping() && isOnRoad()) {
1883 #ifdef DEBUG_STOPS
1884  if (DEBUG_COND) {
1885  std::cout << SIMTIME << " vehicle '" << getID() << "' resumes from stopping." << std::endl;
1886  }
1887 #endif
1889  } else {
1891  if (getVehicleType().getPersonCapacity() == getPersonNumber()) {
1892  WRITE_WARNING("Vehicle '" + getID() + "' ignores triggered stop on lane '" + stop.lane->getID() + "' due to capacity constraints.");
1893  stop.triggered = false;
1894  }
1895  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
1898 #ifdef DEBUG_STOPS
1899  if (DEBUG_COND) {
1900  std::cout << SIMTIME << " vehicle '" << getID() << "' registers as waiting for person." << std::endl;
1901  }
1902 #endif
1903  }
1905  if (getVehicleType().getContainerCapacity() == getContainerNumber()) {
1906  WRITE_WARNING("Vehicle '" + getID() + "' ignores container triggered stop on lane '" + stop.lane->getID() + "' due to capacity constraints.");
1907  stop.containerTriggered = false;
1908  }
1909  // we can only register after waiting for one step. otherwise we might falsely signal a deadlock
1912 #ifdef DEBUG_STOPS
1913  if (DEBUG_COND) {
1914  std::cout << SIMTIME << " vehicle '" << getID() << "' registers as waiting for container." << std::endl;
1915  }
1916 #endif
1917  }
1918  // we have to wait some more time
1919  stop.duration -= getActionStepLength();
1920 
1922  // euler
1923  return stop.pars.speed;
1924  } else {
1925  // ballistic:
1926  return getSpeed() - getCarFollowModel().getMaxDecel();
1927  }
1928  }
1929  } else {
1930 
1931 #ifdef DEBUG_STOPS
1932  if (DEBUG_COND) {
1933  std::cout << SIMTIME << " vehicle '" << getID() << "' hasn't reached next stop." << std::endl;
1934  }
1935 #endif
1936 
1937  // is the next stop on the current lane?
1938  if (stop.edge == myCurrEdge) {
1939  // get the stopping position
1940  bool useStoppingPlace = stop.busstop != nullptr || stop.containerstop != nullptr || stop.parkingarea != nullptr;
1941  bool fitsOnStoppingPlace = true;
1942  if (stop.busstop != nullptr) {
1943  fitsOnStoppingPlace &= stop.busstop->fits(myState.myPos, *this);
1944  }
1945  if (stop.containerstop != nullptr) {
1946  fitsOnStoppingPlace &= stop.containerstop->fits(myState.myPos, *this);
1947  }
1948  // if the stop is a parking area we check if there is a free position on the area
1949  if (stop.parkingarea != nullptr) {
1950  fitsOnStoppingPlace &= myState.myPos > stop.parkingarea->getBeginLanePosition();
1951  if (stop.parkingarea->getOccupancy() >= stop.parkingarea->getCapacity()) {
1952  fitsOnStoppingPlace = false;
1953  // trigger potential parkingZoneReroute
1954  for (std::vector< MSMoveReminder* >::const_iterator rem = myLane->getMoveReminders().begin(); rem != myLane->getMoveReminders().end(); ++rem) {
1955  addReminder(*rem);
1956  }
1957  MSParkingArea* oldParkingArea = stop.parkingarea;
1959  if (myStops.empty() || myStops.front().parkingarea != oldParkingArea) {
1960  // rerouted, keep driving
1961  return currentVelocity;
1962  }
1963  } else if (stop.parkingarea->getOccupancyIncludingBlocked() >= stop.parkingarea->getCapacity()) {
1964  fitsOnStoppingPlace = false;
1965  }
1966  }
1967  const double targetPos = (myLFLinkLanes.empty()
1968  ? stop.getEndPos(*this) // loading simulation state
1969  : myState.myPos + myLFLinkLanes.front().myDistance); // avoid concurrent read/write to stoppingPlace during execute move;
1970  const double reachedThreshold = (useStoppingPlace ? targetPos - STOPPING_PLACE_OFFSET : stop.pars.startPos) - NUMERICAL_EPS;
1971 #ifdef DEBUG_STOPS
1972  if (DEBUG_COND) {
1973  std::cout << " pos=" << myState.pos() << " speed=" << currentVelocity << " targetPos=" << targetPos << " fits=" << fitsOnStoppingPlace << " reachedThresh=" << reachedThreshold << "\n";
1974  }
1975 #endif
1976  if (myState.pos() >= reachedThreshold && fitsOnStoppingPlace && currentVelocity <= stop.pars.speed + SUMO_const_haltingSpeed && myLane == stop.lane
1978  // ok, we may stop (have reached the stop) and either we are not modelling manoeuvering or have completed entry
1979  stop.reached = true;
1980 #ifdef DEBUG_STOPS
1981  if (DEBUG_COND) {
1982  std::cout << SIMTIME << " vehicle '" << getID() << "' reached next stop." << std::endl;
1983  }
1984 #endif
1985  if (MSStopOut::active()) {
1987  }
1988  myLane->getEdge().addWaiting(this);
1990  // compute stopping time
1991  if (stop.pars.until >= 0) {
1992  if (stop.duration == -1) {
1993  stop.duration = stop.pars.until - time;
1994  } else {
1995  stop.duration = MAX2(stop.duration, stop.pars.until - time);
1996  }
1997  }
1998  stop.endBoarding = stop.pars.extension >= 0 ? time + stop.duration + stop.pars.extension : SUMOTime_MAX;
1999  if (stop.pars.speed > 0) {
2000  // ignore duration and until in waypoint mode
2001  stop.duration = 0;
2002  }
2003  if (stop.busstop != nullptr) {
2004  // let the bus stop know the vehicle
2005  stop.busstop->enter(this, myState.pos() + getVehicleType().getMinGap(), myState.pos() - myType->getLength());
2006  }
2007  if (stop.containerstop != nullptr) {
2008  // let the container stop know the vehicle
2009  stop.containerstop->enter(this, myState.pos() + getVehicleType().getMinGap(), myState.pos() - myType->getLength());
2010  }
2011  if (stop.parkingarea != nullptr) {
2012  // let the parking area know the vehicle
2013  stop.parkingarea->enter(this, myState.pos() + getVehicleType().getMinGap(), myState.pos() - myType->getLength());
2014  }
2015 
2016  if (stop.pars.tripId != "") {
2017  ((SUMOVehicleParameter&)getParameter()).setParameter("tripId", stop.pars.tripId);
2018  }
2019  if (stop.pars.line != "") {
2020  ((SUMOVehicleParameter&)getParameter()).line = stop.pars.line;
2021  }
2022  }
2023  }
2024  }
2025  return currentVelocity;
2026 }
2027 
2028 
2029 const ConstMSEdgeVector
2030 MSVehicle::getStopEdges(double& firstPos, double& lastPos) const {
2031  assert(haveValidStopEdges());
2032  ConstMSEdgeVector result;
2033  const Stop* prev = nullptr;
2034  for (const Stop& stop : myStops) {
2035  if (stop.reached) {
2036  continue;
2037  }
2038  const double stopPos = stop.getEndPos(*this);
2039  if (prev == nullptr
2040  || prev->edge != stop.edge
2041  || prev->getEndPos(*this) > stopPos) {
2042  result.push_back(*stop.edge);
2043  }
2044  prev = &stop;
2045  if (firstPos < 0) {
2046  firstPos = stopPos;
2047  }
2048  lastPos = stopPos;
2049  }
2050  //std::cout << "getStopEdges veh=" << getID() << " result=" << toString(result) << "\n";
2051  return result;
2052 }
2053 
2054 
2055 std::vector<std::pair<int, double> >
2057  std::vector<std::pair<int, double> > result;
2058  for (std::list<Stop>::const_iterator iter = myStops.begin(); iter != myStops.end(); ++iter) {
2059  result.push_back(std::make_pair(
2060  (int)(iter->edge - myRoute->begin()),
2061  iter->getEndPos(*this)));
2062  }
2063  return result;
2064 }
2065 
2066 bool
2068  if (stop == nullptr) {
2069  return false;
2070  }
2071  for (const Stop& s : myStops) {
2072  if (s.busstop == stop
2073  || s.containerstop == stop
2074  || s.parkingarea == stop
2075  || s.chargingStation == stop) {
2076  return true;
2077  }
2078  }
2079  return false;
2080 }
2081 
2082 bool
2083 MSVehicle::stopsAtEdge(const MSEdge* edge) const {
2084  for (const Stop& s : myStops) {
2085  if (&s.lane->getEdge() == edge) {
2086  return true;
2087  }
2088  }
2089  return false;
2090 }
2091 
2092 double
2094  return getCarFollowModel().brakeGap(getSpeed());
2095 }
2096 
2097 
2098 double
2099 MSVehicle::basePos(const MSEdge* edge) const {
2100  double result = MIN2(getVehicleType().getLength() + POSITION_EPS, edge->getLength());
2101  if (hasStops()
2102  && myStops.front().edge == myRoute->begin()
2103  && (&myStops.front().lane->getEdge()) == *myStops.front().edge) {
2104  result = MIN2(result, MAX2(0.0, myStops.front().getEndPos(*this)));
2105  }
2106  return result;
2107 }
2108 
2109 
2110 bool
2113  if (myActionStep) {
2114  myLastActionTime = t;
2115  }
2116  return myActionStep;
2117 }
2118 
2119 
2120 void
2121 MSVehicle::resetActionOffset(const SUMOTime timeUntilNextAction) {
2122  myLastActionTime = MSNet::getInstance()->getCurrentTimeStep() + timeUntilNextAction;
2123 }
2124 
2125 
2126 void
2127 MSVehicle::updateActionOffset(const SUMOTime oldActionStepLength, const SUMOTime newActionStepLength) {
2129  SUMOTime timeSinceLastAction = now - myLastActionTime;
2130  if (timeSinceLastAction == 0) {
2131  // Action was scheduled now, may be delayed be new action step length
2132  timeSinceLastAction = oldActionStepLength;
2133  }
2134  if (timeSinceLastAction >= newActionStepLength) {
2135  // Action point required in this step
2136  myLastActionTime = now;
2137  } else {
2138  SUMOTime timeUntilNextAction = newActionStepLength - timeSinceLastAction;
2139  resetActionOffset(timeUntilNextAction);
2140  }
2141 }
2142 
2143 
2144 
2145 void
2146 MSVehicle::planMove(const SUMOTime t, const MSLeaderInfo& ahead, const double lengthsInFront) {
2147 #ifdef DEBUG_PLAN_MOVE
2148  if (DEBUG_COND) {
2149  std::cout
2150  << "\nPLAN_MOVE\n"
2151  << SIMTIME
2152  << std::setprecision(gPrecision)
2153  << " veh=" << getID()
2154  << " lane=" << myLane->getID()
2155  << " pos=" << getPositionOnLane()
2156  << " posLat=" << getLateralPositionOnLane()
2157  << " speed=" << getSpeed()
2158  << "\n";
2159  }
2160 #endif
2161  // Update the driver state
2162  if (hasDriverState()) {
2163  myDriverState->update();
2164  setActionStepLength(myDriverState->getDriverState()->getActionStepLength(), false);
2165  }
2166 
2167  if (!checkActionStep(t)) {
2168 #ifdef DEBUG_ACTIONSTEPS
2169  if (DEBUG_COND) {
2170  std::cout << STEPS2TIME(t) << " vehicle '" << getID() << "' skips action." << std::endl;
2171  }
2172 #endif
2173  // During non-action passed drive items still need to be removed
2174  // @todo rather work with updating myCurrentDriveItem (refs #3714)
2176  return;
2177  } else {
2178 #ifdef DEBUG_ACTIONSTEPS
2179  if (DEBUG_COND) {
2180  std::cout << STEPS2TIME(t) << " vehicle = '" << getID() << "' takes action." << std::endl;
2181  }
2182 #endif
2183 
2186 #ifdef DEBUG_PLAN_MOVE
2187  if (DEBUG_COND) {
2188  DriveItemVector::iterator i;
2189  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
2190  std::cout
2191  << " vPass=" << (*i).myVLinkPass
2192  << " vWait=" << (*i).myVLinkWait
2193  << " linkLane=" << ((*i).myLink == 0 ? "NULL" : (*i).myLink->getViaLaneOrLane()->getID())
2194  << " request=" << (*i).mySetRequest
2195  << "\n";
2196  }
2197  }
2198 #endif
2199  checkRewindLinkLanes(lengthsInFront, myLFLinkLanes);
2200  myNextDriveItem = myLFLinkLanes.begin();
2201  // ideally would only do this with the call inside planMoveInternal - but that needs a const method
2202  // so this is a kludge here - nuisance as it adds an extra check in a busy loop
2206  }
2207  }
2208  }
2210 }
2211 
2212 void
2213 MSVehicle::planMoveInternal(const SUMOTime t, MSLeaderInfo ahead, DriveItemVector& lfLinks, double& myStopDist, std::pair<double, LinkDirection>& myNextTurn) const {
2214  lfLinks.clear();
2215  myStopDist = std::numeric_limits<double>::max();
2216  //
2217  const MSCFModel& cfModel = getCarFollowModel();
2218  const double vehicleLength = getVehicleType().getLength();
2219  const double maxV = cfModel.maxNextSpeed(myState.mySpeed, this);
2220  const bool opposite = getLaneChangeModel().isOpposite();
2221  double laneMaxV = myLane->getVehicleMaxSpeed(this);
2222  const double vMinComfortable = cfModel.minNextSpeed(getSpeed(), this);
2223  double lateralShift = 0;
2224  if (isRailway((SVCPermissions)getVehicleType().getVehicleClass())) {
2225  // speed limits must hold for the whole length of the train
2226  for (MSLane* l : myFurtherLanes) {
2227  laneMaxV = MIN2(laneMaxV, l->getVehicleMaxSpeed(this));
2228  }
2229  }
2230  // speed limits are not emergencies (e.g. when the limit changes suddenly due to TraCI or a variableSpeedSignal)
2231  laneMaxV = MAX2(laneMaxV, vMinComfortable);
2233  laneMaxV = std::numeric_limits<double>::max();
2234  }
2235  // v is the initial maximum velocity of this vehicle in this step
2236  double v = MIN2(maxV, laneMaxV);
2237  // if we are modelling parking then we dawdle until the manoeuvre is complete - by setting a very low max speed
2238  // in practice this only applies to exit manoeuvre because entry manoeuvre just delays setting stop.reached - when the vehicle is virtually stopped
2240  v = NUMERICAL_EPS_SPEED;
2241  }
2242 
2243  if (myInfluencer != nullptr) {
2244  const double vMin = MAX2(0., cfModel.minNextSpeed(myState.mySpeed, this));
2245  v = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), v, v, vMin, maxV);
2246  v = myInfluencer->gapControlSpeed(MSNet::getInstance()->getCurrentTimeStep(), this, v, v, vMin, maxV);
2247  }
2248  // all links within dist are taken into account (potentially)
2249  const double dist = SPEED2DIST(maxV) + cfModel.brakeGap(maxV);
2250 
2251  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation();
2252 #ifdef DEBUG_PLAN_MOVE
2253  if (DEBUG_COND) {
2254  std::cout << " dist=" << dist << " bestLaneConts=" << toString(bestLaneConts) << "\n";
2255  }
2256 #endif
2257  assert(bestLaneConts.size() > 0);
2258  bool hadNonInternal = false;
2259  // the distance already "seen"; in the following always up to the end of the current "lane"
2260  double seen = opposite ? myState.myPos : myLane->getLength() - myState.myPos;
2261  myNextTurn.first = seen;
2262  myNextTurn.second = LINKDIR_NODIR;
2263  bool encounteredTurn = (MSGlobals::gLateralResolution <= 0); // next turn is only needed for sublane
2264  double seenNonInternal = 0;
2265  double seenInternal = myLane->isInternal() ? seen : 0;
2266  double vLinkPass = MIN2(cfModel.estimateSpeedAfterDistance(seen, v, cfModel.getMaxAccel()), laneMaxV); // upper bound
2267  int view = 0;
2268  DriveProcessItem* lastLink = nullptr;
2269  bool slowedDownForMinor = false; // whether the vehicle already had to slow down on approach to a minor link
2270  // iterator over subsequent lanes and fill lfLinks until stopping distance or stopped
2271  const MSLane* lane = opposite ? myLane->getOpposite() : myLane;
2272  assert(lane != 0);
2273  const MSLane* leaderLane = myLane;
2274 #ifdef _MSC_VER
2275 #pragma warning(push)
2276 #pragma warning(disable: 4127) // do not warn about constant conditional expression
2277 #endif
2278  while (true) {
2279 #ifdef _MSC_VER
2280 #pragma warning(pop)
2281 #endif
2282  // check leader on lane
2283  // leader is given for the first edge only
2284  if (opposite &&
2285  (leaderLane->getVehicleNumberWithPartials() > 1
2286  || (leaderLane != myLane && leaderLane->getVehicleNumber() > 0))) {
2287  // find opposite-driving leader that must be respected on the currently looked at lane
2288  // XXX make sure to look no further than leaderLane
2289  CLeaderDist leader = leaderLane->getOppositeLeader(this, getPositionOnLane(), true);
2290  ahead.clear();
2291  if (leader.first != 0 && leader.first->getLane() == leaderLane && leader.first->getLaneChangeModel().isOpposite()) {
2292  ahead.addLeader(leader.first, true);
2293  }
2294  }
2295  adaptToLeaders(ahead, lateralShift, seen, lastLink, leaderLane, v, vLinkPass);
2296  if (lastLink != nullptr) {
2297  lastLink->myVLinkWait = MIN2(lastLink->myVLinkWait, v);
2298  }
2299 #ifdef DEBUG_PLAN_MOVE
2300  if (DEBUG_COND) {
2301  std::cout << "\nv = " << v << "\n";
2302 
2303  }
2304 #endif
2305  // XXX efficiently adapt to shadow leaders using neighAhead by iteration over the whole edge in parallel (lanechanger-style)
2306  if (getLaneChangeModel().getShadowLane() != nullptr) {
2307  // also slow down for leaders on the shadowLane relative to the current lane
2308  const MSLane* shadowLane = getLaneChangeModel().getShadowLane(lane);
2309  if (shadowLane != nullptr) {
2310  const double latOffset = getLane()->getRightSideOnEdge() - getLaneChangeModel().getShadowLane()->getRightSideOnEdge();
2311  adaptToLeaders(shadowLane->getLastVehicleInformation(this, latOffset, lane->getLength() - seen),
2312  latOffset,
2313  seen, lastLink, shadowLane, v, vLinkPass);
2314  }
2315  }
2316  // adapt to pedestrians on the same lane
2317  if (lane->getEdge().getPersons().size() > 0 && MSPModel::getModel()->hasPedestrians(lane)) {
2318  const double relativePos = lane->getLength() - seen;
2319 #ifdef DEBUG_PLAN_MOVE
2320  if (DEBUG_COND) {
2321  std::cout << SIMTIME << " adapt to pedestrians on lane=" << lane->getID() << " relPos=" << relativePos << "\n";
2322  }
2323 #endif
2324  PersonDist leader = MSPModel::getModel()->nextBlocking(lane, relativePos,
2326  if (leader.first != 0) {
2327  const double stopSpeed = cfModel.stopSpeed(this, getSpeed(), leader.second - getVehicleType().getMinGap());
2328  v = MIN2(v, stopSpeed);
2329 #ifdef DEBUG_PLAN_MOVE
2330  if (DEBUG_COND) {
2331  std::cout << SIMTIME << " pedLeader=" << leader.first->getID() << " dist=" << leader.second << " v=" << v << "\n";
2332  }
2333 #endif
2334  }
2335  }
2336 
2337  // process stops
2338  if (!myStops.empty() && &myStops.begin()->lane->getEdge() == &lane->getEdge()
2339  && (!myStops.begin()->reached || (myStops.begin()->pars.speed > 0 && keepStopping()))
2340  // ignore stops that occur later in a looped route
2341  && myStops.front().edge == myCurrEdge + view) {
2342  // we are approaching a stop on the edge; must not drive further
2343  const Stop& stop = *myStops.begin();
2344  double endPos = stop.getEndPos(*this) + NUMERICAL_EPS;
2345  if (stop.parkingarea != nullptr) {
2346  // leave enough space so parking vehicles can exit
2347  endPos = stop.parkingarea->getLastFreePosWithReservation(t, *this);
2348  } else if (stop.pars.speed > 0 && !stop.reached) {
2349  // waypoint mode
2350  endPos = stop.pars.startPos;
2351  }
2352  myStopDist = seen + endPos - lane->getLength();
2353  // regular stops are not emergencies
2354  double stopSpeed;
2355  if (stop.pars.speed > 0) {
2356  // waypoint mode
2357  if (stop.reached) {
2358  stopSpeed = stop.pars.speed;
2359  if (myState.myPos >= stop.pars.endPos) {
2360  myStopDist = std::numeric_limits<double>::max();
2361  }
2362  } else {
2363  stopSpeed = MAX2(cfModel.freeSpeed(this, getSpeed(), myStopDist, stop.pars.speed), vMinComfortable);
2364  if (lastLink != nullptr) {
2365  lastLink->adaptLeaveSpeed(cfModel.freeSpeed(this, vLinkPass, endPos, stop.pars.speed));
2366  }
2367  }
2368  } else {
2369  stopSpeed = MAX2(cfModel.stopSpeed(this, getSpeed(), myStopDist), vMinComfortable);
2370  if (lastLink != nullptr) {
2371  lastLink->adaptLeaveSpeed(cfModel.stopSpeed(this, vLinkPass, endPos));
2372  }
2373  }
2374  v = MIN2(v, stopSpeed);
2375  if (lane->isInternal()) {
2376  MSLinkCont::const_iterator exitLink = MSLane::succLinkSec(*this, view + 1, *lane, bestLaneConts);
2377  assert(!lane->isLinkEnd(exitLink));
2378  bool dummySetRequest;
2379  double dummyVLinkWait;
2380  checkLinkLeaderCurrentAndParallel(*exitLink, lane, seen, lastLink, v, vLinkPass, dummyVLinkWait, dummySetRequest);
2381  }
2382  lfLinks.push_back(DriveProcessItem(v, myStopDist));
2383 
2384 #ifdef DEBUG_PLAN_MOVE
2385  if (DEBUG_COND) {
2386  std::cout << "\n" << SIMTIME << " next stop: distance = " << myStopDist << " requires stopSpeed = " << stopSpeed << "\n";
2387 
2388  }
2389 #endif
2390 
2391  break;
2392  }
2393 
2394  // move to next lane
2395  // get the next link used
2396  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, view + 1, *lane, bestLaneConts);
2397 
2398  // Check whether this is a turn (to save info about the next upcoming turn)
2399  if (!encounteredTurn) {
2400  if (!lane->isLinkEnd(link) && lane->getLinkCont().size() > 1) {
2401  LinkDirection linkDir = (*link)->getDirection();
2402  switch (linkDir) {
2403  case LINKDIR_STRAIGHT:
2404  case LINKDIR_NODIR:
2405  break;
2406  default:
2407  myNextTurn.first = seen;
2408  myNextTurn.second = linkDir;
2409  encounteredTurn = true;
2410 #ifdef DEBUG_NEXT_TURN
2411  if (DEBUG_COND) {
2412  std::cout << SIMTIME << " veh '" << getID() << "' nextTurn: " << toString(myNextTurn.second)
2413  << " at " << myNextTurn.first << "m." << std::endl;
2414  }
2415 #endif
2416  }
2417  }
2418  }
2419 
2420  // check whether the vehicle is on its final edge
2421  if (myCurrEdge + view + 1 == myRoute->end()) {
2422  const double arrivalSpeed = (myParameter->arrivalSpeedProcedure == ARRIVAL_SPEED_GIVEN ?
2423  myParameter->arrivalSpeed : laneMaxV);
2424  // subtract the arrival speed from the remaining distance so we get one additional driving step with arrival speed
2425  // XXX: This does not work for ballistic update refs #2579
2426  const double distToArrival = seen + myArrivalPos - lane->getLength() - SPEED2DIST(arrivalSpeed);
2427  const double va = MAX2(NUMERICAL_EPS, cfModel.freeSpeed(this, getSpeed(), distToArrival, arrivalSpeed));
2428  v = MIN2(v, va);
2429  if (lastLink != nullptr) {
2430  lastLink->adaptLeaveSpeed(va);
2431  }
2432  lfLinks.push_back(DriveProcessItem(v, seen, lane->getEdge().isFringe() ? 1000 : 0));
2433  break;
2434  }
2435  // check whether the lane or the shadowLane is a dead end (allow some leeway on intersections)
2436  if (lane->isLinkEnd(link) ||
2437  ((*link)->getViaLane() == nullptr
2439  // do not get stuck on narrow edges
2440  && getVehicleType().getWidth() <= lane->getEdge().getWidth()
2441  // this is the exit link of a junction. The normal edge should support the shadow
2442  && ((getLaneChangeModel().getShadowLane((*link)->getLane()) == nullptr)
2443  // the internal lane after an internal junction has no parallel lane. make sure there is no shadow before continuing
2444  || (lane->getEdge().isInternal() && lane->getIncomingLanes()[0].lane->getEdge().isInternal()))
2445  // ignore situations where the shadow lane is part of a double-connection with the current lane
2446  && (getLaneChangeModel().getShadowLane() == nullptr
2447  || getLaneChangeModel().getShadowLane()->getLinkCont().size() == 0
2448  || getLaneChangeModel().getShadowLane()->getLinkCont().front()->getLane() != (*link)->getLane())
2449  )) {
2450  double va = cfModel.stopSpeed(this, getSpeed(), seen);
2451  if (lastLink != nullptr) {
2452  lastLink->adaptLeaveSpeed(va);
2453  }
2454  if (getLaneChangeModel().getCommittedSpeed() > 0) {
2455  v = MIN2(getLaneChangeModel().getCommittedSpeed(), v);
2456  } else {
2457  v = MIN2(va, v);
2458  }
2459 #ifdef DEBUG_PLAN_MOVE
2460  if (DEBUG_COND) {
2461  std::cout << " braking for link end lane=" << lane->getID() << " seen=" << seen
2462  << " overlap=" << getLateralOverlap() << " va=" << va << " committed=" << getLaneChangeModel().getCommittedSpeed() << " v=" << v << "\n";
2463 
2464  }
2465 #endif
2466  if (lane->isLinkEnd(link)) {
2467  lfLinks.push_back(DriveProcessItem(v, seen));
2468  break;
2469  }
2470  }
2471  lateralShift += (*link)->getLateralShift();
2472  const bool yellowOrRed = (*link)->haveRed() || (*link)->haveYellow();
2473  // We distinguish 3 cases when determining the point at which a vehicle stops:
2474  // - links that require stopping: here the vehicle needs to stop close to the stop line
2475  // to ensure it gets onto the junction in the next step. Otherwise the vehicle would 'forget'
2476  // that it already stopped and need to stop again. This is necessary pending implementation of #999
2477  // - red/yellow light: here the vehicle 'knows' that it will have priority eventually and does not need to stop on a precise spot
2478  // - other types of minor links: the vehicle needs to stop as close to the junction as necessary
2479  // to minimize the time window for passing the junction. If the
2480  // vehicle 'decides' to accelerate and cannot enter the junction in
2481  // the next step, new foes may appear and cause a collision (see #1096)
2482  // - major links: stopping point is irrelevant
2483  double laneStopOffset;
2484  const double majorStopOffset = MAX2(DIST_TO_STOPLINE_EXPECT_PRIORITY, lane->getStopOffset(this));
2485  const double minorStopOffset = lane->getStopOffset(this);
2486  const double brakeDist = cfModel.brakeGap(myState.mySpeed, cfModel.getMaxDecel(), 0);
2487  const bool canBrakeBeforeLaneEnd = seen >= brakeDist;
2488  const bool canBrakeBeforeStopLine = seen - lane->getStopOffset(this) >= brakeDist;
2489  if (yellowOrRed) {
2490  // Wait at red traffic light with full distance if possible
2491  laneStopOffset = majorStopOffset;
2492  } else if ((*link)->havePriority()) {
2493  // On priority link, we should never stop below visibility distance
2494  laneStopOffset = MIN2((*link)->getFoeVisibilityDistance() - POSITION_EPS, majorStopOffset);
2495  } else {
2496  // On minor link, we should likewise never stop below visibility distance
2497  laneStopOffset = MIN2((*link)->getFoeVisibilityDistance() - POSITION_EPS, minorStopOffset);
2498  }
2499  if (canBrakeBeforeLaneEnd) {
2500  // avoid emergency braking if possible
2501  laneStopOffset = MIN2(laneStopOffset, seen - brakeDist);
2502  }
2503  laneStopOffset = MAX2(POSITION_EPS, laneStopOffset);
2504  const double stopDist = MAX2(0., seen - laneStopOffset);
2505 
2506 #ifdef DEBUG_PLAN_MOVE
2507  if (DEBUG_COND) {
2508  std::cout << SIMTIME << " veh=" << getID() << " effective stopOffset on lane '" << lane->getID()
2509  << "' is " << laneStopOffset << " (-> stopDist=" << stopDist << ")" << std::endl;
2510  }
2511 #endif
2512  // check for train direction reversal
2513  if (canReverse(laneMaxV)) {
2514  // reverse as soon as comfortably possible but also prevent running into a buffer stop
2515  const double vReverse = MIN2(
2516  cfModel.stopSpeed(this, getSpeed(), seen - POSITION_EPS),
2517  vMinComfortable);
2518 #ifdef DEBUG_REVERSE_BIDI
2519  if (DEBUG_COND) {
2520  std::cout << SIMTIME << " seen=" << seen << " vReverse=" << vReverse << "\n";
2521  }
2522 #endif
2523  lfLinks.push_back(DriveProcessItem(*link, vReverse, vReverse, false, t, 0, t, 0, seen));
2524  }
2525 
2526  // check whether we need to slow down in order to finish a continuous lane change
2527  if (getLaneChangeModel().isChangingLanes()) {
2528  if ( // slow down to finish lane change before a turn lane
2529  ((*link)->getDirection() == LINKDIR_LEFT || (*link)->getDirection() == LINKDIR_RIGHT) ||
2530  // slow down to finish lane change before the shadow lane ends
2531  (getLaneChangeModel().getShadowLane() != nullptr &&
2532  (*link)->getViaLaneOrLane()->getParallelLane(getLaneChangeModel().getShadowDirection()) == nullptr)) {
2533  // XXX maybe this is too harsh. Vehicles could cut some corners here
2534  const double timeRemaining = STEPS2TIME(getLaneChangeModel().remainingTime());
2535  assert(timeRemaining != 0);
2536  // XXX: Euler-logic (#860), but I couldn't identify problems from this yet (Leo). Refs. #2575
2537  const double va = MAX2(cfModel.stopSpeed(this, getSpeed(), seen - POSITION_EPS),
2538  (seen - POSITION_EPS) / timeRemaining);
2539 #ifdef DEBUG_PLAN_MOVE
2540  if (DEBUG_COND) {
2541  std::cout << SIMTIME << " veh=" << getID() << " slowing down to finish continuous change before"
2542  << " link=" << (*link)->getViaLaneOrLane()->getID()
2543  << " timeRemaining=" << timeRemaining
2544  << " v=" << v
2545  << " va=" << va
2546  << std::endl;
2547  }
2548 #endif
2549  v = MIN2(va, v);
2550  }
2551  }
2552 
2553  // - always issue a request to leave the intersection we are currently on
2554  const bool leavingCurrentIntersection = myLane->getEdge().isInternal() && lastLink == nullptr;
2555  // - do not issue a request to enter an intersection after we already slowed down for an earlier one
2556  const bool abortRequestAfterMinor = slowedDownForMinor && (*link)->getInternalLaneBefore() == nullptr;
2557  // - even if red, if we cannot break we should issue a request
2558  bool setRequest = (v > NUMERICAL_EPS_SPEED && !abortRequestAfterMinor) || (leavingCurrentIntersection);
2559 
2560  double vLinkWait = MIN2(v, cfModel.stopSpeed(this, getSpeed(), stopDist));
2561 #ifdef DEBUG_PLAN_MOVE
2562  if (DEBUG_COND) {
2563  std::cout
2564  << " stopDist=" << stopDist
2565  << " vLinkWait=" << vLinkWait
2566  << " brakeDist=" << brakeDist
2567  << " seen=" << seen
2568  << " leaveIntersection=" << leavingCurrentIntersection
2569  << " setRequest=" << setRequest
2570  //<< std::setprecision(16)
2571  //<< " v=" << v
2572  //<< " speedEps=" << NUMERICAL_EPS_SPEED
2573  //<< std::setprecision(gPrecision)
2574  << "\n";
2575  }
2576 #endif
2577 
2578  // TODO: Consider option on the CFModel side to allow red/yellow light violation
2579 
2580  if (yellowOrRed && canBrakeBeforeStopLine && !ignoreRed(*link, canBrakeBeforeStopLine)) {
2581  if (lane->isInternal()) {
2582  checkLinkLeaderCurrentAndParallel(*link, lane, seen, lastLink, v, vLinkPass, vLinkWait, setRequest);
2583  }
2584  // the vehicle is able to brake in front of a yellow/red traffic light
2585  lfLinks.push_back(DriveProcessItem(*link, vLinkWait, vLinkWait, false, t + TIME2STEPS(seen / MAX2(vLinkWait, NUMERICAL_EPS)), vLinkWait, 0, 0, seen));
2586  //lfLinks.push_back(DriveProcessItem(0, vLinkWait, vLinkWait, false, 0, 0, stopDist));
2587  break;
2588  }
2589 
2590  if (ignoreRed(*link, canBrakeBeforeStopLine) && STEPS2TIME(t - (*link)->getLastStateChange()) > 2) {
2591  // restrict speed when ignoring a red light
2592  const double redSpeed = MIN2(v, getVehicleType().getParameter().getJMParam(SUMO_ATTR_JM_DRIVE_RED_SPEED, v));
2593  const double va = MAX2(redSpeed, cfModel.freeSpeed(this, getSpeed(), seen, redSpeed));
2594  v = MIN2(va, v);
2595 #ifdef DEBUG_PLAN_MOVE
2596  if (DEBUG_COND) std::cout
2597  << " ignoreRed spent=" << STEPS2TIME(t - (*link)->getLastStateChange())
2598  << " redSpeed=" << redSpeed
2599  << " va=" << va
2600  << " v=" << v
2601  << "\n";
2602 #endif
2603  }
2604 
2605 
2606  checkLinkLeaderCurrentAndParallel(*link, lane, seen, lastLink, v, vLinkPass, vLinkWait, setRequest);
2607 
2608  if (lastLink != nullptr) {
2609  lastLink->adaptLeaveSpeed(laneMaxV);
2610  }
2611  double arrivalSpeed = vLinkPass;
2612  // vehicles should decelerate when approaching a minor link
2613  // - unless they are close enough to have clear visibility of all relevant foe lanes and may start to accelerate again
2614  // - and unless they are so close that stopping is impossible (i.e. when a green light turns to yellow when close to the junction)
2615 
2616  // whether the vehicle/driver is close enough to the link to see all possible foes #2123
2617  double visibilityDistance = (*link)->getFoeVisibilityDistance();
2618  double determinedFoePresence = seen <= visibilityDistance;
2619 // // VARIANT: account for time needed to recognize whether relevant vehicles are on the foe lanes. (Leo)
2620 // double foeRecognitionTime = 0.0;
2621 // double determinedFoePresence = seen < visibilityDistance - myState.mySpeed*foeRecognitionTime;
2622 
2623 #ifdef DEBUG_PLAN_MOVE
2624  if (DEBUG_COND) {
2625  std::cout << " approaching link=" << (*link)->getViaLaneOrLane()->getID() << " prio=" << (*link)->havePriority() << " seen=" << seen << " visibilityDistance=" << visibilityDistance << " brakeDist=" << brakeDist << "\n";
2626  }
2627 #endif
2628 
2629  if (!(*link)->havePriority() && !determinedFoePresence && brakeDist < seen && !(*link)->lastWasContMajor()) {
2630  // vehicle decelerates just enough to be able to stop if necessary and then accelerates
2631  double maxSpeedAtVisibilityDist = cfModel.maximumSafeStopSpeed(visibilityDistance, myState.mySpeed, false, 0.);
2632  // XXX: estimateSpeedAfterDistance does not use euler-logic (thus returns a lower value than possible here...)
2633  double maxArrivalSpeed = cfModel.estimateSpeedAfterDistance(visibilityDistance, maxSpeedAtVisibilityDist, cfModel.getMaxAccel());
2634  arrivalSpeed = MIN2(vLinkPass, maxArrivalSpeed);
2635  slowedDownForMinor = true;
2636 #ifdef DEBUG_PLAN_MOVE
2637  if (DEBUG_COND) {
2638  std::cout << " slowedDownForMinor maxSpeedAtVisDist=" << maxSpeedAtVisibilityDist << " maxArrivalSpeed=" << maxArrivalSpeed << " arrivalSpeed=" << arrivalSpeed << "\n";
2639  }
2640 #endif
2641  } else if ((*link)->getState() == LINKSTATE_EQUAL && myWaitingTime > 0) {
2642  // check for deadlock (circular yielding)
2643  //std::cout << SIMTIME << " veh=" << getID() << " check rbl-deadlock\n";
2644  std::pair<const SUMOVehicle*, const MSLink*> blocker = (*link)->getFirstApproachingFoe();
2645  //std::cout << " blocker=" << Named::getIDSecure(blocker.first) << "\n";
2646  while (blocker.second != nullptr && blocker.second != *link) {
2647  blocker = blocker.second->getFirstApproachingFoe();
2648  //std::cout << " blocker=" << Named::getIDSecure(blocker.first) << "\n";
2649  }
2650  //std::cout << " blockerLink=" << blocker.second << " link=" << *link << "\n";
2651  if (blocker.second == *link) {
2652  const double threshold = (*link)->getDirection() == LINKDIR_STRAIGHT ? 0.25 : 0.75;
2653  if (RandHelper::rand(getRNG()) < threshold) {
2654  //std::cout << " abort request, threshold=" << threshold << "\n";
2655  setRequest = false;
2656  }
2657  }
2658  }
2659 
2660  SUMOTime arrivalTime;
2662  // @note intuitively it would make sense to compare arrivalSpeed with getSpeed() instead of v
2663  // however, due to the current position update rule (ticket #860) the vehicle moves with v in this step
2664  // subtract DELTA_T because t is the time at the end of this step and the movement is not carried out yet
2665  arrivalTime = t - DELTA_T + cfModel.getMinimalArrivalTime(seen, v, arrivalSpeed);
2666  } else {
2667  arrivalTime = t - DELTA_T + cfModel.getMinimalArrivalTime(seen, myState.mySpeed, arrivalSpeed);
2668  }
2669 
2670  // compute arrival speed and arrival time if vehicle starts braking now
2671  // if stopping is possible, arrivalTime can be arbitrarily large. A small value keeps fractional times (impatience) meaningful
2672  double arrivalSpeedBraking = 0;
2673  SUMOTime arrivalTimeBraking = arrivalTime + TIME2STEPS(30);
2674  if (seen < cfModel.brakeGap(v)) { // XXX: should this use the current speed (at least for the ballistic case)? (Leo) Refs. #2575
2675  // vehicle cannot come to a complete stop in time
2677  arrivalSpeedBraking = cfModel.getMinimalArrivalSpeedEuler(seen, v);
2678  // due to discrete/continuous mismatch (when using Euler update) we have to ensure that braking actually helps
2679  arrivalSpeedBraking = MIN2(arrivalSpeedBraking, arrivalSpeed);
2680  } else {
2681  arrivalSpeedBraking = cfModel.getMinimalArrivalSpeed(seen, myState.mySpeed);
2682  }
2683  if (v + arrivalSpeedBraking <= 0.) {
2684  arrivalTimeBraking = std::numeric_limits<long long int>::max();
2685  } else {
2686  arrivalTimeBraking = MAX2(arrivalTime, t + TIME2STEPS(seen / ((v + arrivalSpeedBraking) * 0.5)));
2687  }
2688  }
2689  lfLinks.push_back(DriveProcessItem(*link, v, vLinkWait, setRequest,
2690  arrivalTime, arrivalSpeed,
2691  arrivalTimeBraking, arrivalSpeedBraking,
2692  seen,
2693  estimateLeaveSpeed(*link, arrivalSpeed)));
2694  if ((*link)->getViaLane() == nullptr) {
2695  hadNonInternal = true;
2696  ++view;
2697  }
2698 #ifdef DEBUG_PLAN_MOVE
2699  if (DEBUG_COND) {
2700  std::cout << " checkAbort setRequest=" << setRequest << " v=" << v << " seen=" << seen << " dist=" << dist
2701  << " seenNonInternal=" << seenNonInternal
2702  << " seenInternal=" << seenInternal << " length=" << vehicleLength << "\n";
2703  }
2704 #endif
2705  // we need to look ahead far enough to see available space for checkRewindLinkLanes
2706  if ((!setRequest || v <= 0 || seen > dist) && hadNonInternal && seenNonInternal > MAX2(vehicleLength * CRLL_LOOK_AHEAD, vehicleLength + seenInternal)) {
2707  break;
2708  }
2709  // get the following lane
2710  lane = (*link)->getViaLaneOrLane();
2711  laneMaxV = lane->getVehicleMaxSpeed(this);
2713  laneMaxV = std::numeric_limits<double>::max();
2714  }
2715  // the link was passed
2716  // compute the velocity to use when the link is not blocked by other vehicles
2717  // the vehicle shall be not faster when reaching the next lane than allowed
2718  // speed limits are not emergencies (e.g. when the limit changes suddenly due to TraCI or a variableSpeedSignal)
2719  const double va = MAX2(cfModel.freeSpeed(this, getSpeed(), seen, laneMaxV), vMinComfortable);
2720  v = MIN2(va, v);
2721  if (lane->getEdge().isInternal()) {
2722  seenInternal += lane->getLength();
2723  } else {
2724  seenNonInternal += lane->getLength();
2725  }
2726  // do not restrict results to the current vehicle to allow caching for the current time step
2727  leaderLane = opposite ? lane->getOpposite() : lane;
2728  if (leaderLane == nullptr) {
2729  break;
2730  }
2731  ahead = opposite ? MSLeaderInfo(leaderLane) : leaderLane->getLastVehicleInformation(nullptr, 0);
2732  seen += lane->getLength();
2733  vLinkPass = MIN2(cfModel.estimateSpeedAfterDistance(lane->getLength(), v, cfModel.getMaxAccel()), laneMaxV); // upper bound
2734  lastLink = &lfLinks.back();
2735  }
2736 
2737 //#ifdef DEBUG_PLAN_MOVE
2738 // if(DEBUG_COND){
2739 // std::cout << "planMoveInternal found safe speed v = " << v << std::endl;
2740 // }
2741 //#endif
2742 
2743 }
2744 
2745 
2746 void
2747 MSVehicle::adaptToLeaders(const MSLeaderInfo& ahead, double latOffset,
2748  const double seen, DriveProcessItem* const lastLink,
2749  const MSLane* const lane, double& v, double& vLinkPass) const {
2750  int rightmost;
2751  int leftmost;
2752  ahead.getSubLanes(this, latOffset, rightmost, leftmost);
2753 #ifdef DEBUG_PLAN_MOVE
2754  if (DEBUG_COND) std::cout << SIMTIME
2755  << "\nADAPT_TO_LEADERS\nveh=" << getID()
2756  << " lane=" << lane->getID()
2757  << " latOffset=" << latOffset
2758  << " rm=" << rightmost
2759  << " lm=" << leftmost
2760  << " ahead=" << ahead.toString()
2761  << "\n";
2762 #endif
2763  /*
2764  if (getLaneChangeModel().getCommittedSpeed() > 0) {
2765  v = MIN2(v, getLaneChangeModel().getCommittedSpeed());
2766  vLinkPass = MIN2(vLinkPass, getLaneChangeModel().getCommittedSpeed());
2767  #ifdef DEBUG_PLAN_MOVE
2768  if (DEBUG_COND) std::cout << " hasCommitted=" << getLaneChangeModel().getCommittedSpeed() << "\n";
2769  #endif
2770  return;
2771  }
2772  */
2773  for (int sublane = rightmost; sublane <= leftmost; ++sublane) {
2774  const MSVehicle* pred = ahead[sublane];
2775  if (pred != nullptr && pred != this) {
2776  // @todo avoid multiple adaptations to the same leader
2777  const double predBack = pred->getBackPositionOnLane(lane);
2778  double gap = (lastLink == nullptr
2779  ? predBack - myState.myPos - getVehicleType().getMinGap()
2780  : predBack + seen - lane->getLength() - getVehicleType().getMinGap());
2781  if (getLaneChangeModel().isOpposite()) {
2782  gap *= -1;
2783  }
2784 #ifdef DEBUG_PLAN_MOVE
2785  if (DEBUG_COND) {
2786  std::cout << " pred=" << pred->getID() << " predLane=" << pred->getLane()->getID() << " predPos=" << pred->getPositionOnLane() << " gap=" << gap << " predBack=" << predBack << " seen=" << seen << " lane=" << lane->getID() << " myLane=" << myLane->getID() << "\n";
2787  }
2788 #endif
2789  adaptToLeader(std::make_pair(pred, gap), seen, lastLink, lane, v, vLinkPass);
2790  }
2791  }
2792 }
2793 
2794 
2795 void
2796 MSVehicle::adaptToLeader(const std::pair<const MSVehicle*, double> leaderInfo,
2797  const double seen, DriveProcessItem* const lastLink,
2798  const MSLane* const lane, double& v, double& vLinkPass,
2799  double distToCrossing) const {
2800  if (leaderInfo.first != 0) {
2801  const double vsafeLeader = getSafeFollowSpeed(leaderInfo, seen, lane, distToCrossing);
2802  if (lastLink != nullptr) {
2803  lastLink->adaptLeaveSpeed(vsafeLeader);
2804  }
2805  v = MIN2(v, vsafeLeader);
2806  vLinkPass = MIN2(vLinkPass, vsafeLeader);
2807 
2808 #ifdef DEBUG_PLAN_MOVE
2809  if (DEBUG_COND) std::cout
2810  << SIMTIME
2811  //std::cout << std::setprecision(10);
2812  << " veh=" << getID()
2813  << " lead=" << leaderInfo.first->getID()
2814  << " leadSpeed=" << leaderInfo.first->getSpeed()
2815  << " gap=" << leaderInfo.second
2816  << " leadLane=" << leaderInfo.first->getLane()->getID()
2817  << " predPos=" << leaderInfo.first->getPositionOnLane()
2818  << " seen=" << seen
2819  << " lane=" << lane->getID()
2820  << " myLane=" << myLane->getID()
2821  << " dTC=" << distToCrossing
2822  << " v=" << v
2823  << " vSafeLeader=" << vsafeLeader
2824  << " vLinkPass=" << vLinkPass
2825  << "\n";
2826 #endif
2827  }
2828 }
2829 
2830 
2831 void
2832 MSVehicle::checkLinkLeaderCurrentAndParallel(const MSLink* link, const MSLane* lane, double seen,
2833  DriveProcessItem* const lastLink, double& v, double& vLinkPass, double& vLinkWait, bool& setRequest) const {
2835  // we want to pass the link but need to check for foes on internal lanes
2836  checkLinkLeader(link, lane, seen, lastLink, v, vLinkPass, vLinkWait, setRequest);
2837  if (getLaneChangeModel().getShadowLane() != nullptr) {
2838  MSLink* parallelLink = link->getParallelLink(getLaneChangeModel().getShadowDirection());
2839  if (parallelLink != nullptr) {
2840  checkLinkLeader(parallelLink, lane, seen, lastLink, v, vLinkPass, vLinkWait, setRequest, true);
2841  }
2842  }
2843  }
2844 
2845 }
2846 
2847 void
2848 MSVehicle::checkLinkLeader(const MSLink* link, const MSLane* lane, double seen,
2849  DriveProcessItem* const lastLink, double& v, double& vLinkPass, double& vLinkWait, bool& setRequest,
2850  bool isShadowLink) const {
2851 #ifdef DEBUG_PLAN_MOVE_LEADERINFO
2852  if (DEBUG_COND) {
2853  gDebugFlag1 = true; // See MSLink::getLeaderInfo
2854  }
2855 #endif
2856  const MSLink::LinkLeaders linkLeaders = link->getLeaderInfo(this, seen, nullptr, isShadowLink);
2857 #ifdef DEBUG_PLAN_MOVE_LEADERINFO
2858  if (DEBUG_COND) {
2859  gDebugFlag1 = false; // See MSLink::getLeaderInfo
2860  }
2861 #endif
2862  for (MSLink::LinkLeaders::const_iterator it = linkLeaders.begin(); it != linkLeaders.end(); ++it) {
2863  // the vehicle to enter the junction first has priority
2864  const MSVehicle* leader = (*it).vehAndGap.first;
2865  if (leader == nullptr) {
2866  // leader is a pedestrian. Passing 'this' as a dummy.
2867 #ifdef DEBUG_PLAN_MOVE_LEADERINFO
2868  if (DEBUG_COND) {
2869  std::cout << SIMTIME << " veh=" << getID() << " is blocked on link to " << link->getViaLaneOrLane()->getID() << " by pedestrian. dist=" << it->distToCrossing << "\n";
2870  }
2871 #endif
2872  adaptToLeader(std::make_pair(this, -1), seen, lastLink, lane, v, vLinkPass, it->distToCrossing);
2873  } else if (isLeader(link, leader)) {
2875  // sibling link (XXX: could also be partial occupator where this check fails)
2876  &leader->getLane()->getEdge() == &lane->getEdge()) {
2877  // check for sublane obstruction (trivial for sibling link leaders)
2878  const MSLane* conflictLane = link->getInternalLaneBefore();
2879  MSLeaderInfo linkLeadersAhead = MSLeaderInfo(conflictLane);
2880  linkLeadersAhead.addLeader(leader, false, 0); // assume sibling lane has the same geometry as the leader lane
2881  const double latOffset = isShadowLink ? (getLane()->getRightSideOnEdge() - getLaneChangeModel().getShadowLane()->getRightSideOnEdge()) : 0;
2882  // leader is neither on lane nor conflictLane (the conflict is only established geometrically)
2883  adaptToLeaders(linkLeadersAhead, latOffset, seen, lastLink, leader->getLane(), v, vLinkPass);
2884 #ifdef DEBUG_PLAN_MOVE
2885  if (DEBUG_COND) {
2886  std::cout << SIMTIME << " veh=" << getID()
2887  << " siblingFoe link=" << link->getViaLaneOrLane()->getID()
2888  << " isShadowLink=" << isShadowLink
2889  << " lane=" << lane->getID()
2890  << " foe=" << leader->getID()
2891  << " foeLane=" << leader->getLane()->getID()
2892  << " latOffset=" << latOffset
2893  << " latOffsetFoe=" << leader->getLatOffset(lane)
2894  << " linkLeadersAhead=" << linkLeadersAhead.toString()
2895  << "\n";
2896  }
2897 #endif
2898  } else {
2899 #ifdef DEBUG_PLAN_MOVE
2900  if (DEBUG_COND) {
2901  std::cout << SIMTIME << " veh=" << getID() << " linkLeader=" << leader->getID()
2902  << " ET=" << myJunctionEntryTime << " lET=" << leader->myJunctionEntryTime
2903  << " ETN=" << myJunctionEntryTimeNeverYield << " lETN=" << leader->myJunctionEntryTimeNeverYield
2904  << " CET=" << myJunctionConflictEntryTime << " lCET=" << leader->myJunctionConflictEntryTime
2905  << "\n";
2906  }
2907 #endif
2908  adaptToLeader(it->vehAndGap, seen, lastLink, lane, v, vLinkPass, it->distToCrossing);
2909  }
2910  if (lastLink != nullptr) {
2911  // we are not yet on the junction with this linkLeader.
2912  // at least we can drive up to the previous link and stop there
2913  v = MAX2(v, lastLink->myVLinkWait);
2914  }
2915  // if blocked by a leader from the same or next lane we must yield our request
2916  // also, if blocked by a stopped or blocked leader
2917  if (v < SUMO_const_haltingSpeed
2918  //&& leader->getSpeed() < SUMO_const_haltingSpeed
2920  || leader->getLane()->getLogicalPredecessorLane() == myLane
2921  || leader->isStopped()
2923  setRequest = false;
2924 #ifdef DEBUG_PLAN_MOVE_LEADERINFO
2925  if (DEBUG_COND) {
2926  std::cout << " aborting request\n";
2927  }
2928 #endif
2929  if (lastLink != nullptr && leader->getLane()->getLogicalPredecessorLane() == myLane) {
2930  // we are not yet on the junction so must abort that request as well
2931  // (or maybe we are already on the junction and the leader is a partial occupator beyond)
2932  lastLink->mySetRequest = false;
2933 #ifdef DEBUG_PLAN_MOVE_LEADERINFO
2934  if (DEBUG_COND) {
2935  std::cout << " aborting previous request\n";
2936  }
2937 #endif
2938  }
2939  }
2940  }
2941 #ifdef DEBUG_PLAN_MOVE_LEADERINFO
2942  else {
2943  if (DEBUG_COND) {
2944  std::cout << SIMTIME << " veh=" << getID() << " ignoring leader " << leader->getID()
2945  << " ET=" << myJunctionEntryTime << " lET=" << leader->myJunctionEntryTime
2946  << " ETN=" << myJunctionEntryTimeNeverYield << " lETN=" << leader->myJunctionEntryTimeNeverYield
2947  << " CET=" << myJunctionConflictEntryTime << " lCET=" << leader->myJunctionConflictEntryTime
2948  << "\n";
2949  }
2950  }
2951 #endif
2952  }
2953  // if this is the link between two internal lanes we may have to slow down for pedestrians
2954  vLinkWait = MIN2(vLinkWait, v);
2955 }
2956 
2957 
2958 double
2959 MSVehicle::getSafeFollowSpeed(const std::pair<const MSVehicle*, double> leaderInfo,
2960  const double seen, const MSLane* const lane, double distToCrossing) const {
2961  assert(leaderInfo.first != 0);
2962  const MSCFModel& cfModel = getCarFollowModel();
2963  double vsafeLeader = 0;
2965  vsafeLeader = -std::numeric_limits<double>::max();
2966  }
2967  if (leaderInfo.second >= 0) {
2968  vsafeLeader = cfModel.followSpeed(this, getSpeed(), leaderInfo.second, leaderInfo.first->getSpeed(), leaderInfo.first->getCurrentApparentDecel(), leaderInfo.first);
2969  } else {
2970  // the leading, in-lapping vehicle is occupying the complete next lane
2971  // stop before entering this lane
2972  vsafeLeader = cfModel.stopSpeed(this, getSpeed(), seen - lane->getLength() - POSITION_EPS);
2973 #ifdef DEBUG_PLAN_MOVE_LEADERINFO
2974  if (DEBUG_COND) {
2975  std::cout << SIMTIME << " veh=" << getID() << " stopping before junction: lane=" << lane->getID() << " seen=" << seen
2976  << " laneLength=" << lane->getLength()
2977  << " stopDist=" << seen - lane->getLength() - POSITION_EPS
2978  << " vsafeLeader=" << vsafeLeader
2979  << "\n";
2980  }
2981 #endif
2982  }
2983  if (distToCrossing >= 0) {
2984  // drive up to the crossing point with the current link leader
2985  vsafeLeader = MAX2(vsafeLeader, cfModel.stopSpeed(this, getSpeed(), distToCrossing - getVehicleType().getMinGap()));
2986  }
2987  return vsafeLeader;
2988 }
2989 
2990 double
2991 MSVehicle::getDeltaPos(const double accel) const {
2992  double vNext = myState.mySpeed + ACCEL2SPEED(accel);
2994  // apply implicit Euler positional update
2995  return SPEED2DIST(MAX2(vNext, 0.));
2996  } else {
2997  // apply ballistic update
2998  if (vNext >= 0) {
2999  // assume constant acceleration during this time step
3000  return SPEED2DIST(myState.mySpeed + 0.5 * ACCEL2SPEED(accel));
3001  } else {
3002  // negative vNext indicates a stop within the middle of time step
3003  // The corresponding stop time is s = mySpeed/deceleration \in [0,dt], and the
3004  // covered distance is therefore deltaPos = mySpeed*s - 0.5*deceleration*s^2.
3005  // Here, deceleration = (myState.mySpeed - vNext)/dt is the constant deceleration
3006  // until the vehicle stops.
3007  return -SPEED2DIST(0.5 * myState.mySpeed * myState.mySpeed / ACCEL2SPEED(accel));
3008  }
3009  }
3010 }
3011 
3012 void
3013 MSVehicle::processLinkApproaches(double& vSafe, double& vSafeMin, double& vSafeMinDist) {
3014 
3015  // Speed limit due to zipper merging
3016  double vSafeZipper = std::numeric_limits<double>::max();
3017 
3018  myHaveToWaitOnNextLink = false;
3019  bool canBrakeVSafeMin = false;
3020 
3021  // Get safe velocities from DriveProcessItems.
3022  assert(myLFLinkLanes.size() != 0 || isRemoteControlled());
3023  for (const DriveProcessItem& dpi : myLFLinkLanes) {
3024  MSLink* const link = dpi.myLink;
3025 
3026 #ifdef DEBUG_EXEC_MOVE
3027  if (DEBUG_COND) {
3028  std::cout
3029  << SIMTIME
3030  << " veh=" << getID()
3031  << " link=" << (link == 0 ? "NULL" : link->getViaLaneOrLane()->getID())
3032  << " req=" << dpi.mySetRequest
3033  << " vP=" << dpi.myVLinkPass
3034  << " vW=" << dpi.myVLinkWait
3035  << " d=" << dpi.myDistance
3036  << "\n";
3037  gDebugFlag1 = true; // See MSLink_DEBUG_OPENED
3038  }
3039 #endif
3040 
3041  // the vehicle must change the lane on one of the next lanes (XXX: refs to code further below???, Leo)
3042  if (link != nullptr && dpi.mySetRequest) {
3043 
3044  const LinkState ls = link->getState();
3045  // vehicles should brake when running onto a yellow light if the distance allows to halt in front
3046  const bool yellow = link->haveYellow();
3047  const bool canBrake = (dpi.myDistance > getCarFollowModel().brakeGap(myState.mySpeed, getCarFollowModel().getMaxDecel(), 0.)
3049  assert(link->getLaneBefore() != nullptr);
3050  const bool beyondStopLine = dpi.myDistance < link->getLaneBefore()->getStopOffset(this);
3051  const bool ignoreRedLink = ignoreRed(link, canBrake) || beyondStopLine;
3052  if (yellow && canBrake && !ignoreRedLink) {
3053  vSafe = dpi.myVLinkWait;
3054  myHaveToWaitOnNextLink = true;
3055 #ifdef DEBUG_CHECKREWINDLINKLANES
3056  if (DEBUG_COND) {
3057  std::cout << SIMTIME << " veh=" << getID() << " haveToWait (yellow)\n";
3058  }
3059 #endif
3060  break;
3061  }
3062  const bool influencerPrio = (myInfluencer != nullptr && !myInfluencer->getRespectJunctionPriority());
3063  MSLink::BlockingFoes collectFoes;
3064  bool opened = (yellow || influencerPrio
3065  || link->opened(dpi.myArrivalTime, dpi.myArrivalSpeed, dpi.getLeaveSpeed(),
3067  canBrake ? getImpatience() : 1,
3070  ls == LINKSTATE_ZIPPER ? &collectFoes : nullptr,
3071  ignoreRedLink, this));
3072  if (opened && getLaneChangeModel().getShadowLane() != nullptr) {
3073  MSLink* parallelLink = dpi.myLink->getParallelLink(getLaneChangeModel().getShadowDirection());
3074  if (parallelLink != nullptr) {
3075  const double shadowLatPos = getLateralPositionOnLane() - getLaneChangeModel().getShadowDirection() * 0.5 * (
3077  opened = yellow || influencerPrio || (opened && parallelLink->opened(dpi.myArrivalTime, dpi.myArrivalSpeed, dpi.getLeaveSpeed(),
3080  getWaitingTime(), shadowLatPos, nullptr,
3081  ignoreRedLink, this));
3082 #ifdef DEBUG_EXEC_MOVE
3083  if (DEBUG_COND) {
3084  std::cout << SIMTIME
3085  << " veh=" << getID()
3086  << " shadowLane=" << getLaneChangeModel().getShadowLane()->getID()
3087  << " shadowDir=" << getLaneChangeModel().getShadowDirection()
3088  << " parallelLink=" << (parallelLink == 0 ? "NULL" : parallelLink->getViaLaneOrLane()->getID())
3089  << " opened=" << opened
3090  << "\n";
3091  }
3092 #endif
3093  }
3094  }
3095  // vehicles should decelerate when approaching a minor link
3096 #ifdef DEBUG_EXEC_MOVE
3097  if (DEBUG_COND) {
3098  std::cout << SIMTIME
3099  << " opened=" << opened
3100  << " influencerPrio=" << influencerPrio
3101  << " linkPrio=" << link->havePriority()
3102  << " lastContMajor=" << link->lastWasContMajor()
3103  << " isCont=" << link->isCont()
3104  << " ignoreRed=" << ignoreRedLink
3105  << "\n";
3106  }
3107 #endif
3108  if (opened && !influencerPrio && !link->havePriority() && !link->lastWasContMajor() && !link->isCont() && !ignoreRedLink) {
3109  double visibilityDistance = link->getFoeVisibilityDistance();
3110  double determinedFoePresence = dpi.myDistance <= visibilityDistance;
3111  if (!determinedFoePresence && (canBrake || !yellow)) {
3112  vSafe = dpi.myVLinkWait;
3113  myHaveToWaitOnNextLink = true;
3114 #ifdef DEBUG_CHECKREWINDLINKLANES
3115  if (DEBUG_COND) {
3116  std::cout << SIMTIME << " veh=" << getID() << " haveToWait (minor)\n";
3117  }
3118 #endif
3119  break;
3120  } else {
3121  // past the point of no return. we need to drive fast enough
3122  // to make it across the link. However, minor slowdowns
3123  // should be permissible to follow leading traffic safely
3124  // basically, this code prevents dawdling
3125  // (it's harder to do this later using
3126  // SUMO_ATTR_JM_SIGMA_MINOR because we don't know whether the
3127  // vehicle is already too close to stop at that part of the code)
3128  //
3129  // XXX: There is a problem in subsecond simulation: If we cannot
3130  // make it across the minor link in one step, new traffic
3131  // could appear on a major foe link and cause a collision. Refs. #1845, #2123
3132  vSafeMinDist = dpi.myDistance; // distance that must be covered
3134  vSafeMin = MIN2((double) DIST2SPEED(vSafeMinDist + POSITION_EPS), dpi.myVLinkPass);
3135  } else {
3136  vSafeMin = MIN2((double) DIST2SPEED(2 * vSafeMinDist + NUMERICAL_EPS) - getSpeed(), dpi.myVLinkPass);
3137  }
3138  canBrakeVSafeMin = canBrake;
3139 #ifdef DEBUG_EXEC_MOVE
3140  if (DEBUG_COND) {
3141  std::cout << " vSafeMin=" << vSafeMin << " vSafeMinDist=" << vSafeMinDist << " canBrake=" << canBrake << "\n";
3142  }
3143 #endif
3144  }
3145  }
3146  // have waited; may pass if opened...
3147  if (opened) {
3148  vSafe = dpi.myVLinkPass;
3149  if (vSafe < getCarFollowModel().getMaxDecel() && vSafe <= dpi.myVLinkWait && vSafe < getCarFollowModel().maxNextSpeed(getSpeed(), this)) {
3150  // this vehicle is probably not gonna drive across the next junction (heuristic)
3151  myHaveToWaitOnNextLink = true;
3152 #ifdef DEBUG_CHECKREWINDLINKLANES
3153  if (DEBUG_COND) {
3154  std::cout << SIMTIME << " veh=" << getID() << " haveToWait (very slow)\n";
3155  }
3156 #endif
3157  }
3158  } else if (link->getState() == LINKSTATE_ZIPPER) {
3159  vSafeZipper = MIN2(vSafeZipper,
3160  link->getZipperSpeed(this, dpi.myDistance, dpi.myVLinkPass, dpi.myArrivalTime, &collectFoes));
3161  } else {
3162  vSafe = dpi.myVLinkWait;
3163  myHaveToWaitOnNextLink = true;
3164 #ifdef DEBUG_CHECKREWINDLINKLANES
3165  if (DEBUG_COND) {
3166  std::cout << SIMTIME << " veh=" << getID() << " haveToWait (closed)\n";
3167  }
3168 #endif
3169 #ifdef DEBUG_EXEC_MOVE
3170  if (DEBUG_COND) {
3171  std::cout << SIMTIME << " braking for closed link=" << link->getViaLaneOrLane()->getID() << "\n";
3172  }
3173 #endif
3174  break;
3175  }
3176  } else {
3177  if (link != nullptr && link->getInternalLaneBefore() != nullptr && myLane->isInternal() && link->getJunction() == myLane->getEdge().getToJunction()) {
3178  // blocked on the junction. yield request so other vehicles may
3179  // become junction leader
3180 #ifdef DEBUG_EXEC_MOVE
3181  if (DEBUG_COND) {
3182  std::cout << SIMTIME << " reseting junctionEntryTime at junction '" << link->getJunction()->getID() << "' beause of non-request exitLink\n";
3183  }
3184 #endif
3187  }
3188  // we have: i->link == 0 || !i->setRequest
3189  vSafe = dpi.myVLinkWait;
3190  if (vSafe < getSpeed()) {
3191  myHaveToWaitOnNextLink = true;
3192 #ifdef DEBUG_CHECKREWINDLINKLANES
3193  if (DEBUG_COND) {
3194  std::cout << SIMTIME << " veh=" << getID() << " haveToWait (no request, braking)\n";
3195  }
3196 #endif
3197  } else if (vSafe < SUMO_const_haltingSpeed) {
3198  myHaveToWaitOnNextLink = true;
3199 #ifdef DEBUG_CHECKREWINDLINKLANES
3200  if (DEBUG_COND) {
3201  std::cout << SIMTIME << " veh=" << getID() << " haveToWait (no request, stopping)\n";
3202  }
3203 #endif
3204  }
3205  break;
3206  }
3207  }
3208 
3209 //#ifdef DEBUG_EXEC_MOVE
3210 // if (DEBUG_COND) {
3211 // std::cout << "\nvCurrent = " << toString(getSpeed(), 24) << "" << std::endl;
3212 // std::cout << "vSafe = " << toString(vSafe, 24) << "" << std::endl;
3213 // std::cout << "vSafeMin = " << toString(vSafeMin, 24) << "" << std::endl;
3214 // std::cout << "vSafeMinDist = " << toString(vSafeMinDist, 24) << "" << std::endl;
3215 //
3216 // double gap = getLeader().second;
3217 // std::cout << "gap = " << toString(gap, 24) << std::endl;
3218 // std::cout << "vSafeStoppedLeader = " << toString(getCarFollowModel().stopSpeed(this, getSpeed(), gap), 24)
3219 // << "\n" << std::endl;
3220 // }
3221 //#endif
3222 
3223  if ((MSGlobals::gSemiImplicitEulerUpdate && vSafe + NUMERICAL_EPS < vSafeMin)
3224  || (!MSGlobals::gSemiImplicitEulerUpdate && (vSafe + NUMERICAL_EPS < vSafeMin && vSafeMin != 0))) { // this might be good for the euler case as well
3225  // XXX: (Leo) This often called stopSpeed with vSafeMinDist==0 (for the ballistic update), since vSafe can become negative
3226  // For the Euler update the term '+ NUMERICAL_EPS' prevented a call here... Recheck, consider of -INVALID_SPEED instead of 0 to indicate absence of vSafeMin restrictions. Refs. #2577
3227 #ifdef DEBUG_EXEC_MOVE
3228  if (DEBUG_COND) {
3229  std::cout << "vSafeMin Problem? vSafe=" << vSafe << " vSafeMin=" << vSafeMin << " vSafeMinDist=" << vSafeMinDist << std::endl;
3230  }
3231 #endif
3232  if (canBrakeVSafeMin && vSafe < getSpeed()) {
3233  // cannot drive across a link so we need to stop before it
3234  vSafe = MIN2(vSafe, getCarFollowModel().stopSpeed(this, getSpeed(), vSafeMinDist));
3235  vSafeMin = 0;
3236  myHaveToWaitOnNextLink = true;
3237 #ifdef DEBUG_CHECKREWINDLINKLANES
3238  if (DEBUG_COND) {
3239  std::cout << SIMTIME << " veh=" << getID() << " haveToWait (vSafe=" << vSafe << " < vSafeMin=" << vSafeMin << ")\n";
3240  }
3241 #endif
3242  } else {
3243  // if the link is yellow or visibility distance is large
3244  // then we might not make it across the link in one step anyway..
3245  // Possibly, the lane after the intersection has a lower speed limit so
3246  // we really need to drive slower already
3247  // -> keep driving without dawdling
3248  vSafeMin = vSafe;
3249  }
3250  }
3251 
3252  // vehicles inside a roundabout should maintain their requests
3253  if (myLane->getEdge().isRoundabout()) {
3254  myHaveToWaitOnNextLink = false;
3255  }
3256 
3257  vSafe = MIN2(vSafe, vSafeZipper);
3258 }
3259 
3260 
3261 double
3262 MSVehicle::processTraCISpeedControl(double vSafe, double vNext) {
3263  if (myInfluencer != nullptr) {
3264 #ifdef DEBUG_TRACI
3265  if DEBUG_COND2(this) {
3266  std::cout << SIMTIME << " MSVehicle::processTraCISpeedControl() for vehicle '" << getID() << "'"
3267  << " vSafe=" << vSafe << " (init)vNext=" << vNext;
3268  }
3269 #endif
3272  }
3273  const double vMax = getVehicleType().getCarFollowModel().maxNextSpeed(myState.mySpeed, this);
3274  double vMin = getVehicleType().getCarFollowModel().minNextSpeed(myState.mySpeed, this);
3276  vMin = MAX2(0., vMin);
3277  }
3278  vNext = myInfluencer->influenceSpeed(MSNet::getInstance()->getCurrentTimeStep(), vNext, vSafe, vMin, vMax);
3279 #ifdef DEBUG_TRACI
3280  if DEBUG_COND2(this) {
3281  std::cout << " (processed)vNext=" << vNext << std::endl;
3282  }
3283 #endif
3284  }
3285  return vNext;
3286 }
3287 
3288 
3289 void
3291 #ifdef DEBUG_ACTIONSTEPS
3292  if (DEBUG_COND) {
3293  std::cout << SIMTIME << " veh=" << getID() << " removePassedDriveItems()\n"
3294  << " Current items: ";
3295  for (auto& j : myLFLinkLanes) {
3296  if (j.myLink == 0) {
3297  std::cout << "\n Stop at distance " << j.myDistance;
3298  } else {
3299  const MSLane* to = j.myLink->getViaLaneOrLane();
3300  const MSLane* from = j.myLink->getLaneBefore();
3301  std::cout << "\n Link at distance " << j.myDistance << ": '"
3302  << (from == 0 ? "NONE" : from->getID()) << "' -> '" << (to == 0 ? "NONE" : to->getID()) << "'";
3303  }
3304  }
3305  std::cout << "\n myNextDriveItem: ";
3306  if (myLFLinkLanes.size() != 0) {
3307  if (myNextDriveItem->myLink == 0) {
3308  std::cout << "\n Stop at distance " << myNextDriveItem->myDistance;
3309  } else {
3310  const MSLane* to = myNextDriveItem->myLink->getViaLaneOrLane();
3311  const MSLane* from = myNextDriveItem->myLink->getLaneBefore();
3312  std::cout << "\n Link at distance " << myNextDriveItem->myDistance << ": '"
3313  << (from == 0 ? "NONE" : from->getID()) << "' -> '" << (to == 0 ? "NONE" : to->getID()) << "'";
3314  }
3315  }
3316  std::cout << std::endl;
3317  }
3318 #endif
3319  for (auto j = myLFLinkLanes.begin(); j != myNextDriveItem; ++j) {
3320 #ifdef DEBUG_ACTIONSTEPS
3321  if (DEBUG_COND) {
3322  std::cout << " Removing item: ";
3323  if (j->myLink == 0) {
3324  std::cout << "Stop at distance " << j->myDistance;
3325  } else {
3326  const MSLane* to = j->myLink->getViaLaneOrLane();
3327  const MSLane* from = j->myLink->getLaneBefore();
3328  std::cout << "Link at distance " << j->myDistance << ": '"
3329  << (from == 0 ? "NONE" : from->getID()) << "' -> '" << (to == 0 ? "NONE" : to->getID()) << "'";
3330  }
3331  std::cout << std::endl;
3332  }
3333 #endif
3334  if (j->myLink != nullptr) {
3335  j->myLink->removeApproaching(this);
3336  }
3337  }
3339  myNextDriveItem = myLFLinkLanes.begin();
3340 }
3341 
3342 
3343 void
3345 #ifdef DEBUG_ACTIONSTEPS
3346  if (DEBUG_COND) {
3347  std::cout << SIMTIME << " updateDriveItems(), veh='" << getID() << "' (lane: '" << getLane()->getID() << "')\nCurrent drive items:" << std::endl;
3348  DriveItemVector::iterator i;
3349  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
3350  std::cout
3351  << " vPass=" << dpi.myVLinkPass
3352  << " vWait=" << dpi.myVLinkWait
3353  << " linkLane=" << (dpi.myLink == 0 ? "NULL" : dpi.myLink->getViaLaneOrLane()->getID())
3354  << " request=" << dpi.mySetRequest
3355  << "\n";
3356  }
3357  std::cout << " myNextDriveItem's linked lane: " << (myNextDriveItem->myLink == 0 ? "NULL" : myNextDriveItem->myLink->getViaLaneOrLane()->getID()) << std::endl;
3358  }
3359 #endif
3360  if (myLFLinkLanes.size() == 0) {
3361  // nothing to update
3362  return;
3363  }
3364  const MSLink* nextPlannedLink = nullptr;
3365 // auto i = myLFLinkLanes.begin();
3366  auto i = myNextDriveItem;
3367  while (i != myLFLinkLanes.end() && nextPlannedLink == nullptr) {
3368  nextPlannedLink = i->myLink;
3369  ++i;
3370  }
3371 
3372  if (nextPlannedLink == nullptr) {
3373  // No link for upcoming item -> no need for an update
3374 #ifdef DEBUG_ACTIONSTEPS
3375  if (DEBUG_COND) {
3376  std::cout << "Found no link-related drive item." << std::endl;
3377  }
3378 #endif
3379  return;
3380  }
3381 
3382  if (getLane() == nextPlannedLink->getLaneBefore()) {
3383  // Current lane approaches the stored next link, i.e. no LC happend and no update is required.
3384 #ifdef DEBUG_ACTIONSTEPS
3385  if (DEBUG_COND) {
3386  std::cout << "Continuing on planned lane sequence, no update required." << std::endl;
3387  }
3388 #endif
3389  return;
3390  }
3391  // Lane must have been changed, determine the change direction
3392  MSLink* parallelLink = nextPlannedLink->getParallelLink(1);
3393  if (parallelLink != nullptr && parallelLink->getLaneBefore() == getLane()) {
3394  // lcDir = 1;
3395  } else {
3396  parallelLink = nextPlannedLink->getParallelLink(-1);
3397  if (parallelLink != nullptr && parallelLink->getLaneBefore() == getLane()) {
3398  // lcDir = -1;
3399  } else {
3400  // If the vehicle's current lane is not the approaching lane for the next
3401  // drive process item's link, it is expected to lead to a parallel link,
3402  // XXX: What if the lc was an overtaking maneuver and there is no upcoming link?
3403  // Then a stop item should be scheduled! -> TODO!
3404  //assert(false);
3405  return;
3406  }
3407  }
3408 #ifdef DEBUG_ACTIONSTEPS
3409  if (DEBUG_COND) {
3410  std::cout << "Changed lane. Drive items will be updated along the current lane continuation." << std::endl;
3411  }
3412 #endif
3413  // Trace link sequence along current best lanes and transfer drive items to the corresponding links
3414 // DriveItemVector::iterator driveItemIt = myLFLinkLanes.begin();
3415  DriveItemVector::iterator driveItemIt = myNextDriveItem;
3416  // In the loop below, lane holds the currently considered lane on the vehicles continuation (including internal lanes)
3417  MSLane* lane = myLane;
3418  assert(myLane == parallelLink->getLaneBefore());
3419  // *lit is a pointer to the next lane in best continuations for the current lane (always non-internal)
3420  std::vector<MSLane*>::const_iterator bestLaneIt = getBestLanesContinuation().begin() + 1;
3421  // Pointer to the new link for the current drive process item
3422  MSLink* newLink = nullptr;
3423  while (driveItemIt != myLFLinkLanes.end()) {
3424  if (driveItemIt->myLink == nullptr) {
3425  // Items not related to a specific link are not updated
3426  // (XXX: when a stop item corresponded to a dead end, which is overcome by the LC that made
3427  // the update necessary, this may slow down the vehicle's continuation on the new lane...)
3428  ++driveItemIt;
3429  continue;
3430  }
3431  // Continuation links for current best lanes are less than for the former drive items (myLFLinkLanes)
3432  // We just remove the leftover link-items, as they cannot be mapped to new links.
3433  if (bestLaneIt == getBestLanesContinuation().end()) {
3434 #ifdef DEBUG_ACTIONSTEPS
3435  if (DEBUG_COND) {
3436  std::cout << "Reached end of the new continuation sequence. Erasing leftover link-items." << std::endl;
3437  }
3438 #endif
3439  while (driveItemIt != myLFLinkLanes.end()) {
3440  if (driveItemIt->myLink == nullptr) {
3441  ++driveItemIt;
3442  continue;
3443  } else {
3444  driveItemIt->myLink->removeApproaching(this);
3445  driveItemIt = myLFLinkLanes.erase(driveItemIt);
3446  }
3447  }
3448  break;
3449  }
3450  // Do the actual link-remapping for the item. And un/register approaching information on the corresponding links
3451  newLink = lane->getLinkTo(*bestLaneIt);
3452 
3453  if (newLink == driveItemIt->myLink) {
3454  // new continuation merged into previous - stop update
3455 #ifdef DEBUG_ACTIONSTEPS
3456  if (DEBUG_COND) {
3457  std::cout << "Old and new continuation sequences merge at link\n"
3458  << "'" << newLink->getLaneBefore()->getID() << "'->'" << newLink->getViaLaneOrLane()->getID() << "'"
3459  << "\nNo update beyond merge required." << std::endl;
3460  }
3461 #endif
3462  break;
3463  }
3464 
3465 #ifdef DEBUG_ACTIONSTEPS
3466  if (DEBUG_COND) {
3467  std::cout << "lane=" << lane->getID() << "\nUpdating link\n '" << driveItemIt->myLink->getLaneBefore()->getID() << "'->'" << driveItemIt->myLink->getViaLaneOrLane()->getID() << "'"
3468  << "==> " << "'" << newLink->getLaneBefore()->getID() << "'->'" << newLink->getViaLaneOrLane()->getID() << "'" << std::endl;
3469  }
3470 #endif
3471  newLink->setApproaching(this, driveItemIt->myLink->getApproaching(this));
3472  driveItemIt->myLink->removeApproaching(this);
3473  driveItemIt->myLink = newLink;
3474  lane = newLink->getViaLaneOrLane();
3475  ++driveItemIt;
3476  if (!lane->isInternal()) {
3477  ++bestLaneIt;
3478  }
3479  }
3480 #ifdef DEBUG_ACTIONSTEPS
3481  if (DEBUG_COND) {
3482  std::cout << "Updated drive items:" << std::endl;
3483  DriveItemVector::iterator i;
3484  for (i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
3485  std::cout
3486  << " vPass=" << dpi.myVLinkPass
3487  << " vWait=" << dpi.myVLinkWait
3488  << " linkLane=" << (dpi.myLink == 0 ? "NULL" : dpi.myLink->getViaLaneOrLane()->getID())
3489  << " request=" << dpi.mySetRequest
3490  << "\n";
3491  }
3492  }
3493 #endif
3494 }
3495 
3496 
3497 void
3499  // To avoid casual blinking brake lights at high speeds due to dawdling of the
3500  // leading vehicle, we don't show brake lights when the deceleration could be caused
3501  // by frictional forces and air resistance (i.e. proportional to v^2, coefficient could be adapted further)
3502  double pseudoFriction = (0.05 + 0.005 * getSpeed()) * getSpeed();
3503  bool brakelightsOn = vNext < getSpeed() - ACCEL2SPEED(pseudoFriction);
3504 
3505  if (vNext <= SUMO_const_haltingSpeed) {
3506  brakelightsOn = true;
3507  }
3508  if (brakelightsOn && !isStopped()) {
3510  } else {
3512  }
3513 }
3514 
3515 
3516 void
3518  if (vNext <= SUMO_const_haltingSpeed && !isStopped()) {
3521  } else {
3522  myWaitingTime = 0;
3524  }
3525 }
3526 
3527 
3528 void
3530  // update time loss (depends on the updated edge)
3531  if (!isStopped()) {
3532  const double vmax = myLane->getVehicleMaxSpeed(this);
3533  if (vmax > 0) {
3534  myTimeLoss += TS * (vmax - vNext) / vmax;
3535  }
3536  }
3537 }
3538 
3539 
3540 bool
3541 MSVehicle::canReverse(double speedThreshold) const {
3542 #ifdef DEBUG_REVERSE_BIDI
3543  if (DEBUG_COND) std::cout << SIMTIME << " canReverse lane=" << myLane->getID()
3544  << " pos=" << myState.myPos
3545  << " speed=" << std::setprecision(6) << getPreviousSpeed() << std::setprecision(gPrecision)
3546  << " speedThreshold=" << speedThreshold
3547  << " isRail=" << ((getVClass() & SVC_RAIL_CLASSES) != 0)
3548  << " speedOk=" << (getPreviousSpeed() <= speedThreshold)
3549  << " posOK=" << (myState.myPos <= myLane->getLength())
3550  << " normal=" << !myLane->isInternal()
3551  << " routeOK=" << ((myCurrEdge + 1) != myRoute->end())
3552  << " bidi=" << (myLane->getEdge().getBidiEdge() == *(myCurrEdge + 1))
3553  << " stopOk=" << (myStops.empty() || myStops.front().edge != myCurrEdge)
3554  << "\n";
3555 #endif
3556  if ((getVClass() & SVC_RAIL_CLASSES) != 0
3557  && getPreviousSpeed() <= speedThreshold
3558  && myState.myPos <= myLane->getLength()
3559  && !myLane->isInternal()
3560  && (myCurrEdge + 1) != myRoute->end()
3561  && myLane->getEdge().getBidiEdge() == *(myCurrEdge + 1)
3562  // ensure there are no further stops on this edge
3563  && (myStops.empty() || myStops.front().edge != myCurrEdge)
3564  ) {
3565  //if (isSelected()) std::cout << " check1 passed\n";
3566  // ensure that the vehicle is fully on bidi edges that allow reversal
3567  if ((int)(myRoute->end() - myCurrEdge) <= (int)myFurtherLanes.size()) {
3568  return false;
3569  }
3570  //if (isSelected()) std::cout << " check2 passed\n";
3571  // ensure that the turn-around connection exists from the current edge to it's bidi-edge
3572  const MSEdgeVector& succ = myLane->getEdge().getSuccessors();
3573  if (std::find(succ.begin(), succ.end(), myLane->getEdge().getBidiEdge()) == succ.end()) {
3574  return false;
3575  }
3576 
3577  //if (isSelected()) std::cout << " check3 passed\n";
3578  int view = 2;
3579  for (MSLane* further : myFurtherLanes) {
3580  if (!further->getEdge().isInternal()) {
3581  if (further->getEdge().getBidiEdge() != *(myCurrEdge + view)
3582  || (!myStops.empty() && myStops.front().edge == (myCurrEdge + view))) {
3583  return false;
3584  }
3585  view++;
3586  }
3587  }
3588  return true;
3589  }
3590  return false;
3591 }
3592 
3593 
3594 void
3595 MSVehicle::processLaneAdvances(std::vector<MSLane*>& passedLanes, bool& moved, std::string& emergencyReason) {
3596  for (std::vector<MSLane*>::reverse_iterator i = myFurtherLanes.rbegin(); i != myFurtherLanes.rend(); ++i) {
3597  passedLanes.push_back(*i);
3598  }
3599  if (passedLanes.size() == 0 || passedLanes.back() != myLane) {
3600  passedLanes.push_back(myLane);
3601  }
3602  // let trains reverse direction
3603  const bool reverseTrain = canReverse();
3604  if (reverseTrain) {
3606  myState.mySpeed = 0;
3607  }
3608  // move on lane(s)
3609  if (myState.myPos > myLane->getLength()) {
3610  // The vehicle has moved at least to the next lane (maybe it passed even more than one)
3611  if (myCurrEdge != myRoute->end() - 1) {
3612  MSLane* approachedLane = myLane;
3613  // move the vehicle forward
3614  myNextDriveItem = myLFLinkLanes.begin();
3615  while (myNextDriveItem != myLFLinkLanes.end() && approachedLane != nullptr && myState.myPos > approachedLane->getLength()) {
3616  const MSLink* link = myNextDriveItem->myLink;
3617  const double linkDist = myNextDriveItem->myDistance;
3618  ++myNextDriveItem;
3619  // check whether the vehicle was allowed to enter lane
3620  // otherwise it is decelerated and we do not need to test for it's
3621  // approach on the following lanes when a lane changing is performed
3622  // proceed to the next lane
3623  if (approachedLane->mustCheckJunctionCollisions()) {
3624  // vehicle moves past approachedLane within a single step, collision checking must still be done
3626  }
3627  if (link != nullptr) {
3628  approachedLane = link->getViaLaneOrLane();
3629  if (myInfluencer == nullptr || myInfluencer->getEmergencyBrakeRedLight()) {
3630  bool beyondStopLine = linkDist < link->getLaneBefore()->getStopOffset(this);
3631  if (link->haveRed() && !ignoreRed(link, false) && !beyondStopLine) {
3632  emergencyReason = " because of a red traffic light";
3633  break;
3634  }
3635  }
3636  } else if (myState.myPos < myLane->getLength() + NUMERICAL_EPS) {
3637  // avoid warning due to numerical instability
3638  approachedLane = myLane;
3640  } else if (reverseTrain) {
3641  approachedLane = (*(myCurrEdge + 1))->getLanes()[0];
3643  link = MSLinkContHelper::getConnectingLink(*myLane, *approachedLane);
3644  assert(link != 0);
3645  while (link->getViaLane() != nullptr) {
3646  link = link->getViaLane()->getLinkCont()[0];
3647  }
3648  }
3649  --myNextDriveItem;
3650  } else {
3651  emergencyReason = " because there is no connection to the next edge";
3652  approachedLane = nullptr;
3653  break;
3654  }
3655  if (approachedLane != myLane && approachedLane != nullptr) {
3657  myState.myPos -= myLane->getLength();
3658  assert(myState.myPos > 0);
3659  enterLaneAtMove(approachedLane);
3660  if (link->isEntryLink()) {
3663  }
3664  if (link->isConflictEntryLink()) {
3666  }
3667  if (link->isExitLink()) {
3668  // passed junction, reset for approaching the next one
3672  }
3673 #ifdef DEBUG_PLAN_MOVE_LEADERINFO
3674  if (DEBUG_COND) {
3675  std::cout << "Update junctionTimes link=" << link->getViaLaneOrLane()->getID()
3676  << " entry=" << link->isEntryLink() << " conflict=" << link->isConflictEntryLink() << " exit=" << link->isExitLink()
3677  << " ET=" << myJunctionEntryTime
3678  << " ETN=" << myJunctionEntryTimeNeverYield
3679  << " CET=" << myJunctionConflictEntryTime
3680  << "\n";
3681  }
3682 #endif
3683  if (hasArrived()) {
3684  break;
3685  }
3686  if (getLaneChangeModel().isChangingLanes()) {
3687  if (link->getDirection() == LINKDIR_LEFT || link->getDirection() == LINKDIR_RIGHT) {
3688  // abort lane change
3689  WRITE_WARNING("Vehicle '" + getID() + "' could not finish continuous lane change (turn lane) time=" +
3690  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
3692  }
3693  }
3694  moved = true;
3695  if (approachedLane->getEdge().isVaporizing()) {
3697  break;
3698  }
3699  passedLanes.push_back(approachedLane);
3700  }
3701  }
3702  // NOTE: Passed drive items will be erased in the next simstep's planMove()
3703 
3704 #ifdef DEBUG_ACTIONSTEPS
3705  if (DEBUG_COND && myNextDriveItem != myLFLinkLanes.begin()) {
3706  std::cout << "Updated drive items:" << std::endl;
3707  for (DriveItemVector::iterator i = myLFLinkLanes.begin(); i != myLFLinkLanes.end(); ++i) {
3708  std::cout
3709  << " vPass=" << (*i).myVLinkPass
3710  << " vWait=" << (*i).myVLinkWait
3711  << " linkLane=" << ((*i).myLink == 0 ? "NULL" : (*i).myLink->getViaLaneOrLane()->getID())
3712  << " request=" << (*i).mySetRequest
3713  << "\n";
3714  }
3715  }
3716 #endif
3717  } else if (!hasArrived() && myState.myPos < myLane->getLength() + NUMERICAL_EPS) {
3718  // avoid warning due to numerical instability when stopping at the end of the route
3720  }
3721 
3722  }
3723 }
3724 
3725 
3726 
3727 bool
3729 #ifdef DEBUG_EXEC_MOVE
3730  if (DEBUG_COND) {
3731  std::cout << "\nEXECUTE_MOVE\n"
3732  << SIMTIME
3733  << " veh=" << getID()
3734  << " speed=" << getSpeed() // toString(getSpeed(), 24)
3735  << std::endl;
3736  }
3737 #endif
3738 
3739 
3740  // Maximum safe velocity
3741  double vSafe = std::numeric_limits<double>::max();
3742  // Minimum safe velocity (lower bound).
3743  double vSafeMin = -std::numeric_limits<double>::max();
3744  // The distance to a link, which should either be crossed this step
3745  // or in front of which we need to stop.
3746  double vSafeMinDist = 0;
3747 
3748  if (myActionStep) {
3749  // Actuate control (i.e. choose bounds for safe speed in current simstep (euler), resp. after current sim step (ballistic))
3750  processLinkApproaches(vSafe, vSafeMin, vSafeMinDist);
3751 #ifdef DEBUG_ACTIONSTEPS
3752  if (DEBUG_COND) {
3753  std::cout << SIMTIME << " vehicle '" << getID() << "'\n"
3754  " vsafe from processLinkApproaches(): vsafe " << vSafe << std::endl;
3755  }
3756 #endif
3757  } else {
3758  // Continue with current acceleration
3759  vSafe = getSpeed() + ACCEL2SPEED(myAcceleration);
3760 #ifdef DEBUG_ACTIONSTEPS
3761  if (DEBUG_COND) {
3762  std::cout << SIMTIME << " vehicle '" << getID() << "' skips processLinkApproaches()\n"
3763  " continues with constant accel " << myAcceleration << "...\n"
3764  << "speed: " << getSpeed() << " -> " << vSafe << std::endl;
3765  }
3766 #endif
3767  }
3768 
3769 
3770 //#ifdef DEBUG_EXEC_MOVE
3771 // if (DEBUG_COND) {
3772 // std::cout << "vSafe = " << toString(vSafe,12) << "\n" << std::endl;
3773 // }
3774 //#endif
3775 
3776  // Determine vNext = speed after current sim step (ballistic), resp. in current simstep (euler)
3777  // Call to finalizeSpeed applies speed reduction due to dawdling / lane changing but ensures minimum safe speed
3778  double vNext = vSafe;
3779  if (myActionStep) {
3780  vNext = getCarFollowModel().finalizeSpeed(this, vSafe);
3781  if (vNext > 0) {
3782  vNext = MAX2(vNext, vSafeMin);
3783  }
3784  }
3785  // (Leo) to avoid tiny oscillations (< 1e-10) of vNext in a standing vehicle column (observed for ballistic update), we cap off vNext
3786  // (We assure to do this only for vNext<<NUMERICAL_EPS since otherwise this would nullify the workaround for #2995
3787  if (fabs(vNext) < NUMERICAL_EPS_SPEED) {
3788  vNext = 0.;
3789  }
3790 #ifdef DEBUG_EXEC_MOVE
3791  if (DEBUG_COND) {
3792  std::cout << SIMTIME << " finalizeSpeed vSafe=" << vSafe << " vSafeMin=" << (vSafeMin == -std::numeric_limits<double>::max() ? "-Inf" : toString(vSafeMin))
3793  << " vNext=" << vNext << " (i.e. accel=" << SPEED2ACCEL(vNext - getSpeed()) << ")" << std::endl;
3794  }
3795 #endif
3796 
3797  // vNext may be higher than vSafe without implying a bug:
3798  // - when approaching a green light that suddenly switches to yellow
3799  // - when using unregulated junctions
3800  // - when using tau < step-size
3801  // - when using unsafe car following models
3802  // - when using TraCI and some speedMode / laneChangeMode settings
3803  //if (vNext > vSafe + NUMERICAL_EPS) {
3804  // WRITE_WARNING("vehicle '" + getID() + "' cannot brake hard enough to reach safe speed "
3805  // + toString(vSafe, 4) + ", moving at " + toString(vNext, 4) + " instead. time="
3806  // + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
3807  //}
3808 
3810  vNext = MAX2(vNext, 0.);
3811  } else {
3812  // (Leo) Ballistic: negative vNext can be used to indicate a stop within next step.
3813  }
3814 
3815  // Check for speed advices from the traci client
3816  vNext = processTraCISpeedControl(vSafe, vNext);
3817 
3818  setBrakingSignals(vNext);
3819  updateWaitingTime(vNext);
3820 
3821  // update position and speed
3822  updateState(vNext);
3823 
3824  // Lanes, which the vehicle touched at some moment of the executed simstep
3825  std::vector<MSLane*> passedLanes;
3826  // Whether the vehicle did move to another lane
3827  bool moved = false;
3828  // Reason for a possible emergency stop
3829  std::string emergencyReason = " for unknown reasons";
3830  processLaneAdvances(passedLanes, moved, emergencyReason);
3831 
3832  updateTimeLoss(vNext);
3834 
3835  if (!hasArrived() && !myLane->getEdge().isVaporizing()) {
3836  if (myState.myPos > myLane->getLength()) {
3837  WRITE_WARNING("Vehicle '" + getID() + "' performs emergency stop at the end of lane '" + myLane->getID()
3838  + "'" + emergencyReason
3839  + " (decel=" + toString(myAcceleration - myState.mySpeed)
3840  + ", offset=" + toString(myState.myPos - myLane->getLength())
3841  + "), time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
3845  myState.mySpeed = 0;
3846  myAcceleration = 0;
3847  }
3848  const MSLane* oldBackLane = getBackLane();
3849  if (getLaneChangeModel().isOpposite()) {
3850  passedLanes.clear(); // ignore back occupation
3851  }
3852 #ifdef DEBUG_ACTIONSTEPS
3853  if (DEBUG_COND) {
3854  std::cout << SIMTIME << " veh '" << getID() << "' updates further lanes." << std::endl;
3855  }
3856 #endif
3858  // bestLanes need to be updated before lane changing starts. NOTE: This call is also a presumption for updateDriveItems()
3859  updateBestLanes();
3860  if (moved || oldBackLane != getBackLane()) {
3861  if (getLaneChangeModel().getShadowLane() != nullptr || getLateralOverlap() > POSITION_EPS) {
3862  // shadow lane must be updated if the front or back lane changed
3863  // either if we already have a shadowLane or if there is lateral overlap
3865  }
3867  // The vehicles target lane must be also be updated if the front or back lane changed
3869  }
3870  }
3871  setBlinkerInformation(); // needs updated bestLanes
3872  //change the blue light only for emergency vehicles SUMOVehicleClass
3873  if (myType->getVehicleClass() == SVC_EMERGENCY) {
3874  setEmergencyBlueLight(MSNet::getInstance()->getCurrentTimeStep());
3875  }
3876  // State needs to be reset for all vehicles before the next call to MSEdgeControl::changeLanes
3877  if (myActionStep) {
3878  // check (#2681): Can this be skipped?
3880  } else {
3881 #ifdef DEBUG_ACTIONSTEPS
3882  if (DEBUG_COND) {
3883  std::cout << SIMTIME << " veh '" << getID() << "' skips LCM->prepareStep()." << std::endl;
3884  }
3885 #endif
3886  }
3887  myAngle = computeAngle();
3888  }
3889 
3890 #ifdef DEBUG_EXEC_MOVE
3891  if (DEBUG_COND) {
3892  std::cout << SIMTIME << " executeMove finished veh=" << getID() << " lane=" << myLane->getID() << " myPos=" << getPositionOnLane() << " myPosLat=" << getLateralPositionOnLane() << "\n";
3893  gDebugFlag1 = false; // See MSLink_DEBUG_OPENED
3894  }
3895 #endif
3896  if (getLaneChangeModel().isOpposite()) {
3897  // transform back to the opposite-direction lane
3898  if (myLane->getOpposite() == nullptr) {
3899  WRITE_WARNING("Unexpected end of opposite lane for vehicle '" + getID() + "' at lane '" + myLane->getID() + "', time=" +
3900  time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
3902  } else {
3904  myLane = myLane->getOpposite();
3906  }
3907  }
3909  return moved;
3910 }
3911 
3912 
3913 void
3914 MSVehicle::updateState(double vNext) {
3915  // update position and speed
3916  double deltaPos; // positional change
3918  // euler
3919  deltaPos = SPEED2DIST(vNext);
3920  } else {
3921  // ballistic
3922  deltaPos = getDeltaPos(SPEED2ACCEL(vNext - myState.mySpeed));
3923  }
3924 
3925  // the *mean* acceleration during the next step (probably most appropriate for emission calculation)
3926  // NOTE: for the ballistic update vNext may be negative, indicating a stop.
3927  myAcceleration = SPEED2ACCEL(MAX2(vNext, 0.) - myState.mySpeed);
3928 
3929 #ifdef DEBUG_EXEC_MOVE
3930  if (DEBUG_COND) {
3931  std::cout << SIMTIME << " updateState() for veh '" << getID() << "': deltaPos=" << deltaPos
3932  << " pos=" << myState.myPos << " newPos=" << myState.myPos + deltaPos << std::endl;
3933  }
3934 #endif
3935  double decelPlus = -myAcceleration - getCarFollowModel().getMaxDecel() - NUMERICAL_EPS;
3936  if (decelPlus > 0) {
3937  const double previousAcceleration = SPEED2ACCEL(myState.mySpeed - myState.myPreviousSpeed);
3938  if (myAcceleration + NUMERICAL_EPS < previousAcceleration) {
3939  // vehicle brakes beyond wished maximum deceleration (only warn at the start of the braking manoeuvre)
3940  decelPlus += 2 * NUMERICAL_EPS;
3941  const double emergencyFraction = decelPlus / MAX2(NUMERICAL_EPS, getCarFollowModel().getEmergencyDecel() - getCarFollowModel().getMaxDecel());
3942  if (emergencyFraction >= MSGlobals::gEmergencyDecelWarningThreshold) {
3943  WRITE_WARNING("Vehicle '" + getID()
3944  + "' performs emergency braking with decel=" + toString(myAcceleration)
3945  + " wished=" + toString(getCarFollowModel().getMaxDecel())
3946  + " severity=" + toString(emergencyFraction)
3947  //+ " decelPlus=" + toString(decelPlus)
3948  //+ " prevAccel=" + toString(previousAcceleration)
3949  //+ " reserve=" + toString(MAX2(NUMERICAL_EPS, getCarFollowModel().getEmergencyDecel() - getCarFollowModel().getMaxDecel()))
3950  + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
3951  }
3952  }
3953  }
3954 
3956  myState.mySpeed = MAX2(vNext, 0.);
3957 
3958  if (myInfluencer != nullptr && myInfluencer->isRemoteControlled()) {
3959  deltaPos = myInfluencer->implicitDeltaPosRemote(this);
3960  }
3961 
3962  if (getLaneChangeModel().isOpposite()) {
3963  // transform to the forward-direction lane, move and then transform back
3965  myLane = myLane->getOpposite();
3966  }
3967  myState.myPos += deltaPos;
3968  myState.myLastCoveredDist = deltaPos;
3969  myNextTurn.first -= deltaPos;
3970 
3972 }
3973 
3974 
3975 const MSLane*
3977  if (myFurtherLanes.size() > 0) {
3978  return myFurtherLanes.back();
3979  } else {
3980  return myLane;
3981  }
3982 }
3983 
3984 
3985 double
3986 MSVehicle::updateFurtherLanes(std::vector<MSLane*>& furtherLanes, std::vector<double>& furtherLanesPosLat,
3987  const std::vector<MSLane*>& passedLanes) {
3988 #ifdef DEBUG_SETFURTHER
3989  if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID()
3990  << " updateFurtherLanes oldFurther=" << toString(furtherLanes)
3991  << " oldFurtherPosLat=" << toString(furtherLanesPosLat)
3992  << " passed=" << toString(passedLanes)
3993  << "\n";
3994 #endif
3995  for (std::vector<MSLane*>::iterator i = furtherLanes.begin(); i != furtherLanes.end(); ++i) {
3996  (*i)->resetPartialOccupation(this);
3997  }
3998 
3999  std::vector<MSLane*> newFurther;
4000  std::vector<double> newFurtherPosLat;
4001  double backPosOnPreviousLane = myState.myPos - getLength();
4002  bool widthShift = myFurtherLanesPosLat.size() > myFurtherLanes.size();
4003  if (passedLanes.size() > 1) {
4004  // There are candidates for further lanes. (passedLanes[-1] is the current lane, or current shadow lane in context of updateShadowLanes())
4005  std::vector<MSLane*>::const_iterator fi = furtherLanes.begin();
4006  std::vector<double>::const_iterator fpi = furtherLanesPosLat.begin();
4007  for (auto pi = passedLanes.rbegin() + 1; pi != passedLanes.rend() && backPosOnPreviousLane < 0; ++pi) {
4008  // As long as vehicle back reaches into passed lane, add it to the further lanes
4009  newFurther.push_back(*pi);
4010  backPosOnPreviousLane += (*pi)->setPartialOccupation(this);
4011  if (fi != furtherLanes.end() && *pi == *fi) {
4012  // Lateral position on this lane is already known. Assume constant and use old value.
4013  newFurtherPosLat.push_back(*fpi);
4014  ++fi;
4015  ++fpi;
4016  } else {
4017  // The lane *pi was not in furtherLanes before.
4018  // If it is downstream, we assume as lateral position the current position
4019  // If it is a new lane upstream (can appear as shadow further in case of LC-maneuvering, e.g.)
4020  // we assign the last known lateral position.
4021  if (newFurtherPosLat.size() == 0) {
4022  if (widthShift) {
4023  newFurtherPosLat.push_back(myFurtherLanesPosLat.back());
4024  } else {
4025  newFurtherPosLat.push_back(myState.myPosLat);
4026  }
4027  } else {
4028  newFurtherPosLat.push_back(newFurtherPosLat.back());
4029  }
4030  }
4031 #ifdef DEBUG_SETFURTHER
4032  if (DEBUG_COND) {
4033  std::cout << SIMTIME << " updateFurtherLanes \n"
4034  << " further lane '" << (*pi)->getID() << "' backPosOnPreviousLane=" << backPosOnPreviousLane
4035  << std::endl;
4036  }
4037 #endif
4038  }
4039  furtherLanes = newFurther;
4040  furtherLanesPosLat = newFurtherPosLat;
4041  } else {
4042  furtherLanes.clear();
4043  furtherLanesPosLat.clear();
4044  }
4045 #ifdef DEBUG_SETFURTHER
4046  if (DEBUG_COND) std::cout
4047  << " newFurther=" << toString(furtherLanes)
4048  << " newFurtherPosLat=" << toString(furtherLanesPosLat)
4049  << " newBackPos=" << backPosOnPreviousLane
4050  << "\n";
4051 #endif
4052  return backPosOnPreviousLane;
4053 }
4054 
4055 
4056 double
4058 #ifdef DEBUG_FURTHER
4059  if (DEBUG_COND) {
4060  std::cout << SIMTIME
4061  << " getBackPositionOnLane veh=" << getID()
4062  << " lane=" << Named::getIDSecure(lane)
4063  << " myLane=" << myLane->getID()
4064  << " further=" << toString(myFurtherLanes)
4065  << " furtherPosLat=" << toString(myFurtherLanesPosLat)
4066  << "\n shadowLane=" << Named::getIDSecure(getLaneChangeModel().getShadowLane())
4067  << " shadowFurther=" << toString(getLaneChangeModel().getShadowFurtherLanes())
4068  << " shadowFurtherPosLat=" << toString(getLaneChangeModel().getShadowFurtherLanesPosLat())
4069  << "\n targetLane=" << Named::getIDSecure(getLaneChangeModel().getTargetLane())
4070  << " furtherTargets=" << toString(getLaneChangeModel().getFurtherTargetLanes())
4071  << std::endl;
4072  }
4073 #endif
4074  if (lane == myLane
4075  || lane == getLaneChangeModel().getShadowLane()
4076  || lane == getLaneChangeModel().getTargetLane()) {
4077  if (getLaneChangeModel().isOpposite()) {
4078  return myState.myPos + myType->getLength();
4079  } else {
4080  return myState.myPos - myType->getLength();
4081  }
4082  } else if ((myFurtherLanes.size() > 0 && lane == myFurtherLanes.back())
4083  || (getLaneChangeModel().getShadowFurtherLanes().size() > 0 && lane == getLaneChangeModel().getShadowFurtherLanes().back())
4084  || (getLaneChangeModel().getFurtherTargetLanes().size() > 0 && lane == getLaneChangeModel().getFurtherTargetLanes().back())) {
4085  return myState.myBackPos;
4086  } else {
4087  //if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " myFurtherLanes=" << toString(myFurtherLanes) << "\n";
4088  double leftLength = myType->getLength() - myState.myPos;
4089 
4090  std::vector<MSLane*>::const_iterator i = myFurtherLanes.begin();
4091  while (leftLength > 0 && i != myFurtherLanes.end()) {
4092  leftLength -= (*i)->getLength();
4093  //if (DEBUG_COND) std::cout << " comparing i=" << (*i)->getID() << " lane=" << lane->getID() << "\n";
4094  if (*i == lane) {
4095  return -leftLength;
4096  }
4097  ++i;
4098  }
4099  //if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " myShadowFurtherLanes=" << toString(getLaneChangeModel().getShadowFurtherLanes()) << "\n";
4100  leftLength = myType->getLength() - myState.myPos;
4101  i = getLaneChangeModel().getShadowFurtherLanes().begin();
4102  while (leftLength > 0 && i != getLaneChangeModel().getShadowFurtherLanes().end()) {
4103  leftLength -= (*i)->getLength();
4104  //if (DEBUG_COND) std::cout << " comparing i=" << (*i)->getID() << " lane=" << lane->getID() << "\n";
4105  if (*i == lane) {
4106  return -leftLength;
4107  }
4108  ++i;
4109  }
4110  //if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " myFurtherTargetLanes=" << toString(getLaneChangeModel().getFurtherTargetLanes()) << "\n";
4111  leftLength = myType->getLength() - myState.myPos;
4112  i = getFurtherLanes().begin();
4113  const std::vector<MSLane*> furtherTargetLanes = getLaneChangeModel().getFurtherTargetLanes();
4114  auto j = furtherTargetLanes.begin();
4115  while (leftLength > 0 && j != furtherTargetLanes.end()) {
4116  leftLength -= (*i)->getLength();
4117  // if (DEBUG_COND) std::cout << " comparing i=" << (*i)->getID() << " lane=" << lane->getID() << "\n";
4118  if (*j == lane) {
4119  return -leftLength;
4120  }
4121  ++i;
4122  ++j;
4123  }
4124  WRITE_WARNING("Request backPos of vehicle '" + getID() + "' for invalid lane '" + Named::getIDSecure(lane)
4125  + "' time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".")
4126 #ifdef _MSC_VER
4127 #pragma warning(push)
4128 #pragma warning(disable: 4127) // do not warn about constant conditional expression
4129 #endif
4130  SOFT_ASSERT(false);
4131 #ifdef _MSC_VER
4132 #pragma warning(pop)
4133 #endif
4134  return myState.myBackPos;
4135  }
4136 }
4137 
4138 
4139 double
4141  return getBackPositionOnLane(lane) + myType->getLength();
4142 }
4143 
4144 
4145 bool
4146 MSVehicle::isFrontOnLane(const MSLane* lane) const {
4147  return lane == myLane || lane == getLaneChangeModel().getShadowLane();
4148 }
4149 
4150 
4151 double
4152 MSVehicle::getSpaceTillLastStanding(const MSLane* l, bool& foundStopped) const {
4153  double lengths = 0;
4154  const MSLane::VehCont& vehs = l->getVehiclesSecure();
4155  for (MSLane::VehCont::const_iterator i = vehs.begin(); i != vehs.end(); ++i) {
4156  const MSVehicle* last = *i;
4157  if (last->getSpeed() < SUMO_const_haltingSpeed && !last->getLane()->getEdge().isRoundabout()
4158  && last != this
4159  // @todo recheck
4160  && last->isFrontOnLane(l)) {
4161  foundStopped = true;
4162  const double lastBrakeGap = last->getCarFollowModel().brakeGap(last->getSpeed());
4163  const double ret = last->getBackPositionOnLane() + lastBrakeGap - lengths;
4164  l->releaseVehicles();
4165  return ret;
4166  }
4167  lengths += (*i)->getVehicleType().getLengthWithGap();
4168  }
4169  l->releaseVehicles();
4170  return l->getLength() - lengths;
4171 }
4172 
4173 
4174 void
4175 MSVehicle::checkRewindLinkLanes(const double lengthsInFront, DriveItemVector& lfLinks) const {
4177  double seenSpace = -lengthsInFront;
4178 #ifdef DEBUG_CHECKREWINDLINKLANES
4179  if (DEBUG_COND) {
4180  std::cout << "\nCHECK_REWIND_LINKLANES\n" << " veh=" << getID() << " lengthsInFront=" << lengthsInFront << "\n";
4181  };
4182 #endif
4183  bool foundStopped = false;
4184  // compute available space until a stopped vehicle is found
4185  // this is the sum of non-interal lane length minus in-between vehicle lengths
4186  for (int i = 0; i < (int)lfLinks.size(); ++i) {
4187  // skip unset links
4188  DriveProcessItem& item = lfLinks[i];
4189 #ifdef DEBUG_CHECKREWINDLINKLANES
4190  if (DEBUG_COND) std::cout << SIMTIME
4191  << " link=" << (item.myLink == 0 ? "NULL" : item.myLink->getViaLaneOrLane()->getID())
4192  << " foundStopped=" << foundStopped;
4193 #endif
4194  if (item.myLink == nullptr || foundStopped) {
4195  if (!foundStopped) {
4196  item.availableSpace += seenSpace;
4197  } else {
4198  item.availableSpace = seenSpace;
4199  }
4200 #ifdef DEBUG_CHECKREWINDLINKLANES
4201  if (DEBUG_COND) {
4202  std::cout << " avail=" << item.availableSpace << "\n";
4203  }
4204 #endif
4205  continue;
4206  }
4207  // get the next lane, determine whether it is an internal lane
4208  const MSLane* approachedLane = item.myLink->getViaLane();
4209  if (approachedLane != nullptr) {
4210  if (keepClear(item.myLink)) {
4211  seenSpace = seenSpace - approachedLane->getBruttoVehLenSum();
4212  if (approachedLane == myLane) {
4213  seenSpace += getVehicleType().getLengthWithGap();
4214  }
4215  } else {
4216  seenSpace = seenSpace + getSpaceTillLastStanding(approachedLane, foundStopped);// - approachedLane->getBruttoVehLenSum() + approachedLane->getLength();
4217  }
4218  item.availableSpace = seenSpace;
4219 #ifdef DEBUG_CHECKREWINDLINKLANES
4220  if (DEBUG_COND) std::cout
4221  << " approached=" << approachedLane->getID()
4222  << " approachedBrutto=" << approachedLane->getBruttoVehLenSum()
4223  << " avail=" << item.availableSpace
4224  << " seenSpace=" << seenSpace
4225  << " hadStoppedVehicle=" << item.hadStoppedVehicle
4226  << " lengthsInFront=" << lengthsInFront
4227  << "\n";
4228 #endif
4229  continue;
4230  }
4231  approachedLane = item.myLink->getLane();
4232  const MSVehicle* last = approachedLane->getLastAnyVehicle();
4233  if (last == nullptr || last == this) {
4234  if (approachedLane->getLength() > getVehicleType().getLength()
4235  || keepClear(item.myLink)) {
4236  seenSpace += approachedLane->getLength();
4237  }
4238  item.availableSpace = seenSpace;
4239 #ifdef DEBUG_CHECKREWINDLINKLANES
4240  if (DEBUG_COND) {
4241  std::cout << " last=" << Named::getIDSecure(last) << " laneLength=" << approachedLane->getLength() << " avail=" << item.availableSpace << "\n";
4242  }
4243 #endif
4244  } else {
4245  bool foundStopped2 = false;
4246  const double spaceTillLastStanding = getSpaceTillLastStanding(approachedLane, foundStopped2);
4247  seenSpace += spaceTillLastStanding;
4248  if (foundStopped2) {
4249  foundStopped = true;
4250  item.hadStoppedVehicle = true;
4251  }
4252  item.availableSpace = seenSpace;
4253  if (last->myHaveToWaitOnNextLink || last->isStopped()) {
4254  foundStopped = true;
4255  item.hadStoppedVehicle = true;
4256  }
4257 #ifdef DEBUG_CHECKREWINDLINKLANES
4258  if (DEBUG_COND) std::cout
4259  << " approached=" << approachedLane->getID()
4260  << " last=" << last->getID()
4261  << " lastHasToWait=" << last->myHaveToWaitOnNextLink
4262  << " lastBrakeLight=" << last->signalSet(VEH_SIGNAL_BRAKELIGHT)
4263  << " lastBrakeGap=" << last->getCarFollowModel().brakeGap(last->getSpeed())
4264  << " lastGap=" << (last->getBackPositionOnLane(approachedLane) + last->getCarFollowModel().brakeGap(last->getSpeed()) - last->getSpeed() * last->getCarFollowModel().getHeadwayTime()
4265  // gap of last up to the next intersection
4266  - last->getVehicleType().getMinGap())
4267  << " stls=" << spaceTillLastStanding
4268  << " avail=" << item.availableSpace
4269  << " seenSpace=" << seenSpace
4270  << " foundStopped=" << foundStopped
4271  << " foundStopped2=" << foundStopped2
4272  << "\n";
4273 #endif
4274  }
4275  }
4276 
4277  // check which links allow continuation and add pass available to the previous item
4278  for (int i = ((int)lfLinks.size() - 1); i > 0; --i) {
4279  DriveProcessItem& item = lfLinks[i - 1];
4280  DriveProcessItem& nextItem = lfLinks[i];
4281  const bool canLeaveJunction = item.myLink->getViaLane() == nullptr || nextItem.myLink == nullptr || nextItem.mySetRequest;
4282  const bool opened = (item.myLink != nullptr
4283  && (canLeaveJunction || (
4284  // indirect bicycle turn
4285  nextItem.myLink != nullptr && nextItem.myLink->isInternalJunctionLink() && nextItem.myLink->haveRed()))
4286  && (
4287  item.myLink->havePriority()
4288  || i == 1 // the upcoming link (item 0) is checked in executeMove anyway. No need to use outdata approachData here
4290  || item.myLink->opened(item.myArrivalTime, item.myArrivalSpeed,
4293  bool allowsContinuation = (item.myLink == nullptr || item.myLink->isCont() || opened) && !item.hadStoppedVehicle;
4294 #ifdef DEBUG_CHECKREWINDLINKLANES
4295  if (DEBUG_COND) std::cout
4296  << " link=" << (item.myLink == 0 ? "NULL" : item.myLink->getViaLaneOrLane()->getID())
4297  << " canLeave=" << canLeaveJunction
4298  << " opened=" << opened
4299  << " allowsContinuation=" << allowsContinuation
4300  << " foundStopped=" << foundStopped
4301  << "\n";
4302 #endif
4303  if (!opened && item.myLink != nullptr) {
4304  foundStopped = true;
4305  if (i > 1) {
4306  DriveProcessItem& item2 = lfLinks[i - 2];
4307  if (item2.myLink != nullptr && item2.myLink->isCont()) {
4308  allowsContinuation = true;
4309  }
4310  }
4311  }
4312  if (allowsContinuation) {
4313  item.availableSpace = nextItem.availableSpace;
4314 #ifdef DEBUG_CHECKREWINDLINKLANES
4315  if (DEBUG_COND) std::cout
4316  << " link=" << (item.myLink == nullptr ? "NULL" : item.myLink->getViaLaneOrLane()->getID())
4317  << " copy nextAvail=" << nextItem.availableSpace
4318  << "\n";
4319 #endif
4320  }
4321  }
4322 
4323  // find removalBegin
4324  int removalBegin = -1;
4325  for (int i = 0; foundStopped && i < (int)lfLinks.size() && removalBegin < 0; ++i) {
4326  // skip unset links
4327  const DriveProcessItem& item = lfLinks[i];
4328  if (item.myLink == nullptr) {
4329  continue;
4330  }
4331  /*
4332  double impatienceCorrection = MAX2(0., double(double(myWaitingTime)));
4333  if (seenSpace<getVehicleType().getLengthWithGap()-impatienceCorrection/10.&&nextSeenNonInternal!=0) {
4334  removalBegin = lastLinkToInternal;
4335  }
4336  */
4337 
4338  const double leftSpace = item.availableSpace - getVehicleType().getLengthWithGap();
4339 #ifdef DEBUG_CHECKREWINDLINKLANES
4340  if (DEBUG_COND) std::cout
4341  << SIMTIME
4342  << " veh=" << getID()
4343  << " link=" << (item.myLink == 0 ? "NULL" : item.myLink->getViaLaneOrLane()->getID())
4344  << " avail=" << item.availableSpace
4345  << " leftSpace=" << leftSpace
4346  << "\n";
4347 #endif
4348  if (leftSpace < 0/* && item.myLink->willHaveBlockedFoe()*/) {
4349  double impatienceCorrection = 0;
4350  /*
4351  if(item.myLink->getState()==LINKSTATE_MINOR) {
4352  impatienceCorrection = MAX2(0., STEPS2TIME(myWaitingTime));
4353  }
4354  */
4355  // may ignore keepClear rules
4356  if (leftSpace < -impatienceCorrection / 10. && keepClear(item.myLink)) {
4357  removalBegin = i;
4358  }
4359  //removalBegin = i;
4360  }
4361  }
4362  // abort requests
4363  if (removalBegin != -1 && !(removalBegin == 0 && myLane->getEdge().isInternal())) {
4364  while (removalBegin < (int)(lfLinks.size())) {
4365  const double brakeGap = getCarFollowModel().brakeGap(myState.mySpeed, getCarFollowModel().getMaxDecel(), 0.);
4366  lfLinks[removalBegin].myVLinkPass = lfLinks[removalBegin].myVLinkWait;
4367 #ifdef DEBUG_CHECKREWINDLINKLANES
4368  if (DEBUG_COND) {
4369  std::cout << " removalBegin=" << removalBegin << " brakeGap=" << brakeGap << " dist=" << lfLinks[removalBegin].myDistance << " speed=" << myState.mySpeed << " a2s=" << ACCEL2SPEED(getCarFollowModel().getMaxDecel()) << "\n";
4370  }
4371 #endif
4372  if (lfLinks[removalBegin].myDistance >= brakeGap || (lfLinks[removalBegin].myDistance > 0 && myState.mySpeed < ACCEL2SPEED(getCarFollowModel().getMaxDecel()))) {
4373  lfLinks[removalBegin].mySetRequest = false;
4374  }
4375  ++removalBegin;
4376  }
4377  }
4378  }
4379 }
4380 
4381 
4382 void
4384  if (!checkActionStep(t)) {
4385  return;
4386  }
4388  for (DriveProcessItem& dpi : myLFLinkLanes) {
4389  if (dpi.myLink != nullptr) {
4390  if (dpi.myLink->getState() == LINKSTATE_ALLWAY_STOP) {
4391  dpi.myArrivalTime += (SUMOTime)RandHelper::rand((int)2, getRNG()); // tie braker
4392  }
4393  dpi.myLink->setApproaching(this, dpi.myArrivalTime, dpi.myArrivalSpeed, dpi.getLeaveSpeed(),
4394  dpi.mySetRequest, dpi.myArrivalTimeBraking, dpi.myArrivalSpeedBraking, getWaitingTime(), dpi.myDistance);
4395  }
4396  }
4397  if (getLaneChangeModel().getShadowLane() != nullptr) {
4398  // register on all shadow links
4399  for (const DriveProcessItem& dpi : myLFLinkLanes) {
4400  if (dpi.myLink != nullptr) {
4401  MSLink* parallelLink = dpi.myLink->getParallelLink(getLaneChangeModel().getShadowDirection());
4402  if (parallelLink != nullptr) {
4403  parallelLink->setApproaching(this, dpi.myArrivalTime, dpi.myArrivalSpeed, dpi.getLeaveSpeed(),
4404  dpi.mySetRequest, dpi.myArrivalTimeBraking, dpi.myArrivalSpeedBraking, getWaitingTime(), dpi.myDistance);
4406  }
4407  }
4408  }
4409  }
4410 #ifdef DEBUG_PLAN_MOVE
4411  if (DEBUG_COND) {
4412  std::cout << SIMTIME
4413  << " veh=" << getID()
4414  << " after checkRewindLinkLanes\n";
4415  for (DriveProcessItem& dpi : myLFLinkLanes) {
4416  std::cout
4417  << " vPass=" << dpi.myVLinkPass
4418  << " vWait=" << dpi.myVLinkWait
4419  << " linkLane=" << (dpi.myLink == 0 ? "NULL" : dpi.myLink->getViaLaneOrLane()->getID())
4420  << " request=" << dpi.mySetRequest
4421  << " atime=" << dpi.myArrivalTime
4422  << " atimeB=" << dpi.myArrivalTimeBraking
4423  << "\n";
4424  }
4425  }
4426 #endif
4427 }
4428 
4429 void
4431  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
4432  // skip the reminder if it is a lane reminder but not for my lane (indicated by rem->second > 0.)
4433  if (rem->first->getLane() != nullptr && rem->second > 0.) {
4434 #ifdef _DEBUG
4435  if (myTraceMoveReminders) {
4436  traceMoveReminder("notifyEnter_skipped", rem->first, rem->second, true);
4437  }
4438 #endif
4439  ++rem;
4440  } else {
4441  if (rem->first->notifyEnter(*this, reason, enteredLane)) {
4442 #ifdef _DEBUG
4443  if (myTraceMoveReminders) {
4444  traceMoveReminder("notifyEnter", rem->first, rem->second, true);
4445  }
4446 #endif
4447  ++rem;
4448  } else {
4449 #ifdef _DEBUG
4450  if (myTraceMoveReminders) {
4451  traceMoveReminder("notifyEnter", rem->first, rem->second, false);
4452  }
4453 // std::cout << SIMTIME << " Vehicle '" << getID() << "' erases MoveReminder (with offset " << rem->second << ")" << std::endl;
4454 #endif
4455  rem = myMoveReminders.erase(rem);
4456  }
4457  }
4458  }
4459 }
4460 
4461 
4462 bool
4463 MSVehicle::enterLaneAtMove(MSLane* enteredLane, bool onTeleporting) {
4464  myAmOnNet = !onTeleporting;
4465  // vaporizing edge?
4466  /*
4467  if (enteredLane->getEdge().isVaporizing()) {
4468  // yep, let's do the vaporization...
4469  myLane = enteredLane;
4470  return true;
4471  }
4472  */
4473  // Adjust MoveReminder offset to the next lane
4474  adaptLaneEntering2MoveReminder(*enteredLane);
4475  // set the entered lane as the current lane
4476  MSLane* oldLane = myLane;
4477  myLane = enteredLane;
4478  myLastBestLanesEdge = nullptr;
4479 
4480  // internal edges are not a part of the route...
4481  if (!enteredLane->getEdge().isInternal()) {
4482  ++myCurrEdge;
4483  assert(haveValidStopEdges());
4484  }
4485  if (myInfluencer != nullptr) {
4487  }
4488  if (!onTeleporting) {
4491  // transform lateral position when the lane width changes
4492  assert(oldLane != 0);
4493  MSLink* link = oldLane->getLinkTo(myLane);
4494  if (link) {
4496  myState.myPosLat += link->getLateralShift();
4497  }
4498  }
4499 
4500  } else {
4501  // normal move() isn't called so reset position here. must be done
4502  // before calling reminders
4503  myState.myPos = 0;
4506  }
4507  // update via
4508  if (myParameter->via.size() > 0 && myLane->getEdge().getID() == myParameter->via.front()) {
4509  myParameter->via.erase(myParameter->via.begin());
4510  }
4511  return hasArrived();
4512 }
4513 
4514 
4515 void
4517  myAmOnNet = true;
4518  myLane = enteredLane;
4520  // need to update myCurrentLaneInBestLanes
4521  updateBestLanes();
4522  // switch to and activate the new lane's reminders
4523  // keep OldLaneReminders
4524  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
4525  addReminder(*rem);
4526  }
4528  MSLane* lane = myLane;
4529  double leftLength = getVehicleType().getLength() - myState.myPos;
4530  for (int i = 0; i < (int)myFurtherLanes.size(); i++) {
4531  if (lane != nullptr) {
4532  lane = lane->getLogicalPredecessorLane(myFurtherLanes[i]->getEdge());
4533  }
4534  if (lane != nullptr) {
4535 #ifdef DEBUG_SETFURTHER
4536  if (DEBUG_COND) {
4537  std::cout << SIMTIME << " enterLaneAtLaneChange \n";
4538  }
4539 #endif
4540  myFurtherLanes[i]->resetPartialOccupation(this);
4541  myFurtherLanes[i] = lane;
4543 #ifdef DEBUG_SETFURTHER
4544  if (DEBUG_COND) {
4545  std::cout << SIMTIME << " enterLaneAtLaneChange \n";
4546  }
4547 #endif
4548  leftLength -= (lane)->setPartialOccupation(this);
4549  } else {
4550  // keep the old values, but ensure there is no shadow
4553  }
4554  }
4555  }
4556 #ifdef DEBUG_SETFURTHER
4557  if (DEBUG_COND) {
4558  std::cout << SIMTIME << " enterLaneAtLaneChange new furtherLanes=" << toString(myFurtherLanes)
4559  << " furterLanesPosLat=" << toString(myFurtherLanesPosLat) << "\n";
4560  }
4561 #endif
4562  myAngle = computeAngle();
4563 }
4564 
4565 
4566 void
4567 MSVehicle::enterLaneAtInsertion(MSLane* enteredLane, double pos, double speed, double posLat, MSMoveReminder::Notification notification) {
4568  myState = State(pos, speed, posLat, pos - getVehicleType().getLength());
4569  if (myDeparture == NOT_YET_DEPARTED) {
4570  onDepart();
4571  }
4573  assert(myState.myPos >= 0);
4574  assert(myState.mySpeed >= 0);
4575  myLane = enteredLane;
4576  myAmOnNet = true;
4577  // schedule action for the next timestep
4579  if (notification != MSMoveReminder::NOTIFICATION_TELEPORT) {
4580  // set and activate the new lane's reminders, teleports already did that at enterLaneAtMove
4581  for (std::vector< MSMoveReminder* >::const_iterator rem = enteredLane->getMoveReminders().begin(); rem != enteredLane->getMoveReminders().end(); ++rem) {
4582  addReminder(*rem);
4583  }
4584  activateReminders(notification, enteredLane);
4585  }
4586  // build the list of lanes the vehicle is lapping into
4587  if (!myLaneChangeModel->isOpposite()) {
4588  double leftLength = myType->getLength() - pos;
4589  MSLane* clane = enteredLane;
4590  while (leftLength > 0) {
4591  clane = clane->getLogicalPredecessorLane();
4592  if (clane == nullptr || clane == myLane || clane == myLane->getBidiLane()) {
4593  break;
4594  }
4595  myFurtherLanes.push_back(clane);
4597  leftLength -= (clane)->setPartialOccupation(this);
4598  }
4599  myState.myBackPos = -leftLength;
4600  } else {
4601  // clear partial occupation
4602  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
4603 #ifdef DEBUG_FURTHER
4604  if (DEBUG_COND) {
4605  std::cout << SIMTIME << " enterLaneAtInsertion \n";
4606  }
4607 #endif
4608  (*i)->resetPartialOccupation(this);
4609  }
4610  myFurtherLanes.clear();
4611  myFurtherLanesPosLat.clear();
4612  }
4616  } else if (MSGlobals::gLaneChangeDuration > 0) {
4618  }
4619  myAngle = computeAngle();
4620  if (getLaneChangeModel().isOpposite()) {
4621  myAngle += M_PI;
4622  }
4623 }
4624 
4625 
4626 void
4627 MSVehicle::leaveLane(const MSMoveReminder::Notification reason, const MSLane* approachedLane) {
4628  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
4629  if (rem->first->notifyLeave(*this, myState.myPos + rem->second, reason, approachedLane)) {
4630 #ifdef _DEBUG
4631  if (myTraceMoveReminders) {
4632  traceMoveReminder("notifyLeave", rem->first, rem->second, true);
4633  }
4634 #endif
4635  ++rem;
4636  } else {
4637 #ifdef _DEBUG
4638  if (myTraceMoveReminders) {
4639  traceMoveReminder("notifyLeave", rem->first, rem->second, false);
4640  }
4641 #endif
4642  rem = myMoveReminders.erase(rem);
4643  }
4644  }
4645  if ((reason == MSMoveReminder::NOTIFICATION_JUNCTION || reason == MSMoveReminder::NOTIFICATION_TELEPORT) && myLane != nullptr) {
4646  myOdometer += getLane()->getLength();
4647  }
4649  // @note. In case of lane change, myFurtherLanes and partial occupation
4650  // are handled in enterLaneAtLaneChange()
4651  for (std::vector<MSLane*>::iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
4652 #ifdef DEBUG_FURTHER
4653  if (DEBUG_COND) {
4654  std::cout << SIMTIME << " leaveLane \n";
4655  }
4656 #endif
4657  (*i)->resetPartialOccupation(this);
4658  }
4659  myFurtherLanes.clear();
4660  myFurtherLanesPosLat.clear();
4661  }
4662  if (reason >= MSMoveReminder::NOTIFICATION_TELEPORT) {
4663  myAmOnNet = false;
4664  myWaitingTime = 0;
4665  }
4667  WRITE_WARNING("Vehicle '" + getID() + "' aborts stop.");
4668  }
4670  while (!myStops.empty() && myStops.front().edge == myCurrEdge && &myStops.front().lane->getEdge() == &myLane->getEdge()) {
4671  WRITE_WARNING("Vehicle '" + getID() + "' skips stop on lane '" + myStops.front().lane->getID()
4672  + "' time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".")
4673  myStops.pop_front();
4674  }
4675  }
4676 }
4677 
4678 
4681  return *myLaneChangeModel;
4682 }
4683 
4684 
4687  return *myLaneChangeModel;
4688 }
4689 
4690 
4691 const std::vector<MSVehicle::LaneQ>&
4693  return *myBestLanes.begin();
4694 }
4695 
4696 
4697 void
4698 MSVehicle::updateBestLanes(bool forceRebuild, const MSLane* startLane) {
4699 #ifdef DEBUG_BESTLANES
4700  if (DEBUG_COND) {
4701  std::cout << SIMTIME << " updateBestLanes veh=" << getID() << " force=" << forceRebuild << " startLane1=" << Named::getIDSecure(startLane) << " myLane=" << Named::getIDSecure(myLane) << "\n";
4702  }
4703 #endif
4704  if (startLane == nullptr) {
4705  startLane = myLane;
4706  }
4707  assert(startLane != 0);
4708  if (getLaneChangeModel().isOpposite()) {
4709  // depending on the calling context, startLane might be the forward lane
4710  // or the reverse-direction lane. In the latter case we need to
4711  // transform it to the forward lane.
4712  bool startLaneIsOpposite = (startLane->isInternal()
4713  ? & (startLane->getLinkCont()[0]->getLane()->getEdge()) != *(myCurrEdge + 1)
4714  : &startLane->getEdge() != *myCurrEdge);
4715  if (startLaneIsOpposite) {
4716  startLane = startLane->getOpposite();
4717  assert(startLane != 0);
4718  }
4719  }
4720  if (myBestLanes.size() > 0 && !forceRebuild && myLastBestLanesEdge == &startLane->getEdge()) {
4722 #ifdef DEBUG_BESTLANES
4723  if (DEBUG_COND) {
4724  std::cout << " only updateOccupancyAndCurrentBestLane\n";
4725  }
4726 #endif
4727  return;
4728  }
4729  if (startLane->getEdge().isInternal()) {
4730  if (myBestLanes.size() == 0 || forceRebuild) {
4731  // rebuilt from previous non-internal lane (may backtrack twice if behind an internal junction)
4732  updateBestLanes(true, startLane->getLogicalPredecessorLane());
4733  }
4734  if (myLastBestLanesInternalLane == startLane && !forceRebuild) {
4735 #ifdef DEBUG_BESTLANES
4736  if (DEBUG_COND) {
4737  std::cout << " nothing to do on internal\n";
4738  }
4739 #endif
4740  return;
4741  }
4742  // adapt best lanes to fit the current internal edge:
4743  // keep the entries that are reachable from this edge
4744  const MSEdge* nextEdge = startLane->getNextNormal();
4745  assert(!nextEdge->isInternal());
4746  for (std::vector<std::vector<LaneQ> >::iterator it = myBestLanes.begin(); it != myBestLanes.end();) {
4747  std::vector<LaneQ>& lanes = *it;
4748  assert(lanes.size() > 0);
4749  if (&(lanes[0].lane->getEdge()) == nextEdge) {
4750  // keep those lanes which are successors of internal lanes from the edge of startLane
4751  std::vector<LaneQ> oldLanes = lanes;
4752  lanes.clear();
4753  const std::vector<MSLane*>& sourceLanes = startLane->getEdge().getLanes();
4754  for (std::vector<MSLane*>::const_iterator it_source = sourceLanes.begin(); it_source != sourceLanes.end(); ++it_source) {
4755  for (std::vector<LaneQ>::iterator it_lane = oldLanes.begin(); it_lane != oldLanes.end(); ++it_lane) {
4756  if ((*it_source)->getLinkCont()[0]->getLane() == (*it_lane).lane) {
4757  lanes.push_back(*it_lane);
4758  break;
4759  }
4760  }
4761  }
4762  assert(lanes.size() == startLane->getEdge().getLanes().size());
4763  // patch invalid bestLaneOffset and updated myCurrentLaneInBestLanes
4764  for (int i = 0; i < (int)lanes.size(); ++i) {
4765  if (i + lanes[i].bestLaneOffset < 0) {
4766  lanes[i].bestLaneOffset = -i;
4767  }
4768  if (i + lanes[i].bestLaneOffset >= (int)lanes.size()) {
4769  lanes[i].bestLaneOffset = (int)lanes.size() - i - 1;
4770  }
4771  assert(i + lanes[i].bestLaneOffset >= 0);
4772  assert(i + lanes[i].bestLaneOffset < (int)lanes.size());
4773  if (lanes[i].bestContinuations[0] != 0) {
4774  // patch length of bestContinuation to match expectations (only once)
4775  lanes[i].bestContinuations.insert(lanes[i].bestContinuations.begin(), (MSLane*)nullptr);
4776  }
4777  if (startLane->getLinkCont()[0]->getLane() == lanes[i].lane) {
4778  myCurrentLaneInBestLanes = lanes.begin() + i;
4779  }
4780  assert(&(lanes[i].lane->getEdge()) == nextEdge);
4781  }
4782  myLastBestLanesInternalLane = startLane;
4784 #ifdef DEBUG_BESTLANES
4785  if (DEBUG_COND) {
4786  std::cout << " updated for internal\n";
4787  }
4788 #endif
4789  return;
4790  } else {
4791  // remove passed edges
4792  it = myBestLanes.erase(it);
4793  }
4794  }
4795  assert(false); // should always find the next edge
4796  }
4797  // start rebuilding
4798  myLastBestLanesEdge = &startLane->getEdge();
4799  myBestLanes.clear();
4800 
4801  // get information about the next stop
4802  MSRouteIterator nextStopEdge = myRoute->end();
4803  const MSLane* nextStopLane = nullptr;
4804  double nextStopPos = 0;
4805  if (!myStops.empty()) {
4806  const Stop& nextStop = myStops.front();
4807  nextStopLane = nextStop.lane;
4808  nextStopEdge = nextStop.edge;
4809  nextStopPos = nextStop.pars.startPos;
4810  }
4811  if (myParameter->arrivalLaneProcedure == ARRIVAL_LANE_GIVEN && nextStopEdge == myRoute->end()) {
4812  nextStopEdge = (myRoute->end() - 1);
4813  nextStopLane = (*nextStopEdge)->getLanes()[myArrivalLane];
4814  nextStopPos = myArrivalPos;
4815  }
4816  if (nextStopEdge != myRoute->end()) {
4817  // make sure that the "wrong" lanes get a penalty. (penalty needs to be
4818  // large enough to overcome a magic threshold in MSLCM_DK2004.cpp:383)
4819  nextStopPos = MAX2(POSITION_EPS, MIN2((double)nextStopPos, (double)(nextStopLane->getLength() - 2 * POSITION_EPS)));
4820  if (nextStopLane->isInternal()) {
4821  // switch to the correct lane before entering the intersection
4822  nextStopPos = (*nextStopEdge)->getLength();
4823  }
4824  }
4825 
4826  // go forward along the next lanes;
4827  int seen = 0;
4828  double seenLength = 0;
4829  bool progress = true;
4830  for (MSRouteIterator ce = myCurrEdge; progress;) {
4831  std::vector<LaneQ> currentLanes;
4832  const std::vector<MSLane*>* allowed = nullptr;
4833  const MSEdge* nextEdge = nullptr;
4834  if (ce != myRoute->end() && ce + 1 != myRoute->end()) {
4835  nextEdge = *(ce + 1);
4836  allowed = (*ce)->allowedLanes(*nextEdge, myType->getVehicleClass());
4837  }
4838  const std::vector<MSLane*>& lanes = (*ce)->getLanes();
4839  for (std::vector<MSLane*>::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
4840  LaneQ q;
4841  MSLane* cl = *i;
4842  q.lane = cl;
4843  q.bestContinuations.push_back(cl);
4844  q.bestLaneOffset = 0;
4845  q.length = cl->allowsVehicleClass(myType->getVehicleClass()) ? cl->getLength() : 0;
4846  q.currentLength = q.length;
4847  q.allowsContinuation = allowed == nullptr || std::find(allowed->begin(), allowed->end(), cl) != allowed->end();
4848  q.occupation = 0;
4849  q.nextOccupation = 0;
4850  currentLanes.push_back(q);
4851  }
4852  //
4853  if (nextStopEdge == ce
4854  // already past the stop edge
4855  && !(ce == myCurrEdge && myLane != nullptr && myLane->isInternal())) {
4856  if (!nextStopLane->isInternal()) {
4857  progress = false;
4858  }
4859  const MSLane* normalStopLane = nextStopLane->getNormalPredecessorLane();
4860  for (std::vector<LaneQ>::iterator q = currentLanes.begin(); q != currentLanes.end(); ++q) {
4861  if (nextStopLane != nullptr && normalStopLane != (*q).lane) {
4862  (*q).allowsContinuation = false;
4863  (*q).length = nextStopPos;
4864  (*q).currentLength = (*q).length;
4865  }
4866  }
4867  }
4868 
4869  myBestLanes.push_back(currentLanes);
4870  ++seen;
4871  seenLength += currentLanes[0].lane->getLength();
4872  ++ce;
4873  progress &= (seen <= 4 || seenLength < 3000); // motorway
4874  progress &= (seen <= 8 || seenLength < 200); // urban
4875  progress &= ce != myRoute->end();
4876  /*
4877  if(progress) {
4878  progress &= (currentLanes.size()!=1||(*ce)->getLanes().size()!=1);
4879  }
4880  */
4881  }
4882 
4883  // we are examining the last lane explicitly
4884  if (myBestLanes.size() != 0) {
4885  double bestLength = -1;
4886  int bestThisIndex = 0;
4887  int index = 0;
4888  std::vector<LaneQ>& last = myBestLanes.back();
4889  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
4890  if ((*j).length > bestLength) {
4891  bestLength = (*j).length;
4892  bestThisIndex = index;
4893  }
4894  }
4895  index = 0;
4896  for (std::vector<LaneQ>::iterator j = last.begin(); j != last.end(); ++j, ++index) {
4897  if ((*j).length < bestLength) {
4898  (*j).bestLaneOffset = bestThisIndex - index;
4899  }
4900  }
4901  }
4902 #ifdef DEBUG_BESTLANES
4903  if (DEBUG_COND) {
4904  std::cout << " last edge:\n";
4905  std::vector<LaneQ>& laneQs = myBestLanes.back();
4906  for (std::vector<LaneQ>::iterator j = laneQs.begin(); j != laneQs.end(); ++j) {
4907  std::cout << " lane=" << (*j).lane->getID() << " length=" << (*j).length << " bestOffset=" << (*j).bestLaneOffset << "\n";
4908  }
4909  }
4910 #endif
4911  // go backward through the lanes
4912  // track back best lane and compute the best prior lane(s)
4913  for (std::vector<std::vector<LaneQ> >::reverse_iterator i = myBestLanes.rbegin() + 1; i != myBestLanes.rend(); ++i) {
4914  std::vector<LaneQ>& nextLanes = (*(i - 1));
4915  std::vector<LaneQ>& clanes = (*i);
4916  MSEdge& cE = clanes[0].lane->getEdge();
4917  int index = 0;
4918  double bestConnectedLength = -1;
4919  double bestLength = -1;
4920  for (std::vector<LaneQ>::iterator j = nextLanes.begin(); j != nextLanes.end(); ++j, ++index) {
4921  if ((*j).lane->isApproachedFrom(&cE) && bestConnectedLength < (*j).length) {
4922  bestConnectedLength = (*j).length;
4923  }
4924  if (bestLength < (*j).length) {
4925  bestLength = (*j).length;
4926  }
4927  }
4928  // compute index of the best lane (highest length and least offset from the best next lane)
4929  int bestThisIndex = 0;
4930  if (bestConnectedLength > 0) {
4931  index = 0;
4932  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
4933  LaneQ bestConnectedNext;
4934  bestConnectedNext.length = -1;
4935  if ((*j).allowsContinuation) {
4936  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m) {
4937  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
4938  if (bestConnectedNext.length < (*m).length || (bestConnectedNext.length == (*m).length && abs(bestConnectedNext.bestLaneOffset) > abs((*m).bestLaneOffset))) {
4939  bestConnectedNext = *m;
4940  }
4941  }
4942  }
4943  if (bestConnectedNext.length == bestConnectedLength && abs(bestConnectedNext.bestLaneOffset) < 2) {
4944  (*j).length += bestLength;
4945  } else {
4946  (*j).length += bestConnectedNext.length;
4947  }
4948  (*j).bestLaneOffset = bestConnectedNext.bestLaneOffset;
4949  }
4950  copy(bestConnectedNext.bestContinuations.begin(), bestConnectedNext.bestContinuations.end(), back_inserter((*j).bestContinuations));
4951  if (clanes[bestThisIndex].length < (*j).length
4952  || (clanes[bestThisIndex].length == (*j).length && abs(clanes[bestThisIndex].bestLaneOffset) > abs((*j).bestLaneOffset))
4953  || (clanes[bestThisIndex].length == (*j).length && abs(clanes[bestThisIndex].bestLaneOffset) == abs((*j).bestLaneOffset) &&
4954  nextLinkPriority(clanes[bestThisIndex].bestContinuations) < nextLinkPriority((*j).bestContinuations))
4955  ) {
4956  bestThisIndex = index;
4957  }
4958  }
4959 #ifdef DEBUG_BESTLANES
4960  if (DEBUG_COND) {
4961  std::cout << " edge=" << cE.getID() << "\n";
4962  std::vector<LaneQ>& laneQs = clanes;
4963  for (std::vector<LaneQ>::iterator j = laneQs.begin(); j != laneQs.end(); ++j) {
4964  std::cout << " lane=" << (*j).lane->getID() << " length=" << (*j).length << " bestOffset=" << (*j).bestLaneOffset << "\n";
4965  }
4966  }
4967 #endif
4968 
4969  } else {
4970  // only needed in case of disconnected routes
4971  int bestNextIndex = 0;
4972  int bestDistToNeeded = (int) clanes.size();
4973  index = 0;
4974  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
4975  if ((*j).allowsContinuation) {
4976  int nextIndex = 0;
4977  for (std::vector<LaneQ>::const_iterator m = nextLanes.begin(); m != nextLanes.end(); ++m, ++nextIndex) {
4978  if ((*m).lane->isApproachedFrom(&cE, (*j).lane)) {
4979  if (bestDistToNeeded > abs((*m).bestLaneOffset)) {
4980  bestDistToNeeded = abs((*m).bestLaneOffset);
4981  bestThisIndex = index;
4982  bestNextIndex = nextIndex;
4983  }
4984  }
4985  }
4986  }
4987  }
4988  clanes[bestThisIndex].length += nextLanes[bestNextIndex].length;
4989  copy(nextLanes[bestNextIndex].bestContinuations.begin(), nextLanes[bestNextIndex].bestContinuations.end(), back_inserter(clanes[bestThisIndex].bestContinuations));
4990 
4991  }
4992  // set bestLaneOffset for all lanes
4993  index = 0;
4994  for (std::vector<LaneQ>::iterator j = clanes.begin(); j != clanes.end(); ++j, ++index) {
4995  if ((*j).length < clanes[bestThisIndex].length
4996  || ((*j).length == clanes[bestThisIndex].length && abs((*j).bestLaneOffset) > abs(clanes[bestThisIndex].bestLaneOffset))
4997  || (nextLinkPriority((*j).bestContinuations)) < nextLinkPriority(clanes[bestThisIndex].bestContinuations)
4998  ) {
4999  (*j).bestLaneOffset = bestThisIndex - index;
5000  if ((nextLinkPriority((*j).bestContinuations)) < nextLinkPriority(clanes[bestThisIndex].bestContinuations)) {
5001  // try to move away from the lower-priority lane before it ends
5002  (*j).length = (*j).currentLength;
5003  }
5004  } else {
5005  (*j).bestLaneOffset = 0;
5006  }
5007  }
5008  }
5010 #ifdef DEBUG_BESTLANES
5011  if (DEBUG_COND) {
5012  std::cout << SIMTIME << " veh=" << getID() << " bestCont=" << toString(getBestLanesContinuation()) << "\n";
5013  }
5014 #endif
5015  return;
5016 }
5017 
5018 
5019 int
5020 MSVehicle::nextLinkPriority(const std::vector<MSLane*>& conts) {
5021  if (conts.size() < 2) {
5022  return -1;
5023  } else {
5024  MSLink* link = MSLinkContHelper::getConnectingLink(*conts[0], *conts[1]);
5025  if (link != nullptr) {
5026  return link->havePriority() ? 1 : 0;
5027  } else {
5028  // disconnected route
5029  return -1;
5030  }
5031  }
5032 }
5033 
5034 
5035 void
5037  std::vector<LaneQ>& currLanes = *myBestLanes.begin();
5038  std::vector<LaneQ>::iterator i;
5039  for (i = currLanes.begin(); i != currLanes.end(); ++i) {
5040  double nextOccupation = 0;
5041  for (std::vector<MSLane*>::const_iterator j = (*i).bestContinuations.begin() + 1; j != (*i).bestContinuations.end(); ++j) {
5042  nextOccupation += (*j)->getBruttoVehLenSum();
5043  }
5044  (*i).nextOccupation = nextOccupation;
5045 #ifdef DEBUG_BESTLANES
5046  if (DEBUG_COND) {
5047  std::cout << " lane=" << (*i).lane->getID() << " nextOccupation=" << nextOccupation << "\n";
5048  }
5049 #endif
5050  if ((*i).lane == startLane) {
5052  }
5053  }
5054 }
5055 
5056 
5057 const std::vector<MSLane*>&
5059  if (myBestLanes.empty() || myBestLanes[0].empty()) {
5060  return myEmptyLaneVector;
5061  }
5062  return (*myCurrentLaneInBestLanes).bestContinuations;
5063 }
5064 
5065 
5066 const std::vector<MSLane*>&
5068  const MSLane* lane = l;
5069  // XXX: shouldn't this be a "while" to cover more than one internal lane? (Leo) Refs. #2575
5070  if (lane->getEdge().isInternal()) {
5071  // internal edges are not kept inside the bestLanes structure
5072  lane = lane->getLinkCont()[0]->getLane();
5073  }
5074  if (myBestLanes.size() == 0) {
5075  return myEmptyLaneVector;
5076  }
5077  for (std::vector<LaneQ>::const_iterator i = myBestLanes[0].begin(); i != myBestLanes[0].end(); ++i) {
5078  if ((*i).lane == lane) {
5079  return (*i).bestContinuations;
5080  }
5081  }
5082  return myEmptyLaneVector;
5083 }
5084 
5085 
5086 int
5088  if (myBestLanes.empty() || myBestLanes[0].empty()) {
5089  return 0;
5090  } else {
5091  return (*myCurrentLaneInBestLanes).bestLaneOffset;
5092  }
5093 }
5094 
5095 
5096 void
5097 MSVehicle::adaptBestLanesOccupation(int laneIndex, double density) {
5098  std::vector<MSVehicle::LaneQ>& preb = myBestLanes.front();
5099  assert(laneIndex < (int)preb.size());
5100  preb[laneIndex].occupation = density + preb[laneIndex].nextOccupation;
5101 }
5102 
5103 
5104 void
5106  if (MSGlobals::gLaneChangeDuration > 0 && !getLaneChangeModel().isChangingLanes()) {
5107  myState.myPosLat = 0;
5108  }
5109 }
5110 
5111 
5112 double
5113 MSVehicle::getDistanceToPosition(double destPos, const MSEdge* destEdge) const {
5114  double distance = std::numeric_limits<double>::max();
5115  if (isOnRoad() && destEdge != nullptr) {
5116  if (myLane->isInternal()) {
5117  // vehicle is on inner junction edge
5118  distance = myLane->getLength() - getPositionOnLane();
5119  distance += myRoute->getDistanceBetween(0, destPos, *(myCurrEdge + 1), destEdge);
5120  } else {
5121  // vehicle is on a normal edge
5122  distance = myRoute->getDistanceBetween(getPositionOnLane(), destPos, *myCurrEdge, destEdge);
5123  }
5124  }
5125  return distance;
5126 }
5127 
5128 
5129 std::pair<const MSVehicle* const, double>
5130 MSVehicle::getLeader(double dist) const {
5131  if (myLane == nullptr) {
5132  return std::make_pair(static_cast<const MSVehicle*>(nullptr), -1);
5133  }
5134  if (dist == 0) {
5136  }
5137  const MSVehicle* lead = nullptr;
5138  const MSLane* lane = myLane; // ensure lane does not change between getVehiclesSecure and releaseVehicles;
5139  const MSLane::VehCont& vehs = lane->getVehiclesSecure();
5140  // vehicle might be outside the road network
5141  MSLane::VehCont::const_iterator it = std::find(vehs.begin(), vehs.end(), this);
5142  if (it != vehs.end() && it + 1 != vehs.end()) {
5143  lead = *(it + 1);
5144  }
5145  if (lead != nullptr) {
5146  std::pair<const MSVehicle* const, double> result(
5147  lead, lead->getBackPositionOnLane(myLane) - getPositionOnLane() - getVehicleType().getMinGap());
5148  lane->releaseVehicles();
5149  return result;
5150  }
5151  const double seen = myLane->getLength() - getPositionOnLane();
5152  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation(myLane);
5153  std::pair<const MSVehicle* const, double> result = myLane->getLeaderOnConsecutive(dist, seen, getSpeed(), *this, bestLaneConts);
5154  lane->releaseVehicles();
5155  return result;
5156 }
5157 
5158 
5159 double
5161  // calling getLeader with 0 would induce a dist calculation but we only want to look for the leaders on the current lane
5162  std::pair<const MSVehicle* const, double> leaderInfo = getLeader(-1);
5163  if (leaderInfo.first == nullptr || getSpeed() == 0) {
5164  return -1;
5165  }
5166  return (leaderInfo.second + getVehicleType().getMinGap()) / getSpeed();
5167 }
5168 
5169 
5170 double
5173 }
5174 
5175 
5176 double
5179 }
5180 
5181 
5182 double
5185 }
5186 
5187 
5188 double
5191 }
5192 
5193 
5194 double
5197 }
5198 
5199 
5200 double
5203 }
5204 
5205 
5206 double
5209 }
5210 
5211 
5212 double
5215 }
5216 
5217 
5218 void
5220  MSBaseVehicle::addPerson(person);
5221  if (myStops.size() > 0 && myStops.front().reached && myStops.front().triggered && myStops.front().numExpectedPerson > 0) {
5222  myStops.front().numExpectedPerson -= (int)myStops.front().pars.awaitedPersons.count(person->getID());
5223  }
5224 }
5225 
5226 void
5228  MSBaseVehicle::addContainer(container);
5229  if (myStops.size() > 0 && myStops.front().reached && myStops.front().pars.containerTriggered && myStops.front().numExpectedContainer > 0) {
5230  myStops.front().numExpectedContainer -= (int)myStops.front().pars.awaitedContainers.count(container->getID());
5231  }
5232 }
5233 
5234 
5235 void
5238  int state = getLaneChangeModel().getOwnState();
5239  // do not set blinker for sublane changes or when blocked from changing to the right
5240  const bool blinkerManoeuvre = (((state & LCA_SUBLANE) == 0) && (
5241  (state & LCA_KEEPRIGHT) == 0 || (state & LCA_BLOCKED) == 0));
5244  if (MSNet::getInstance()->lefthand()) {
5245  // lane indices increase from left to right
5246  std::swap(left, right);
5247  }
5248  if ((state & LCA_LEFT) != 0 && blinkerManoeuvre) {
5249  switchOnSignal(left);
5250  } else if ((state & LCA_RIGHT) != 0 && blinkerManoeuvre) {
5251  switchOnSignal(right);
5252  } else if (getLaneChangeModel().isChangingLanes()) {
5253  if (getLaneChangeModel().getLaneChangeDirection() == 1) {
5254  switchOnSignal(left);
5255  } else {
5256  switchOnSignal(right);
5257  }
5258  } else {
5259  const MSLane* lane = getLane();
5260  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, 1, *lane, getBestLanesContinuation());
5261  if (link != lane->getLinkCont().end() && lane->getLength() - getPositionOnLane() < lane->getVehicleMaxSpeed(this) * (double) 7.) {
5262  switch ((*link)->getDirection()) {
5263  case LINKDIR_TURN:
5264  case LINKDIR_LEFT:
5265  case LINKDIR_PARTLEFT:
5267  break;
5268  case LINKDIR_RIGHT:
5269  case LINKDIR_PARTRIGHT:
5271  break;
5272  default:
5273  break;
5274  }
5275  }
5276  }
5278  // signal parking stop on the current lane when within braking distance (~2 seconds before braking)
5279  && myStops.begin()->pars.parking
5280  && myStopDist < getCarFollowModel().brakeGap(myLane->getVehicleMaxSpeed(this), getCarFollowModel().getMaxDecel(), 3)) {
5282  }
5283  if (myInfluencer != nullptr && myInfluencer->getSignals() >= 0) {
5285  myInfluencer->setSignals(-1); // overwrite computed signals only once
5286  }
5287 }
5288 
5289 void
5291 
5292  //TODO look if timestep ist SIMSTEP
5293  if (currentTime % 1000 == 0) {
5296  } else {
5298  }
5299  }
5300 }
5301 
5302 
5303 int
5305  std::vector<MSLane*>::const_iterator laneP = std::find(myLane->getEdge().getLanes().begin(), myLane->getEdge().getLanes().end(), myLane);
5306  return (int) std::distance(myLane->getEdge().getLanes().begin(), laneP);
5307 }
5308 
5309 
5310 void
5311 MSVehicle::setTentativeLaneAndPosition(MSLane* lane, double pos, double posLat) {
5312  assert(lane != 0);
5313  myLane = lane;
5314  myState.myPos = pos;
5315  myState.myPosLat = posLat;
5317 }
5318 
5319 
5320 double
5322  return myState.myPosLat + 0.5 * myLane->getWidth() - 0.5 * getVehicleType().getWidth();
5323 }
5324 
5325 
5326 double
5328  return getCenterOnEdge(lane) - 0.5 * getVehicleType().getWidth();
5329 }
5330 
5331 
5332 double
5334  if (lane == nullptr || &lane->getEdge() == &myLane->getEdge()) {
5335  return myLane->getRightSideOnEdge() + myState.myPosLat + 0.5 * myLane->getWidth();
5336  } else if (lane == getLaneChangeModel().getShadowLane()) {
5337  if (getLaneChangeModel().getShadowDirection() == -1) {
5338  return lane->getRightSideOnEdge() + lane->getWidth() + myState.myPosLat + 0.5 * myLane->getWidth();
5339  } else {
5340  return lane->getRightSideOnEdge() - myLane->getWidth() + myState.myPosLat + 0.5 * myLane->getWidth();
5341  }
5342  } else {
5343  assert(myFurtherLanes.size() == myFurtherLanesPosLat.size());
5344  for (int i = 0; i < (int)myFurtherLanes.size(); ++i) {
5345  if (myFurtherLanes[i] == lane) {
5346 #ifdef DEBUG_FURTHER
5347  if (DEBUG_COND) std::cout << " getCenterOnEdge veh=" << getID() << " lane=" << lane->getID() << " i=" << i << " furtherLat=" << myFurtherLanesPosLat[i]
5348  << " result=" << lane->getRightSideOnEdge() + myFurtherLanesPosLat[i] + 0.5 * lane->getWidth()
5349  << "\n";
5350 #endif
5351  return lane->getRightSideOnEdge() + myFurtherLanesPosLat[i] + 0.5 * lane->getWidth();
5352  }
5353  }
5354  //if (DEBUG_COND) std::cout << SIMTIME << " veh=" << getID() << " myShadowFurtherLanes=" << toString(getLaneChangeModel().getShadowFurtherLanes()) << "\n";
5355  const std::vector<MSLane*>& shadowFurther = getLaneChangeModel().getShadowFurtherLanes();
5356  for (int i = 0; i < (int)shadowFurther.size(); ++i) {
5357  //if (DEBUG_COND) std::cout << " comparing i=" << (*i)->getID() << " lane=" << lane->getID() << "\n";
5358  if (shadowFurther[i] == lane) {
5359  assert(getLaneChangeModel().getShadowLane() != 0);
5360  return (lane->getRightSideOnEdge() + getLaneChangeModel().getShadowFurtherLanesPosLat()[i] + 0.5 * lane->getWidth()
5361  + (myLane->getCenterOnEdge() - getLaneChangeModel().getShadowLane()->getCenterOnEdge()));
5362  }
5363  }
5364  assert(false);
5365  throw ProcessError("Request lateral pos of vehicle '" + getID() + "' for invalid lane '" + Named::getIDSecure(lane) + "'");
5366  }
5367 }
5368 
5369 
5370 double
5371 MSVehicle::getLatOffset(const MSLane* lane) const {
5372  assert(lane != 0);
5373  if (&lane->getEdge() == &myLane->getEdge()) {
5374  return myLane->getRightSideOnEdge() - lane->getRightSideOnEdge();
5375  } else if (myLane->getOpposite() == lane) {
5376  return (myLane->getWidth() + lane->getWidth()) * 0.5 * (getLaneChangeModel().isOpposite() ? -1 : 1);
5377  } else {
5378  // Check whether the lane is a further lane for the vehicle
5379  for (int i = 0; i < (int)myFurtherLanes.size(); ++i) {
5380  if (myFurtherLanes[i] == lane) {
5381 #ifdef DEBUG_FURTHER
5382  if (DEBUG_COND) {
5383  std::cout << " getLatOffset veh=" << getID() << " lane=" << lane->getID() << " i=" << i << " posLat=" << myState.myPosLat << " furtherLat=" << myFurtherLanesPosLat[i] << "\n";
5384  }
5385 #endif
5387  }
5388  }
5389 #ifdef DEBUG_FURTHER
5390  if (DEBUG_COND) {
5391  std::cout << SIMTIME << " veh=" << getID() << " myShadowFurtherLanes=" << toString(getLaneChangeModel().getShadowFurtherLanes()) << "\n";
5392  }
5393 #endif
5394  // Check whether the lane is a "shadow further lane" for the vehicle
5395  const std::vector<MSLane*>& shadowFurther = getLaneChangeModel().getShadowFurtherLanes();
5396  for (int i = 0; i < (int)shadowFurther.size(); ++i) {
5397  if (shadowFurther[i] == lane) {
5398 #ifdef DEBUG_FURTHER
5399  if (DEBUG_COND) std::cout << " getLatOffset veh=" << getID()
5400  << " shadowLane=" << Named::getIDSecure(getLaneChangeModel().getShadowLane())
5401  << " lane=" << lane->getID()
5402  << " i=" << i
5403  << " posLat=" << myState.myPosLat
5404  << " shadowPosLat=" << getLatOffset(getLaneChangeModel().getShadowLane())
5405  << " shadowFurtherLat=" << getLaneChangeModel().getShadowFurtherLanesPosLat()[i]
5406  << "\n";
5407 #endif
5409  }
5410  }
5411  // Check whether the vehicle issued a maneuverReservation on the lane.
5412  assert(&getLaneChangeModel().getTargetLane()->getEdge() == &myLane->getEdge()); // should have been handled in (&lane->getEdge() == &myLane->getEdge())-block
5413  const std::vector<MSLane*>& furtherTargets = getLaneChangeModel().getFurtherTargetLanes();
5414  for (int i = 0; i < (int)myFurtherLanes.size(); ++i) {
5415  // Further target lanes are just neighboring lanes of the vehicle's further lanes, @see MSAbstractLaneChangeModel::updateTargetLane()
5416  MSLane* targetLane = furtherTargets[i];
5417  if (targetLane == lane) {
5418  const double targetDir = getLaneChangeModel().getManeuverDist() < 0 ? -1. : 1.;
5419  const double latOffset = myFurtherLanesPosLat[i] - myState.myPosLat + targetDir * 0.5 * (myFurtherLanes[i]->getWidth() + targetLane->getWidth());
5420 #ifdef DEBUG_TARGET_LANE
5421  if (DEBUG_COND) {
5422  std::cout << " getLatOffset veh=" << getID()
5423  << " wrt targetLane=" << Named::getIDSecure(getLaneChangeModel().getTargetLane())
5424  << "\n i=" << i
5425  << " posLat=" << myState.myPosLat
5426  << " furtherPosLat=" << myFurtherLanesPosLat[i]
5427  << " maneuverDist=" << getLaneChangeModel().getManeuverDist()
5428  << " targetDir=" << targetDir
5429  << " latOffset=" << latOffset
5430  << std::endl;
5431  }
5432 #endif
5433  return latOffset;
5434  }
5435  }
5436  assert(false);
5437  throw ProcessError("Request lateral offset of vehicle '" + getID() + "' for invalid lane '" + Named::getIDSecure(lane) + "'");
5438  }
5439 }
5440 
5441 
5442 double
5443 MSVehicle::lateralDistanceToLane(const int offset) const {
5444  // compute the distance when changing to the neighboring lane
5445  // (ensure we do not lap into the line behind neighLane since there might be unseen blockers)
5446  assert(offset == 0 || offset == 1 || offset == -1);
5447  assert(myLane != nullptr);
5448  assert(myLane->getParallelLane(offset) != nullptr);
5449  const double halfCurrentLaneWidth = 0.5 * myLane->getWidth();
5450  const double halfVehWidth = 0.5 * (getWidth() + NUMERICAL_EPS);
5451  const double latPos = getLateralPositionOnLane();
5452  double leftLimit = halfCurrentLaneWidth - halfVehWidth - latPos;
5453  double rightLimit = -halfCurrentLaneWidth + halfVehWidth - latPos;
5454  double latLaneDist = 0; // minimum distance to move the vehicle fully onto the new lane
5455  if (offset == 0) {
5456  if (latPos + halfVehWidth > halfCurrentLaneWidth) {
5457  // correct overlapping left
5458  latLaneDist = halfCurrentLaneWidth - latPos - halfVehWidth;
5459  } else if (latPos - halfVehWidth < - halfCurrentLaneWidth) {
5460  // correct overlapping left
5461  latLaneDist = halfCurrentLaneWidth - latPos + halfVehWidth;
5462  }
5463  } else if (offset == -1) {
5464  latLaneDist = rightLimit - (getWidth() + NUMERICAL_EPS);
5465  } else if (offset == 1) {
5466  latLaneDist = leftLimit + (getWidth() + NUMERICAL_EPS);
5467  }
5468 #ifdef DEBUG_ACTIONSTEPS
5469  if (DEBUG_COND) {
5470  std::cout << SIMTIME
5471  << " veh=" << getID()
5472  << " halfCurrentLaneWidth=" << halfCurrentLaneWidth
5473  << " halfVehWidth=" << halfVehWidth
5474  << " latPos=" << latPos
5475  << " latLaneDist=" << latLaneDist
5476  << " leftLimit=" << leftLimit
5477  << " rightLimit=" << rightLimit
5478  << "\n";
5479  }
5480 #endif
5481  return latLaneDist;
5482 }
5483 
5484 
5485 double
5486 MSVehicle::getLateralOverlap(double posLat) const {
5487  return (fabs(posLat) + 0.5 * getVehicleType().getWidth()
5488  - 0.5 * myLane->getWidth());
5489 }
5490 
5491 
5492 double
5495 }
5496 
5497 
5498 void
5500  for (const DriveProcessItem& dpi : lfLinks) {
5501  if (dpi.myLink != nullptr) {
5502  dpi.myLink->removeApproaching(this);
5503  }
5504  }
5505  // unregister on all shadow links
5507 }
5508 
5509 
5510 bool
5512  // the following links are unsafe:
5513  // - zipper links if they are close enough and have approaching vehicles in the relevant time range
5514  // - unprioritized links if the vehicle is currently approaching a prioritzed link and unable to stop in time
5515  double seen = myLane->getLength() - getPositionOnLane();
5516  const double dist = getCarFollowModel().brakeGap(getSpeed(), getCarFollowModel().getMaxDecel(), 0);
5517  if (seen < dist) {
5518  const std::vector<MSLane*>& bestLaneConts = getBestLanesContinuation(lane);
5519  int view = 1;
5520  MSLinkCont::const_iterator link = MSLane::succLinkSec(*this, view, *lane, bestLaneConts);
5521  DriveItemVector::const_iterator di = myLFLinkLanes.begin();
5522  while (!lane->isLinkEnd(link) && seen <= dist) {
5523  if (!lane->getEdge().isInternal()
5524  && (((*link)->getState() == LINKSTATE_ZIPPER && seen < MSLink::ZIPPER_ADAPT_DIST)
5525  || !(*link)->havePriority())) {
5526  // find the drive item corresponding to this link
5527  bool found = false;
5528  while (di != myLFLinkLanes.end() && !found) {
5529  if ((*di).myLink != nullptr) {
5530  const MSLane* diPredLane = (*di).myLink->getLaneBefore();
5531  if (diPredLane != nullptr) {
5532  if (&diPredLane->getEdge() == &lane->getEdge()) {
5533  found = true;
5534  }
5535  }
5536  }
5537  if (!found) {
5538  di++;
5539  }
5540  }
5541  if (found) {
5542  const SUMOTime leaveTime = (*link)->getLeaveTime((*di).myArrivalTime, (*di).myArrivalSpeed,
5543  (*di).getLeaveSpeed(), getVehicleType().getLength());
5544  if ((*link)->hasApproachingFoe((*di).myArrivalTime, leaveTime, (*di).myArrivalSpeed, getCarFollowModel().getMaxDecel())) {
5545  //std::cout << SIMTIME << " veh=" << getID() << " aborting changeTo=" << Named::getIDSecure(bestLaneConts.front()) << " linkState=" << toString((*link)->getState()) << " seen=" << seen << " dist=" << dist << "\n";
5546  return true;
5547  }
5548  }
5549  // no drive item is found if the vehicle aborts it's request within dist
5550  }
5551  lane = (*link)->getViaLaneOrLane();
5552  if (!lane->getEdge().isInternal()) {
5553  view++;
5554  }
5555  seen += lane->getLength();
5556  link = MSLane::succLinkSec(*this, view, *lane, bestLaneConts);
5557  }
5558  }
5559  return false;
5560 }
5561 
5562 
5565  PositionVector centerLine;
5566  centerLine.push_back(getPosition());
5567  for (MSLane* lane : myFurtherLanes) {
5568  centerLine.push_back(lane->getShape().back());
5569  }
5570  centerLine.push_back(getBackPosition());
5571  centerLine.move2side(0.5 * myType->getWidth());
5572  PositionVector result = centerLine;
5573  centerLine.move2side(-myType->getWidth());
5574  result.append(centerLine.reverse(), POSITION_EPS);
5575  return result;
5576 }
5577 
5578 
5581  // XXX implement more types
5582  switch (myType->getGuiShape()) {
5583  case SVS_PASSENGER:
5584  case SVS_PASSENGER_SEDAN:
5586  case SVS_PASSENGER_WAGON:
5587  case SVS_PASSENGER_VAN: {
5588  PositionVector result;
5589  PositionVector centerLine;
5590  centerLine.push_back(getPosition());
5591  centerLine.push_back(getBackPosition());
5592  PositionVector line1 = centerLine;
5593  PositionVector line2 = centerLine;
5594  line1.move2side(0.3 * myType->getWidth());
5595  line2.move2side(0.5 * myType->getWidth());
5596  line2.scaleRelative(0.8);
5597  result.push_back(line1[0]);
5598  result.push_back(line2[0]);
5599  result.push_back(line2[1]);
5600  result.push_back(line1[1]);
5601  line1.move2side(-0.6 * myType->getWidth());
5602  line2.move2side(-1.0 * myType->getWidth());
5603  result.push_back(line1[1]);
5604  result.push_back(line2[1]);
5605  result.push_back(line2[0]);
5606  result.push_back(line1[0]);
5607  return result;
5608  }
5609  default:
5610  return getBoundingBox();
5611  }
5612 }
5613 
5614 
5615 bool
5616 MSVehicle::onFurtherEdge(const MSEdge* edge) const {
5617  for (std::vector<MSLane*>::const_iterator i = myFurtherLanes.begin(); i != myFurtherLanes.end(); ++i) {
5618  if (&(*i)->getEdge() == edge) {
5619  return true;
5620  }
5621  }
5622  return false;
5623 }
5624 
5625 bool
5626 MSVehicle::rerouteParkingArea(const std::string& parkingAreaID, std::string& errorMsg) {
5627  // this function is based on MSTriggeredRerouter::rerouteParkingArea in order to keep
5628  // consistency in the behaviour.
5629 
5630  // get vehicle params
5631  MSParkingArea* destParkArea = getNextParkingArea();
5632  const MSRoute& route = getRoute();
5633  const MSEdge* lastEdge = route.getLastEdge();
5634 
5635  if (destParkArea == nullptr) {
5636  // not driving towards a parking area
5637  errorMsg = "Vehicle " + getID() + " is not driving to a parking area so it cannot be rerouted.";
5638  return false;
5639  }
5640 
5641  // if the current route ends at the parking area, the new route will also and at the new area
5642  bool newDestination = (&destParkArea->getLane().getEdge() == route.getLastEdge()
5643  && getArrivalPos() >= destParkArea->getBeginLanePosition()
5644  && getArrivalPos() <= destParkArea->getEndLanePosition());
5645 
5646  // retrieve info on the new parking area
5648  parkingAreaID, SumoXMLTag::SUMO_TAG_PARKING_AREA);
5649 
5650  if (newParkingArea == nullptr) {
5651  errorMsg = "Parking area ID " + toString(parkingAreaID) + " not found in the network.";
5652  return false;
5653  }
5654 
5655  const MSEdge* newEdge = &(newParkingArea->getLane().getEdge());
5657 
5658  // Compute the route from the current edge to the parking area edge
5659  ConstMSEdgeVector edgesToPark;
5660  router.compute(getEdge(), newEdge, this, MSNet::getInstance()->getCurrentTimeStep(), edgesToPark);
5661 
5662  // Compute the route from the parking area edge to the end of the route
5663  ConstMSEdgeVector edgesFromPark;
5664  if (!newDestination) {
5665  router.compute(newEdge, lastEdge, this, MSNet::getInstance()->getCurrentTimeStep(), edgesFromPark);
5666  } else {
5667  // adapt plans of any riders
5668  for (MSTransportable* p : getPersons()) {
5669  p->rerouteParkingArea(getNextParkingArea(), newParkingArea);
5670  }
5671  }
5672 
5673  // we have a new destination, let's replace the vehicle route
5674  ConstMSEdgeVector edges = edgesToPark;
5675  if (edgesFromPark.size() > 0) {
5676  edges.insert(edges.end(), edgesFromPark.begin() + 1, edgesFromPark.end());
5677  }
5678 
5679  if (newDestination) {
5680  SUMOVehicleParameter* newParameter = new SUMOVehicleParameter();
5681  *newParameter = getParameter();
5682  newParameter->arrivalPosProcedure = ARRIVAL_POS_GIVEN;
5683  newParameter->arrivalPos = newParkingArea->getEndLanePosition();
5684  replaceParameter(newParameter);
5685  }
5686  const double routeCost = router.recomputeCosts(edges, this, MSNet::getInstance()->getCurrentTimeStep());
5687  ConstMSEdgeVector prevEdges(myCurrEdge, myRoute->end());
5688  const double savings = router.recomputeCosts(prevEdges, this, MSNet::getInstance()->getCurrentTimeStep());
5689  if (replaceParkingArea(newParkingArea, errorMsg)) {
5690  replaceRouteEdges(edges, routeCost, savings, "TraCI:" + toString(SUMO_TAG_PARKING_ZONE_REROUTE), false, false, false);
5691  } else {
5692  WRITE_WARNING("Vehicle '" + getID() + "' could not reroute to new parkingArea '" + newParkingArea->getID()
5693  + "' reason=" + errorMsg + ", time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
5694  return false;
5695  }
5696  return true;
5697 }
5698 
5699 bool
5700 MSVehicle::addTraciStop(MSLane* const lane, const double startPos, const double endPos, const SUMOTime duration, const SUMOTime until,
5701  const bool parking, const bool triggered, const bool containerTriggered, std::string& errorMsg) {
5702  //if the stop exists update the duration
5703  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
5704  if (iter->lane == lane && fabs(iter->pars.endPos - endPos) < POSITION_EPS) {
5705  // update existing stop
5706  if (duration == 0 && until < 0 && !iter->reached) {
5707  myStops.erase(iter);
5708  // XXX also erase from myParameter->stops ?
5709  updateBestLanes(true);
5710  } else {
5711  iter->duration = duration;
5712  iter->triggered = triggered;
5713  iter->containerTriggered = containerTriggered;
5714  const_cast<SUMOVehicleParameter::Stop&>(iter->pars).until = until;
5715  const_cast<SUMOVehicleParameter::Stop&>(iter->pars).parking = parking;
5716  }
5717  return true;
5718  }
5719  }
5721  newStop.lane = lane->getID();
5722  newStop.startPos = startPos;
5723  newStop.endPos = endPos;
5724  newStop.duration = duration;
5725  newStop.until = until;
5726  newStop.triggered = triggered;
5727  newStop.containerTriggered = containerTriggered;
5728  newStop.parking = parking;
5729  newStop.index = STOP_INDEX_FIT;
5731  if (triggered) {
5732  newStop.parametersSet |= STOP_TRIGGER_SET;
5733  }
5734  if (containerTriggered) {
5736  }
5737  if (parking) {
5738  newStop.parametersSet |= STOP_PARKING_SET;
5739  }
5740  if (duration >= 0) {
5741  newStop.parametersSet |= STOP_DURATION_SET;
5742  }
5743  if (until >= 0) {
5744  newStop.parametersSet |= STOP_UNTIL_SET;
5745  }
5746  const bool result = addStop(newStop, errorMsg);
5747  if (result) {
5749  myParameter->stops.push_back(newStop);
5750  }
5751  if (myLane != nullptr) {
5752  updateBestLanes(true);
5753  }
5754  return result;
5755 }
5756 
5757 
5758 bool
5759 MSVehicle::addTraciStopAtStoppingPlace(const std::string& stopId, const SUMOTime duration, const SUMOTime until, const bool parking,
5760  const bool triggered, const bool containerTriggered, const SumoXMLTag stoppingPlaceType, std::string& errorMsg) {
5761  //if the stop exists update the duration
5762  for (std::list<Stop>::iterator iter = myStops.begin(); iter != myStops.end(); iter++) {
5763  Named* stop = nullptr;
5764  switch (stoppingPlaceType) {
5765  case SUMO_TAG_BUS_STOP:
5766  stop = iter->busstop;
5767  break;
5769  stop = iter->containerstop;
5770  break;
5772  stop = iter->chargingStation;
5773  break;
5774  case SUMO_TAG_PARKING_AREA:
5775  stop = iter->parkingarea;
5776  break;
5777  default:
5778  throw ProcessError("Invalid stopping place type '" + toString(stoppingPlaceType) + "'");
5779  }
5780  if (stop != nullptr && stop->getID() == stopId) {
5781  if (duration == 0 && !iter->reached) {
5782  myStops.erase(iter);
5783  updateBestLanes(true);
5784  } else {
5785  iter->duration = duration;
5786  }
5787  return true;
5788  }
5789  }
5790 
5792  switch (stoppingPlaceType) {
5793  case SUMO_TAG_BUS_STOP:
5794  newStop.busstop = stopId;
5795  break;
5797  newStop.containerstop = stopId;
5798  break;
5800  newStop.chargingStation = stopId;
5801  break;
5802  case SUMO_TAG_PARKING_AREA:
5803  newStop.parkingarea = stopId;
5804  break;
5805  default:
5806  throw ProcessError("Invalid stopping place type '" + toString(stoppingPlaceType) + "'");
5807  }
5808  MSStoppingPlace* bs = MSNet::getInstance()->getStoppingPlace(stopId, stoppingPlaceType);
5809  if (bs == nullptr) {
5810  errorMsg = "The " + toString(stoppingPlaceType) + " '" + stopId + "' is not known for vehicle '" + getID() + "'";
5811  return false;
5812  }
5813  newStop.duration = duration;
5814  newStop.until = until;
5815  newStop.triggered = triggered;
5816  newStop.containerTriggered = containerTriggered;
5817  newStop.parking = parking;
5818  newStop.index = STOP_INDEX_FIT;
5819  newStop.lane = bs->getLane().getID();
5820  newStop.endPos = bs->getEndLanePosition();
5821  newStop.startPos = bs->getBeginLanePosition();
5822  if (triggered) {
5823  newStop.parametersSet |= STOP_TRIGGER_SET;
5824  }
5825  if (containerTriggered) {
5827  }
5828  if (parking) {
5829  newStop.parametersSet |= STOP_PARKING_SET;
5830  }
5831  const bool result = addStop(newStop, errorMsg);
5832  if (myLane != nullptr) {
5833  updateBestLanes(true);
5834  }
5835  return result;
5836 }
5837 
5838 bool
5840  if (isStopped()) {
5844  }
5848  }
5849  // we have waited long enough and fulfilled any passenger-requirements
5850  if (myStops.front().busstop != nullptr) {
5851  // inform bus stop about leaving it
5852  myStops.front().busstop->leaveFrom(this);
5853  }
5854  // we have waited long enough and fulfilled any container-requirements
5855  if (myStops.front().containerstop != nullptr) {
5856  // inform container stop about leaving it
5857  myStops.front().containerstop->leaveFrom(this);
5858  }
5859  if (myStops.front().parkingarea != nullptr) {
5860  // inform parking area about leaving it
5861  myStops.front().parkingarea->leaveFrom(this);
5862  }
5863  // the current stop is no longer valid
5864  myLane->getEdge().removeWaiting(this);
5865  MSDevice_Vehroutes* vehroutes = static_cast<MSDevice_Vehroutes*>(getDevice(typeid(MSDevice_Vehroutes)));
5866  if (vehroutes != nullptr) {
5867  vehroutes->stopEnded(myStops.front().pars);
5868  }
5869  if (MSStopOut::active()) {
5870  MSStopOut::getInstance()->stopEnded(this, myStops.front().pars, myStops.front().lane->getID());
5871  }
5872  if (myStops.front().collision && MSLane::getCollisionAction() == MSLane::COLLISION_ACTION_WARN) {
5873  myCollisionImmunity = TIME2STEPS(5); // leave the conflict area
5874  }
5875  myStops.pop_front();
5876  // do not count the stopping time towards gridlock time.
5877  // Other outputs use an independent counter and are not affected.
5878  myWaitingTime = 0;
5879  // maybe the next stop is on the same edge; let's rebuild best lanes
5880  updateBestLanes(true);
5881  // continue as wished...
5883  return true;
5884  }
5885  return false;
5886 }
5887 
5888 
5891  return myStops.front();
5892 }
5893 
5894 std::list<MSVehicle::Stop>
5896  return myStops;
5897 }
5898 
5901  if (myInfluencer == nullptr) {
5902  myInfluencer = new Influencer();
5903  }
5904  return *myInfluencer;
5905 }
5906 
5907 
5908 const MSVehicle::Influencer*
5910  return myInfluencer;
5911 }
5912 
5913 
5914 double
5916  if (myInfluencer != nullptr && myInfluencer->getOriginalSpeed() != -1) {
5917  return myInfluencer->getOriginalSpeed();
5918  }
5919  return myState.mySpeed;
5920 }
5921 
5922 
5923 int
5925  if (hasInfluencer()) {
5927  MSNet::getInstance()->getCurrentTimeStep(),
5928  myLane->getEdge(),
5929  getLaneIndex(),
5930  state);
5931  }
5932  return state;
5933 }
5934 
5935 
5936 void
5938  myCachedPosition = xyPos;
5939 }
5940 
5941 
5942 bool
5944  return myInfluencer != nullptr && myInfluencer->isRemoteControlled();
5945 }
5946 
5947 
5948 bool
5950  return myInfluencer != nullptr && myInfluencer->getLastAccessTimeStep() + lookBack >= MSNet::getInstance()->getCurrentTimeStep();
5951 }
5952 
5953 
5954 bool
5955 MSVehicle::keepClear(const MSLink* link) const {
5956  if (link->hasFoes() && link->keepClear() /* && item.myLink->willHaveBlockedFoe()*/) {
5957  const double keepClearTime = getVehicleType().getParameter().getJMParam(SUMO_ATTR_JM_IGNORE_KEEPCLEAR_TIME, -1);
5958  //std::cout << SIMTIME << " veh=" << getID() << " keepClearTime=" << keepClearTime << " accWait=" << getAccumulatedWaitingSeconds() << " keepClear=" << (keepClearTime < 0 || getAccumulatedWaitingSeconds() < keepClearTime) << "\n";
5959  return keepClearTime < 0 || getAccumulatedWaitingSeconds() < keepClearTime;
5960  } else {
5961  return false;
5962  }
5963 }
5964 
5965 
5966 bool
5967 MSVehicle::ignoreRed(const MSLink* link, bool canBrake) const {
5968  if ((myInfluencer != nullptr && !myInfluencer->getEmergencyBrakeRedLight())) {
5969  return true;
5970  }
5971  const double ignoreRedTime = getVehicleType().getParameter().getJMParam(SUMO_ATTR_JM_DRIVE_AFTER_RED_TIME, -1);
5972 #ifdef DEBUG_IGNORE_RED
5973  if (DEBUG_COND) {
5974  std::cout << SIMTIME << " veh=" << getID() << " link=" << link->getViaLaneOrLane()->getID() << " state=" << toString(link->getState()) << "\n";
5975  }
5976 #endif
5977  if (ignoreRedTime < 0) {
5978  const double ignoreYellowTime = getVehicleType().getParameter().getJMParam(SUMO_ATTR_JM_DRIVE_AFTER_YELLOW_TIME, 0);
5979  if (ignoreYellowTime > 0 && link->haveYellow()) {
5980  assert(link->getTLLogic() != 0);
5981  const double yellowDuration = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep() - link->getLastStateChange());
5982  // when activating ignoreYellow behavior, vehicles will drive if they cannot brake
5983  return !canBrake || ignoreYellowTime > yellowDuration;
5984  } else {
5985  return false;
5986  }
5987  } else if (link->haveYellow()) {
5988  // always drive at yellow when ignoring red
5989  return true;
5990  } else if (link->haveRed()) {
5991  assert(link->getTLLogic() != 0);
5992  const double redDuration = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep() - link->getLastStateChange());
5993 #ifdef DEBUG_IGNORE_RED
5994  if (DEBUG_COND) {
5995  std::cout
5996  // << SIMTIME << " veh=" << getID() << " link=" << link->getViaLaneOrLane()->getID()
5997  << " ignoreRedTime=" << ignoreRedTime
5998  << " spentRed=" << redDuration
5999  << " canBrake=" << canBrake << "\n";
6000  }
6001 #endif
6002  // when activating ignoreRed behavior, vehicles will always drive if they cannot brake
6003  return !canBrake || ignoreRedTime > redDuration;
6004  } else {
6005  return false;
6006  }
6007 }
6008 
6009 
6010 bool
6012  // either on an internal lane that was entered via minor link
6013  // or on approach to minor link below visibility distance
6014  if (myLane == nullptr) {
6015  return false;
6016  }
6017  if (myLane->getEdge().isInternal()) {
6018  return !myLane->getIncomingLanes().front().viaLink->havePriority();
6019  } else if (myLFLinkLanes.size() > 0 && myLFLinkLanes.front().myLink != nullptr) {
6020  MSLink* link = myLFLinkLanes.front().myLink;
6021  return !link->havePriority() && myLFLinkLanes.front().myDistance <= link->getFoeVisibilityDistance();
6022  }
6023  return false;
6024 }
6025 
6026 bool
6027 MSVehicle::isLeader(const MSLink* link, const MSVehicle* veh) const {
6028  assert(link->fromInternalLane());
6029  if (veh == nullptr) {
6030  return false;
6031  }
6032  if (!myLane->isInternal() || myLane->getEdge().getToJunction() != link->getJunction()) {
6033  // if this vehicle is not yet on the junction, every vehicle is a leader
6034  return true;
6035  }
6036  const MSLane* foeLane = veh->getLane();
6037  if (foeLane->isInternal()) {
6038  if (foeLane->getEdge().getFromJunction() == link->getJunction()) {
6040  SUMOTime foeET = veh->myJunctionEntryTime;
6041  // check relationship between link and foeLane
6042  if (foeLane->getEdge().getNormalBefore() == link->getInternalLaneBefore()->getEdge().getNormalBefore()) {
6043  // we are entering the junction from the same edge
6045  foeET = veh->myJunctionEntryTimeNeverYield;
6046  } else {
6047  const MSLink* foeLink = foeLane->getIncomingLanes()[0].viaLink;
6048  const MSJunctionLogic* logic = link->getJunction()->getLogic();
6049  assert(logic != nullptr);
6050  const bool response = logic->getResponseFor(link->getIndex()).test(foeLink->getIndex());
6051  const bool response2 = logic->getResponseFor(foeLink->getIndex()).test(link->getIndex());
6052 #ifdef DEBUG_PLAN_MOVE_LEADERINFO
6053  if (DEBUG_COND) {
6054  std::cout << SIMTIME
6055  << " foeLane=" << foeLane->getID()
6056  << " foeLink=" << foeLink->getViaLaneOrLane()->getID()
6057  << " linkIndex=" << link->getIndex()
6058  << " foeLinkIndex=" << foeLink->getIndex()
6059  << " response=" << response
6060  << " response2=" << response2
6061  << "\n";
6062  }
6063 #endif
6064  if (!response) {
6065  // if we have right of way over the foe, entryTime does not matter
6066  foeET = veh->myJunctionConflictEntryTime;
6067  egoET = myJunctionEntryTime;
6068  } else if (response && response2) {
6069  // in a mutual conflict scenario, use entry time to avoid deadlock
6070  foeET = veh->myJunctionEntryTime;
6071  egoET = myJunctionEntryTime;
6072  }
6073  }
6074  if (egoET == foeET) {
6075  // try to use speed as tie braker
6076  if (getSpeed() == veh->getSpeed()) {
6077  // use ID as tie braker
6078 #ifdef DEBUG_PLAN_MOVE_LEADERINFO
6079  if (DEBUG_COND) {
6080  std::cout << SIMTIME << " veh=" << getID() << " equal ET " << egoET << " with foe " << veh->getID()
6081  << " foeIsLeaderByID=" << (getID() < veh->getID()) << "\n";
6082  }
6083 #endif
6084  return getID() < veh->getID();
6085  } else {
6086 #ifdef DEBUG_PLAN_MOVE_LEADERINFO
6087  if (DEBUG_COND) {
6088  std::cout << SIMTIME << " veh=" << getID() << " equal ET " << egoET << " with foe " << veh->getID()
6089  << " foeIsLeaderBySpeed=" << (getSpeed() < veh->getSpeed())
6090  << " v=" << getSpeed() << " foeV=" << veh->getSpeed()
6091  << "\n";
6092  }
6093 #endif
6094  return getSpeed() < veh->getSpeed();
6095  }
6096  } else {
6097  // leader was on the junction first
6098 #ifdef DEBUG_PLAN_MOVE_LEADERINFO
6099  if (DEBUG_COND) {
6100  std::cout << " egoET=" << egoET << " foeET=" << foeET << " isLeader=" << (egoET > foeET) << "\n";
6101  }
6102 #endif
6103  return egoET > foeET;
6104  }
6105  } else {
6106  // vehicle can only be partially on the junction. Must be a leader
6107  return true;
6108  }
6109  } else {
6110  // vehicle can only be partially on the junction. Must be a leader
6111  return true;
6112  }
6113 }
6114 
6115 void
6118  // here starts the vehicle internal part (see loading)
6119  std::vector<std::string> internals;
6120  internals.push_back(toString(myDeparture));
6121  internals.push_back(toString(distance(myRoute->begin(), myCurrEdge)));
6122  internals.push_back(toString(myDepartPos));
6123  internals.push_back(toString(myWaitingTime));
6124  internals.push_back(toString(myLastActionTime));
6125  out.writeAttr(SUMO_ATTR_STATE, internals);
6129  // save stops and parameters
6130  for (std::list<Stop>::const_iterator it = myStops.begin(); it != myStops.end(); ++it) {
6131  it->write(out);
6132  }
6133  myParameter->writeParams(out);
6134  for (MSVehicleDevice* const dev : myDevices) {
6135  dev->saveState(out);
6136  }
6137  out.closeTag();
6138 }
6139 
6140 void
6141 MSVehicle::loadState(const SUMOSAXAttributes& attrs, const SUMOTime offset) {
6142  if (!attrs.hasAttribute(SUMO_ATTR_POSITION)) {
6143  throw ProcessError("Error: Invalid vehicles in state (may be a meso state)!");
6144  }
6145  int routeOffset;
6146  std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
6147  bis >> myDeparture;
6148  bis >> routeOffset;
6149  bis >> myDepartPos;
6150  bis >> myWaitingTime;
6151  bis >> myLastActionTime;
6152  if (hasDeparted()) {
6153  myCurrEdge += routeOffset;
6154  myDeparture -= offset;
6155  }
6159 
6160  // no need to reset myCachedPosition here since state loading happens directly after creation
6161 }
6162 
6163 bool
6165  MSRouteIterator start = myCurrEdge;
6166  const std::string err = "for vehicle '" + getID() + "' at time " + time2string(MSNet::getInstance()->getCurrentTimeStep());
6167  int i = 0;
6168  bool ok = true;
6169  double lastPos = getPositionOnLane();
6170  if (myLane != nullptr && myLane->isInternal()
6171  && myStops.size() > 0 && !myStops.front().lane->isInternal()) {
6172  // start edge is still incoming to the intersection so lastPos
6173  // relative to that edge must be adapted
6174  lastPos += (*myCurrEdge)->getLength();
6175  }
6176  for (const Stop& stop : myStops) {
6177  const double endPos = stop.getEndPos(*this);
6178  const MSEdge* const stopEdge = &stop.lane->getEdge();
6179  const MSRouteIterator it = std::find(start, myRoute->end(), stopEdge);
6180  const std::string prefix = "Stop " + toString(i) + " on edge '" + stopEdge->getID() + "' ";
6181  if (it == myRoute->end()) {
6182  WRITE_ERROR(prefix + "is not found after edge '" + (*start)->getID() + "' (" + toString(start - myCurrEdge) + " after current " + err);
6183  ok = false;
6184  } else {
6185  MSRouteIterator it2;
6186  for (it2 = myRoute->begin(); it2 != myRoute->end(); it2++) {
6187  if (it2 == stop.edge) {
6188  break;
6189  }
6190  }
6191  if (it2 == myRoute->end()) {
6192  WRITE_ERROR(prefix + "used invalid route index " + err);
6193  ok = false;
6194  } else if (it2 < start) {
6195  WRITE_ERROR(prefix + "used invalid (relative) route index " + toString(it2 - myCurrEdge) + " expected after " + toString(start - myCurrEdge) + " " + err);
6196  ok = false;
6197  } else {
6198  if (it != stop.edge && endPos >= lastPos) {
6199  WRITE_WARNING(prefix + "is used in " + toString(stop.edge - myCurrEdge) + " edges but first encounter is in "
6200  + toString(it - myCurrEdge) + " edges " + err);
6201  }
6202  start = stop.edge;
6203  }
6204  }
6205  lastPos = endPos;
6206  i++;
6207  }
6208  return ok;
6209 }
6210 
6211 std::shared_ptr<MSSimpleDriverState>
6213  return myDriverState->getDriverState();
6214 }
6215 
6216 
6217 double
6219  //return MAX2(-myAcceleration, getCarFollowModel().getApparentDecel());
6221 }
6222 
6223 /****************************************************************************/
6224 bool
6226  return (myManoeuvre.configureExitManoeuvre(this));
6227 }
6228 
6229 /* -------------------------------------------------------------------------
6230  * methods of MSVehicle::manoeuvre
6231  * ----------------------------------------------------------------------- */
6232 
6233 MSVehicle::Manoeuvre::Manoeuvre() : myManoeuvreStop(""), myManoeuvreStartTime(0), myManoeuvreCompleteTime(0), myManoeuvreType(MSVehicle::MANOEUVRE_NONE), myManoeuvreAngle(0) {}
6234 
6236  myManoeuvreStop = manoeuvre.myManoeuvreStop;
6237  myManoeuvreStartTime = manoeuvre.myManoeuvreStartTime;
6238  myManoeuvreCompleteTime = manoeuvre.myManoeuvreCompleteTime;
6239  myManoeuvreType = manoeuvre.myManoeuvreType;
6240  myManoeuvreAngle = manoeuvre.myManoeuvreAngle;
6241 }
6242 
6245  myManoeuvreStop = manoeuvre.myManoeuvreStop;
6246  myManoeuvreStartTime = manoeuvre.myManoeuvreStartTime;
6247  myManoeuvreCompleteTime = manoeuvre.myManoeuvreCompleteTime;
6248  myManoeuvreType = manoeuvre.myManoeuvreType;
6249  myManoeuvreAngle = manoeuvre.myManoeuvreAngle;
6250  return *this;
6251 }
6252 
6253 bool
6255  return (myManoeuvreStop != manoeuvre.myManoeuvreStop ||
6256  myManoeuvreStartTime != manoeuvre.myManoeuvreStartTime ||
6257  myManoeuvreCompleteTime != manoeuvre.myManoeuvreCompleteTime ||
6258  myManoeuvreType != manoeuvre.myManoeuvreType ||
6259  myManoeuvreAngle != manoeuvre.myManoeuvreAngle
6260  );
6261 }
6262 
6263 int
6265  return (myManoeuvreAngle);
6266 }
6267 
6270  return (myManoeuvreType);
6271 }
6272 
6275  return (myManoeuvre.getManoeuvreType());
6276 }
6277 
6278 
6279 void
6282 }
6283 
6284 void
6286  myManoeuvreType = mType;
6287 }
6288 
6289 
6290 bool
6292  if (!veh->hasStops()) {
6293  return false; // should never happen - checked before call
6294  }
6295 
6296  const SUMOTime currentTime = MSNet::getInstance()->getCurrentTimeStep();
6297  const Stop& stop = veh->getMyStops().front();
6298 
6299  myManoeuvreVehicleID = veh->getID();
6300  myManoeuvreStop = stop.parkingarea->getID();
6301  myManoeuvreType = MSVehicle::MANOEUVRE_ENTRY;
6302  myManoeuvreAngle = stop.parkingarea->getLastFreeLotAngle();
6303  myManoeuvreStartTime = currentTime;
6304  myManoeuvreCompleteTime = currentTime + veh->myType->getEntryManoeuvreTime(myManoeuvreAngle);
6305 #ifdef DEBUG_STOPS
6306  if (veh->isSelected()) {
6307  std::cout << "ENTRY manoeuvre start: vehicle=" << veh->getID() << " Angle=" << myManoeuvreAngle << " currentTime=" << currentTime <<
6308  " endTime=" << myManoeuvreCompleteTime << " manoeuvre time=" << myManoeuvreCompleteTime - currentTime << " parkArea=" << myManoeuvreStop << std::endl;
6309  }
6310 #endif
6311 
6312  return (true);
6313 }
6314 
6315 bool
6317  // At the moment we only want to set for parking areas
6318  if (!veh->hasStops()) {
6319  return true;
6320  }
6321  if (veh->getNextStop().parkingarea == nullptr) {
6322  return true;
6323  }
6324 
6325  if (myManoeuvreType != MSVehicle::MANOEUVRE_NONE) {
6326  return (false);
6327  }
6328 
6329  const SUMOTime currentTime = MSNet::getInstance()->getCurrentTimeStep();
6330 
6331  myManoeuvreVehicleID = veh->getID();
6332  myManoeuvreStop = veh->getCurrentParkingArea()->getID();
6333  myManoeuvreType = MSVehicle::MANOEUVRE_EXIT;
6334  myManoeuvreStartTime = currentTime;
6335  myManoeuvreCompleteTime = currentTime + veh->myType->getExitManoeuvreTime(myManoeuvreAngle);
6336  if (veh->remainingStopDuration() > 0) {
6337  myManoeuvreCompleteTime += veh->remainingStopDuration();
6338  }
6339 
6340 #ifdef DEBUG_STOPS
6341  if (veh->isSelected()) {
6342  std::cout << "EXIT manoeuvre start: vehicle=" << veh->getID() << " Angle=" << myManoeuvreAngle << " currentTime=" << currentTime
6343  << " endTime=" << myManoeuvreCompleteTime << " manoeuvre time=" << myManoeuvreCompleteTime - currentTime << " parkArea=" << myManoeuvreStop << std::endl;
6344  }
6345 #endif
6346 
6347  return (true);
6348 }
6349 
6350 bool
6352  // At the moment we only want to consider parking areas - need to check because we could be setting up a manoeuvre
6353  if (!veh->hasStops()) {
6354  return (true);
6355  }
6356  Stop* currentStop = &veh->myStops.front();
6357  if (currentStop->parkingarea == nullptr) {
6358  return true;
6359  } else if (currentStop->parkingarea->getID() != myManoeuvreStop || MSVehicle::MANOEUVRE_ENTRY != myManoeuvreType) {
6360  if (configureEntryManoeuvre(veh)) {
6362  return (false);
6363  } else { // cannot configure entry so stop trying
6364  return true;
6365  }
6366  } else if (MSNet::getInstance()->getCurrentTimeStep() < myManoeuvreCompleteTime) {
6367  return false;
6368  } else { // manoeuvre complete
6369  // in case we ended up in a different lot - reset the angle for exit - to allow recompute
6370  myManoeuvreAngle = currentStop->parkingarea->getLastFreeLotAngle();
6371  myManoeuvreType = MSVehicle::MANOEUVRE_NONE;
6372  return true;
6373  }
6374 }
6375 
6376 
6377 bool
6379  if (checkType != myManoeuvreType) {
6380  return true; // we're not manoeuvering / wrong manoeuvre
6381  }
6382 
6383  if (MSNet::getInstance()->getCurrentTimeStep() < myManoeuvreCompleteTime) {
6384  return false;
6385  } else {
6386  return true;
6387  }
6388 }
6389 
6390 
6391 bool
6393  return (MSNet::getInstance()->getCurrentTimeStep() >= myManoeuvreCompleteTime);
6394 }
6395 bool
6397  return (myManoeuvre.manoeuvreIsComplete());
6398 }
6399 
6400 /****************************************************************************/
MSLane::releaseVehicles
virtual void releaseVehicles() const
Allows to use the container for microsimulation again.
Definition: MSLane.h:457
MSVehicleType
The car-following model and parameter.
Definition: MSVehicleType.h:65
MSVehicle::processNextStop
double processNextStop(double currentVelocity)
Processes stops, returns the velocity needed to reach the stop.
Definition: MSVehicle.cpp:1806
SUMOAbstractRouter::compute
virtual bool compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent=false)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
MSStoppingPlace::getLane
const MSLane & getLane() const
Returns the lane this stop is located at.
Definition: MSStoppingPlace.cpp:57
MSVehicle::LC_ALWAYS
@ LC_ALWAYS
Definition: MSVehicle.h:1220
MSVehicle::Influencer::cleanup
static void cleanup()
Static cleanup.
Definition: MSVehicle.cpp:381
MSVehicle::Influencer::myTraCISignals
int myTraCISignals
Definition: MSVehicle.h:1760
MSVehicle::updateBestLanes
void updateBestLanes(bool forceRebuild=false, const MSLane *startLane=0)
computes the best lanes to use in order to continue the route
Definition: MSVehicle.cpp:4698
MSVehicle::Manoeuvre::Manoeuvre
Manoeuvre()
Constructor.
Definition: MSVehicle.cpp:6233
SUMOVehicleParameter::Stop::awaitedPersons
std::set< std::string > awaitedPersons
IDs of persons the vehicle has to wait for until departing.
Definition: SUMOVehicleParameter.h:625
MSVehicle::REQUEST_RIGHT
@ REQUEST_RIGHT
vehicle want's to change to right lane
Definition: MSVehicle.h:224
MSTransportableControl::boardAnyWaiting
bool boardAnyWaiting(MSEdge *edge, SUMOVehicle *vehicle, const SUMOVehicleParameter::Stop &stop, SUMOTime &timeToBoardNextPerson, SUMOTime &stopDuration)
board any applicable persons Boards any people who wait on that edge for the given vehicle and remove...
Definition: MSTransportableControl.cpp:153
MSMoveReminder::NOTIFICATION_LANE_CHANGE
@ NOTIFICATION_LANE_CHANGE
The vehicle changes lanes (micro only)
Definition: MSMoveReminder.h:99
MSDevice_DriverState.h
MSVehicle::getCenterOnEdge
double getCenterOnEdge(const MSLane *lane=0) const
Get the vehicle's lateral position on the edge of the given lane (or its current edge if lane == 0)
Definition: MSVehicle.cpp:5333
MSVehicleType::getEmissionClass
SUMOEmissionClass getEmissionClass() const
Get this vehicle type's emission class.
Definition: MSVehicleType.h:193
MSEdge::isRoundabout
bool isRoundabout() const
Definition: MSEdge.h:640
MSVehicle::getSpeedWithoutTraciInfluence
double getSpeedWithoutTraciInfluence() const
Returns the uninfluenced velocity.
Definition: MSVehicle.cpp:5915
MSDevice_Transportable::getTransportables
const std::vector< MSTransportable * > & getTransportables() const
Returns the list of transportables using this vehicle.
Definition: MSDevice_Transportable.h:134
MSVehicle::collisionStopTime
SUMOTime collisionStopTime() const
Returns the remaining time a vehicle needs to stop due to a collision. A negative value indicates tha...
Definition: MSVehicle.cpp:1774
MSVehicle::VEH_SIGNAL_BLINKER_LEFT
@ VEH_SIGNAL_BLINKER_LEFT
Left blinker lights are switched on.
Definition: MSVehicle.h:1185
MSVehicle::LaneQ::bestLaneOffset
int bestLaneOffset
The (signed) number of lanes to be crossed to get to the lane which allows to continue the drive.
Definition: MSVehicle.h:822
MSLane::getVehiclesSecure
virtual const VehCont & getVehiclesSecure() const
Returns the vehicles container; locks it for microsimulation.
Definition: MSLane.h:427
SPEED2DIST
#define SPEED2DIST(x)
Definition: SUMOTime.h:46
MSVehicle::Stop::busstop
MSStoppingPlace * busstop
(Optional) bus stop if one is assigned to the stop
Definition: MSVehicle.h:928
MSNet::getRouterTT
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const int rngIndex, const MSEdgeVector &prohibited=MSEdgeVector()) const
Definition: MSNet.cpp:968
MSRoute::release
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:100
MSNet::getStoppingPlace
MSStoppingPlace * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Returns the named stopping place of the given category.
Definition: MSNet.cpp:911
ToString.h
ARRIVAL_POS_GIVEN
@ ARRIVAL_POS_GIVEN
The arrival position is given.
Definition: SUMOVehicleParameter.h:234
MSLane::dictionary
static bool dictionary(const std::string &id, MSLane *lane)
Static (sic!) container methods {.
Definition: MSLane.cpp:1866
MSCFModel::brakeGap
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time tau (i....
Definition: MSCFModel.h:312
MSBaseVehicle::getParameter
const SUMOVehicleParameter & getParameter() const
Returns the vehicle's parameter (including departure definition)
Definition: MSBaseVehicle.cpp:144
MSVehicleType::getID
const std::string & getID() const
Returns the name of the vehicle type.
Definition: MSVehicleType.h:93
MSVehicle::getBestLaneOffset
int getBestLaneOffset() const
Definition: MSVehicle.cpp:5087
MSVehicle::getPreviousSpeed
double getPreviousSpeed() const
Returns the vehicle's speed before the previous time step.
Definition: MSVehicle.h:484
MSVehicle::Influencer::getLastAccessTimeStep
SUMOTime getLastAccessTimeStep() const
Definition: MSVehicle.h:1662
STOPPING_PLACE_OFFSET
#define STOPPING_PLACE_OFFSET
Definition: MSVehicle.cpp:110
MSVehicleControl::registerOneWaiting
void registerOneWaiting(const bool isPerson)
increases the count of vehicles waiting for a transport to allow recognition of person / container re...
Definition: MSVehicleControl.h:416
MSBaseVehicle::hasDeparted
bool hasDeparted() const
Returns whether this vehicle has already departed.
Definition: MSBaseVehicle.cpp:379
LINKSTATE_EQUAL
@ LINKSTATE_EQUAL
This is an uncontrolled, right-before-left link.
Definition: SUMOXMLDefinitions.h:1159
MSStoppingPlace
A lane area vehicles can halt at.
Definition: MSStoppingPlace.h:59
SUMOSAXAttributes::hasAttribute
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list.
MSEdge::getSuccessors
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:959
MSCFModel::getMaxAccel
double getMaxAccel() const
Get the vehicle type's maximum acceleration [m/s^2].
Definition: MSCFModel.h:209
MSVehicle::ManoeuvreType
ManoeuvreType
flag identifying which, if any, manoeuvre is in progress
Definition: MSVehicle.h:1352
MSVehicle::haveValidStopEdges
bool haveValidStopEdges() const
check whether all stop.edge MSRouteIterators are valid and in order
Definition: MSVehicle.cpp:6164
MIN2
T MIN2(T a, T b)
Definition: StdDefs.h:73
MSVehicle::hasArrived
bool hasArrived() const
Returns whether this vehicle has already arived (reached the arrivalPosition on its final edge)
Definition: MSVehicle.cpp:1074
MSVehicle::Stop::numExpectedPerson
int numExpectedPerson
The number of still expected persons.
Definition: MSVehicle.h:946
MSVehicle::myAmRegisteredAsWaitingForPerson
bool myAmRegisteredAsWaitingForPerson
Whether this vehicle is registered as waiting for a person (for deadlock-recognition)
Definition: MSVehicle.h:1987
MSEdge::getPersons
const std::set< MSTransportable * > & getPersons() const
Returns this edge's persons set.
Definition: MSEdge.h:176
MSStopOut.h
MSBaseVehicle::getArrivalPos
virtual double getArrivalPos() const
Returns this vehicle's desired arrivalPos for its current route (may change on reroute)
Definition: MSBaseVehicle.h:282
MSParkingArea
A lane area vehicles can halt at.
Definition: MSParkingArea.h:59
MSVehicle::Influencer
Changes the wished vehicle speed / lanes.
Definition: MSVehicle.h:1455
MSCFModel::getMaxDecel
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:217
SUMO_ATTR_JM_IGNORE_KEEPCLEAR_TIME
@ SUMO_ATTR_JM_IGNORE_KEEPCLEAR_TIME
Definition: SUMOXMLDefinitions.h:617
SVC_EMERGENCY
@ SVC_EMERGENCY
public emergency vehicles
Definition: SUMOVehicleClass.h:143
MSVehicle::myFurtherLanes
std::vector< MSLane * > myFurtherLanes
The information into which lanes the vehicle laps into.
Definition: MSVehicle.h:1976
MSVehicle::myStopDist
double myStopDist
distance to the next stop or doubleMax if there is none
Definition: MSVehicle.h:1998
MSAbstractLaneChangeModel::setNoShadowPartialOccupator
void setNoShadowPartialOccupator(MSLane *lane)
Definition: MSAbstractLaneChangeModel.h:515
MSParkingArea::enter
void enter(SUMOVehicle *what, double beg, double end)
Called if a vehicle enters this stop.
Definition: MSParkingArea.cpp:202
MSVehicle::Influencer::influenceSpeed
double influenceSpeed(SUMOTime currentTime, double speed, double vSafe, double vMin, double vMax)
Applies stored velocity information on the speed to use.
Definition: MSVehicle.cpp:469
WRITE_WARNING
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:275
MSNet::hasContainers
bool hasContainers() const
Returns whether containers are simulated.
Definition: MSNet.h:369
DIST2SPEED
#define DIST2SPEED(x)
Definition: SUMOTime.h:48
MSVehicle::Stop::reached
bool reached
Information whether the stop has been reached.
Definition: MSVehicle.h:944
MSVehicle::getMyStops
std::list< Stop > getMyStops()
Definition: MSVehicle.cpp:5895
MSVehicle::getBestLanes
const std::vector< LaneQ > & getBestLanes() const
Returns the description of best lanes to use in order to continue the route.
Definition: MSVehicle.cpp:4692
MSBaseVehicle::getContainerNumber
int getContainerNumber() const
Returns the number of containers.
Definition: MSBaseVehicle.cpp:633
MSVehicle::enterLaneAtMove
bool enterLaneAtMove(MSLane *enteredLane, bool onTeleporting=false)
Update when the vehicle enters a new lane in the move step.
Definition: MSVehicle.cpp:4463
MSNet.h
DEBUG_COND
#define DEBUG_COND
Definition: MSVehicle.cpp:105
SUMO_ATTR_CONTAINER_STOP
@ SUMO_ATTR_CONTAINER_STOP
Definition: SUMOXMLDefinitions.h:770
MSBaseVehicle::getRNGIndex
int getRNGIndex() const
Definition: MSBaseVehicle.cpp:747
MSLane
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
MSVehicle::Manoeuvre::myManoeuvreAngle
int myManoeuvreAngle
Definition: MSVehicle.h:1437
MSVehicle::isStopped
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MSVehicle.cpp:1737
Named
Base class for objects which have an id.
Definition: Named.h:56
SUMOVehicleParameter::arrivalSpeedProcedure
ArrivalSpeedDefinition arrivalSpeedProcedure
Information how the vehicle's end speed shall be chosen.
Definition: SUMOVehicleParameter.h:537
MSVehicle::wasRemoteControlled
bool wasRemoteControlled(SUMOTime lookBack=DELTA_T) const
Returns the information whether the vehicle is fully controlled via TraCI within the lookBack time.
Definition: MSVehicle.cpp:5949
MSLane::isLinkEnd
bool isLinkEnd(MSLinkCont::const_iterator &i) const
Definition: MSLane.cpp:1994
MSEdge::isVaporizing
bool isVaporizing() const
Returns whether vehicles on this edge shall be vaporized.
Definition: MSEdge.h:379
MSVehicle::myCollisionImmunity
SUMOTime myCollisionImmunity
amount of time for which the vehicle is immune from collisions
Definition: MSVehicle.h:2001
MSVehicle::Stop::parkingarea
MSParkingArea * parkingarea
(Optional) parkingArea if one is assigned to the stop
Definition: MSVehicle.h:932
MSVehicle::executeMove
bool executeMove()
Executes planned vehicle movements with regards to right-of-way.
Definition: MSVehicle.cpp:3728
MSEdge::addWaiting
void addWaiting(SUMOVehicle *vehicle) const
Adds a vehicle to the list of waiting vehicles.
Definition: MSEdge.cpp:1106
SUMOSAXAttributes::getString
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
SUMOVehicleParameter::Stop::lane
std::string lane
The lane to stop at.
Definition: SUMOVehicleParameter.h:586
MSVehicleType::isVehicleSpecific
bool isVehicleSpecific() const
Returns whether this type belongs to a single vehicle only (was modified)
Definition: MSVehicleType.h:547
MSVehicleTransfer::remove
void remove(MSVehicle *veh)
Remove a vehicle from this transfer object.
Definition: MSVehicleTransfer.cpp:78
MSVehicle::myLFLinkLanesPrev
DriveItemVector myLFLinkLanesPrev
planned speeds from the previous step for un-registering from junctions after the new container is fi...
Definition: MSVehicle.h:2075
LCA_LEFT
@ LCA_LEFT
Wants go to the left.
Definition: SUMOXMLDefinitions.h:1226
MSVehicle::isOnRoad
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
Definition: MSVehicle.h:582
ARRIVAL_LANE_GIVEN
@ ARRIVAL_LANE_GIVEN
The arrival lane is given.
Definition: SUMOVehicleParameter.h:218
MSVehicle::isRemoteControlled
bool isRemoteControlled() const
Returns the information whether the vehicle is fully controlled via TraCI.
Definition: MSVehicle.cpp:5943
MSVehicleControl::removeVType
void removeVType(const MSVehicleType *vehType)
Definition: MSVehicleControl.cpp:311
MSLane::getLastAnyVehicle
MSVehicle * getLastAnyVehicle() const
returns the last vehicle that is fully or partially on this lane
Definition: MSLane.cpp:2033
MSVehicle::Stop::duration
SUMOTime duration
The stopping duration.
Definition: MSVehicle.h:938
MSStoppingPlace::getEndLanePosition
double getEndLanePosition() const
Returns the end position of this stop.
Definition: MSStoppingPlace.cpp:69
MSDevice_DriverState::getDriverState
std::shared_ptr< MSSimpleDriverState > getDriverState() const
return internal state
Definition: MSDevice_DriverState.h:78
OutputDevice
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:63
MSVehicle::Influencer::mySpeedGainLC
LaneChangeMode mySpeedGainLC
lane changing to travel with higher speed
Definition: MSVehicle.h:1750
MSCFModel::maxNextSpeed
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
Definition: MSCFModel.cpp:238
MSNet::removeVehicleStateListener
void removeVehicleStateListener(VehicleStateListener *listener)
Removes a vehicle states listener.
Definition: MSNet.cpp:885
MSBaseVehicle::myDeparture
SUMOTime myDeparture
The real departure time.
Definition: MSBaseVehicle.h:551
MSVehicle::mySignals
int mySignals
State of things of the vehicle that can be on or off.
Definition: MSVehicle.h:1981
MSVehicle::VEH_SIGNAL_BLINKER_RIGHT
@ VEH_SIGNAL_BLINKER_RIGHT
Right blinker lights are switched on.
Definition: MSVehicle.h:1183
DELTA_T
SUMOTime DELTA_T
Definition: SUMOTime.cpp:36
SUMO_ATTR_UNTIL
@ SUMO_ATTR_UNTIL
Definition: SUMOXMLDefinitions.h:668
MSVehicle::influenceChangeDecision
int influenceChangeDecision(int state)
allow TraCI to influence a lane change decision
Definition: MSVehicle.cpp:5924
MSRoute::end
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:75
MSVehicleType::getGuiShape
SUMOVehicleShape getGuiShape() const
Get this vehicle type's shape.
Definition: MSVehicleType.h:261
MSVehicle::setTentativeLaneAndPosition
void setTentativeLaneAndPosition(MSLane *lane, double pos, double posLat=0)
set tentative lane and position during insertion to ensure that all cfmodels work (some of them requi...
Definition: MSVehicle.cpp:5311
MSVehicle::hasInfluencer
bool hasInfluencer() const
Definition: MSVehicle.h:1777
MSVehicle::REQUEST_HOLD
@ REQUEST_HOLD
vehicle want's to keep the current lane
Definition: MSVehicle.h:226
NUMERICAL_EPS
#define NUMERICAL_EPS
Definition: config.h:148
MSRouteIterator
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:57
SUMOVehicleParserHelper.h
MSVehicle::LC_NEVER
@ LC_NEVER
Definition: MSVehicle.h:1218
MSVehicle::WaitingTimeCollector::passTime
void passTime(SUMOTime dt, bool waiting)
Definition: MSVehicle.cpp:215
MSVehicle::updateOccupancyAndCurrentBestLane
void updateOccupancyAndCurrentBestLane(const MSLane *startLane)
updates LaneQ::nextOccupation and myCurrentLaneInBestLanes
Definition: MSVehicle.cpp:5036
Position::INVALID
static const Position INVALID
used to indicate that a position is valid
Definition: Position.h:284
MSStopOut::getInstance
static MSStopOut * getInstance()
Definition: MSStopOut.h:62
SUMOVehicleParameter::departSpeed
double departSpeed
(optional) The initial speed of the vehicle
Definition: SUMOVehicleParameter.h:506
MSVehicle::getLatOffset
double getLatOffset(const MSLane *lane) const
Get the offset that that must be added to interpret myState.myPosLat for the given lane.
Definition: MSVehicle.cpp:5371
MSVehicle::myLastBestLanesEdge
const MSEdge * myLastBestLanesEdge
Definition: MSVehicle.h:1948
MSVehicle::State::operator!=
bool operator!=(const State &state)
Operator !=.
Definition: MSVehicle.cpp:156
MSVehicle::getBoundingBox
PositionVector getBoundingBox() const
get bounding rectangle
Definition: MSVehicle.cpp:5564
MSLeaderInfo.h
MSDevice_Transportable.h
MSVehicle::LaneQ::length
double length
The overall length which may be driven when using this lane without a lane change.
Definition: MSVehicle.h:814
PollutantsInterface::FUEL
@ FUEL
Definition: PollutantsInterface.h:55
MSVehicle::DriveProcessItem::availableSpace
double availableSpace
Definition: MSVehicle.h:2027
MSNet::getContainerControl
virtual MSTransportableControl & getContainerControl()
Returns the container control.
Definition: MSNet.cpp:818
MSBaseVehicle::myDevices
std::vector< MSVehicleDevice * > myDevices
The devices this vehicle has.
Definition: MSBaseVehicle.h:542
MSNet::informVehicleStateListener
void informVehicleStateListener(const SUMOVehicle *const vehicle, VehicleState to, const std::string &info="")
Informs all added listeners about a vehicle's state change.
Definition: MSNet.cpp:894
MSJunctionLogic.h
MSVehicle::State::myBackPos
double myBackPos
the stored back position
Definition: MSVehicle.h:147
MSNet::VehicleStateListener
Interface for objects listening to vehicle state changes.
Definition: MSNet.h:568
MSVehicle::getBrakeGap
double getBrakeGap() const
get distance for coming to a stop (used for rerouting checks)
Definition: MSVehicle.cpp:2093
MSEdge::isFringe
bool isFringe() const
return whether this edge is at the fringe of the network
Definition: MSEdge.h:674
ACCEL2SPEED
#define ACCEL2SPEED(x)
Definition: SUMOTime.h:52
SUMOVehicleParameter::departPosProcedure
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.
Definition: SUMOVehicleParameter.h:497
MSLane::getLastVehicleInformation
const MSLeaderInfo getLastVehicleInformation(const MSVehicle *ego, double latOffset, double minPos=0, bool allowCached=true) const
Returns the last vehicles on the lane.
Definition: MSLane.cpp:1062
MSVehicle::DriveProcessItem::myLink
MSLink * myLink
Definition: MSVehicle.h:2016
MSVehicle::Manoeuvre::getManoeuvreAngle
int getManoeuvreAngle() const
Accessor for manoeuvre angle.
Definition: MSVehicle.cpp:6264
MSNet
The simulated network and simulation perfomer.
Definition: MSNet.h:91
MSCFModel::getApparentDecel
double getApparentDecel() const
Get the vehicle type's apparent deceleration [m/s^2] (the one regarded by its followers.
Definition: MSCFModel.h:233
MSVehicle::getBackPosition
const Position getBackPosition() const
Definition: MSVehicle.cpp:1484
SUMO_TAG_CONTAINER_STOP
@ SUMO_TAG_CONTAINER_STOP
A container stop.
Definition: SUMOXMLDefinitions.h:105
MSVehicle::Manoeuvre::operator!=
bool operator!=(const Manoeuvre &manoeuvre)
Operator !=.
Definition: MSVehicle.cpp:6254
LINKDIR_PARTRIGHT
@ LINKDIR_PARTRIGHT
The link is a partial right direction.
Definition: SUMOXMLDefinitions.h:1190
MSVehicle::Manoeuvre::operator=
Manoeuvre & operator=(const Manoeuvre &manoeuvre)
Assignment operator.
Definition: MSVehicle.cpp:6244
MSStoppingPlace::getBeginLanePosition
double getBeginLanePosition() const
Returns the begin position of this stop.
Definition: MSStoppingPlace.cpp:63
MSVehicle::Influencer::myTraciLaneChangePriority
TraciLaneChangePriority myTraciLaneChangePriority
flags for determining the priority of traci lane change requests
Definition: MSVehicle.h:1757
MSCFModel::getMinimalArrivalTime
SUMOTime getMinimalArrivalTime(double dist, double currentSpeed, double arrivalSpeed) const
Computes the minimal time needed to cover a distance given the desired speed at arrival.
Definition: MSCFModel.cpp:375
JUNCTION_BLOCKAGE_TIME
#define JUNCTION_BLOCKAGE_TIME
Definition: MSVehicle.cpp:114
SPEED2ACCEL
#define SPEED2ACCEL(x)
Definition: SUMOTime.h:54
SUMOVehicleParameter::Stop::busstop
std::string busstop
(Optional) bus stop if one is assigned to the stop
Definition: SUMOVehicleParameter.h:589
STOP_UNTIL_SET
const int STOP_UNTIL_SET
Definition: SUMOVehicleParameter.h:77
MSVehicle::LCP_ALWAYS
@ LCP_ALWAYS
Definition: MSVehicle.h:1226
MSVehicle::Influencer::setLaneTimeLine
void setLaneTimeLine(const std::vector< std::pair< SUMOTime, int > > &laneTimeLine)
Sets a new lane timeline.
Definition: MSVehicle.cpp:407
SUMOVehicleParameter::Stop::parametersSet
int parametersSet
Information for the output which parameter were set.
Definition: SUMOVehicleParameter.h:652
MSVehicle::addTraciStopAtStoppingPlace
bool addTraciStopAtStoppingPlace(const std::string &stopId, const SUMOTime duration, const SUMOTime until, const bool parking, const bool triggered, const bool containerTriggered, const SumoXMLTag stoppingPlaceType, std::string &errorMsg)
Definition: MSVehicle.cpp:5759
MSVehicle::isParking
bool isParking() const
Returns whether the vehicle is parking.
Definition: MSVehicle.cpp:1780
SUMO_ATTR_JM_DRIVE_AFTER_YELLOW_TIME
@ SUMO_ATTR_JM_DRIVE_AFTER_YELLOW_TIME
Definition: SUMOXMLDefinitions.h:614
MSVehicle::getBackPositionOnLane
double getBackPositionOnLane() const
Get the vehicle's position relative to its current lane.
Definition: MSVehicle.h:421
MSLane::getRightSideOnEdge
double getRightSideOnEdge() const
Definition: MSLane.h:1067
MSNet::warnOnce
bool warnOnce(const std::string &typeAndID)
return whether a warning regarding the given object shall be issued
Definition: MSNet.cpp:1093
MSBaseVehicle::getLength
double getLength() const
Returns the vehicle's length.
Definition: MSBaseVehicle.h:410
DEPART_POS_DEFAULT
@ DEPART_POS_DEFAULT
No information given; use default.
Definition: SUMOVehicleParameter.h:142
MSLane::succLinkSec
static MSLinkCont::const_iterator succLinkSec(const SUMOVehicle &veh, int nRouteSuccs, const MSLane &succLinkSource, const std::vector< MSLane * > &conts)
Definition: MSLane.cpp:2061
FileHelpers.h
MSRoute::getLastEdge
const MSEdge * getLastEdge() const
returns the destination edge
Definition: MSRoute.cpp:87
MSBaseVehicle::getDeparture
SUMOTime getDeparture() const
Returns this vehicle's real departure time.
Definition: MSBaseVehicle.h:261
MSVehicle::State
Container that holds the vehicles driving state (position+speed).
Definition: MSVehicle.h:89
MSVehicle::getActionStepLength
SUMOTime getActionStepLength() const
Returns the vehicle's action step length in millisecs, i.e. the interval between two action points.
Definition: MSVehicle.h:504
MSVehicle::stopsAt
bool stopsAt(MSStoppingPlace *stop) const
Returns whether the vehicle stops at the given stopping place.
Definition: MSVehicle.cpp:2067
MSVehicle::addPerson
void addPerson(MSTransportable *person)
Adds a passenger.
Definition: MSVehicle.cpp:5219
MSVehicle::LaneQ
A structure representing the best lanes for continuing the current route starting at 'lane'.
Definition: MSVehicle.h:810
MSVehicle::REQUEST_LEFT
@ REQUEST_LEFT
vehicle want's to change to left lane
Definition: MSVehicle.h:222
MSVehicle::Influencer::init
static void init()
Static initalization.
Definition: MSVehicle.cpp:376
SUMOTime
long long int SUMOTime
Definition: SUMOTime.h:34
SUMOVehicle
Representation of a vehicle.
Definition: SUMOVehicle.h:60
MSLane::VehCont
std::vector< MSVehicle * > VehCont
Container for vehicles.
Definition: MSLane.h:92
MSCFModel::getMinimalArrivalSpeed
double getMinimalArrivalSpeed(double dist, double currentSpeed) const
Computes the minimal possible arrival speed after covering a given distance.
Definition: MSCFModel.cpp:476
GeomHelper::naviDegree
static double naviDegree(const double angle)
Definition: GeomHelper.cpp:193
MSBaseVehicle::myRoute
const MSRoute * myRoute
This vehicle's route.
Definition: MSBaseVehicle.h:515
MSBaseVehicle::getRoute
const MSRoute & getRoute() const
Returns the current route.
Definition: MSBaseVehicle.h:115
MSVehicle::resumeFromStopping
bool resumeFromStopping()
Definition: MSVehicle.cpp:5839
PositionVector::scaleRelative
void scaleRelative(double factor)
enlarges/shrinks the polygon by a factor based at the centroid
Definition: PositionVector.cpp:456
MSVehicle::State::mySpeed
double mySpeed
the stored speed (should be >=0 at any time)
Definition: MSVehicle.h:139
PositionVector::slopeDegreeAtOffset
double slopeDegreeAtOffset(double pos) const
Returns the slope at the given length.
Definition: PositionVector.cpp:325
MSVehicle::State::State
State(double pos, double speed, double posLat, double backPos)
Constructor.
Definition: MSVehicle.cpp:166
ConstMSEdgeVector
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:75
MSVehicle::Manoeuvre::myManoeuvreType
ManoeuvreType myManoeuvreType
Manoeuvre type - currently entry, exit or none.
Definition: MSVehicle.h:1434
MSVehicle::State::speed
double speed() const
Speed of this state.
Definition: MSVehicle.h:114
MSVehicle::keepStopping
bool keepStopping(bool afterProcessing=false) const
Returns whether the vehicle is stopped and must continue to do so.
Definition: MSVehicle.cpp:1753
MSBaseVehicle::replaceParameter
void replaceParameter(const SUMOVehicleParameter *newParameter)
replace the vehicle parameter (deleting the old one)
Definition: MSBaseVehicle.cpp:159
MSVehicle::updateActionOffset
void updateActionOffset(const SUMOTime oldActionStepLength, const SUMOTime newActionStepLength)
Process an updated action step length value (only affects the vehicle's action offset,...
Definition: MSVehicle.cpp:2127
MSVehicle::Influencer::activateGapController
void activateGapController(double originalTau, double newTimeHeadway, double newSpaceHeadway, double duration, double changeRate, double maxDecel, MSVehicle *refVeh=nullptr)
Activates the gap control with the given parameters,.
Definition: MSVehicle.cpp:392
MSVehicle::nextLinkPriority
static int nextLinkPriority(const std::vector< MSLane * > &conts)
get a numerical value for the priority of the upcoming link
Definition: MSVehicle.cpp:5020
LCA_SPEEDGAIN
@ LCA_SPEEDGAIN
The action is due to the wish to be faster (tactical lc)
Definition: SUMOXMLDefinitions.h:1234
MSVehicle::Influencer::myOriginalSpeed
double myOriginalSpeed
The velocity before influence.
Definition: MSVehicle.h:1711
MSVehicle::Influencer::adaptLaneTimeLine
void adaptLaneTimeLine(int indexShift)
Adapts lane timeline when moving to a new lane and the lane index changes.
Definition: MSVehicle.cpp:413
MSBaseVehicle::myArrivalLane
int myArrivalLane
The destination lane where the vehicle stops.
Definition: MSBaseVehicle.h:560
MSVehicle::myWaitingTimeCollector
WaitingTimeCollector myWaitingTimeCollector
Definition: MSVehicle.h:1924
MSVehicle::Influencer::GapControlVehStateListener::vehicleStateChanged
void vehicleStateChanged(const SUMOVehicle *const vehicle, MSNet::VehicleState to, const std::string &info="")
Called if a vehicle changes its state.
Definition: MSVehicle.cpp:252
MSVehicle::getTimeGapOnLane
double getTimeGapOnLane() const
Returns the time gap in seconds to the leader of the vehicle on the same lane.
Definition: MSVehicle.cpp:5160
MSAbstractLaneChangeModel::resetChanged
void resetChanged()
reset the flag whether a vehicle already moved to false
Definition: MSAbstractLaneChangeModel.h:467
SUMOVehicleParameter::Stop::line
std::string line
the new line id of the trip within a cyclical public transport route
Definition: SUMOVehicleParameter.h:640
MSVehicle::addStop
bool addStop(const SUMOVehicleParameter::Stop &stopPar, std::string &errorMsg, SUMOTime untilOffset=0, bool collision=false, MSRouteIterator *searchStart=0)
Adds a stop.
Definition: MSVehicle.cpp:1513
LCA_URGENT
@ LCA_URGENT
The action is urgent (to be defined by lc-model)
Definition: SUMOXMLDefinitions.h:1240
MSVehicle::isStoppedOnLane
bool isStoppedOnLane() const
Definition: MSVehicle.cpp:1748
MSVehicle::Stop::getDescription
std::string getDescription() const
get a short description for showing in the gui
Definition: MSVehicle.cpp:929
MSNet::hasPersons
bool hasPersons() const
Returns whether persons are simulated.
Definition: MSNet.h:353
SUMO_const_laneWidth
const double SUMO_const_laneWidth
Definition: StdDefs.h:49
MSGlobals::gUseMesoSim
static bool gUseMesoSim
Definition: MSGlobals.h:90
MSVehicle::onRemovalFromNet
void onRemovalFromNet(const MSMoveReminder::Notification reason)
Called when the vehicle is removed from the network.
Definition: MSVehicle.cpp:1060
MSStoppingPlace::removeTransportable
void removeTransportable(MSTransportable *p)
Removes a transportable from this stop.
Definition: MSStoppingPlace.cpp:198
MSVehicle::Influencer::considerSafeVelocity
bool considerSafeVelocity() const
Returns whether safe velocities shall be considered.
Definition: MSVehicle.h:1634
MSVehicle::Stop::collision
bool collision
Whether this stop was triggered by a collision.
Definition: MSVehicle.h:954
RAD2DEG
#define RAD2DEG(x)
Definition: GeomHelper.h:38
MSRoute::getEdges
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:120
SUMO_ATTR_SPEED
@ SUMO_ATTR_SPEED
Definition: SUMOXMLDefinitions.h:384
MSVehicle::DriveItemVector
std::vector< DriveProcessItem > DriveItemVector
Container for used Links/visited Lanes during planMove() and executeMove.
Definition: MSVehicle.h:2069
MSChargingStation.h
MSVehicle::enterLaneAtInsertion
void enterLaneAtInsertion(MSLane *enteredLane, double pos, double speed, double posLat, MSMoveReminder::Notification notification)
Update when the vehicle enters a new lane in the emit step.
Definition: MSVehicle.cpp:4567
MSVehicle::setManoeuvreType
void setManoeuvreType(const MSVehicle::ManoeuvreType mType)
accessor function to myManoeuvre equivalent
Definition: MSVehicle.cpp:6280
MSVehicle::Influencer::myStrategicLC
LaneChangeMode myStrategicLC
lane changing which is necessary to follow the current route
Definition: MSVehicle.h:1746
SUMOVehicleParameter::Stop::parkingarea
std::string parkingarea
(Optional) parking area if one is assigned to the stop
Definition: SUMOVehicleParameter.h:595
MSVehicle::Influencer::myConsiderMaxAcceleration
bool myConsiderMaxAcceleration
Whether the maximum acceleration shall be regarded.
Definition: MSVehicle.h:1723
SUMOVehicleParameter
Structure representing possible vehicle parameter.
Definition: SUMOVehicleParameter.h:297
MSEdge.h
MSVehicle::State::myPreviousSpeed
double myPreviousSpeed
the speed at the begin of the previous time step
Definition: MSVehicle.h:150
MSVehicle::myHaveToWaitOnNextLink
bool myHaveToWaitOnNextLink
Definition: MSVehicle.h:1992
SUMO_ATTR_LANE
@ SUMO_ATTR_LANE
Definition: SUMOXMLDefinitions.h:637
MSVehicle::getHarmonoise_NoiseEmissions
double getHarmonoise_NoiseEmissions() const
Returns noise emissions of the current state.
Definition: MSVehicle.cpp:5213
DEBUG_COND2
#define DEBUG_COND2(obj)
Definition: MSVehicle.cpp:107
LinkDirection
LinkDirection
The different directions a link between two lanes may take (or a stream between two edges)....
Definition: SUMOXMLDefinitions.h:1176
MSTransportable
Definition: MSTransportable.h:58
SUMOSAXAttributes::getFloat
virtual double getFloat(int id) const =0
Returns the double-value of the named (by its enum-value) attribute.
MSVehicle::Influencer::myConsiderSafeVelocity
bool myConsiderSafeVelocity
Whether the safe velocity shall be regarded.
Definition: MSVehicle.h:1720
SUMO_ATTR_ENDPOS
@ SUMO_ATTR_ENDPOS
Definition: SUMOXMLDefinitions.h:798
MSVehicle::Manoeuvre
Container for manouevering time associated with stopping.
Definition: MSVehicle.h:1379
MSVehicle::Influencer::myRoutingMode
int myRoutingMode
routing mode (see TraCIConstants.h)
Definition: MSVehicle.h:1763
MSVehicle::myLFLinkLanes
DriveItemVector myLFLinkLanes
container for the planned speeds in the current step
Definition: MSVehicle.h:2072
MSLane::getCollisionAction
static CollisionAction getCollisionAction()
Definition: MSLane.h:1201
PositionVector
A list of positions.
Definition: PositionVector.h:45
MSNet::VEHICLE_STATE_ARRIVED
@ VEHICLE_STATE_ARRIVED
The vehicle arrived at his destination (is deleted)
Definition: MSNet.h:545
MSMoveReminder::NOTIFICATION_TELEPORT_ARRIVED
@ NOTIFICATION_TELEPORT_ARRIVED
The vehicle was teleported out of the net.
Definition: MSMoveReminder.h:111
MSRoutingEngine::getRouterTT
static SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const int rngIndex, const MSEdgeVector &prohibited=MSEdgeVector())
return the router instance
Definition: MSRoutingEngine.cpp:307
MSVehicle::getNextStop
Stop & getNextStop()
Definition: MSVehicle.cpp:5890
MSEdge::getLength
double getLength() const
return the length of the edge
Definition: MSEdge.h:589
MSLane::getBidiLane
MSLane * getBidiLane() const
retrieve bidirectional lane or nullptr
Definition: MSLane.cpp:3706
MSLeaderInfo::addLeader
virtual int addLeader(const MSVehicle *veh, bool beyond, double latOffset=0)
Definition: MSLeaderInfo.cpp:62
MSCFModel::finalizeSpeed
virtual double finalizeSpeed(MSVehicle *const veh, double vPos) const
Applies interaction with stops and lane changing model influences. Called at most once per simulation...
Definition: MSCFModel.cpp:164
MSVehicle::getSafeFollowSpeed
double getSafeFollowSpeed(const std::pair< const MSVehicle *, double > leaderInfo, const double seen, const MSLane *const lane, double distToCrossing) const
compute safe speed for following the given leader
Definition: MSVehicle.cpp:2959
LINKDIR_NODIR
@ LINKDIR_NODIR
The link has no direction (is a dead end link)
Definition: SUMOXMLDefinitions.h:1192
SUMOVehicleParameter::Stop::triggered
bool triggered
whether an arriving person lets the vehicle continue
Definition: SUMOVehicleParameter.h:616
MSVehicle::getCarFollowModel
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
Definition: MSVehicle.h:893
MSVehicle::myNextTurn
std::pair< double, LinkDirection > myNextTurn
the upcoming turn for the vehicle
Definition: MSVehicle.h:1973
MSNet::VEHICLE_STATE_NEWROUTE
@ VEHICLE_STATE_NEWROUTE
The vehicle got a new route.
Definition: MSNet.h:547
MSVehicle::getBackLane
const MSLane * getBackLane() const
Definition: MSVehicle.cpp:3976
MSVehicle::getSlope
double getSlope() const
Returns the slope of the road at vehicle's position.
Definition: MSVehicle.cpp:1258
MSDevice_DriverState
The ToC Device controls transition of control between automated and manual driving.
Definition: MSDevice_DriverState.h:54
MSVehicle::Signalling
Signalling
Some boolean values which describe the state of some vehicle parts.
Definition: MSVehicle.h:1179
MSRoute
Definition: MSRoute.h:66
MSCFModel::setHeadwayTime
virtual void setHeadwayTime(double headwayTime)
Sets a new value for desired headway [s].
Definition: MSCFModel.h:507
MSVehicle::Manoeuvre::manoeuvreIsComplete
bool manoeuvreIsComplete(const ManoeuvreType checkType) const
Check if specific manoeuver is ongoing and whether the completion time is beyond currentTime.
Definition: MSVehicle.cpp:6378
MSVehicle::Influencer::myCooperativeLC
LaneChangeMode myCooperativeLC
lane changing with the intent to help other vehicles
Definition: MSVehicle.h:1748
MSVehicle::myFurtherLanesPosLat
std::vector< double > myFurtherLanesPosLat
lateral positions on further lanes
Definition: MSVehicle.h:1978
SumoXMLTag
SumoXMLTag
Numbers representing SUMO-XML - element names.
Definition: SUMOXMLDefinitions.h:41
MSTransportableControl::loadAnyWaiting
bool loadAnyWaiting(MSEdge *edge, SUMOVehicle *vehicle, const SUMOVehicleParameter::Stop &stop, SUMOTime &timeToLoadNextContainer, SUMOTime &stopDuration)
load any applicable containers Loads any container that is waiting on that edge for the given vehicle...
Definition: MSTransportableControl.cpp:198
STOP_START_SET
const int STOP_START_SET
Definition: SUMOVehicleParameter.h:74
MSAbstractLaneChangeModel::updateTargetLane
MSLane * updateTargetLane()
Definition: MSAbstractLaneChangeModel.cpp:592
MSVehicle::Influencer::getEmergencyBrakeRedLight
bool getEmergencyBrakeRedLight() const
Returns whether red lights shall be a reason to brake.
Definition: MSVehicle.h:1628
MSEdgeWeightsStorage
A storage for edge travel times and efforts.
Definition: MSEdgeWeightsStorage.h:43
MSAbstractLaneChangeModel::isChangingLanes
bool isChangingLanes() const
return true if the vehicle currently performs a lane change maneuver
Definition: MSAbstractLaneChangeModel.h:441
MSVehicle::planMoveInternal
void planMoveInternal(const SUMOTime t, MSLeaderInfo ahead, DriveItemVector &lfLinks, double &myStopDist, std::pair< double, LinkDirection > &myNextTurn) const
Definition: MSVehicle.cpp:2213
MSBaseVehicle::getMaxSpeed
double getMaxSpeed() const
Returns the maximum speed.
Definition: MSBaseVehicle.cpp:165
SUMO_const_haltingSpeed
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:60
MSBaseVehicle::isSelected
virtual bool isSelected() const
whether this vehicle is selected in the GUI
Definition: MSBaseVehicle.h:479
MSGlobals::gEmergencyDecelWarningThreshold
static double gEmergencyDecelWarningThreshold
treshold for warning about strong deceleration
Definition: MSGlobals.h:129
MSLane::getIncomingLanes
const std::vector< IncomingLaneInfo > & getIncomingLanes() const
Definition: MSLane.h:818
MSNet::VEHICLE_STATE_EMERGENCYSTOP
@ VEHICLE_STATE_EMERGENCYSTOP
The vehicle had to brake harder than permitted.
Definition: MSNet.h:559
MSVehicle::removeApproachingInformation
void removeApproachingInformation(const DriveItemVector &lfLinks) const
unregister approach from all upcoming links
Definition: MSVehicle.cpp:5499
Parameterised::writeParams
void writeParams(OutputDevice &device) const
write Params in the given outputdevice
Definition: Parameterised.cpp:154
MSBaseVehicle::calculateArrivalParams
void calculateArrivalParams()
(Re-)Calculates the arrival position and lane from the vehicle parameters
Definition: MSBaseVehicle.cpp:512
MSGlobals::gLateralResolution
static double gLateralResolution
Definition: MSGlobals.h:84
MSVehicle.h
SVS_PASSENGER_SEDAN
@ SVS_PASSENGER_SEDAN
render as a sedan passenger vehicle ("Stufenheck")
Definition: SUMOVehicleClass.h:64
MSMoveReminder::NOTIFICATION_VAPORIZED
@ NOTIFICATION_VAPORIZED
The vehicle got vaporized.
Definition: MSMoveReminder.h:109
OutputDevice::closeTag
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
Definition: OutputDevice.cpp:253
PollutantsInterface::CO
@ CO
Definition: PollutantsInterface.h:55
MSVehicle::Stop::timeToBoardNextPerson
SUMOTime timeToBoardNextPerson
The time at which the vehicle is able to board another person.
Definition: MSVehicle.h:950
MSVehicle::Influencer::getOriginalSpeed
double getOriginalSpeed() const
Returns the originally longitudinal speed to use.
Definition: MSVehicle.cpp:648
MSVehicleType.h
MSBaseVehicle::myParameter
const SUMOVehicleParameter * myParameter
This vehicle's parameter.
Definition: MSBaseVehicle.h:512
HelpersHarmonoise.h
MSBaseVehicle::myArrivalPos
double myArrivalPos
The position on the destination lane where the vehicle stops.
Definition: MSBaseVehicle.h:557
MSMoveReminder::NOTIFICATION_PARKING_REROUTE
@ NOTIFICATION_PARKING_REROUTE
The vehicle needs another parking area.
Definition: MSMoveReminder.h:113
INVALID
#define INVALID
Definition: MSDevice_SSM.cpp:70
MSVehicleTransfer::getInstance
static MSVehicleTransfer * getInstance()
Returns the instance of this object.
Definition: MSVehicleTransfer.cpp:185
MSVehicle::getLateralPositionOnLane
double getLateralPositionOnLane() const
Get the vehicle's lateral position on the lane.
Definition: MSVehicle.h:429
MSLane::getVehicleNumber
int getVehicleNumber() const
Returns the number of vehicles on this lane (for which this lane is responsible)
Definition: MSLane.h:400
MSVehicle::adaptLaneEntering2MoveReminder
void adaptLaneEntering2MoveReminder(const MSLane &enteredLane)
Adapts the vehicle's entering of a new lane.
Definition: MSVehicle.cpp:1236
MSVehicle::REQUEST_NONE
@ REQUEST_NONE
vehicle doesn't want to change
Definition: MSVehicle.h:220
MSBaseVehicle::getEdge
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
Definition: MSBaseVehicle.cpp:181
MSVehicle::saveState
void saveState(OutputDevice &out)
Saves the states of a vehicle.
Definition: MSVehicle.cpp:6116
MSVehicle::stopsAtEdge
bool stopsAtEdge(const MSEdge *edge) const
Returns whether the vehicle stops at the given edge.
Definition: MSVehicle.cpp:2083
MSVehicle::removePassedDriveItems
void removePassedDriveItems()
Erase passed drive items from myLFLinkLanes (and unregister approaching information for corresponding...
Definition: MSVehicle.cpp:3290
LCA_OVERLAPPING
@ LCA_OVERLAPPING
The vehicle is blocked being overlapping.
Definition: SUMOXMLDefinitions.h:1256
LINKDIR_RIGHT
@ LINKDIR_RIGHT
The link is a (hard) right direction.
Definition: SUMOXMLDefinitions.h:1186
MSVehicle::planMove
void planMove(const SUMOTime t, const MSLeaderInfo &ahead, const double lengthsInFront)
Compute safe velocities for the upcoming lanes based on positions and speeds from the last time step....
Definition: MSVehicle.cpp:2146
MAX2
T MAX2(T a, T b)
Definition: StdDefs.h:79
MSEdge::isInternal
bool isInternal() const
return whether this edge is an internal edge
Definition: MSEdge.h:235
MSVehicle::LaneChangeMode
LaneChangeMode
modes for resolving conflicts between external control (traci) and vehicle control over lane changing...
Definition: MSVehicle.h:1217
MSEdge::getWidth
double getWidth() const
Returns the edges's width (sum over all lanes)
Definition: MSEdge.h:560
MSTrafficLightLogic.h
MSVehicle::Stop::write
void write(OutputDevice &dev) const
Write the current stop configuration (used for state saving)
Definition: MSVehicle.cpp:945
MSAbstractLaneChangeModel::removeShadowApproachingInformation
void removeShadowApproachingInformation() const
Definition: MSAbstractLaneChangeModel.cpp:799
MSVehicle::switchOffSignal
void switchOffSignal(int signal)
Switches the given signal off.
Definition: MSVehicle.h:1244
MSVehicle::fixPosition
void fixPosition()
repair errors in vehicle position after changing between internal edges
Definition: MSVehicle.cpp:5105
MSVehicle::switchOnSignal
void switchOnSignal(int signal)
Switches the given signal on.
Definition: MSVehicle.h:1236
MSVehicle::getPosition
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
Definition: MSVehicle.cpp:1269
MSLeaderInfo
Definition: MSLeaderInfo.h:49
SUMO_TAG_PARKING_ZONE_REROUTE
@ SUMO_TAG_PARKING_ZONE_REROUTE
entry for an alternative parking zone
Definition: SUMOXMLDefinitions.h:198
MSLane::getBruttoVehLenSum
double getBruttoVehLenSum() const
Returns the sum of lengths of vehicles, including their minGaps, which were on the lane during the la...
Definition: MSLane.h:1004
MSVehicle::WaitingTimeCollector::getWaitingIntervals
const waitingIntervalList & getWaitingIntervals() const
Definition: MSVehicle.h:197
BinaryInputDevice.h
MSVehicleControl::registerEmergencyStop
void registerEmergencyStop()
register emergency stop
Definition: MSVehicleControl.h:455
LINKDIR_TURN
@ LINKDIR_TURN
The link is a 180 degree turn.
Definition: SUMOXMLDefinitions.h:1180
MSVehicle::addContainer
void addContainer(MSTransportable *container)
Adds a container.
Definition: MSVehicle.cpp:5227
MSVehicle::Influencer::getSpeedMode
int getSpeedMode() const
return the current speed mode
Definition: MSVehicle.cpp:426
OutputDevice::writeAttr
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:255
SUMOVehicleParserHelper::processActionStepLength
static SUMOTime processActionStepLength(double given)
Checks and converts given value for the action step length from seconds to miliseconds assuring it be...
Definition: SUMOVehicleParserHelper.cpp:1456
MSEdgeControl::checkCollisionForInactive
void checkCollisionForInactive(MSLane *l)
trigger collision checking for inactive lane
Definition: MSEdgeControl.cpp:318
MSEdge::getFromJunction
const MSJunction * getFromJunction() const
Definition: MSEdge.h:359
MSLeaderInfo::getSubLanes
void getSubLanes(const MSVehicle *veh, double latOffset, int &rightmost, int &leftmost) const
Definition: MSLeaderInfo.cpp:105
LinkState
LinkState
The right-of-way state of a link between two lanes used when constructing a NBTrafficLightLogic,...
Definition: SUMOXMLDefinitions.h:1137
MSVehicle::Manoeuvre::myManoeuvreStop
std::string myManoeuvreStop
The name of the stop associated with the Manoeuvre - for debug output.
Definition: MSVehicle.h:1425
MSMoveReminder.h
MSJunctionLogic
Definition: MSJunctionLogic.h:38
MSVehicle::leaveLane
void leaveLane(const MSMoveReminder::Notification reason, const MSLane *approachedLane=0)
Update of members if vehicle leaves a new lane in the lane change step or at arrival.
Definition: MSVehicle.cpp:4627
MSVehicle::getPMxEmissions
double getPMxEmissions() const
Returns PMx emission of the current state.
Definition: MSVehicle.cpp:5195
RandHelper::rand
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
Definition: RandHelper.h:53
MSBaseVehicle::saveState
virtual void saveState(OutputDevice &out)
Saves the (common) state of a vehicle.
Definition: MSBaseVehicle.cpp:575
MSCFModel::freeSpeed
virtual double freeSpeed(const MSVehicle *const veh, double speed, double seen, double maxSpeed, const bool onInsertion=false) const
Computes the vehicle's safe speed without a leader.
Definition: MSCFModel.cpp:267
LINKDIR_STRAIGHT
@ LINKDIR_STRAIGHT
The link is a straight direction.
Definition: SUMOXMLDefinitions.h:1178
MSVehicle::myAmOnNet
bool myAmOnNet
Whether the vehicle is on the network (not parking, teleported, vaporized, or arrived)
Definition: MSVehicle.h:1984
SIMTIME
#define SIMTIME
Definition: SUMOTime.h:63
MSVehicle::setBlinkerInformation
void setBlinkerInformation()
sets the blue flashing light for emergency vehicles
Definition: MSVehicle.cpp:5236
MSBaseVehicle::myPersonDevice
MSDevice_Transportable * myPersonDevice
The passengers this vehicle may have.
Definition: MSBaseVehicle.h:545
MSVehicle::getCurrentApparentDecel
double getCurrentApparentDecel() const
get apparent deceleration based on vType parameters and current acceleration
Definition: MSVehicle.cpp:6218
MSVehicle::Influencer::myRightDriveLC
LaneChangeMode myRightDriveLC
changing to the rightmost lane
Definition: MSVehicle.h:1752
MSVehicle::Influencer::mySpeedAdaptationStarted
bool mySpeedAdaptationStarted
Whether influencing the speed has already started.
Definition: MSVehicle.h:1717
SUMOVehicleParameter::Stop::tripId
std::string tripId
id of the trip within a cyclical public transport route
Definition: SUMOVehicleParameter.h:637
MSVehicle::getSpaceTillLastStanding
double getSpaceTillLastStanding(const MSLane *l, bool &foundStopped) const
Definition: MSVehicle.cpp:4152
MSNet::VEHICLE_STATE_STARTING_PARKING
@ VEHICLE_STATE_STARTING_PARKING
The vehicles starts to park.
Definition: MSNet.h:549
MSVehicle::Influencer::implicitSpeedRemote
double implicitSpeedRemote(const MSVehicle *veh, double oldSpeed)
return the speed that is implicit in the new remote position
Definition: MSVehicle.cpp:853
MSLane::COLLISION_ACTION_WARN
@ COLLISION_ACTION_WARN
Definition: MSLane.h:183
PersonDist
std::pair< const MSPerson *, double > PersonDist
Definition: MSPModel.h:40
MSVehicle::manoeuvreIsComplete
bool manoeuvreIsComplete() const
accessor function to myManoeuvre equivalent
Definition: MSVehicle.cpp:6396
LCA_STRATEGIC
@ LCA_STRATEGIC
The action is needed to follow the route (navigational lc)
Definition: SUMOXMLDefinitions.h:1230
MSVehicle::myEmptyLaneVector
static std::vector< MSLane * > myEmptyLaneVector
Definition: MSVehicle.h:1963
HelpersHarmonoise::computeNoise
static double computeNoise(SUMOEmissionClass c, double v, double a)
Returns the noise produced by the a vehicle of the given type at the given speed.
Definition: HelpersHarmonoise.cpp:96
MSVehicle::getPositionOnLane
double getPositionOnLane() const
Get the vehicle's position along the lane.
Definition: MSVehicle.h:392
MSLeaderInfo::clear
virtual void clear()
discard all information
Definition: MSLeaderInfo.cpp:94
MSVehicle::getLeader
std::pair< const MSVehicle *const, double > getLeader(double dist=0) const
Returns the leader of the vehicle looking for a fixed distance.
Definition: MSVehicle.cpp:5130
SUMO_ATTR_STARTPOS
@ SUMO_ATTR_STARTPOS
Definition: SUMOXMLDefinitions.h:797
MSVehicle::getDriverState
std::shared_ptr< MSSimpleDriverState > getDriverState() const
Returns the vehicle driver's state.
Definition: MSVehicle.cpp:6212
SUMO_TAG_CHARGING_STATION
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
Definition: SUMOXMLDefinitions.h:111
MSVehicleType::getCarFollowModel
const MSCFModel & getCarFollowModel() const
Returns the vehicle type's car following model definition (const version)
Definition: MSVehicleType.h:140
MSEdgeWeightsStorage.h
MSVehicle::keepClear
bool keepClear(const MSLink *link) const
decide whether the given link must be kept clear
Definition: MSVehicle.cpp:5955
SUMOVehicleParameter::arrivalLaneProcedure
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
Definition: SUMOVehicleParameter.h:519
MSBaseVehicle::getImpatience
double getImpatience() const
Returns this vehicles impatience.
Definition: MSBaseVehicle.cpp:557
MSVehicle::remainingStopDuration
SUMOTime remainingStopDuration() const
Returns the remaining stop duration for a stopped vehicle or 0.
Definition: MSVehicle.cpp:1765
MSVehicle::myJunctionEntryTime
SUMOTime myJunctionEntryTime
time at which the current junction was entered
Definition: MSVehicle.h:2006
MSVehicleType::getWidth
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
Definition: MSVehicleType.h:246
SVCPermissions
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
Definition: SUMOVehicleClass.h:218
MSTransportableControl.h
PollutantsInterface.h
MSLeaderInfo::toString
virtual std::string toString() const
print a debugging representation
Definition: MSLeaderInfo.cpp:163
TIME2STEPS
#define TIME2STEPS(x)
Definition: SUMOTime.h:58
SVC_RAIL_CLASSES
@ SVC_RAIL_CLASSES
classes which drive on tracks
Definition: SUMOVehicleClass.h:204
MSNet::VehicleState
VehicleState
Definition of a vehicle state.
Definition: MSNet.h:535
MSJunction.h
MSLane::getVehicleNumberWithPartials
int getVehicleNumberWithPartials() const
Returns the number of vehicles on this lane (including partial occupators)
Definition: MSLane.h:408
MSVehicle::TraciLaneChangePriority
TraciLaneChangePriority
modes for prioritizing traci lane change requests
Definition: MSVehicle.h:1225
MSLane::getMoveReminders
const std::vector< MSMoveReminder * > & getMoveReminders() const
Return the list of this lane's move reminders.
Definition: MSLane.h:267
MSLane::getStopOffset
double getStopOffset(const MSVehicle *veh) const
Returns vehicle class specific stopOffset for the vehicle.
Definition: MSLane.cpp:3064
MSAbstractLaneChangeModel::getShadowLane
MSLane * getShadowLane() const
Returns the lane the vehicle's shadow is on during continuous/sublane lane change.
Definition: MSAbstractLaneChangeModel.h:380
MSVehicleType::getLengthWithGap
double getLengthWithGap() const
Get vehicle's length including the minimum gap [m].
Definition: MSVehicleType.h:117
TS
#define TS
Definition: SUMOTime.h:43
MSNet::lefthand
bool lefthand() const
return whether the network was built for lefthand traffic
Definition: MSNet.h:663
MSVehicle::processTraCISpeedControl
double processTraCISpeedControl(double vSafe, double vNext)
Check for speed advices from the traci client and adjust the speed vNext in the current (euler) / aft...
Definition: MSVehicle.cpp:3262
MSBaseVehicle::addPerson
virtual void addPerson(MSTransportable *person)
Adds a person to this vehicle.
Definition: MSBaseVehicle.cpp:411
MSAbstractLaneChangeModel::prepareStep
virtual void prepareStep()
Definition: MSAbstractLaneChangeModel.cpp:889
MSVehicle::getCOEmissions
double getCOEmissions() const
Returns CO emission of the current state.
Definition: MSVehicle.cpp:5177
MSAbstractLaneChangeModel::updateShadowLane
void updateShadowLane()
Definition: MSAbstractLaneChangeModel.cpp:515
DEPART_SPEED_GIVEN
@ DEPART_SPEED_GIVEN
The speed is given.
Definition: SUMOVehicleParameter.h:196
SUMOVehicleParameter::Stop::until
SUMOTime until
The time at which the vehicle may continue its journey.
Definition: SUMOVehicleParameter.h:610
MSJunctionLogic::getResponseFor
virtual const MSLogicJunction::LinkBits & getResponseFor(int linkIndex) const
Returns the response for the given link.
Definition: MSJunctionLogic.h:47
MSNet::getCurrentTimeStep
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:283
SUMO_TAG_STOP
@ SUMO_TAG_STOP
stop for vehicles
Definition: SUMOXMLDefinitions.h:178
PollutantsInterface::PM_X
@ PM_X
Definition: PollutantsInterface.h:55
MSAbstractLaneChangeModel::build
static MSAbstractLaneChangeModel * build(LaneChangeModel lcm, MSVehicle &vehicle)
Factory method for instantiating new lane changing models.
Definition: MSAbstractLaneChangeModel.cpp:71
MSVehicle::Influencer::postProcessRemoteControl
void postProcessRemoteControl(MSVehicle *v)
Definition: MSVehicle.cpp:802
MSParkingArea::getCapacity
int getCapacity() const
Returns the area capacity.
Definition: MSParkingArea.cpp:348
MSVehicle::_getWeightsStorage
MSEdgeWeightsStorage & _getWeightsStorage() const
Definition: MSVehicle.cpp:1197
MSCFModel::maximumSafeStopSpeed
double maximumSafeStopSpeed(double gap, double currentSpeed, bool onInsertion=false, double headway=-1) const
Returns the maximum next velocity for stopping within gap.
Definition: MSCFModel.cpp:711
SOFT_ASSERT
#define SOFT_ASSERT(expr)
define SOFT_ASSERT raise an assertion in debug mode everywhere except on the windows test server
Definition: UtilExceptions.h:176
MSVehicle::DriveProcessItem::myArrivalTime
SUMOTime myArrivalTime
Definition: MSVehicle.h:2020
DEPART_LANE_GIVEN
@ DEPART_LANE_GIVEN
The lane is given.
Definition: SUMOVehicleParameter.h:120
MSVehicle::hasDriverState
bool hasDriverState() const
Whether this vehicle is equipped with a MSDriverState.
Definition: MSVehicle.h:1003
STEPS2TIME
#define STEPS2TIME(x)
Definition: SUMOTime.h:56
MSVehicle::Manoeuvre::configureEntryManoeuvre
bool configureEntryManoeuvre(MSVehicle *veh)
Setup the entry manoeuvre for this vehicle (Sets completion time and manoeuvre type)
Definition: MSVehicle.cpp:6291
MSVehicle::Influencer::setSpeedTimeLine
void setSpeedTimeLine(const std::vector< std::pair< SUMOTime, double > > &speedTimeLine)
Sets a new velocity timeline.
Definition: MSVehicle.cpp:386
STOP_INDEX_FIT
const int STOP_INDEX_FIT
Definition: SUMOVehicleParameter.h:72
PositionVector::positionAtOffset
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
Definition: PositionVector.cpp:248
MSVehicle::LCP_URGENT
@ LCP_URGENT
Definition: MSVehicle.h:1228
MSVehicle::myJunctionConflictEntryTime
SUMOTime myJunctionConflictEntryTime
Definition: MSVehicle.h:2008
MSAbstractLaneChangeModel::cleanupShadowLane
void cleanupShadowLane()
Definition: MSAbstractLaneChangeModel.cpp:456
SUMOVehicleParameter::id
std::string id
The vehicle's id.
Definition: SUMOVehicleParameter.h:468
PollutantsInterface::HC
@ HC
Definition: PollutantsInterface.h:55
MSVehicle::LaneQ::currentLength
double currentLength
The length which may be driven on this lane.
Definition: MSVehicle.h:816
MSBaseVehicle::myDepartPos
double myDepartPos
The real depart position.
Definition: MSBaseVehicle.h:554
MSVehicle::myWaitingTime
SUMOTime myWaitingTime
The time the vehicle waits (is not faster than 0.1m/s) in seconds.
Definition: MSVehicle.h:1920
MSVehicle::canReverse
bool canReverse(double speedThreshold=SUMO_const_haltingSpeed) const
whether the vehicle is a train that can reverse its direction at the current point in its route
Definition: MSVehicle.cpp:3541
MSLane::interpolateLanePosToGeometryPos
double interpolateLanePosToGeometryPos(double lanePos) const
Definition: MSLane.h:498
LINKSTATE_ZIPPER
@ LINKSTATE_ZIPPER
This is an uncontrolled, zipper-merge link.
Definition: SUMOXMLDefinitions.h:1165
SUMO_TAG_PARKING_AREA
@ SUMO_TAG_PARKING_AREA
A parking area.
Definition: SUMOXMLDefinitions.h:107
MSLane::getLength
double getLength() const
Returns the lane's length.
Definition: MSLane.h:540
SUMO_ATTR_JM_DRIVE_RED_SPEED
@ SUMO_ATTR_JM_DRIVE_RED_SPEED
Definition: SUMOXMLDefinitions.h:616
MSVehicle::getBoundingPoly
PositionVector getBoundingPoly() const
get bounding polygon
Definition: MSVehicle.cpp:5580
OutputDevice.h
MSVehicle::myCFVariables
MSCFModel::VehicleVariables * myCFVariables
The per vehicle variables of the car following model.
Definition: MSVehicle.h:2173
MSVehicle::Influencer::myLatDist
double myLatDist
The requested lateral change.
Definition: MSVehicle.h:1714
MSVehicleType::setActionStepLength
void setActionStepLength(const SUMOTime actionStepLength, bool resetActionOffset)
Set a new value for this type's action step length.
Definition: MSVehicleType.cpp:201
MSVehicle::updateDriveItems
void updateDriveItems()
Check whether the drive items (myLFLinkLanes) are up to date, and update them if required.
Definition: MSVehicle.cpp:3344
MSNet::addVehicleStateListener
void addVehicleStateListener(VehicleStateListener *listener)
Adds a vehicle states listener.
Definition: MSNet.cpp:877
MSLane::getOppositePos
double getOppositePos(double pos) const
return the corresponding position on the opposite lane
Definition: MSLane.cpp:3527
SUMO_ATTR_TRIGGERED
@ SUMO_ATTR_TRIGGERED
Definition: SUMOXMLDefinitions.h:799
SUMOVehicleParameter::arrivalPos
double arrivalPos
(optional) The position the vehicle shall arrive on
Definition: SUMOVehicleParameter.h:522
MSStopOut::active
static bool active()
Definition: MSStopOut.h:56
MSVehicle::State::myPosLat
double myPosLat
the stored lateral position
Definition: MSVehicle.h:142
MSVehicle::Stop::endBoarding
SUMOTime endBoarding
the maximum time at which persons may board this vehicle
Definition: MSVehicle.h:956
MSVehicle::Influencer::setSublaneChange
void setSublaneChange(double latDist)
Sets a new sublane-change request.
Definition: MSVehicle.cpp:421
ProcessError
Definition: UtilExceptions.h:39
SVS_PASSENGER_HATCHBACK
@ SVS_PASSENGER_HATCHBACK
render as a hatchback passenger vehicle ("Fliessheck")
Definition: SUMOVehicleClass.h:66
MSVehicle::getLaneChangeModel
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:4680
MSAbstractLaneChangeModel::setShadowApproachingInformation
void setShadowApproachingInformation(MSLink *link) const
set approach information for the shadow vehicle
Definition: MSAbstractLaneChangeModel.cpp:793
MSLane::getOppositeLeader
std::pair< MSVehicle *const, double > getOppositeLeader(const MSVehicle *ego, double dist, bool oppositeDir) const
Definition: MSLane.cpp:3558
MSVehicle::myManoeuvre
Manoeuvre myManoeuvre
Definition: MSVehicle.h:1441
MSCFModel::minNextSpeedEmergency
virtual double minNextSpeedEmergency(double speed, const MSVehicle *const veh=0) const
Returns the minimum speed after emergency braking, given the current speed (depends on the numerical ...
Definition: MSCFModel.cpp:255
MSAbstractLaneChangeModel::isOpposite
bool isOpposite() const
Definition: MSAbstractLaneChangeModel.h:535
isRailway
bool isRailway(SVCPermissions permissions)
Returns whether an edge with the given permission is a railway edge.
Definition: SUMOVehicleClass.cpp:363
MSNet::VEHICLE_STATE_STARTING_TELEPORT
@ VEHICLE_STATE_STARTING_TELEPORT
The vehicle started to teleport.
Definition: MSNet.h:541
MSVehicle::ignoreRed
bool ignoreRed(const MSLink *link, bool canBrake) const
decide whether a red (or yellow light) may be ignore
Definition: MSVehicle.cpp:5967
SUMOVehicleParameter::arrivalPosProcedure
ArrivalPosDefinition arrivalPosProcedure
Information how the vehicle shall choose the arrival position.
Definition: SUMOVehicleParameter.h:525
MSVehicle::myBestLanes
std::vector< std::vector< LaneQ > > myBestLanes
Definition: MSVehicle.h:1956
MSVehicle::myCurrentLaneInBestLanes
std::vector< LaneQ >::iterator myCurrentLaneInBestLanes
Definition: MSVehicle.h:1961
MSGlobals::gModelParkingManoeuver
static bool gModelParkingManoeuver
whether parking simulation includes manoeuver time and any associated lane blocking
Definition: MSGlobals.h:135
Position
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:38
MSVehicle::LaneQ::lane
MSLane * lane
The described lane.
Definition: MSVehicle.h:812
MSVehicle::Influencer::GapControlState::vehStateListener
static GapControlVehStateListener vehStateListener
Definition: MSVehicle.h:1517
MSVehicle::Stop::getEndPos
double getEndPos(const SUMOVehicle &veh) const
return halting position for upcoming stop;
Definition: MSVehicle.cpp:914
MSVehicle::getHCEmissions
double getHCEmissions() const
Returns HC emission of the current state.
Definition: MSVehicle.cpp:5183
MSVehicle::Influencer::getSignals
int getSignals() const
Definition: MSVehicle.h:1682
MSVehicle::Manoeuvre::manoeuvreIsComplete
bool manoeuvreIsComplete() const
Check if any manoeuver is ongoing and whether the completion time is beyond currentTime.
Definition: MSVehicle.cpp:6392
MSVehicle::Stop::containerstop
MSStoppingPlace * containerstop
(Optional) container stop if one is assigned to the stop
Definition: MSVehicle.h:930
PollutantsInterface::NO_X
@ NO_X
Definition: PollutantsInterface.h:55
MSJunction::getLogic
virtual const MSJunctionLogic * getLogic() const
Definition: MSJunction.h:134
time2string
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:67
MSVehicle::Influencer::Influencer
Influencer()
Constructor.
Definition: MSVehicle.cpp:351
MSNet::VEHICLE_STATE_STARTING_STOP
@ VEHICLE_STATE_STARTING_STOP
The vehicles starts to stop.
Definition: MSNet.h:553
PositionVector::append
void append(const PositionVector &v, double sameThreshold=2.0)
Definition: PositionVector.cpp:696
MSVehicle::DriveProcessItem::mySetRequest
bool mySetRequest
Definition: MSVehicle.h:2019
MSVehicle::myLastBestLanesInternalLane
const MSLane * myLastBestLanesInternalLane
Definition: MSVehicle.h:1949
MSVehicle::getStopIndices
std::vector< std::pair< int, double > > getStopIndices() const
return list of route indices for the remaining stops
Definition: MSVehicle.cpp:2056
MSGlobals.h
MSVehicle::Stop::lane
const MSLane * lane
The lane to stop at.
Definition: MSVehicle.h:926
MSEdge::getBidiEdge
const MSEdge * getBidiEdge() const
return opposite superposable/congruent edge, if it exist and 0 else
Definition: MSEdge.h:249
MSLane::getNextNormal
const MSEdge * getNextNormal() const
Returns the lane's follower if it is an internal lane, the edge of the lane otherwise.
Definition: MSLane.cpp:1838
MSVehicleType::getMinGap
double getMinGap() const
Get the free space in front of vehicles of this class.
Definition: MSVehicleType.h:125
MSVehicle::MANOEUVRE_NONE
@ MANOEUVRE_NONE
not manouevring
Definition: MSVehicle.h:1358
MSLane::removeVehicle
virtual MSVehicle * removeVehicle(MSVehicle *remVehicle, MSMoveReminder::Notification notification, bool notify=true)
Definition: MSLane.cpp:2180
MSVehicle::myStops
std::list< Stop > myStops
The vehicle's list of stops.
Definition: MSVehicle.h:1966
MSEdge
A road/street connecting two junctions.
Definition: MSEdge.h:78
MSAbstractLaneChangeModel::getShadowFurtherLanes
const std::vector< MSLane * > & getShadowFurtherLanes() const
Definition: MSAbstractLaneChangeModel.h:395
MSDevice_DriverState::update
void update()
update internal state
Definition: MSDevice_DriverState.cpp:214
MSVehicle::Stop::edge
MSRouteIterator edge
The edge in the route to stop at.
Definition: MSVehicle.h:924
MSVehicleType::getLaneChangeModel
LaneChangeModel getLaneChangeModel() const
Definition: MSVehicleType.h:153
LCA_SUBLANE
@ LCA_SUBLANE
used by the sublane model
Definition: SUMOXMLDefinitions.h:1260
SUMOVehicleParameter::Stop::endPos
double endPos
The stopping position end.
Definition: SUMOVehicleParameter.h:604
MSVehicle::LaneQ::occupation
double occupation
The overall vehicle sum on consecutive lanes which can be passed without a lane change.
Definition: MSVehicle.h:818
SIMSTEP
#define SIMSTEP
Definition: SUMOTime.h:62
MSVehicle::LaneQ::allowsContinuation
bool allowsContinuation
Whether this lane allows to continue the drive.
Definition: MSVehicle.h:824
LINKDIR_LEFT
@ LINKDIR_LEFT
The link is a (hard) left direction.
Definition: SUMOXMLDefinitions.h:1184
MSVehicle::workOnMoveReminders
void workOnMoveReminders(double oldPos, double newPos, double newSpeed)
Processes active move reminder.
Definition: MSVehicle.cpp:1207
MSVehicle::getRerouteOrigin
const MSEdge * getRerouteOrigin() const
Returns the starting point for reroutes (usually the current edge)
Definition: MSVehicle.cpp:1386
MSVehicle::getNOxEmissions
double getNOxEmissions() const
Returns NOx emission of the current state.
Definition: MSVehicle.cpp:5189
MSEdge::getToJunction
const MSJunction * getToJunction() const
Definition: MSEdge.h:363
MSVehicle::isLeader
bool isLeader(const MSLink *link, const MSVehicle *veh) const
whether the given vehicle must be followed at the given junction
Definition: MSVehicle.cpp:6027
MSGlobals::gCheckRoutes
static bool gCheckRoutes
Definition: MSGlobals.h:78
MSVehicle::myLastActionTime
SUMOTime myLastActionTime
Action offset (actions are taken at time myActionOffset + N*getActionStepLength()) Initialized to 0,...
Definition: MSVehicle.h:1939
MSVehicle::myLane
MSLane * myLane
The lane the vehicle is on.
Definition: MSVehicle.h:1944
MSVehicle::LC_NOCONFLICT
@ LC_NOCONFLICT
Definition: MSVehicle.h:1219
MSVehicle::isStoppedInRange
bool isStoppedInRange(const double pos, const double tolerance) const
return whether the given position is within range of the current stop
Definition: MSVehicle.cpp:1793
MSBaseVehicle::getVehicleType
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
Definition: MSBaseVehicle.h:123
MSVehicle::loadState
void loadState(const SUMOSAXAttributes &attrs, const SUMOTime offset)
Loads the state of this vehicle from the given description.
Definition: MSVehicle.cpp:6141
MSVehicle::myEdgeWeights
MSEdgeWeightsStorage * myEdgeWeights
Definition: MSVehicle.h:2170
MSParkingArea.h
MSVehicle::Influencer::myEmergencyBrakeRedLight
bool myEmergencyBrakeRedLight
Whether red lights are a reason to brake.
Definition: MSVehicle.h:1732
MSMoveReminder::NOTIFICATION_DEPARTED
@ NOTIFICATION_DEPARTED
The vehicle has departed (was inserted into the network)
Definition: MSMoveReminder.h:93
MSRoutingEngine.h
MSEdge::allowedLanes
const std::vector< MSLane * > * allowedLanes(const MSEdge &destination, SUMOVehicleClass vclass=SVC_IGNORING) const
Get the allowed lanes to reach the destination-edge.
Definition: MSEdge.cpp:359
PollutantsInterface::ELEC
@ ELEC
Definition: PollutantsInterface.h:55
MSLane::getLinkCont
const MSLinkCont & getLinkCont() const
returns the container with all links !!!
Definition: MSLane.cpp:2110
MSVehicle::getAccumulatedWaitingSeconds
double getAccumulatedWaitingSeconds() const
Returns the number of seconds waited (speed was lesser than 0.1m/s) within the last millisecs.
Definition: MSVehicle.h:666
ARRIVAL_SPEED_GIVEN
@ ARRIVAL_SPEED_GIVEN
The speed is given.
Definition: SUMOVehicleParameter.h:274
MSAbstractLaneChangeModel::getManeuverDist
double getManeuverDist() const
Returns the remaining unblocked distance for the current maneuver. (only used by sublane model)
Definition: MSAbstractLaneChangeModel.cpp:169
MSVehicle::Influencer::GapControlState::GapControlState
GapControlState()
Definition: MSVehicle.cpp:280
PollutantsInterface::CO2
@ CO2
Definition: PollutantsInterface.h:55
MSVehicle::Influencer::myGapControlState
std::shared_ptr< GapControlState > myGapControlState
The gap control state.
Definition: MSVehicle.h:1708
MSVehicle::State::pos
double pos() const
Position of this state.
Definition: MSVehicle.h:109
MSVehicle::MANOEUVRE_EXIT
@ MANOEUVRE_EXIT
Manoeuvre out of stopping place.
Definition: MSVehicle.h:1356
MSVehicle::State::myLastCoveredDist
double myLastCoveredDist
Definition: MSVehicle.h:156
MSVehicle::myJunctionEntryTimeNeverYield
SUMOTime myJunctionEntryTimeNeverYield
Definition: MSVehicle.h:2007
MSVehicle::getLaneIndex
int getLaneIndex() const
Definition: MSVehicle.cpp:5304
MSVehicle::Influencer::mySublaneLC
LaneChangeMode mySublaneLC
changing to the prefered lateral alignment
Definition: MSVehicle.h:1754
MSVehicle::Influencer::GapControlState::init
static void init()
Static initalization (adds vehicle state listener)
Definition: MSVehicle.cpp:291
NUMERICAL_EPS_SPEED
#define NUMERICAL_EPS_SPEED
Definition: MSVehicle.cpp:119
MSVehicle::Influencer::myConsiderMaxDeceleration
bool myConsiderMaxDeceleration
Whether the maximum deceleration shall be regarded.
Definition: MSVehicle.h:1726
MSVehicle::setRemoteState
void setRemoteState(Position xyPos)
sets position outside the road network
Definition: MSVehicle.cpp:5937
MSBaseVehicle::replaceRouteEdges
bool replaceRouteEdges(ConstMSEdgeVector &edges, double cost, double savings, const std::string &info, bool onInit=false, bool check=false, bool removeStops=true)
Replaces the current route by the given edges.
Definition: MSBaseVehicle.cpp:303
MSVehicle::DriveProcessItem::myArrivalSpeed
double myArrivalSpeed
Definition: MSVehicle.h:2021
MSVehicleType::getEntryManoeuvreTime
SUMOTime getEntryManoeuvreTime(const int angle) const
Accessor function for parameter equivalent returning entry time for a specific manoeuver angle.
Definition: MSVehicleType.cpp:353
MSVehicle::myCachedPosition
Position myCachedPosition
Definition: MSVehicle.h:2003
MSLane::allowsVehicleClass
bool allowsVehicleClass(SUMOVehicleClass vclass) const
Definition: MSLane.h:805
MSVehicle::myAmRegisteredAsWaitingForContainer
bool myAmRegisteredAsWaitingForContainer
Whether this vehicle is registered as waiting for a container (for deadlock-recognition)
Definition: MSVehicle.h:1990
SUMO_ATTR_POSITION
@ SUMO_ATTR_POSITION
Definition: SUMOXMLDefinitions.h:660
MSVehicle::basePos
double basePos(const MSEdge *edge) const
departure position where the vehicle fits fully onto the edge (if possible)
Definition: MSVehicle.cpp:2099
MSVehicle::setAngle
void setAngle(double angle, bool straightenFurther=false)
Set a custom vehicle angle in rad, optionally updates furtherLanePosLat.
Definition: MSVehicle.cpp:1399
MSStoppingPlace::enter
void enter(SUMOVehicle *what, double beg, double end)
Called if a vehicle enters this stop.
Definition: MSStoppingPlace.cpp:75
MSVehicle::Influencer::~Influencer
~Influencer()
Destructor.
Definition: MSVehicle.cpp:373
DEG2RAD
#define DEG2RAD(x)
Definition: GeomHelper.h:37
MSVehicle::Stop::pars
const SUMOVehicleParameter::Stop pars
The stop parameter.
Definition: MSVehicle.h:936
MSLane::getLogicalPredecessorLane
MSLane * getLogicalPredecessorLane() const
get the most likely precedecessor lane (sorted using by_connections_to_sorter). The result is cached ...
Definition: MSLane.cpp:2543
MSLane::getOpposite
MSLane * getOpposite() const
return the opposite direction lane for lane changing or 0
Definition: MSLane.cpp:3518
MSVehicle::Influencer::isRemoteControlled
bool isRemoteControlled() const
Definition: MSVehicle.cpp:791
MSPerson.h
MSVehicle::Influencer::GapControlState::refVehMap
static std::map< const MSVehicle *, GapControlState * > refVehMap
stores reference vehicles currently in use by a gapController
Definition: MSVehicle.h:1514
MSVehicle::WaitingTimeCollector::cumulatedWaitingTime
SUMOTime cumulatedWaitingTime(SUMOTime memory=-1) const
Definition: MSVehicle.cpp:194
CRLL_LOOK_AHEAD
#define CRLL_LOOK_AHEAD
Definition: MSVehicle.cpp:112
MSPModel::nextBlocking
virtual PersonDist nextBlocking(const MSLane *lane, double minPos, double minRight, double maxLeft, double stopTime=0)
returns the next pedestrian beyond minPos that is laterally between minRight and maxLeft or 0
Definition: MSPModel.h:93
MSVehicle::activateReminders
void activateReminders(const MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
"Activates" all current move reminder
Definition: MSVehicle.cpp:4430
MSVehicle::myAngle
double myAngle
the angle in radians (
Definition: MSVehicle.h:1995
MSVehicle::Stop
Definition of vehicle stop (position and duration)
Definition: MSVehicle.h:920
MSGlobals::gUsingInternalLanes
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:68
SUMOVehicleParameter::Stop::startPos
double startPos
The stopping position start.
Definition: SUMOVehicleParameter.h:601
MSBaseVehicle::myNumberReroutes
int myNumberReroutes
The number of reroutings.
Definition: MSBaseVehicle.h:563
SUMOAbstractRouter< MSEdge, SUMOVehicle >
SVS_PASSENGER_VAN
@ SVS_PASSENGER_VAN
render as a van
Definition: SUMOVehicleClass.h:70
MSVehicle::getLane
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:560
MSVehicle::getStopEdges
const ConstMSEdgeVector getStopEdges(double &firstPos, double &lastPos) const
Returns the list of still pending stop edges also returns the first and last stop position.
Definition: MSVehicle.cpp:2030
Position::angleTo2D
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position
Definition: Position.h:253
MSLane::getEdge
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:669
MSVehicle::VEH_SIGNAL_EMERGENCY_BLUE
@ VEH_SIGNAL_EMERGENCY_BLUE
A blue emergency light is on.
Definition: MSVehicle.h:1205
Position::distanceTo2D
double distanceTo2D(const Position &p2) const
returns the euclidean distance in the x-y-plane
Definition: Position.h:243
MSLane::getCenterOnEdge
double getCenterOnEdge() const
Definition: MSLane.h:1075
MSVehicle::setBrakingSignals
void setBrakingSignals(double vNext)
sets the braking lights on/off
Definition: MSVehicle.cpp:3498
MSEdgeControl.h
MSVehicle::processLaneAdvances
void processLaneAdvances(std::vector< MSLane * > &passedLanes, bool &moved, std::string &emergencyReason)
This method checks if the vehicle has advanced over one or several lanes along its route and triggers...
Definition: MSVehicle.cpp:3595
MSBaseVehicle::addStops
void addStops(const bool ignoreStopErrors)
Adds stops to the built vehicle.
Definition: MSBaseVehicle.cpp:593
MSVehicle::willStop
bool willStop() const
Returns whether the vehicle will stop on the current edge.
Definition: MSVehicle.cpp:1743
MSDevice_Vehroutes::stopEnded
void stopEnded(const SUMOVehicleParameter::Stop &stop)
Definition: MSDevice_Vehroutes.cpp:170
MSVehicle::LCP_NOOVERLAP
@ LCP_NOOVERLAP
Definition: MSVehicle.h:1227
MSVehicle::Stop::chargingStation
MSStoppingPlace * chargingStation
(Optional) charging station if one is assigned to the stop
Definition: MSVehicle.h:934
MSVehicle::getInfluencer
Influencer & getInfluencer()
Returns the velocity/lane influencer.
Definition: MSVehicle.cpp:5900
MSVehicle::adaptBestLanesOccupation
void adaptBestLanesOccupation(int laneIndex, double density)
update occupation from MSLaneChanger
Definition: MSVehicle.cpp:5097
MSVehicle::DriveProcessItem::myVLinkWait
double myVLinkWait
Definition: MSVehicle.h:2018
MSVehicle::State::myPos
double myPos
the stored position
Definition: MSVehicle.h:136
MSVehicle::WaitingTimeCollector::getMemorySize
SUMOTime getMemorySize() const
Definition: MSVehicle.h:192
MSVehicle::myState
State myState
This Vehicles driving state (pos and speed)
Definition: MSVehicle.h:1930
OutputDevice::openTag
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
Definition: OutputDevice.cpp:239
toString
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:47
MSVehicle::Influencer::implicitDeltaPosRemote
double implicitDeltaPosRemote(const MSVehicle *veh)
return the change in longitudinal position that is implicit in the new remote position
Definition: MSVehicle.cpp:880
MSVehicle::myActionStep
bool myActionStep
The flag myActionStep indicates whether the current time step is an action point for the vehicle.
Definition: MSVehicle.h:1936
MSNet::VEHICLE_STATE_MANEUVERING
@ VEHICLE_STATE_MANEUVERING
Vehicle maneuvering either entering or exiting a parking space.
Definition: MSNet.h:561
StringUtils.h
MSVehicle::Stop::numExpectedContainer
int numExpectedContainer
The number of still expected containers.
Definition: MSVehicle.h:948
SUMO_TAG_BUS_STOP
@ SUMO_TAG_BUS_STOP
A bus stop.
Definition: SUMOXMLDefinitions.h:97
MSVehicle::myAcceleration
double myAcceleration
The current acceleration after dawdling in m/s.
Definition: MSVehicle.h:1969
MSLane::getShape
const PositionVector & getShape() const
Returns this lane's shape.
Definition: MSLane.h:477
MSVehicle::Manoeuvre::myManoeuvreStartTime
SUMOTime myManoeuvreStartTime
Time at which the Manoeuvre for this stop started.
Definition: MSVehicle.h:1428
MSVehicle::getWeightsStorage
const MSEdgeWeightsStorage & getWeightsStorage() const
Returns the vehicle's internal edge travel times/efforts container.
Definition: MSVehicle.cpp:1185
SUMO_ATTR_STATE
@ SUMO_ATTR_STATE
The state of a link.
Definition: SUMOXMLDefinitions.h:708
MSPModel::hasPedestrians
virtual bool hasPedestrians(const MSLane *lane)
whether the given lane has pedestrians on it
Definition: MSPModel.h:87
SUMOVehicleParameter::departLaneProcedure
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
Definition: SUMOVehicleParameter.h:491
MSMoveReminder::NOTIFICATION_PARKING
@ NOTIFICATION_PARKING
The vehicle starts or ends parking.
Definition: MSMoveReminder.h:105
MSVehicle::VEH_SIGNAL_BRAKELIGHT
@ VEH_SIGNAL_BRAKELIGHT
The brake lights are on.
Definition: MSVehicle.h:1189
LCA_RIGHT
@ LCA_RIGHT
Wants go to the right.
Definition: SUMOXMLDefinitions.h:1228
MSParkingArea::getOccupancy
int getOccupancy() const
Returns the area occupancy.
Definition: MSParkingArea.cpp:354
SUMOVehicleParameter::Stop::containerTriggered
bool containerTriggered
whether an arriving container lets the vehicle continue
Definition: SUMOVehicleParameter.h:619
MSCFModel::createVehicleVariables
virtual VehicleVariables * createVehicleVariables() const
Returns model specific values which are stored inside a vehicle and must be used with casting.
Definition: MSCFModel.h:200
MSVehicle::Influencer::setRemoteControlled
void setRemoteControlled(Position xyPos, MSLane *l, double pos, double posLat, double angle, int edgeOffset, const ConstMSEdgeVector &route, SUMOTime t)
Definition: MSVehicle.cpp:778
MSVehicle::LaneQ::bestContinuations
std::vector< MSLane * > bestContinuations
Definition: MSVehicle.h:830
MSDriverState.h
MSVehicleType::getExitManoeuvreTime
SUMOTime getExitManoeuvreTime(const int angle) const
Accessor function for parameter equivalent returning exit time for a specific manoeuver angle.
Definition: MSVehicleType.cpp:358
SUMO_ATTR_DURATION
@ SUMO_ATTR_DURATION
Definition: SUMOXMLDefinitions.h:667
MSCFModel::minNextSpeed
virtual double minNextSpeed(double speed, const MSVehicle *const veh=0) const
Returns the minimum speed given the current speed (depends on the numerical update scheme and its ste...
Definition: MSCFModel.cpp:244
MSVehicle::getFurtherLanes
const std::vector< MSLane * > & getFurtherLanes() const
Definition: MSVehicle.h:791
MSNet::getInstance
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:167
MSNet::getPersonControl
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition: MSNet.cpp:810
LCA_STAY
@ LCA_STAY
Needs to stay on the current lane.
Definition: SUMOXMLDefinitions.h:1224
MSVehicle::MSVehicle
MSVehicle()
invalidated default constructor
MSVehicle::updateTimeLoss
void updateTimeLoss(double vNext)
Updates the vehicle's time loss.
Definition: MSVehicle.cpp:3529
MSParkingArea::getLastFreeLotAngle
int getLastFreeLotAngle() const
Return the angle of myLastFreeLot - the next parking lot only expected to be called after we have est...
Definition: MSParkingArea.cpp:148
MSVehicle::myTimeLoss
double myTimeLoss
the time loss in seconds due to driving with less than maximum speed
Definition: MSVehicle.h:1927
MSBaseVehicle::myCurrEdge
MSRouteIterator myCurrEdge
Iterator to current route-edge.
Definition: MSBaseVehicle.h:521
MSDevice_Vehroutes
A device which collects info on the vehicle trip (mainly on departure and arrival)
Definition: MSDevice_Vehroutes.h:52
SUMOVehicleParameter::via
std::vector< std::string > via
List of the via-edges the vehicle must visit.
Definition: SUMOVehicleParameter.h:659
MSVehicle::passingMinor
bool passingMinor() const
decide whether the vehicle is passing a minor link or has comitted to do so
Definition: MSVehicle.cpp:6011
MSLane::mustCheckJunctionCollisions
bool mustCheckJunctionCollisions() const
whether this lane must check for junction collisions
Definition: MSLane.cpp:3719
MSCFModel::getHeadwayTime
virtual double getHeadwayTime() const
Get the driver's desired headway [s].
Definition: MSCFModel.h:258
MSVehicle::adaptToLeaders
void adaptToLeaders(const MSLeaderInfo &ahead, double latOffset, const double seen, DriveProcessItem *const lastLink, const MSLane *const lane, double &v, double &vLinkPass) const
Definition: MSVehicle.cpp:2747
SUMO_ATTR_EXPECTED
@ SUMO_ATTR_EXPECTED
Definition: SUMOXMLDefinitions.h:802
SUMOVehicleParameter::Stop::index
int index
at which position in the stops list
Definition: SUMOVehicleParameter.h:649
M_PI
#define M_PI
Definition: odrSpiral.cpp:40
MSVehicle::DriveProcessItem::adaptLeaveSpeed
void adaptLeaveSpeed(const double v)
Definition: MSVehicle.h:2055
MSVehicle::updateWaitingTime
void updateWaitingTime(double vNext)
Updates the vehicle's waiting time counters (accumulated and consecutive)
Definition: MSVehicle.cpp:3517
MSParkingArea::getLastFreePosWithReservation
double getLastFreePosWithReservation(SUMOTime t, const SUMOVehicle &forVehicle)
Returns the last free position on this stop including reservatiosn from the current lane and time ste...
Definition: MSParkingArea.cpp:270
SUMOAbstractRouter::recomputeCosts
double recomputeCosts(const std::vector< const E * > &edges, const V *const v, SUMOTime msTime, double *lengthp=nullptr) const
Definition: SUMOAbstractRouter.h:195
PositionVector::reverse
PositionVector reverse() const
reverse position vector
Definition: PositionVector.cpp:1086
SUMO_ATTR_EXPECTED_CONTAINERS
@ SUMO_ATTR_EXPECTED_CONTAINERS
Definition: SUMOXMLDefinitions.h:803
MSVehicle::isActionStep
bool isActionStep(SUMOTime t) const
Returns whether the next simulation step will be an action point for the vehicle.
Definition: MSVehicle.h:597
MSVehicle::checkRewindLinkLanes
void checkRewindLinkLanes(const double lengthsInFront, DriveItemVector &lfLinks) const
runs heuristic for keeping the intersection clear in case of downstream jamming
Definition: MSVehicle.cpp:4175
PositionVector::rotationAtOffset
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
Definition: PositionVector.cpp:294
MSVehicle::Influencer::myRespectJunctionPriority
bool myRespectJunctionPriority
Whether the junction priority rules are respected.
Definition: MSVehicle.h:1729
MSAbstractLaneChangeModel::endLaneChangeManeuver
void endLaneChangeManeuver(const MSMoveReminder::Notification reason=MSMoveReminder::NOTIFICATION_LANE_CHANGE)
Definition: MSAbstractLaneChangeModel.cpp:401
MSVehicle::myLaneChangeModel
MSAbstractLaneChangeModel * myLaneChangeModel
Definition: MSVehicle.h:1946
LCA_WANTS_LANECHANGE_OR_STAY
@ LCA_WANTS_LANECHANGE_OR_STAY
lane can change or stay
Definition: SUMOXMLDefinitions.h:1266
MSVehicle::addTraciStop
bool addTraciStop(MSLane *const lane, const double startPos, const double endPos, const SUMOTime duration, const SUMOTime until, const bool parking, const bool triggered, const bool containerTriggered, std::string &errorMsg)
Definition: MSVehicle.cpp:5700
MSVehicle::lateralDistanceToLane
double lateralDistanceToLane(const int offset) const
Get the minimal lateral distance required to move fully onto the lane at given offset.
Definition: MSVehicle.cpp:5443
MSVehicleType::getLength
double getLength() const
Get vehicle's length [m].
Definition: MSVehicleType.h:109
MSCFModel::stopSpeed
virtual double stopSpeed(const MSVehicle *const veh, const double speed, double gap) const =0
Computes the vehicle's safe speed for approaching a non-moving obstacle (no dawdling)
MSVehicle::getManoeuvreType
MSVehicle::ManoeuvreType getManoeuvreType() const
accessor function to myManoeuvre equivalent
Definition: MSVehicle.cpp:6274
MSVehicle::Influencer::setLaneChangeMode
void setLaneChangeMode(int value)
Sets lane changing behavior.
Definition: MSVehicle.cpp:767
MSParkingArea::getOccupancyIncludingBlocked
int getOccupancyIncludingBlocked() const
Returns the area occupancy.
Definition: MSParkingArea.cpp:360
MSVehicle::getElectricityConsumption
double getElectricityConsumption() const
Returns electricity consumption of the current state.
Definition: MSVehicle.cpp:5207
SUMOVehicleParameter::Stop::extension
SUMOTime extension
The maximum time extension for boarding / loading.
Definition: SUMOVehicleParameter.h:613
SUMO_ATTR_CONTAINER_TRIGGERED
@ SUMO_ATTR_CONTAINER_TRIGGERED
Definition: SUMOXMLDefinitions.h:800
GeomHelper::fromNaviDegree
static double fromNaviDegree(const double angle)
Definition: GeomHelper.cpp:210
MSVehicle::checkLinkLeader
void checkLinkLeader(const MSLink *link, const MSLane *lane, double seen, DriveProcessItem *const lastLink, double &v, double &vLinkPass, double &vLinkWait, bool &setRequest, bool isShadowLink=false) const
checks for link leaders on the given link
Definition: MSVehicle.cpp:2848
MSBaseVehicle::getPersons
const std::vector< MSTransportable * > & getPersons() const
retrieve riding persons
Definition: MSBaseVehicle.cpp:652
MSVehicle::getRightSideOnEdge
double getRightSideOnEdge(const MSLane *lane=0) const
Get the vehicle's lateral position on the edge of the given lane (or its current edge if lane == 0)
Definition: MSVehicle.cpp:5327
MSVehicle::Influencer::setSignals
void setSignals(int signals)
Definition: MSVehicle.h:1678
MSStopOut::stopStarted
void stopStarted(const SUMOVehicle *veh, int numPersons, int numContainers, SUMOTime time)
Definition: MSStopOut.cpp:63
MSVehicle::resetActionOffset
void resetActionOffset(const SUMOTime timeUntilNextAction=0)
Resets the action offset for the vehicle.
Definition: MSVehicle.cpp:2121
MSVehicle::Influencer::isRemoteAffected
bool isRemoteAffected(SUMOTime t) const
Definition: MSVehicle.cpp:797
MSEdgeVector
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:74
MSRoute.h
MSVehicle::getRightSideOnLane
double getRightSideOnLane() const
Get the vehicle's lateral position on the lane:
Definition: MSVehicle.cpp:5321
MSBaseVehicle::getVClass
SUMOVehicleClass getVClass() const
Returns the vehicle's access class.
Definition: MSBaseVehicle.h:131
MSLane::getLinkTo
MSLink * getLinkTo(const MSLane *) const
returns the link to the given lane or 0, if it is not connected
Definition: MSLane.cpp:2117
MSBaseVehicle::getSingularType
MSVehicleType & getSingularType()
Replaces the current vehicle type with a new one used by this vehicle only.
Definition: MSBaseVehicle.cpp:736
MSBaseVehicle::getPersonNumber
int getPersonNumber() const
Returns the number of persons.
Definition: MSBaseVehicle.cpp:617
STOP_DURATION_SET
const int STOP_DURATION_SET
Definition: SUMOVehicleParameter.h:76
SVS_PASSENGER
@ SVS_PASSENGER
render as a passenger vehicle
Definition: SUMOVehicleClass.h:62
MSVehicle::Manoeuvre::myManoeuvreCompleteTime
SUMOTime myManoeuvreCompleteTime
Time at which this manoeuvre should complete.
Definition: MSVehicle.h:1431
MSVehicle::DriveProcessItem::getLeaveSpeed
double getLeaveSpeed() const
Definition: MSVehicle.h:2062
MSVehicle::Influencer::GapControlState::activate
void activate(double tauOriginal, double tauTarget, double additionalGap, double duration, double changeRate, double maxDecel, const MSVehicle *refVeh)
Start gap control with given params.
Definition: MSVehicle.cpp:308
MSPModel.h
MSVehicle::myInfluencer
Influencer * myInfluencer
An instance of a velocity/lane influencing instance; built in "getInfluencer".
Definition: MSVehicle.h:2176
MSRoute::getStops
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition: MSRoute.cpp:376
SUMO_ATTR_POSITION_LAT
@ SUMO_ATTR_POSITION_LAT
Definition: SUMOXMLDefinitions.h:661
MSTransportable::getID
const std::string & getID() const
returns the id of the transportable
Definition: MSTransportable.cpp:699
MSVehicle::processLinkApproaches
void processLinkApproaches(double &vSafe, double &vSafeMin, double &vSafeMinDist)
This method iterates through the driveprocess items for the vehicle and adapts the given in/out param...
Definition: MSVehicle.cpp:3013
MSVehicleType::getParameter
const SUMOVTypeParameter & getParameter() const
Definition: MSVehicleType.h:560
MSVehicle::Influencer::GapControlState::~GapControlState
virtual ~GapControlState()
Definition: MSVehicle.cpp:286
SUMOSAXAttributes.h
MSBaseVehicle
The base class for microscopic and mesoscopic vehicles.
Definition: MSBaseVehicle.h:51
SUMO_ATTR_JM_DRIVE_AFTER_RED_TIME
@ SUMO_ATTR_JM_DRIVE_AFTER_RED_TIME
Definition: SUMOXMLDefinitions.h:615
MSVehicle::getBestLanesContinuation
const std::vector< MSLane * > & getBestLanesContinuation() const
Returns the best sequence of lanes to continue the route starting at myLane.
Definition: MSVehicle.cpp:5058
STOP_INDEX_END
const int STOP_INDEX_END
Definition: SUMOVehicleParameter.h:71
joinToString
std::string joinToString(const std::vector< T > &v, const T_BETWEEN &between, std::streamsize accuracy=gPrecision)
Definition: ToString.h:246
MSVehicle::Stop::triggered
bool triggered
whether an arriving person lets the vehicle continue
Definition: MSVehicle.h:940
MSBaseVehicle::getID
const std::string & getID() const
Returns the name of the vehicle.
Definition: MSBaseVehicle.cpp:138
MSVehicle::WaitingTimeCollector::WaitingTimeCollector
WaitingTimeCollector(SUMOTime memory=MSGlobals::gWaitingTimeMemory)
Constructor.
Definition: MSVehicle.cpp:175
MSVehicle::setApproachingForAllLinks
void setApproachingForAllLinks(const SUMOTime t)
Register junction approaches for all link items in the current plan.
Definition: MSVehicle.cpp:4383
MSLane::getParallelLane
MSLane * getParallelLane(int offset, bool includeOpposite=true) const
Returns the lane with the given offset parallel to this one or 0 if it does not exist.
Definition: MSLane.cpp:2198
MSVehicle::signalSet
bool signalSet(int which) const
Returns whether the given signal is on.
Definition: MSVehicle.h:1261
MSEdge::getLanes
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:167
MSDevice_Vehroutes.h
MSBaseVehicle::addReminder
void addReminder(MSMoveReminder *rem)
Adds a MoveReminder dynamically.
Definition: MSBaseVehicle.cpp:463
MSVehicle::Influencer::getLaneChangeMode
int getLaneChangeMode() const
return the current lane change mode
Definition: MSVehicle.cpp:436
MSVehicle::Influencer::GapControlState::deactivate
void deactivate()
Stop gap control.
Definition: MSVehicle.cpp:338
MSVehicle::getFuelConsumption
double getFuelConsumption() const
Returns fuel consumption of the current state.
Definition: MSVehicle.cpp:5201
MSVehicle::getBackPositionOnLane
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle's position relative to the given lane.
Definition: MSVehicle.cpp:4057
MSVehicle::Manoeuvre::setManoeuvreType
void setManoeuvreType(const MSVehicle::ManoeuvreType mType)
Accessor (set) for manoeuvre type.
Definition: MSVehicle.cpp:6285
MSVehicleType::getMaxSpeed
double getMaxSpeed() const
Get vehicle's maximum speed [m/s].
Definition: MSVehicleType.h:161
MSVehicle::checkLinkLeaderCurrentAndParallel
void checkLinkLeaderCurrentAndParallel(const MSLink *link, const MSLane *lane, double seen, DriveProcessItem *const lastLink, double &v, double &vLinkPass, double &vLinkWait, bool &setRequest) const
checks for link leaders of the current link as well as the parallel link (if there is one)
Definition: MSVehicle.cpp:2832
MSRoute::begin
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:69
SUMO_ATTR_PARKING
@ SUMO_ATTR_PARKING
Definition: SUMOXMLDefinitions.h:801
MSLane::getWidth
double getWidth() const
Returns the lane's width.
Definition: MSLane.h:556
MSAbstractLaneChangeModel::getCommittedSpeed
double getCommittedSpeed() const
Definition: MSAbstractLaneChangeModel.h:539
MSVehicle::Influencer::influenceChangeDecision
int influenceChangeDecision(const SUMOTime currentTime, const MSEdge &currentEdge, const int currentLaneIndex, int state)
Applies stored LaneChangeMode information and laneTimeLine.
Definition: MSVehicle.cpp:654
MSVehicle::computeAngle
double computeAngle() const
compute the current vehicle angle
Definition: MSVehicle.cpp:1439
MSPModel::getModel
static MSPModel * getModel()
Definition: MSPModel.cpp:63
STOP_TRIGGER_SET
const int STOP_TRIGGER_SET
Definition: SUMOVehicleParameter.h:79
STOP_CONTAINER_TRIGGER_SET
const int STOP_CONTAINER_TRIGGER_SET
Definition: SUMOVehicleParameter.h:82
MSCFModel
The car-following model abstraction.
Definition: MSCFModel.h:56
MSEdge::getNormalBefore
const MSEdge * getNormalBefore() const
if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
Definition: MSEdge.cpp:702
MSBaseVehicle::getWidth
double getWidth() const
Returns the vehicle's width.
Definition: MSBaseVehicle.h:418
MSVehicle::setEmergencyBlueLight
void setEmergencyBlueLight(SUMOTime currentTime)
sets the blue flashing light for emergency vehicles
Definition: MSVehicle.cpp:5290
MSNet::hasInstance
static bool hasInstance()
Returns whether the network was already constructed.
Definition: MSNet.h:143
MSVehicle::getWaitingTime
SUMOTime getWaitingTime() const
Returns the SUMOTime waited (speed was lesser than 0.1m/s)
Definition: MSVehicle.h:624
MSBaseVehicle::onDepart
void onDepart()
Called when the vehicle is inserted into the network.
Definition: MSBaseVehicle.cpp:371
LINKSTATE_ALLWAY_STOP
@ LINKSTATE_ALLWAY_STOP
This is an uncontrolled, all-way stop link.
Definition: SUMOXMLDefinitions.h:1163
MSAbstractLaneChangeModel::getOwnState
int getOwnState() const
Definition: MSAbstractLaneChangeModel.h:174
MSAbstractLaneChangeModel::getShadowDirection
int getShadowDirection() const
return the direction in which the current shadow lane lies
Definition: MSAbstractLaneChangeModel.cpp:572
PollutantsInterface::compute
static double compute(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const std::map< int, double > *param=0)
Returns the amount of the emitted pollutant given the vehicle type and state (in mg/s or ml/s for fue...
Definition: PollutantsInterface.cpp:148
config.h
DEPART_POS_BASE
@ DEPART_POS_BASE
Back-at-zero position.
Definition: SUMOVehicleParameter.h:150
Named::getIDSecure
static std::string getIDSecure(const T *obj, const std::string &fallBack="NULL")
get an identifier for Named-like object which may be Null
Definition: Named.h:69
MSAbstractLaneChangeModel
Interface for lane-change models.
Definition: MSAbstractLaneChangeModel.h:45
MSVehicle::validatePosition
Position validatePosition(Position result, double offset=0) const
ensure that a vehicle-relative position is not invalid
Definition: MSVehicle.cpp:1365
MSLane::isInternal
bool isInternal() const
Definition: MSLane.cpp:2010
GeomHelper.h
DIST_TO_STOPLINE_EXPECT_PRIORITY
#define DIST_TO_STOPLINE_EXPECT_PRIORITY
Definition: MSVehicle.cpp:117
gDebugFlag1
bool gDebugFlag1
global utility flags for debugging
Definition: StdDefs.cpp:32
MSVehicle::updateFurtherLanes
double updateFurtherLanes(std::vector< MSLane * > &furtherLanes, std::vector< double > &furtherLanesPosLat, const std::vector< MSLane * > &passedLanes)
update a vector of further lanes and return the new backPos
Definition: MSVehicle.cpp:3986
MSVehicle::getSpeed
double getSpeed() const
Returns the vehicle's current speed.
Definition: MSVehicle.h:476
STOP_PARKING_SET
const int STOP_PARKING_SET
Definition: SUMOVehicleParameter.h:80
RandHelper.h
DijkstraRouter.h
MSAbstractLaneChangeModel::cleanupTargetLane
void cleanupTargetLane()
Definition: MSAbstractLaneChangeModel.cpp:475
MSVehicle::Influencer::getLaneTimeLineDuration
SUMOTime getLaneTimeLineDuration()
Definition: MSVehicle.cpp:446
LCA_KEEPRIGHT
@ LCA_KEEPRIGHT
The action is due to the default of keeping right "Rechtsfahrgebot".
Definition: SUMOXMLDefinitions.h:1236
MSVehicle::Influencer::getLaneTimeLineEnd
SUMOTime getLaneTimeLineEnd()
Definition: MSVehicle.cpp:459
gPrecision
int gPrecision
the precision for floating point outputs
Definition: StdDefs.cpp:26
StdDefs.h
MSVehicle::Influencer::gapControlSpeed
double gapControlSpeed(SUMOTime currentTime, const SUMOVehicle *veh, double speed, double vSafe, double vMin, double vMax)
Applies gap control logic on the speed.
Definition: MSVehicle.cpp:501
MSVehicle::Influencer::GapControlState::cleanup
static void cleanup()
Static cleanup (removes vehicle state listener)
Definition: MSVehicle.cpp:302
MSVehicle::setActionStepLength
void setActionStepLength(double actionStepLength, bool resetActionOffset=true)
Sets the action steplength of the vehicle.
Definition: MSVehicle.cpp:1422
MSLane::geometryPositionAtOffset
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition: MSLane.h:504
MSVehicle::replaceRoute
bool replaceRoute(const MSRoute *route, const std::string &info, bool onInit=false, int offset=0, bool addStops=true, bool removeStops=true)
Replaces the current route by the given one.
Definition: MSVehicle.cpp:1083
MSVehicle::getLateralOverlap
double getLateralOverlap() const
return the amount by which the vehicle extends laterally outside it's primary lane
Definition: MSVehicle.cpp:5493
MSVehicle::DriveProcessItem::hadStoppedVehicle
bool hadStoppedVehicle
Definition: MSVehicle.h:2026
MSVehicle::Manoeuvre::getManoeuvreType
MSVehicle::ManoeuvreType getManoeuvreType() const
Accessor (get) for manoeuvre type.
Definition: MSVehicle.cpp:6269
SVS_PASSENGER_WAGON
@ SVS_PASSENGER_WAGON
render as a wagon passenger vehicle ("Combi")
Definition: SUMOVehicleClass.h:68
MSVehicle::Stop::containerTriggered
bool containerTriggered
whether an arriving container lets the vehicle continue
Definition: MSVehicle.h:942
MSVehicle::Influencer::deactivateGapController
void deactivateGapController()
Deactivates the gap control.
Definition: MSVehicle.cpp:400
STOP_END_SET
const int STOP_END_SET
Definition: SUMOVehicleParameter.h:75
MSVehicle::ChangeRequest
ChangeRequest
Requests set via TraCI.
Definition: MSVehicle.h:218
MSGlobals::gLaneChangeDuration
static SUMOTime gLaneChangeDuration
Definition: MSGlobals.h:81
DEPART_POS_GIVEN
@ DEPART_POS_GIVEN
The position is given.
Definition: SUMOVehicleParameter.h:144
SUMOTime_MAX
#define SUMOTime_MAX
Definition: SUMOTime.h:35
MSVehicle::isFrontOnLane
bool isFrontOnLane(const MSLane *lane) const
Returns the information whether the front of the vehicle is on the given lane.
Definition: MSVehicle.cpp:4146
MSVehicle::getNextParkingArea
MSParkingArea * getNextParkingArea()
get the upcoming parking area stop or nullptr
Definition: MSVehicle.cpp:1713
MSRoute::addReference
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:94
MSLane.h
MSLane::getOutgoingViaLanes
const std::vector< std::pair< const MSLane *, const MSEdge * > > getOutgoingViaLanes() const
get the list of outgoing lanes
Definition: MSLane.cpp:2641
MSVehicle::drawOutsideNetwork
virtual void drawOutsideNetwork(bool)
register vehicle for drawing while outside the network
Definition: MSVehicle.h:1920
SUMOVehicleParameter::Stop::speed
double speed
the speed at which this stop counts as reached (waypoint mode)
Definition: SUMOVehicleParameter.h:643
MSLane::getNormalPredecessorLane
const MSLane * getNormalPredecessorLane() const
get normal lane leading to this internal lane, for normal lanes, the lane itself is returned
Definition: MSLane.cpp:2568
MSVehicle::getCurrentParkingArea
MSParkingArea * getCurrentParkingArea()
get the current parking area stop or nullptr
Definition: MSVehicle.cpp:1727
MSVehicle::setExitManoeuvre
bool setExitManoeuvre()
accessor function to myManoeuvre equivalent
Definition: MSVehicle.cpp:6225
MSVehicle::estimateLeaveSpeed
double estimateLeaveSpeed(const MSLink *const link, const double vLinkPass) const
estimate leaving speed when accelerating across a link
Definition: MSVehicle.h:2095
MSLane::getVehicleMaxSpeed
double getVehicleMaxSpeed(const SUMOTrafficObject *const veh) const
Returns the lane's maximum speed, given a vehicle's speed limit adaptation.
Definition: MSLane.h:518
MSVehicle::Influencer::changeRequestRemainingSeconds
double changeRequestRemainingSeconds(const SUMOTime currentTime) const
Return the remaining number of seconds of the current laneTimeLine assuming one exists.
Definition: MSVehicle.cpp:749
SUMOVehicleParameter::Stop::duration
SUMOTime duration
The stopping duration.
Definition: SUMOVehicleParameter.h:607
MSStoppingPlace::fits
bool fits(double pos, const SUMOVehicle &veh) const
return whether the given vehicle fits at the given position
Definition: MSStoppingPlace.cpp:115
MSVehicle::adaptToLeader
void adaptToLeader(const std::pair< const MSVehicle *, double > leaderInfo, const double seen, DriveProcessItem *const lastLink, const MSLane *const lane, double &v, double &vLinkPass, double distToCrossing=-1) const
Definition: MSVehicle.cpp:2796
MSVehicle::Influencer::getRespectJunctionPriority
bool getRespectJunctionPriority() const
Returns whether junction priority rules shall be respected.
Definition: MSVehicle.h:1620
MSEdge::removeWaiting
void removeWaiting(const SUMOVehicle *vehicle) const
Removes a vehicle from the list of waiting vehicles.
Definition: MSEdge.cpp:1115
CLeaderDist
std::pair< const MSVehicle *, double > CLeaderDist
Definition: MSLeaderInfo.h:34
MSBaseVehicle::myType
MSVehicleType * myType
This vehicle's type.
Definition: MSBaseVehicle.h:518
MSVehicleType::getVehicleClass
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
Definition: MSVehicleType.h:184
MSCFModel::estimateSpeedAfterDistance
double estimateSpeedAfterDistance(const double dist, const double v, const double accel) const
Definition: MSCFModel.cpp:702
MSVehicle::onFurtherEdge
bool onFurtherEdge(const MSEdge *edge) const
whether this vehicle has its back (and no its front) on the given edge
Definition: MSVehicle.cpp:5616
MSBaseVehicle::myOdometer
double myOdometer
A simple odometer to keep track of the length of the route already driven.
Definition: MSBaseVehicle.h:566
MSNet::getEdgeControl
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:379
MSGlobals::gSemiImplicitEulerUpdate
static bool gSemiImplicitEulerUpdate
Definition: MSGlobals.h:55
MSRoute::contains
bool contains(const MSEdge *const edge) const
Definition: MSRoute.h:102
MSStopOut::stopEnded
void stopEnded(const SUMOVehicle *veh, const SUMOVehicleParameter::Stop &stop, const std::string &laneOrEdgeID)
Definition: MSStopOut.cpp:98
SUMO_ATTR_BUS_STOP
@ SUMO_ATTR_BUS_STOP
Definition: SUMOXMLDefinitions.h:769
MSVehicle::WaitingTimeCollector::operator=
WaitingTimeCollector & operator=(const WaitingTimeCollector &wt)
Assignment operator.
Definition: MSVehicle.cpp:180
SUMOVehicleParameter::stops
std::vector< Stop > stops
List of the stops the vehicle will make, TraCI may add entries here.
Definition: SUMOVehicleParameter.h:656
MSAbstractLaneChangeModel::changedToOpposite
void changedToOpposite()
called when a vehicle changes between lanes in opposite directions
Definition: MSAbstractLaneChangeModel.cpp:856
MSVehicle::Influencer::setSpeedMode
void setSpeedMode(int speedMode)
Sets speed-constraining behaviors.
Definition: MSVehicle.cpp:757
MSBaseVehicle::getDevice
MSVehicleDevice * getDevice(const std::type_info &type) const
Returns a device of the given type if it exists or 0.
Definition: MSBaseVehicle.cpp:564
MSBaseVehicle::NOT_YET_DEPARTED
static const SUMOTime NOT_YET_DEPARTED
Definition: MSBaseVehicle.h:571
MSAbstractLaneChangeModel::getShadowFurtherLanesPosLat
const std::vector< double > & getShadowFurtherLanesPosLat() const
Definition: MSAbstractLaneChangeModel.h:399
MSRoute::getDistanceBetween
double getDistanceBetween(double fromPos, double toPos, const MSEdge *fromEdge, const MSEdge *toEdge, bool includeInternal=true, int routePosition=0) const
Compute the distance between 2 given edges on this route, including the length of internal lanes....
Definition: MSRoute.cpp:278
MSStoppingPlace.h
SUMOSAXAttributes
Encapsulated SAX-Attributes.
Definition: SUMOSAXAttributes.h:56
MSBaseVehicle::myContainerDevice
MSDevice_Transportable * myContainerDevice
The containers this vehicle may have.
Definition: MSBaseVehicle.h:548
MSVehicle::Manoeuvre::configureExitManoeuvre
bool configureExitManoeuvre(MSVehicle *veh)
Setup the myManoeuvre for exiting (Sets completion time and manoeuvre type)
Definition: MSVehicle.cpp:6316
SUMOVehicleParameter::Stop::awaitedContainers
std::set< std::string > awaitedContainers
IDs of containers the vehicle has to wait for until departing.
Definition: SUMOVehicleParameter.h:628
MSVehicle::WaitingTimeCollector
Stores the waiting intervals over the previous seconds (memory is to be specified in ms....
Definition: MSVehicle.h:164
SUMOVehicleParameter::Stop::parking
bool parking
whether the vehicle is removed from the net while stopping
Definition: SUMOVehicleParameter.h:622
LINKDIR_PARTLEFT
@ LINKDIR_PARTLEFT
The link is a partial left direction.
Definition: SUMOXMLDefinitions.h:1188
MSBaseVehicle::myMoveReminders
MoveReminderCont myMoveReminders
Currently relevant move reminders.
Definition: MSBaseVehicle.h:538
SUMOVehicleParameter::Stop::chargingStation
std::string chargingStation
(Optional) charging station if one is assigned to the stop
Definition: SUMOVehicleParameter.h:598
MSVehicleControl.h
MSVehicle::LaneQ::nextOccupation
double nextOccupation
As occupation, but without the first lane.
Definition: MSVehicle.h:820
MSVehicle::enterLaneAtLaneChange
void enterLaneAtLaneChange(MSLane *enteredLane)
Update when the vehicle enters a new lane in the laneChange step.
Definition: MSVehicle.cpp:4516
MSVehicle::Influencer::GapControlVehStateListener
A static instance of this class in GapControlState deactivates gap control for vehicles whose referen...
Definition: MSVehicle.h:1460
Named::getID
const std::string & getID() const
Returns the id.
Definition: Named.h:76
MSMoveReminder::Notification
Notification
Definition of a vehicle state.
Definition: MSMoveReminder.h:91
SUMOVehicleParameter::Stop::containerstop
std::string containerstop
(Optional) container stop if one is assigned to the stop
Definition: SUMOVehicleParameter.h:592
POSITION_EPS
#define POSITION_EPS
Definition: config.h:172
MSVehicle::getCO2Emissions
double getCO2Emissions() const
Returns CO2 emission of the current state.
Definition: MSVehicle.cpp:5171
MSMoveReminder::NOTIFICATION_JUNCTION
@ NOTIFICATION_JUNCTION
The vehicle arrived at a junction.
Definition: MSMoveReminder.h:95
MSVehicle::checkActionStep
bool checkActionStep(const SUMOTime t)
Returns whether the vehicle is supposed to take action in the current simulation step Updates myActio...
Definition: MSVehicle.cpp:2111
MSVehicle::~MSVehicle
virtual ~MSVehicle()
Destructor.
Definition: MSVehicle.cpp:1038
MSVehicleTransfer.h
WRITE_ERROR
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:283
MSVehicle::LCP_OPPORTUNISTIC
@ LCP_OPPORTUNISTIC
Definition: MSVehicle.h:1229
MSCFModel::followSpeed
virtual double followSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel, const MSVehicle *const pred=0) const =0
Computes the vehicle's follow speed (no dawdling)
LCA_COOPERATIVE
@ LCA_COOPERATIVE
The action is done to help someone else.
Definition: SUMOXMLDefinitions.h:1232
MIN_STOP_LENGTH
const double MIN_STOP_LENGTH
Definition: SUMOVehicleParameter.h:88
MSVehicle::updateState
void updateState(double vNext)
updates the vehicles state, given a next value for its speed. This value can be negative in case of t...
Definition: MSVehicle.cpp:3914
MSNet::VEHICLE_STATE_ENDING_STOP
@ VEHICLE_STATE_ENDING_STOP
The vehicle ends to stop.
Definition: MSNet.h:555
MSLane::getIndex
int getIndex() const
Returns the lane's index.
Definition: MSLane.h:563
SUMOVTypeParameter::getJMParam
double getJMParam(const SumoXMLAttr attr, const double defaultValue) const
Returns the named value from the map, or the default if it is not contained there.
Definition: SUMOVTypeParameter.cpp:504
MSVehicle::Influencer::getRouterTT
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouterTT(const int rngIndex) const
Definition: MSVehicle.cpp:901
MSVehicle::isStoppedTriggered
bool isStoppedTriggered() const
Returns whether the vehicle is on a triggered stop.
Definition: MSVehicle.cpp:1787
MSVehicle::myDriverState
MSDevice_DriverState * myDriverState
This vehicle's driver state.
Definition: MSVehicle.h:1933
MSCFModel::getMinimalArrivalSpeedEuler
double getMinimalArrivalSpeedEuler(double dist, double currentSpeed) const
Computes the minimal possible arrival speed after covering a given distance for Euler update.
Definition: MSCFModel.cpp:483
MSAbstractLaneChangeModel::getFurtherTargetLanes
const std::vector< MSLane * > & getFurtherTargetLanes() const
Definition: MSAbstractLaneChangeModel.h:410
MSNet::getVehicleControl
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition: MSNet.h:336
MSVehicle::getDeltaPos
double getDeltaPos(const double accel) const
calculates the distance covered in the next integration step given an acceleration and assuming the c...
Definition: MSVehicle.cpp:2991
MSVehicle::rerouteParkingArea
bool rerouteParkingArea(const std::string &parkingAreaID, std::string &errorMsg)
Definition: MSVehicle.cpp:5626
MSMoveReminder::NOTIFICATION_TELEPORT
@ NOTIFICATION_TELEPORT
The vehicle is being teleported.
Definition: MSMoveReminder.h:103
MSVehicle::Influencer::myLastRemoteAccess
SUMOTime myLastRemoteAccess
Definition: MSVehicle.h:1741
SUMOVehicleParameter::departPos
double departPos
(optional) The position the vehicle shall depart from
Definition: SUMOVehicleParameter.h:494
MSVehicle::getPositionAlongBestLanes
Position getPositionAlongBestLanes(double offset) const
Return the (x,y)-position, which the vehicle would reach if it continued along its best continuation ...
Definition: MSVehicle.cpp:1302
SUMOVehicleParameter::departSpeedProcedure
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle's initial speed shall be chosen.
Definition: SUMOVehicleParameter.h:509
PositionVector::move2side
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
Definition: PositionVector.cpp:1103
LCA_TRACI
@ LCA_TRACI
The action is due to a TraCI request.
Definition: SUMOXMLDefinitions.h:1238
MSLane::getLeaderOnConsecutive
std::pair< MSVehicle *const, double > getLeaderOnConsecutive(double dist, double seen, double speed, const MSVehicle &veh, const std::vector< MSLane * > &bestLaneConts) const
Returns the immediate leader and the distance to him.
Definition: MSLane.cpp:2344
MSVehicleControl::unregisterOneWaiting
void unregisterOneWaiting(const bool isPerson)
decreases the count of vehicles waiting for a transport to allow recognition of person / container re...
Definition: MSVehicleControl.h:426
MSVehicle::unsafeLinkAhead
bool unsafeLinkAhead(const MSLane *lane) const
whether the vehicle may safely move to the given lane with regard to upcoming links
Definition: MSVehicle.cpp:5511
SUMOVehicleParameter::Stop
Definition of vehicle stop (position and duration)
Definition: SUMOVehicleParameter.h:572
SUMOTrafficObject::getSpeed
virtual double getSpeed() const =0
Returns the vehicle's current speed.
LCA_BLOCKED
@ LCA_BLOCKED
blocked in all directions
Definition: SUMOXMLDefinitions.h:1276
MSVehicle::DriveProcessItem
Drive process items represent bounds on the safe velocity corresponding to the upcoming links.
Definition: MSVehicle.h:2015
MSAbstractLaneChangeModel.h
SUMOVehicleParameter::arrivalSpeed
double arrivalSpeed
(optional) The final speed of the vehicle (not used yet)
Definition: SUMOVehicleParameter.h:534
MSVehicle::MANOEUVRE_ENTRY
@ MANOEUVRE_ENTRY
Manoeuvre into stopping place.
Definition: MSVehicle.h:1354
MSVehicle::replaceParkingArea
bool replaceParkingArea(MSParkingArea *parkingArea, std::string &errorMsg)
replace the current parking area stop with a new stop with merge duration
Definition: MSVehicle.cpp:1676
MSVehicle::State::operator=
State & operator=(const State &state)
Assignment operator.
Definition: MSVehicle.cpp:144
MSVehicle::Stop::timeToLoadNextContainer
SUMOTime timeToLoadNextContainer
The time at which the vehicle is able to load another container.
Definition: MSVehicle.h:952
MSBaseVehicle::getRNG
std::mt19937 * getRNG() const
Definition: MSBaseVehicle.cpp:758
MSVehicle::hasStops
bool hasStops() const
Returns whether the vehicle has to stop somewhere.
Definition: MSVehicle.h:997
MSVehicle::Manoeuvre::entryManoeuvreIsComplete
bool entryManoeuvreIsComplete(MSVehicle *veh)
Configure an entry manoeuvre if nothing is configured - otherwise check if complete.
Definition: MSVehicle.cpp:6351
MSVehicle
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:79
MSVehicle::getDistanceToPosition
double getDistanceToPosition(double destPos, const MSEdge *destEdge) const
Definition: MSVehicle.cpp:5113
MSVehicle::myNextDriveItem
DriveItemVector::iterator myNextDriveItem
iterator pointing to the next item in myLFLinkLanes
Definition: MSVehicle.h:2082
MSVehicleDevice
Abstract in-vehicle device.
Definition: MSVehicleDevice.h:54
MSBaseVehicle::addContainer
virtual void addContainer(MSTransportable *container)
Adds a container to this vehicle.
Definition: MSBaseVehicle.cpp:423