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