SUMO - Simulation of Urban MObility
MSCFModel.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-2018 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 /****************************************************************************/
20 // The car-following model abstraction
21 /****************************************************************************/
22 
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #include <config.h>
28 
29 #include <cmath>
30 #include <microsim/MSGlobals.h>
31 #include <microsim/MSVehicleType.h>
32 #include <microsim/MSVehicle.h>
33 #include <microsim/MSNet.h>
34 #include <microsim/MSLane.h>
36 #include <microsim/MSDriverState.h>
37 #include "MSCFModel.h"
38 
39 // ===========================================================================
40 // DEBUG constants
41 // ===========================================================================
42 //#define DEBUG_FINALIZE_SPEED
43 //#define DEBUG_DRIVER_ERRORS
44 //#define DEBUG_EMERGENCYDECEL
45 //#define DEBUG_COND (true)
46 #define DEBUG_COND (veh->isSelected())
47 //#define DEBUG_COND2 (SIMTIME == 176)
48 //#define DEBUG_COND2 (gDebugFlag1)
49 
50 
51 
52 // ===========================================================================
53 // method definitions
54 // ===========================================================================
56  myType(vtype),
57  myAccel(vtype->getParameter().getCFParam(SUMO_ATTR_ACCEL, SUMOVTypeParameter::getDefaultAccel(vtype->getParameter().vehicleClass))),
58  myDecel(vtype->getParameter().getCFParam(SUMO_ATTR_DECEL, SUMOVTypeParameter::getDefaultDecel(vtype->getParameter().vehicleClass))),
59  myEmergencyDecel(vtype->getParameter().getCFParam(SUMO_ATTR_EMERGENCYDECEL,
60  SUMOVTypeParameter::getDefaultEmergencyDecel(vtype->getParameter().vehicleClass, myDecel))),
61  myApparentDecel(vtype->getParameter().getCFParam(SUMO_ATTR_APPARENTDECEL, myDecel)),
62  myHeadwayTime(vtype->getParameter().getCFParam(SUMO_ATTR_TAU, 1.0)) {
63 }
64 
65 
67 
68 
70 
71 
72 double
73 MSCFModel::brakeGap(const double speed, const double decel, const double headwayTime) {
75  return brakeGapEuler(speed, decel, headwayTime);
76  } else {
77  // ballistic
78  if (speed <= 0) {
79  return 0.;
80  } else {
81  return speed * (headwayTime + 0.5 * speed / decel);
82  }
83  }
84 }
85 
86 
87 double
88 MSCFModel::brakeGapEuler(const double speed, const double decel, const double headwayTime) {
89  /* one possibility to speed this up is to calculate speedReduction * steps * (steps+1) / 2
90  for small values of steps (up to 10 maybe) and store them in an array */
91  const double speedReduction = ACCEL2SPEED(decel);
92  const int steps = int(speed / speedReduction);
93  return SPEED2DIST(steps * speed - speedReduction * steps * (steps + 1) / 2) + speed * headwayTime;
94 }
95 
96 
97 double
98 MSCFModel::freeSpeed(const double currentSpeed, const double decel, const double dist, const double targetSpeed, const bool onInsertion, const double actionStepLength) {
99  // XXX: (Leo) This seems to be exclusively called with decel = myDecel (max deceleration) and is not overridden
100  // by any specific CFModel. That may cause undesirable hard braking (at junctions where the vehicle
101  // changes to a road with a lower speed limit).
102 
104  // adapt speed to succeeding lane, no reaction time is involved
105  // when breaking for y steps the following distance g is covered
106  // (drive with v in the final step)
107  // g = (y^2 + y) * 0.5 * b + y * v
108  // y = ((((sqrt((b + 2.0*v)*(b + 2.0*v) + 8.0*b*g)) - b)*0.5 - v)/b)
109  const double v = SPEED2DIST(targetSpeed);
110  if (dist < v) {
111  return targetSpeed;
112  }
113  const double b = ACCEL2DIST(decel);
114  const double y = MAX2(0.0, ((sqrt((b + 2.0 * v) * (b + 2.0 * v) + 8.0 * b * dist) - b) * 0.5 - v) / b);
115  const double yFull = floor(y);
116  const double exactGap = (yFull * yFull + yFull) * 0.5 * b + yFull * v + (y > yFull ? v : 0.0);
117  const double fullSpeedGain = (yFull + (onInsertion ? 1. : 0.)) * ACCEL2SPEED(decel);
118  return DIST2SPEED(MAX2(0.0, dist - exactGap) / (yFull + 1)) + fullSpeedGain + targetSpeed;
119  } else {
120  // ballistic update (Leo)
121  // calculate maximum next speed vN that is adjustable to vT=targetSpeed after a distance d=dist
122  // and given a maximal deceleration b=decel, denote the current speed by v0.
123  // the distance covered by a trajectory that attains vN in the next action step (length=dt) and decelerates afterwards
124  // with b is given as
125  // d = 0.5*dt*(v0+vN) + (t-dt)*vN - 0.5*b*(t-dt)^2, (1)
126  // where time t of arrival at d with speed vT is
127  // t = dt + (vN-vT)/b. (2)
128  // We insert (2) into (1) to obtain
129  // d = 0.5*dt*(v0+vN) + vN*(vN-vT)/b - 0.5*b*((vN-vT)/b)^2
130  // 0 = (dt*b*v0 - vT*vT - 2*b*d) + dt*b*vN + vN*vN
131  // and solve for vN
132 
133  assert(currentSpeed >= 0);
134  assert(targetSpeed >= 0);
135 
136  const double dt = onInsertion ? 0 : actionStepLength; // handles case that vehicle is inserted just now (at the end of move)
137  const double v0 = currentSpeed;
138  const double vT = targetSpeed;
139  const double b = decel;
140  const double d = dist - NUMERICAL_EPS; // prevent returning a value > targetSpeed due to rounding errors
141 
142  // Solvability for positive vN (if d is small relative to v0):
143  // 1) If 0.5*(v0+vT)*dt > d, we set vN=vT.
144  // (In case vT<v0, this implies that on the interpolated trajectory there are points beyond d where
145  // the interpolated velocity is larger than vT, but at least on the temporal discretization grid, vT is not exceeded)
146  // 2) We ignore the (possible) constraint vN >= v0 - b*dt, which could lead to a problem if v0 - t*b > vT.
147  // (finalizeSpeed() is responsible for assuring that the next velocity is chosen in accordance with maximal decelerations)
148 
149  // If implied accel a leads to v0 + a*asl < vT, choose acceleration s.th. v0 + a*asl = vT
150  if (0.5 * (v0 + vT)*dt >= d) {
151  // Attain vT after time asl
152  return v0 + TS * (vT - v0) / actionStepLength;
153  } else {
154  const double q = ((dt * v0 - 2 * d) * b - vT * vT); // (q < 0 is fulfilled because of (#))
155  const double p = 0.5 * b * dt;
156  const double vN = -p + sqrt(p * p - q); // target speed at time t0+asl
157  return v0 + TS * (vN - v0) / actionStepLength;
158  }
159  }
160 }
161 
162 double
163 MSCFModel::finalizeSpeed(MSVehicle* const veh, double vPos) const {
164  // save old v for optional acceleration computation
165  const double oldV = veh->getSpeed();
166  // process stops (includes update of stopping state)
167  const double vStop = MIN2(vPos, veh->processNextStop(vPos));
168  // apply deceleration bounds
169  const double vMinEmergency = minNextSpeedEmergency(oldV, veh);
170  // vPos contains the uppper bound on safe speed. allow emergency braking here
171  const double vMin = MIN2(minNextSpeed(oldV, veh), MAX2(vPos, vMinEmergency));
172  // aMax: Maximal admissible acceleration until the next action step, such that the vehicle's maximal
173  // desired speed on the current lane will not be exceeded when the
174  // acceleration is maintained until the next action step.
175  double aMax = (veh->getLane()->getVehicleMaxSpeed(veh) - oldV) / veh->getActionStepLengthSecs();
176  // apply planned speed constraints and acceleration constraints
177  double vMax = MIN3(oldV + ACCEL2SPEED(aMax), maxNextSpeed(oldV, veh), vStop);
178  // do not exceed max decel even if it is unsafe
179 #ifdef _DEBUG
180  //if (vMin > vMax) {
181  // WRITE_WARNING("Maximum speed of vehicle '" + veh->getID() + "' is lower than the minimum speed (min: " + toString(vMin) + ", max: " + toString(vMax) + ").");
182  //}
183 #endif
184 
185 #ifdef DEBUG_FINALIZE_SPEED
186  if DEBUG_COND {
187  std::cout << "\n" << SIMTIME << " FINALIZE_SPEED\n";
188 }
189 #endif
190 
191 vMax = MAX2(vMin, vMax);
192  // apply further speed adaptations
193  double vNext = patchSpeedBeforeLC(veh, vMin, vMax);
194  assert(vNext >= vMin);
195  assert(vNext <= vMax);
196  // apply lane-changing related speed adaptations
197  vNext = veh->getLaneChangeModel().patchSpeed(vMin, vNext, vMax, *this);
198  assert(vNext >= vMin);
199  assert(vNext <= vMax);
200 
201 #ifdef DEBUG_FINALIZE_SPEED
202  if DEBUG_COND {
203  std::cout << std::setprecision(gPrecision)
204  << "veh '" << veh->getID() << "' oldV=" << oldV
205  << " vMin=" << vMin
206  << " vMax=" << vMax
207  << " vPos" << vStop
208  << " vStop" << vStop
209  << " vNext=" << vNext
210  << "\n";
211  }
212 #endif
213  return vNext;
214 }
215 
216 
217 double
218 MSCFModel::interactionGap(const MSVehicle* const veh, double vL) const {
219  // Resolve the vsafe equation to gap. Assume predecessor has
220  // speed != 0 and that vsafe will be the current speed plus acceleration,
221  // i.e that with this gap there will be no interaction.
222  const double vNext = MIN2(maxNextSpeed(veh->getSpeed(), veh), veh->getLane()->getVehicleMaxSpeed(veh));
223  const double gap = (vNext - vL) *
224  ((veh->getSpeed() + vL) / (2.*myDecel) + myHeadwayTime) +
225  vL * myHeadwayTime;
226 
227  // Don't allow timeHeadWay < deltaT situations.
228  return MAX2(gap, SPEED2DIST(vNext));
229 }
230 
231 
232 double
233 MSCFModel::maxNextSpeed(double speed, const MSVehicle* const /*veh*/) const {
234  return MIN2(speed + (double) ACCEL2SPEED(getMaxAccel()), myType->getMaxSpeed());
235 }
236 
237 
238 double
239 MSCFModel::minNextSpeed(double speed, const MSVehicle* const /*veh*/) const {
241  return MAX2(speed - ACCEL2SPEED(myDecel), 0.);
242  } else {
243  // NOTE: ballistic update allows for negative speeds to indicate a stop within the next timestep
244  return speed - ACCEL2SPEED(myDecel);
245  }
246 }
247 
248 
249 double
250 MSCFModel::minNextSpeedEmergency(double speed, const MSVehicle* const /*veh*/) const {
252  return MAX2(speed - ACCEL2SPEED(myEmergencyDecel), 0.);
253  } else {
254  // NOTE: ballistic update allows for negative speeds to indicate a stop within the next timestep
255  return speed - ACCEL2SPEED(myEmergencyDecel);
256  }
257 }
258 
259 
260 
261 double
262 MSCFModel::freeSpeed(const MSVehicle* const veh, double speed, double seen, double maxSpeed, const bool onInsertion) const {
263  if (maxSpeed < 0.) {
264  // can occur for ballistic update (in context of driving at red light)
265  return maxSpeed;
266  }
267  double vSafe = freeSpeed(speed, myDecel, seen, maxSpeed, onInsertion, veh->getActionStepLengthSecs());
268  return vSafe;
269 }
270 
271 
272 double
273 MSCFModel::insertionFollowSpeed(const MSVehicle* const /* v */, double speed, double gap2pred, double predSpeed, double predMaxDecel) const {
275  return maximumSafeFollowSpeed(gap2pred, speed, predSpeed, predMaxDecel, true);
276  } else {
277  // NOTE: Even for ballistic update, the current speed is irrelevant at insertion, therefore passing 0. (Leo)
278  return maximumSafeFollowSpeed(gap2pred, 0., predSpeed, predMaxDecel, true);
279  }
280 }
281 
282 
283 double
284 MSCFModel::insertionStopSpeed(const MSVehicle* const veh, double speed, double gap) const {
286  return stopSpeed(veh, speed, gap);
287  } else {
288  return MIN2(maximumSafeStopSpeed(gap, 0., true, 0.), myType->getMaxSpeed());
289  }
290 }
291 
292 
293 double
294 MSCFModel::followSpeedTransient(double duration, const MSVehicle* const /*veh*/, double /*speed*/, double gap2pred, double predSpeed, double predMaxDecel) const {
295  // minimium distance covered by the leader if braking
296  double leaderMinDist = gap2pred + distAfterTime(duration, predSpeed, -predMaxDecel);
297  // if ego would not brake it could drive with speed leaderMinDist / duration
298  // due to potentential ego braking it can safely drive faster
300  // number of potential braking steps
301  int a = (int)ceil(duration / TS - TS);
302  // can we brake for the whole time?
303  const double bg = brakeGap(a * myDecel, myDecel, 0);
304  if (bg <= leaderMinDist) {
305  // braking continuously for duration
306  // distance reduction due to braking
307  double b = TS * getMaxDecel() * 0.5 * (a * a - a);
308  if (gDebugFlag2) std::cout << " followSpeedTransient"
309  << " duration=" << duration
310  << " gap=" << gap2pred
311  << " leaderMinDist=" << leaderMinDist
312  << " decel=" << getMaxDecel()
313  << " a=" << a
314  << " bg=" << bg
315  << " b=" << b
316  << " x=" << (b + leaderMinDist) / duration
317  << "\n";
318  return (b + leaderMinDist) / duration;
319  } else {
320  // @todo improve efficiency
321  double bg = 0;
322  double speed = 0;
323  while (bg < leaderMinDist) {
324  speed += ACCEL2SPEED(myDecel);
325  bg += SPEED2DIST(speed);
326  }
327  speed -= DIST2SPEED(bg - leaderMinDist);
328  return speed;
329  }
330  } else {
331  // can we brake for the whole time?
332  const double fullBrakingSeconds = sqrt(leaderMinDist * 2 / myDecel);
333  if (fullBrakingSeconds >= duration) {
334  // braking continuously for duration
335  // average speed after braking for duration is x2 = x - 0.5 * duration * myDecel
336  // x2 * duration <= leaderMinDist must hold
337  return leaderMinDist / duration + duration * getMaxDecel() / 2;
338  } else {
339  return fullBrakingSeconds * myDecel;
340  }
341  }
342 }
343 
344 double
345 MSCFModel::distAfterTime(double t, double speed, const double accel) {
346  if (accel >= 0.) {
347  return (speed + 0.5 * accel * t) * t;
348  }
349  const double decel = -accel;
350  if (speed <= decel * t) {
351  // braking to a full stop
352  return brakeGap(speed, decel, 0);
353  }
355  // @todo improve efficiency
356  double result = 0;
357  while (t > 0) {
358  speed -= ACCEL2SPEED(decel);
359  result += MAX2(0.0, SPEED2DIST(speed));
360  t -= TS;
361  }
362  return result;
363  } else {
364  const double speed2 = speed - t * decel;
365  return 0.5 * (speed + speed2) * t;
366  }
367 }
368 
369 SUMOTime
370 MSCFModel::getMinimalArrivalTime(double dist, double currentSpeed, double arrivalSpeed) const {
371  const double accel = (arrivalSpeed >= currentSpeed) ? getMaxAccel() : -getMaxDecel();
372  const double accelTime = (arrivalSpeed - currentSpeed) / accel;
373  const double accelWay = accelTime * (arrivalSpeed + currentSpeed) * 0.5;
374  const double nonAccelWay = MAX2(0., dist - accelWay);
375  // will either drive as fast as possible and decelerate as late as possible
376  // or accelerate as fast as possible and then hold that speed
377  const double nonAccelSpeed = MAX3(currentSpeed, arrivalSpeed, SUMO_const_haltingSpeed);
378  return TIME2STEPS(accelTime + nonAccelWay / nonAccelSpeed);
379 }
380 
381 
382 double
383 MSCFModel::estimateArrivalTime(double dist, double speed, double maxSpeed, double accel) {
384  assert(speed >= 0.);
385  assert(dist >= 0.);
386 
387  if (dist == 0.) {
388  return 0.;
389  }
390 
391  if ((accel < 0. && -0.5 * speed * speed / accel < dist) || (accel <= 0. && speed == 0.)) {
392  // distance will never be covered with these values
393  return INVALID_DOUBLE;
394  }
395 
396  if (accel == 0.) {
397  return dist / speed;
398  }
399 
400  double p = speed / accel;
401 
402  if (accel < 0.) {
403  // we already know, that the distance will be covered despite breaking
404  return (-p - sqrt(p * p + 2 * dist / accel));
405  }
406 
407  // Here, accel > 0
408  // t1 is the time to use the given acceleration
409  double t1 = (maxSpeed - speed) / accel;
410  // distance covered until t1
411  double d1 = speed * t1 + 0.5 * accel * t1 * t1;
412  if (d1 >= dist) {
413  // dist is covered before changing the speed
414  return (-p + sqrt(p * p + 2 * dist / accel));
415  } else {
416  return (-p + sqrt(p * p + 2 * d1 / accel)) + (dist - d1) / maxSpeed;
417  }
418 
419 }
420 
421 double
422 MSCFModel::estimateArrivalTime(double dist, double initialSpeed, double arrivalSpeed, double maxSpeed, double accel, double decel) {
423  UNUSED_PARAMETER(arrivalSpeed); // only in assertion
424  UNUSED_PARAMETER(decel); // only in assertion
425  if (dist <= 0) {
426  return 0.;
427  }
428 
429  // stub-assumptions
430  assert(accel == decel);
431  assert(accel > 0);
432  assert(initialSpeed == 0);
433  assert(arrivalSpeed == 0);
434  assert(maxSpeed > 0);
435 
436 
437  double accelTime = (maxSpeed - initialSpeed) / accel;
438  // "ballistic" estimate for the distance covered during acceleration phase
439  double accelDist = accelTime * (initialSpeed + 0.5 * (maxSpeed - initialSpeed));
440  double arrivalTime;
441  if (accelDist >= dist * 0.5) {
442  // maximal speed will not be attained during maneuver
443  arrivalTime = 4 * sqrt(accelDist) / accel;
444  } else {
445  // Calculate time to move with constant, maximal lateral speed
446  const double constSpeedTime = (dist - accelDist * 2) / maxSpeed;
447  arrivalTime = accelTime + constSpeedTime;
448  }
449  return arrivalTime;
450 }
451 
452 
453 double
454 MSCFModel::avoidArrivalAccel(double dist, double time, double speed) {
455  assert(time > 0 || dist == 0);
456  if (dist <= 0) {
457  return -std::numeric_limits<double>::max();
458  } else if (time * speed > 2 * dist) {
459  // stop before dist is necessary. We need
460  // d = v*v/(2*a)
461  return - 0.5 * speed * speed / dist;
462  } else {
463  // we seek the solution a of
464  // d = v*t + a*t*t/2
465  return 2 * (dist / time - speed) / time;
466  }
467 }
468 
469 
470 double
471 MSCFModel::getMinimalArrivalSpeed(double dist, double currentSpeed) const {
472  // ballistic update
473  return estimateSpeedAfterDistance(dist - currentSpeed * getHeadwayTime(), currentSpeed, -getMaxDecel());
474 }
475 
476 
477 double
478 MSCFModel::getMinimalArrivalSpeedEuler(double dist, double currentSpeed) const {
479  double arrivalSpeedBraking;
480  // Because we use a continuous formula for computing the possible slow-down
481  // we need to handle the mismatch with the discrete dynamics
482  if (dist < currentSpeed) {
483  arrivalSpeedBraking = INVALID_SPEED; // no time left for braking after this step
484  // (inserted max() to get rid of arrivalSpeed dependency within method) (Leo)
485  } else if (2 * (dist - currentSpeed * getHeadwayTime()) * -getMaxDecel() + currentSpeed * currentSpeed >= 0) {
486  arrivalSpeedBraking = estimateSpeedAfterDistance(dist - currentSpeed * getHeadwayTime(), currentSpeed, -getMaxDecel());
487  } else {
488  arrivalSpeedBraking = getMaxDecel();
489  }
490  return arrivalSpeedBraking;
491 }
492 
493 
494 
495 
496 double
497 MSCFModel::gapExtrapolation(const double duration, const double currentGap, double v1, double v2, double a1, double a2, const double maxV1, const double maxV2) {
498 
499  double newGap = currentGap;
500 
502  for (unsigned int steps = 1; steps * TS <= duration; ++steps) {
503  v1 = MIN2(MAX2(v1 + a1, 0.), maxV1);
504  v2 = MIN2(MAX2(v2 + a2, 0.), maxV2);
505  newGap += TS * (v1 - v2);
506  }
507  } else {
508  // determine times t1, t2 for which vehicles can break until stop (within duration)
509  // and t3, t4 for which they reach their maximal speed on their current lanes.
510  double t1 = 0, t2 = 0, t3 = 0, t4 = 0;
511 
512  // t1: ego veh stops
513  if (a1 < 0 && v1 > 0) {
514  const double leaderStopTime = - v1 / a1;
515  t1 = MIN2(leaderStopTime, duration);
516  } else if (a1 >= 0) {
517  t1 = duration;
518  }
519  // t2: veh2 stops
520  if (a2 < 0 && v2 > 0) {
521  const double followerStopTime = -v2 / a2;
522  t2 = MIN2(followerStopTime, duration);
523  } else if (a2 >= 0) {
524  t2 = duration;
525  }
526  // t3: ego veh reaches vMax
527  if (a1 > 0 && v1 < maxV1) {
528  const double leaderMaxSpeedTime = (maxV1 - v1) / a1;
529  t3 = MIN2(leaderMaxSpeedTime, duration);
530  } else if (a1 <= 0) {
531  t3 = duration;
532  }
533  // t4: veh2 reaches vMax
534  if (a2 > 0 && v2 < maxV2) {
535  const double followerMaxSpeedTime = (maxV2 - v2) / a2;
536  t4 = MIN2(followerMaxSpeedTime, duration);
537  } else if (a2 <= 0) {
538  t4 = duration;
539  }
540 
541  // NOTE: this assumes that the accelerations a1 and a2 are constant over the next
542  // followerBreakTime seconds (if no vehicle stops before or reaches vMax)
543  std::list<double> l;
544  l.push_back(t1);
545  l.push_back(t2);
546  l.push_back(t3);
547  l.push_back(t4);
548  l.sort();
549  std::list<double>::const_iterator i;
550  double tLast = 0.;
551  for (i = l.begin(); i != l.end(); ++i) {
552  if (*i != tLast) {
553  double dt = MIN2(*i, duration) - tLast; // time between *i and tLast
554  double dv = v1 - v2; // current velocity difference
555  double da = a1 - a2; // current acceleration difference
556  newGap += dv * dt + da * dt * dt / 2.; // update gap
557  v1 += dt * a1;
558  v2 += dt * a2;
559  }
560  if (*i == t1 || *i == t3) {
561  // ego veh reached velocity bound
562  a1 = 0.;
563  }
564 
565  if (*i == t2 || *i == t4) {
566  // veh2 reached velocity bound
567  a2 = 0.;
568  }
569 
570  tLast = MIN2(*i, duration);
571  if (tLast == duration) {
572  break;
573  }
574  }
575 
576  if (duration != tLast) {
577  // (both vehicles have zero acceleration)
578  assert(a1 == 0. && a2 == 0.);
579  double dt = duration - tLast; // remaining time until duration
580  double dv = v1 - v2; // current velocity difference
581  newGap += dv * dt; // update gap
582  }
583  }
584 
585  return newGap;
586 }
587 
588 
589 
590 double
591 MSCFModel::passingTime(const double lastPos, const double passedPos, const double currentPos, const double lastSpeed, const double currentSpeed) {
592 
593  assert(passedPos <= currentPos);
594  assert(passedPos >= lastPos);
595  assert(currentPos > lastPos);
596  assert(currentSpeed >= 0);
597 
598  if (passedPos > currentPos || passedPos < lastPos) {
599  std::stringstream ss;
600  // Debug (Leo)
602  // NOTE: error is guarded to maintain original test output for euler update (Leo).
603  ss << "passingTime(): given argument passedPos = " << passedPos << " doesn't lie within [lastPos, currentPos] = [" << lastPos << ", " << currentPos << "]\nExtrapolating...";
604  std::cout << ss.str() << "\n";
605  WRITE_ERROR(ss.str());
606  }
607  const double lastCoveredDist = currentPos - lastPos;
608  const double extrapolated = passedPos > currentPos ? TS * (passedPos - lastPos) / lastCoveredDist : TS * (currentPos - passedPos) / lastCoveredDist;
609  return extrapolated;
610  } else if (currentSpeed < 0) {
611  WRITE_ERROR("passingTime(): given argument 'currentSpeed' is negative. This case is not handled yet.");
612  return -1;
613  }
614 
615  const double distanceOldToPassed = passedPos - lastPos; // assert: >=0
616 
618  // euler update (constantly moving with currentSpeed during [0,TS])
619  const double t = distanceOldToPassed / currentSpeed;
620  return MIN2(TS, MAX2(0., t)); //rounding errors could give results out of the admissible result range
621 
622  } else {
623  // ballistic update (constant acceleration a during [0,TS], except in case of a stop)
624 
625  // determine acceleration
626  double a;
627  if (currentSpeed > 0) {
628  // the acceleration was constant within the last time step
629  a = SPEED2ACCEL(currentSpeed - lastSpeed);
630  } else {
631  // the currentSpeed is zero (the last was not because lastPos<currentPos).
632  assert(currentSpeed == 0 && lastSpeed != 0);
633  // In general the stop has taken place within the last time step.
634  // The acceleration (a<0) is obtained from
635  // deltaPos = - lastSpeed^2/(2*a)
636  a = lastSpeed * lastSpeed / (2 * (lastPos - currentPos));
637 
638  assert(a < 0);
639  }
640 
641  // determine passing time t
642  // we solve distanceOldToPassed = lastSpeed*t + a*t^2/2
643  if (fabs(a) < NUMERICAL_EPS) {
644  // treat as constant speed within [0, TS]
645  const double t = 2 * distanceOldToPassed / (lastSpeed + currentSpeed);
646  return MIN2(TS, MAX2(0., t)); //rounding errors could give results out of the admissible result range
647  } else if (a > 0) {
648  // positive acceleration => only one positive solution
649  const double va = lastSpeed / a;
650  const double t = -va + sqrt(va * va + 2 * distanceOldToPassed / a);
651  assert(t < 1 && t >= 0);
652  return t;
653  } else {
654  // negative acceleration => two positive solutions (pick the smaller one.)
655  const double va = lastSpeed / a;
656  const double t = -va - sqrt(va * va + 2 * distanceOldToPassed / a);
657  assert(t < 1 && t >= 0);
658  return t;
659  }
660  }
661 }
662 
663 
664 double
665 MSCFModel::speedAfterTime(const double t, const double v0, const double dist) {
666  assert(dist >= 0);
667  assert(t >= 0 && t <= TS);
669  // euler: constant speed within [0,TS]
670  return DIST2SPEED(dist);
671  } else {
672  // ballistic: piecewise constant acceleration in [0,TS] (may become 0 for a stop within TS)
673  // We reconstruct acceleration at time t=0. Note that the covered distance in case
674  // of a stop exactly at t=TS is TS*v0/2.
675  if (dist < TS * v0 / 2) {
676  // stop must have occurred within [0,TS], use dist = -v0^2/(2a) (stopping dist),
677  // i.e., a = -v0^2/(2*dist)
678  const double accel = - v0 * v0 / (2 * dist);
679  // The speed at time t is then
680  return v0 + accel * t;
681  } else {
682  // no stop occurred within [0,TS], thus (from dist = v0*TS + accel*TS^2/2)
683  const double accel = 2 * (dist / TS - v0) / TS;
684  // The speed at time t is then
685  return v0 + accel * t;
686  }
687  }
688 }
689 
690 
691 
692 
693 double
694 MSCFModel::estimateSpeedAfterDistance(const double dist, const double v, const double accel) const {
695  // dist=v*t + 0.5*accel*t^2, solve for t and use v1 = v + accel*t
696  return MAX2(0., MIN2(myType->getMaxSpeed(),
697  (double)sqrt(2 * dist * accel + v * v)));
698 }
699 
700 
701 
702 double
703 MSCFModel::maximumSafeStopSpeed(double g /*gap*/, double v /*currentSpeed*/, bool onInsertion, double headway) const {
704  double vsafe;
706  // XXX pass headway argument
707  vsafe = maximumSafeStopSpeedEuler(g);
708  } else {
709  vsafe = maximumSafeStopSpeedBallistic(g, v, onInsertion, headway);
710  }
711 
712 // if (myDecel != myEmergencyDecel) {
713 //#ifdef DEBUG_EMERGENCYDECEL
714 // if (true) {
715 // std::cout << SIMTIME << " maximumSafeStopSpeed()"
716 // << " g=" << g
717 // << " v=" << v
718 // << " initial vsafe=" << vsafe << "(decel=" << SPEED2ACCEL(v-vsafe) << ")" << std::endl;
719 // }
720 //#endif
721 //
722 // if (vsafe < v - ACCEL2SPEED(myDecel + NUMERICAL_EPS)) {
723 // // emergency deceleration required
724 //
725 //#ifdef DEBUG_EMERGENCYDECEL
726 // if (true) {
727 // std::cout << SIMTIME << " maximumSafeStopSpeed() results in emergency deceleration "
728 // << "initial vsafe=" << vsafe << " egoSpeed=" << v << "(decel=" << SPEED2ACCEL(v-vsafe) << ")" << std::endl;
729 // }
730 //#endif
731 //
732 // const double safeDecel = calculateEmergencyDeceleration(g, v, 0., 1);
733 // assert(myDecel <= safeDecel);
734 // vsafe = v - ACCEL2SPEED(myDecel + EMERGENCY_DECEL_AMPLIFIER * (safeDecel - myDecel));
735 //
736 // if(MSGlobals::gSemiImplicitEulerUpdate) {
737 // vsafe = MAX2(vsafe,0.);
738 // }
739 //
740 //#ifdef DEBUG_EMERGENCYDECEL
741 // if (true) {
742 // std::cout << " -> corrected emergency deceleration: " << SPEED2ACCEL(v-vsafe) << std::endl;
743 // }
744 //#endif
745 //
746 // }
747 // }
748 
749  return vsafe;
750 }
751 
752 
753 double
754 MSCFModel::maximumSafeStopSpeedEuler(double gap, double headway) const {
755  gap -= NUMERICAL_EPS; // lots of code relies on some slack XXX: it shouldn't...
756  if (gap <= 0) {
757  return 0;
758  } else if (gap <= ACCEL2SPEED(myDecel)) {
759  // workaround for #2310
760  return MIN2(ACCEL2SPEED(myDecel), DIST2SPEED(gap));
761  }
762  const double g = gap;
763  const double b = ACCEL2SPEED(myDecel);
764  const double t = headway >= 0 ? headway : myHeadwayTime;
765  const double s = TS;
766 
767 
768  // h = the distance that would be covered if it were possible to stop
769  // exactly after gap and decelerate with b every simulation step
770  // h = 0.5 * n * (n-1) * b * s + n * b * t (solve for n)
771  //n = ((1.0/2.0) - ((t + (pow(((s*s) + (4.0*((s*((2.0*h/b) - t)) + (t*t)))), (1.0/2.0))*sign/2.0))/s));
772  const double n = floor(.5 - ((t + (sqrt(((s * s) + (4.0 * ((s * (2.0 * g / b - t)) + (t * t))))) * -0.5)) / s));
773  const double h = 0.5 * n * (n - 1) * b * s + n * b * t;
774  assert(h <= g + NUMERICAL_EPS);
775  // compute the additional speed that must be used during deceleration to fix
776  // the discrepancy between g and h
777  const double r = (g - h) / (n * s + t);
778  const double x = n * b + r;
779  assert(x >= 0);
780  return x;
781 }
782 
783 
784 double
785 MSCFModel::maximumSafeStopSpeedBallistic(double g /*gap*/, double v /*currentSpeed*/, bool onInsertion, double headway) const {
786  // decrease gap slightly (to avoid passing end of lane by values of magnitude ~1e-12, when exact stop is required)
787  g = MAX2(0., g - NUMERICAL_EPS);
788  headway = headway >= 0 ? headway : myHeadwayTime;
789 
790  // (Leo) Note that in contrast to the Euler update, for the ballistic update
791  // the distance covered in the coming step depends on the current velocity, in general.
792  // one exception is the situation when the vehicle is just being inserted.
793  // In that case, it will not cover any distance until the next timestep by convention.
794 
795  // We treat the latter case first:
796  if (onInsertion) {
797  // The distance covered with constant insertion speed v0 until time tau is given as
798  // G1 = tau*v0
799  // The distance covered between time tau and the stopping moment at time tau+v0/b is
800  // G2 = v0^2/(2b),
801  // where b is an assumed constant deceleration (= myDecel)
802  // We solve g = G1 + G2 for v0:
803  const double btau = myDecel * headway;
804  const double v0 = -btau + sqrt(btau * btau + 2 * myDecel * g);
805  return v0;
806  }
807 
808  // In the usual case during the driving task, the vehicle goes by
809  // a current speed v0=v, and we seek to determine a safe acceleration a (possibly <0)
810  // such that starting to break after accelerating with a for the time tau=headway
811  // still allows us to stop in time.
812 
813  const double tau = headway;
814  const double v0 = MAX2(0., v);
815  // We first consider the case that a stop has to take place within time tau
816  if (v0 * tau >= 2 * g) {
817  if (g == 0.) {
818  if (v0 > 0.) {
819  // indicate to brake as hard as possible
820  return -std::numeric_limits<double>::max();
821  } else {
822  // stay stopped
823  return 0.;
824  }
825  }
826  // In general we solve g = v0^2/(-2a), where the the rhs is the distance
827  // covered until stop when breaking with a<0
828  const double a = -v0 * v0 / (2 * g);
829  return v0 + a * TS;
830  }
831 
832  // The last case corresponds to a situation, where the vehicle may go with a positive
833  // speed v1 = v0 + tau*a after time tau.
834  // The distance covered until time tau is given as
835  // G1 = tau*(v0+v1)/2
836  // The distance covered between time tau and the stopping moment at time tau+v1/b is
837  // G2 = v1^2/(2b),
838  // where b is an assumed constant deceleration (= myDecel)
839  // We solve g = G1 + G2 for v1>0:
840  // <=> 0 = v1^2 + b*tau*v1 + b*tau*v0 - 2bg
841  // => v1 = -b*tau/2 + sqrt( (b*tau)^2/4 + b(2g - tau*v0) )
842 
843  const double btau2 = myDecel * tau / 2;
844  const double v1 = -btau2 + sqrt(btau2 * btau2 + myDecel * (2 * g - tau * v0));
845  const double a = (v1 - v0) / tau;
846  return v0 + a * TS;
847 }
848 
849 
851 double
852 MSCFModel::maximumSafeFollowSpeed(double gap, double egoSpeed, double predSpeed, double predMaxDecel, bool onInsertion) const {
853  // the speed is safe if allows the ego vehicle to come to a stop behind the leader even if
854  // the leaders starts braking hard until stopped
855  // unfortunately it is not sufficient to compare stopping distances if the follower can brake harder than the leader
856  // (the trajectories might intersect before both vehicles are stopped even if the follower has a shorter stopping distance than the leader)
857  // To make things safe, we ensure that the leaders brake distance is computed with an deceleration that is at least as high as the follower's.
858  // @todo: this is a conservative estimate for safe speed which could be increased
859 
860 // // For negative gaps, we return the lowest meaningful value by convention
861 // // XXX: check whether this is desireable (changes test results, therefore I exclude it for now (Leo), refs. #2575)
862 
863 // // It must be done. Otherwise, negative gaps at high speeds can create nonsense results from the call to maximumSafeStopSpeed() below
864 
865 // if(gap<0){
866 // if(MSGlobals::gSemiImplicitEulerUpdate){
867 // return 0.;
868 // } else {
869 // return -INVALID_SPEED;
870 // }
871 // }
872 
873  // The following commented code is a variant to assure brief stopping behind a stopped leading vehicle:
874  // if leader is stopped, calculate stopSpeed without time-headway to prevent creeping stop
875  // NOTE: this can lead to the strange phenomenon (for the Krauss-model at least) that if the leader comes to a stop,
876  // the follower accelerates for a short period of time. Refs #2310 (Leo)
877  // const double headway = predSpeed > 0. ? myHeadwayTime : 0.;
878 
879  const double headway = myHeadwayTime;
880  double x = maximumSafeStopSpeed(gap + brakeGap(predSpeed, MAX2(myDecel, predMaxDecel), 0), egoSpeed, onInsertion, headway);
881 
882  if (myDecel != myEmergencyDecel && !onInsertion && !MSGlobals::gComputeLC) {
883  double origSafeDecel = SPEED2ACCEL(egoSpeed - x);
884  if (origSafeDecel > myDecel + NUMERICAL_EPS) {
885  // Braking harder than myDecel was requested -> calculate required emergency deceleration.
886  // Note that the resulting safeDecel can be smaller than the origSafeDecel, since the call to maximumSafeStopSpeed() above
887  // can result in corrupted values (leading to intersecting trajectories) if, e.g. leader and follower are fast (leader still faster) and the gap is very small,
888  // such that braking harder than myDecel is required.
889 
890 #ifdef DEBUG_EMERGENCYDECEL
891  if (DEBUG_COND2) {
892  std::cout << SIMTIME << " initial vsafe=" << x
893  << " egoSpeed=" << egoSpeed << " (origSafeDecel=" << origSafeDecel << ")"
894  << " predSpeed=" << predSpeed << " (predDecel=" << predMaxDecel << ")"
895  << std::endl;
896  }
897 #endif
898 
899  const double safeDecel = EMERGENCY_DECEL_AMPLIFIER * calculateEmergencyDeceleration(gap, egoSpeed, predSpeed, predMaxDecel);
900  // Don't be riskier than the usual method (myDecel <= safeDecel may occur, because a headway>0 is used above)
901  x = egoSpeed - ACCEL2SPEED(MAX2(safeDecel, myDecel));
903  x = MAX2(x, 0.);
904  }
905  // don't brake harder than originally planned (possible due to euler/ballistic mismatch)
906  x = MIN2(origSafeDecel, x);
907 
908 #ifdef DEBUG_EMERGENCYDECEL
909  if (DEBUG_COND2) {
910  std::cout << " -> corrected emergency deceleration: " << safeDecel << std::endl;
911  }
912 #endif
913 
914  }
915  }
916  assert(x >= 0 || !MSGlobals::gSemiImplicitEulerUpdate);
917  assert(!ISNAN(x));
918  return x;
919 }
920 
921 
922 double
923 MSCFModel::calculateEmergencyDeceleration(double gap, double egoSpeed, double predSpeed, double predMaxDecel) const {
924  // There are two cases:
925  // 1) Either, stopping in time is possible with a deceleration b <= predMaxDecel, then this value is returned
926  // 2) Or, b > predMaxDecel is required in this case the minimal value b allowing to stop safely under the assumption maxPredDecel=b is returned
927 
928  // Apparent braking distance for the leader
929  const double predBrakeDist = 0.5 * predSpeed * predSpeed / predMaxDecel;
930  // Required deceleration according to case 1)
931  const double b1 = 0.5 * egoSpeed * egoSpeed / (gap + predBrakeDist);
932 
933 #ifdef DEBUG_EMERGENCYDECEL
934  if (DEBUG_COND2) {
935  std::cout << SIMTIME << " calculateEmergencyDeceleration()"
936  << " gap=" << gap << " egoSpeed=" << egoSpeed << " predSpeed=" << predSpeed
937  << " predBrakeDist=" << predBrakeDist
938  << " b1=" << b1
939  << std::endl;
940  }
941 #endif
942 
943  if (b1 <= predMaxDecel) {
944  // Case 1) applies
945 #ifdef DEBUG_EMERGENCYDECEL
946  if (DEBUG_COND2) {
947  std::cout << " case 1 ..." << std::endl;
948  }
949 #endif
950  return b1;
951  }
952 #ifdef DEBUG_EMERGENCYDECEL
953  if (DEBUG_COND2) {
954  std::cout << " case 2 ...";
955  }
956 #endif
957 
958  // Case 2) applies
959  assert(gap < 0 || predSpeed < egoSpeed);
960  if (gap <= 0.) {
961  return - std::numeric_limits<double>::max();
962  }
963  // Required deceleration according to case 2)
964  const double b2 = 0.5 * (egoSpeed * egoSpeed - predSpeed * predSpeed) / gap;
965 
966 #ifdef DEBUG_EMERGENCYDECEL
967  if (DEBUG_COND2) {
968  std::cout << " b2=" << b2 << std::endl;
969  }
970 #endif
971  return b2;
972 }
973 
974 
975 
976 void
977 MSCFModel::applyHeadwayAndSpeedDifferencePerceptionErrors(const MSVehicle* const veh, double speed, double& gap, double& predSpeed, double predMaxDecel, const MSVehicle* const pred) const {
978  UNUSED_PARAMETER(speed);
979  UNUSED_PARAMETER(predMaxDecel);
980  assert(veh->hasDriverState());
981 
982  // Obtain perceived gap and headway from the driver state
983  const double perceivedGap = veh->getDriverState()->getPerceivedHeadway(gap, pred);
984  const double perceivedSpeedDifference = veh->getDriverState()->getPerceivedSpeedDifference(predSpeed - speed, gap, pred);
985 
986 #ifdef DEBUG_DRIVER_ERRORS
987  if DEBUG_COND {
988  if (!veh->getDriverState()->debugLocked()) {
989  veh->getDriverState()->lockDebug();
990  std::cout << SIMTIME << " veh '" << veh->getID() << "' -> MSCFModel_Krauss::applyHeadwayAndSpeedDifferencePerceptionErrors()\n"
991  << " speed=" << speed << " gap=" << gap << " leaderSpeed=" << predSpeed
992  << "\n perceivedGap=" << perceivedGap << " perceivedLeaderSpeed=" << speed + perceivedSpeedDifference
993  << " perceivedSpeedDifference=" << perceivedSpeedDifference
994  << std::endl;
995  const double exactFollowSpeed = followSpeed(veh, speed, gap, predSpeed, predMaxDecel);
996  const double errorFollowSpeed = followSpeed(veh, speed, perceivedGap, speed + perceivedSpeedDifference, predMaxDecel);
997  const double accelError = SPEED2ACCEL(errorFollowSpeed - exactFollowSpeed);
998  std::cout << " gapError=" << perceivedGap - gap << " dvError=" << perceivedSpeedDifference - (predSpeed - speed)
999  << "\n resulting accelError: " << accelError << std::endl;
1000  veh->getDriverState()->unlockDebug();
1001  }
1002  }
1003 #endif
1004 
1005  gap = perceivedGap;
1006  predSpeed = speed + perceivedSpeedDifference;
1007 }
1008 
1009 
1010 void
1011 MSCFModel::applyHeadwayPerceptionError(const MSVehicle* const veh, double speed, double& gap) const {
1012  UNUSED_PARAMETER(speed);
1013  assert(veh->hasDriverState());
1014 
1015  // Obtain perceived gap from driver state
1016  const double perceivedGap = veh->getDriverState()->getPerceivedHeadway(gap);
1017 
1018 #ifdef DEBUG_DRIVER_ERRORS
1019  if DEBUG_COND {
1020  if (!veh->getDriverState()->debugLocked()) {
1021  veh->getDriverState()->lockDebug();
1022  std::cout << SIMTIME << " veh '" << veh->getID() << "' -> MSCFModel_Krauss::applyHeadwayPerceptionError()\n"
1023  << " speed=" << speed << " gap=" << gap << "\n perceivedGap=" << perceivedGap << std::endl;
1024  const double exactStopSpeed = stopSpeed(veh, speed, gap);
1025  const double errorStopSpeed = stopSpeed(veh, speed, perceivedGap);
1026  const double accelError = SPEED2ACCEL(errorStopSpeed - exactStopSpeed);
1027  std::cout << " gapError=" << perceivedGap - gap << "\n resulting accelError: " << accelError << std::endl;
1028  veh->getDriverState()->unlockDebug();
1029  }
1030  }
1031 #endif
1032 
1033  gap = perceivedGap;
1034 }
1035 
1036 
1037 
1038 
1039 
1040 /****************************************************************************/
static double speedAfterTime(const double t, const double oldSpeed, const double dist)
Calculates the speed after a time t [0,TS] given the initial speed and the distance traveled in an i...
Definition: MSCFModel.cpp:665
#define DIST2SPEED(x)
Definition: SUMOTime.h:50
double getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane&#39;s maximum speed, given a vehicle&#39;s speed limit adaptation.
Definition: MSLane.h:485
double maximumSafeFollowSpeed(double gap, double egoSpeed, double predSpeed, double predMaxDecel, bool onInsertion=false) const
Returns the maximum safe velocity for following the given leader.
Definition: MSCFModel.cpp:852
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver&#39;s reaction time tau (i...
Definition: MSCFModel.h:307
virtual double freeSpeed(const MSVehicle *const veh, double speed, double seen, double maxSpeed, const bool onInsertion=false) const
Computes the vehicle&#39;s safe speed without a leader.
Definition: MSCFModel.cpp:262
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:79
long long int SUMOTime
Definition: SUMOTime.h:36
#define DEBUG_COND2(obj)
Definition: MESegment.cpp:55
const MSVehicleType * myType
The type to which this model definition belongs to.
Definition: MSCFModel.h:581
#define SPEED2DIST(x)
Definition: SUMOTime.h:48
#define ACCEL2SPEED(x)
Definition: SUMOTime.h:54
#define EMERGENCY_DECEL_AMPLIFIER
Definition: MSCFModel.h:35
MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:561
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:239
Structure representing possible vehicle parameter.
int gPrecision
the precision for floating point outputs
Definition: StdDefs.cpp:27
static bool gComputeLC
whether the simulationLoop is in the lane changing phase
Definition: MSGlobals.h:115
MSCFModel(const MSVehicleType *vtype)
Constructor.
Definition: MSCFModel.cpp:55
virtual double maxNextSpeed(double speed, const MSVehicle *const veh) const
Returns the maximum speed given the current speed.
Definition: MSCFModel.cpp:233
T MAX2(T a, T b)
Definition: StdDefs.h:68
#define TIME2STEPS(x)
Definition: SUMOTime.h:60
#define TS
Definition: SUMOTime.h:45
virtual double insertionStopSpeed(const MSVehicle *const veh, double speed, double gap) const
Computes the vehicle&#39;s safe speed for approaching an obstacle at insertion without constraints due to...
Definition: MSCFModel.cpp:284
static double avoidArrivalAccel(double dist, double time, double speed)
Computes the acceleration needed to arrive not before the given time.
Definition: MSCFModel.cpp:454
#define SPEED2ACCEL(x)
Definition: SUMOTime.h:56
T MAX3(T a, T b, T c)
Definition: StdDefs.h:82
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:33
virtual double insertionFollowSpeed(const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel) const
Computes the vehicle&#39;s safe speed (no dawdling) This method is used during the insertion stage...
Definition: MSCFModel.cpp:273
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:163
The car-following model and parameter.
Definition: MSVehicleType.h:66
MSAbstractLaneChangeModel & getLaneChangeModel()
Definition: MSVehicle.cpp:4027
#define SIMTIME
Definition: SUMOTime.h:65
virtual double patchSpeed(const double min, const double wanted, const double max, const MSCFModel &cfModel)=0
Called to adapt the speed in order to allow a lane change. It uses information on LC-related desired ...
double getMaxAccel() const
Get the vehicle type&#39;s maximum acceleration [m/s^2].
Definition: MSCFModel.h:210
bool hasDriverState() const
Whether this vehicle is equipped with a MSDriverState.
Definition: MSVehicle.h:996
static double distAfterTime(double t, double speed, double accel)
calculates the distance travelled after accelerating for time t
Definition: MSCFModel.cpp:345
double getActionStepLengthSecs() const
Returns the vehicle&#39;s action step length in secs, i.e. the interval between two action points...
Definition: MSVehicle.h:513
#define ACCEL2DIST(x)
Definition: SUMOTime.h:52
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:250
static double brakeGapEuler(const double speed, const double decel, const double headwayTime)
Definition: MSCFModel.cpp:88
double getMaxSpeed() const
Get vehicle&#39;s maximum speed [m/s].
virtual double interactionGap(const MSVehicle *const veh, double vL) const
Returns the maximum gap at which an interaction between both vehicles occurs.
Definition: MSCFModel.cpp:218
T MIN2(T a, T b)
Definition: StdDefs.h:62
double getMaxDecel() const
Get the vehicle type&#39;s maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:218
double calculateEmergencyDeceleration(double gap, double egoSpeed, double predSpeed, double predMaxDecel) const
Returns the minimal deceleration for following the given leader safely.
Definition: MSCFModel.cpp:923
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:703
double getMinimalArrivalSpeedEuler(double dist, double currentSpeed) const
Computes the minimal possible arrival speed after covering a given distance for Euler update...
Definition: MSCFModel.cpp:478
T ISNAN(T a)
Definition: StdDefs.h:103
double myDecel
The vehicle&#39;s maximum deceleration [m/s^2].
Definition: MSCFModel.h:587
void applyHeadwayAndSpeedDifferencePerceptionErrors(const MSVehicle *const veh, double speed, double &gap, double &predSpeed, double predMaxDecel, const MSVehicle *const pred) const
Overwrites gap2pred and predSpeed by the perceived values obtained from the vehicle&#39;s driver state...
Definition: MSCFModel.cpp:977
static double gapExtrapolation(const double duration, const double currentGap, double v1, double v2, double a1=0, double a2=0, const double maxV1=std::numeric_limits< double >::max(), const double maxV2=std::numeric_limits< double >::max())
return the resulting gap if, starting with gap currentGap, two vehicles continue with constant accele...
Definition: MSCFModel.cpp:497
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:248
virtual ~MSCFModel()
Destructor.
Definition: MSCFModel.cpp:66
static double passingTime(const double lastPos, const double passedPos, const double currentPos, const double lastSpeed, const double currentSpeed)
Calculates the time at which the position passedPosition has been passed In case of a ballistic updat...
Definition: MSCFModel.cpp:591
double processNextStop(double currentVelocity)
Processes stops, returns the velocity needed to reach the stop.
Definition: MSVehicle.cpp:1446
double maximumSafeStopSpeedBallistic(double gap, double currentSpeed, bool onInsertion=false, double headway=-1) const
Returns the maximum next velocity for stopping within gap when using the ballistic positional update...
Definition: MSCFModel.cpp:785
virtual double getHeadwayTime() const
Get the driver&#39;s desired headway [s].
Definition: MSCFModel.h:253
static double estimateArrivalTime(double dist, double speed, double maxSpeed, double accel)
Computes the time needed to travel a distance dist given an initial speed and constant acceleration...
Definition: MSCFModel.cpp:383
double myEmergencyDecel
The vehicle&#39;s maximum emergency deceleration [m/s^2].
Definition: MSCFModel.h:589
double getMinimalArrivalSpeed(double dist, double currentSpeed) const
Computes the minimal possible arrival speed after covering a given distance.
Definition: MSCFModel.cpp:471
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:370
#define INVALID_SPEED
Definition: MSCFModel.h:33
const double SUMO_const_haltingSpeed
the speed threshold at which vehicles are considered as halting
Definition: StdDefs.h:52
virtual double followSpeedTransient(double duration, const MSVehicle *const veh, double speed, double gap2pred, double predSpeed, double predMaxDecel) const
Computes the vehicle&#39;s follow speed that avoids a collision for the given amount of time...
Definition: MSCFModel.cpp:294
double estimateSpeedAfterDistance(const double dist, const double v, const double accel) const
Definition: MSCFModel.cpp:694
virtual double patchSpeedBeforeLC(const MSVehicle *veh, double vMin, double vMax) const
apply custom speed adaptations within the given speed bounds
Definition: MSCFModel.h:89
#define DEBUG_COND
Definition: MSCFModel.cpp:46
bool gDebugFlag2
Definition: StdDefs.cpp:33
static bool gSemiImplicitEulerUpdate
Definition: MSGlobals.h:56
std::shared_ptr< MSSimpleDriverState > getDriverState() const
Returns the vehicle driver&#39;s state.
Definition: MSVehicle.h:896
T MIN3(T a, T b, T c)
Definition: StdDefs.h:75
#define NUMERICAL_EPS
Definition: config.h:148
const double INVALID_DOUBLE
Definition: StdDefs.h:54
double myHeadwayTime
The driver&#39;s desired time headway (aka reaction time tau) [s].
Definition: MSCFModel.h:594
double getSpeed() const
Returns the vehicle&#39;s current speed.
Definition: MSVehicle.h:479
double maximumSafeStopSpeedEuler(double gap, double headway=-1) const
Returns the maximum next velocity for stopping within gap when using the semi-implicit Euler update...
Definition: MSCFModel.cpp:754
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&#39;s follow speed (no dawdling)
const std::string & getID() const
Returns the name of the vehicle.
void applyHeadwayPerceptionError(const MSVehicle *const veh, double speed, double &gap) const
Overwrites gap by the perceived value obtained from the vehicle&#39;s driver state.
Definition: MSCFModel.cpp:1011
virtual double stopSpeed(const MSVehicle *const veh, const double speed, double gap) const =0
Computes the vehicle&#39;s safe speed for approaching a non-moving obstacle (no dawdling) ...