Developer/Implementation Notes/Vehicle Models

Caution:
Please note that this is a working document...


Contents

Implementing new Car-Following Models

Model Implementation

A car-following model in SUMO is an implementation of the abstract class MSCFModel. The following table shows this class' interfaces.

Method Description
SUMOReal moveHelper(MSVehicle * const veh, const MSLane * const lane, SUMOReal vPos) Adapts the vehicle's speed to its stops, and to the influence of lane-changing; sets the information about the vehicle's acceleration needed for emissions computation
SUMOReal ffeV(const MSVehicle * const veh, SUMOReal speed, SUMOReal gap2pred, SUMOReal predSpeed)
SUMOReal ffeV(const MSVehicle * const veh, SUMOReal gap2pred, SUMOReal predSpeed)
SUMOReal ffeV(const MSVehicle * const veh, const MSVehicle * const pred)
Returns the velocity of the vehicle in dependence to the vehicle's and its leader's values and the distance between them.
SUMOReal ffeS(const MSVehicle * const veh, SUMOReal gap2pred) Returns the velocity of the vehicle when approaching a static object (such as the end of a lane) assuming no reaction time is needed.
SUMOReal interactionGap(const MSVehicle * const , SUMOReal vL) Returns the maximum gap at which an interaction between both vehicles occurs; "interaction" means that the LEADER influences EGO's speed.
bool hasSafeGap(SUMOReal speed, SUMOReal gap, SUMOReal predSpeed, SUMOReal laneMaxSpeed) Returns whether the given gap is safe; "safe" means that no collision occur when using the gap, given other values.
Note:
Dismissed on 21.07.2010
SUMOReal getMaxAccel(SUMOReal v) Get the vehicle's maximum acceleration [m/s^2]; As some models describe that a vehicle is accelerating slower the higher its speed is, the velocity is given.
int getModelID() Returns the model's ID; the XML-Tag number is used
Method Description
SUMOReal getTau() Get the driver's reaction time [s]
Method Description
void leftVehicleVsafe(const MSVehicle * const ego, const MSVehicle * const neigh, SUMOReal &vSafe) Incorporates the influence of the vehicle on the left lane; in Germany vehicles on the right lane must not pass a vehicle on the lane left to the if the allowed velocity>60km/h
SUMOReal maxNextSpeed(SUMOReal speed) Returns the maximum speed given the current speed; Due to air brake or other influences, the vehicle's next maximum speed may depend on the vehicle's current speed (given).
SUMOReal getMaxDecel() Get the vehicle's maximum deceleration [m/s^2]
SUMOReal brakeGap(SUMOReal speed) Returns the distance the vehicle needs to halt including driver's reaction time
SUMOReal getSecureGap(const SUMOReal speed, const SUMOReal leaderSpeedAfterDecel) Returns the minimum gap to reserve if the leader is braking at maximum
SUMOReal getSpeedAfterMaxDecel(SUMOReal v) Returns the velocity after maximum deceleration

Model Embedding

Reading the Parameter from XML

Quite clumsy, you have to:

  1. . define the Name of the XML-element in SUMOVehicleClass.h; you should look for other already existing definitions, such as "Krauss", or "IDM" and do what is done to them...
  2. . let the XML-parser know them by adding their mapping from name to int in SUMOXMLDefinitions.h and SUMOXMLDefinitions.cpp; look for SUMO_TAG_CF_KRAUSS for an example
  3. . Add them for being written when writing the vehicle type in SUMOVTypeParameter::write; again, you should look for an example like SUMO_TAG_CF_KRAUSS
  4. . Add a call to an attributes parsing method in SUMOVehicleParserHelper::parseVTypeEmbedded; the method should be named like "parseVTypeEmbedded_<MODELNAME>"
  5. . Implement this method; again, use a template...

Now the definitions are read and are also written, for example within routers. Just as a hint: probably, you should just look for a special car-following model which name is unique (such as IDM) and then redo everything for your model what was done here.

