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