Instantiating the Model's Instance

Building is done within MSVehicleType::build. Besides calling your constructor, giving it the values stored in the map, you should not forget to include the header-file of your model's implementation (yes, they are sorted alphabetically, here).

Defining Vehicle Types

Before starting to hack, we should decide how vehicle type shall be represented. Some facts and needs (unsorted):

  • ok Both the simulation and the routing modules must be able to parse vehicle type definitions
  • It would be nice to allow a validation against XML Schemata
  • At least two sub-types must be able to be defined: car-following model and lane-changing model (maybe the lane-changing model even splits into a navigational and a tactical part)
  • ok Parameter should have default values
  • ok a default vehicle type must exist
  • Models differ in parameter sets

Possible Descriptions

Index Sample pros/cons
A <vtype cfModel="xxx" xxxParam1="..." xxxParam2="..." ...
  • (-) hard to verify - parameter change in dependence to the value of "cfModel"
B <vtype-XXX xxxParam1="..." xxxParam2="..." ...
  • (-) large number of different elements needed
C <cfmodel id="#id" model="xxx" param1="..." param2="..." .../><vtype cfModelId="#id" .../>
  • (+) straight forward; many combinations possible
  • (+) is similar to how every vehicle references its vtype
  • (-) hard to verify - parameter change in dependence to the value of "cfModel"
D <vtype cfModel="xxx" param1="..." param2="..." ...>
  • (--) parameter sets differ between models
  • (-) hard to verify - parameter change in dependence to the value of "cfModel"
E <vtype ...><cfmodel model="xxx" param1="..." param2="..." .../></vtype>
  • (+) straight forward
  • (-) hard to verify - parameter change in dependence to the value of "cfModel"
  • 1 vote (Mayer)
F <vtype ...><cfmodel-XXX model="xxx" param1="..." param2="..." .../></vtype>
  • (+) straight forward
  • (-) large number of different elements needed
  • 2 votes (Behrisch, Krajzewicz)

(currently) Chosen Description

After some talks, the following description of vehicle types was chosen:

<vtype id="..." ...>
	<carFollowing-Krauss ...
	<laneChanging-DK2002 ...
</vtype>

vtype will contain parameters which can neither be counted to the lane-changing nor the car-following model, such as the vehicle type's color, the width of the vehicle etc. which are (currently) used for visualisation only. Also, the vehicle's length and other parameter which are not only used by one of the models are stored herein.

The embedded carFollowing-Krauss-Element in this example describes the car-following model (Krauss in this case), the laneChanging-DK2002 the lane-changing model (Daniel Krajzewicz's from 2002 :-) ), each with their own parameter.

The known vtype-definition is wanted to be kept. In this case, the Krauss-model stays chosen per default.
Note:
Probably, it will not be possible to validate this against a schema.

Car-following Model Interface

Currently, it is assumed that the following methods should be re-implemented for each model; the "generic" column should identify those which may be same across models:

method generic? description
ffeV no
ffeS no
maxNextSpeed no internal SUMO-tweak
brakeGap maybe should depend on maximum deceleration (a rather common value) and physics, only
approachingBrakeGap maybe almost same as brakeGap, only not incorporating the driver's reaction time
interactionGap no
hasSafeGap no
safeEmitGap no
dawdle no
decelAbility rather no

Loading and Parsing Vehicle Types

As already implemented for vehicles, a new intermediate structure <SUMO_HOME>/src/utils/common/SUMOVTypeParameter which contains vehicle type descriptions was added. When reading XML-definitions, both routers and the simulation use the additionally implemented helper methods located in <SUMO_HOME>/src/utils/xml/SUMOVehicleParserHelper for filling this structure.

SUMOVTypeParameter has member variables for those vehicle type parameters which are assumed to be neither part of the car-following model nor part of the lane-change model: id, length, maxSpeed, defaultProbability, speedFactor, speedDev, emissionClass, color, vehicleClass, width, offset, shape. These values are initialised with defaults. When reading values, SUMOVehicleParserHelper stores the information about which value was set from the XML description in SUMOVTypeParameter::setParameter. This allows to save (pass) only set values when writing the definitions back to a file - routers need this.

Parameters of the car-following model are saved into a map, SUMOVTypeParameter::cfParameter, the model's name to SUMOVTypeParameter::cfModel. Note that lane-changing model parameter handling is not implemented. The map contains only those parameter of the model which were given in the read XML file; no defaults are inserted at this time. In order to allow processing of old vtype-definitions, parameter stored directly within the vtype-element for the Krauss car-following model are stored within this map, too.

The routers consume the SUMOVTypeParameter class directly - making ROVehicleType unnecessary. The simulation uses the new method MSVehicleType::build for building the described MSVehicleType/MSCFModel combination. Missing defaults are set within this method for obtaining complete vehicle type/model descriptions.


Reworking Microsim

Step 1: get rid of critical/uncritical move methods

dkrajzew: "Uncritical" vehicles are those which are not yet interacting with their next junctions. By now, they are moved as first - all lanes currently used by vehicles are visited, and the state (position and speed) of the last vehicle on the lane is saved. This is needed, because the lanes are always visited in random order, but the car-following model needs the speed/position of a leading car before it has been updated.

Now, I would like to get rid of this first iteration over lanes. The reasons: a) the simulation should run faster, b) less code duplication.

My intension is to save two last vehicle states. The first stores the state as it was before the lane was touched in the current step, the second after. In addition, the current simulation step is stored in the lane - as the "visiting" time of the last change.

When asking for the state, the current simulation time is given. It is then easy to decide which of the stored values shall be used - the old one if the given time is larger than the visiting time. This change should make the "non-critical" methods obsolete.

Tobias Mayer: this seems to be a reasonable step, but there will still be the need to distinguish between vehicles that interact with a junction and those that don't.


Step 2(?): saving vehicle's ends

dkrajzew: By now, a vehicle is only positioned at the lane it's front is on. Several tweaks are done for determining how much the vehicle overlaps at the lane's begin. I would hope that saving the vehicle's first and last lane would reduce the computation done in moveCriticalCont and solve several issues - mainly within lane changing. In addition, it would allow a nicer visualisation.

Tobias Mayer: see Christoph's comment (keep a list of all currently touched lanes)


Step 3(?): changing the right of-way rules

dkrajzew: That's basically the main step towards moving to subseconds simulation. By now, vehicles are letting approached intersections know about their approach. Then, the intersections determine which vehicles may pass. Then the vehicles are moving over the intersection - if the intersection allowed them to do so.

Now, the issue I have currently no solution for is as following: each vehicle must decide for each intersection it wants to pass whether it has to wait or not. In many cases, this depends on whether other vehicles approach this intersection or not. By now, this is solved as above. The reason for changing it is again two-fold: a) to speed-up the simulation, and b) for revisiting and more realistic behaviour on intersections.

My initial idea would be to store each vehicle's arrival time and speed at the intersection. Then, a vehicle could ask whether vehicles with a higher right-of-way will pass the intersection in the next time or not. Still, I am not sure whether the random order of seeing the vehicles has any side-effects.

Tobias Mayer: I also think the decision about how to approach an intersection should be left to the vehicle/driver, with the intersection only handing out the "rules". Then, a vehicle can determine its own right-of-way. For speed reasons, that could be shared with all other interacting vehicles (best way would be to add it to each vehicle at the intersection's list, imho). About the randomness of vehicle registration: The right-of-way value should be computed without consideration of any other vehicle, and be an absolute numerical value. Of course those have to be calculated at every step, since changes in speed can not be known beforehand but will likely have an effect.


This page was last modified on 12 September 2011, at 06:34.