SUMO - Simulation of Urban MObility

MSCFModel_Wiedemann.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // The psycho-physical model of Wiedemann
00008 // references:
00009 // Andre Stebens - Traffic simulation with the Wiedemann model
00010 // Werner - Integration von Fahrzeugfolge- und Fahrstreifenwechselmodellen in die Nachtfahrsimulation LucidDrive
00011 // Olstam, Tapani - Comparison of Car-following models
00012 /****************************************************************************/
00013 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00014 // Copyright (C) 2001-2011 DLR (http://www.dlr.de/) and contributors
00015 /****************************************************************************/
00016 //
00017 //   This program is free software; you can redistribute it and/or modify
00018 //   it under the terms of the GNU General Public License as published by
00019 //   the Free Software Foundation; either version 2 of the License, or
00020 //   (at your option) any later version.
00021 //
00022 /****************************************************************************/
00023 
00024 
00025 // ===========================================================================
00026 // included modules
00027 // ===========================================================================
00028 #ifdef _MSC_VER
00029 #include <windows_config.h>
00030 #else
00031 #include <config.h>
00032 #endif
00033 
00034 #include <cmath>
00035 #include "MSCFModel_Wiedemann.h"
00036 #include <microsim/MSVehicle.h>
00037 #include <microsim/MSLane.h>
00038 #include <utils/common/RandHelper.h>
00039 
00040 
00041 // ===========================================================================
00042 // static members
00043 // ===========================================================================
00044 
00045 // magic constant proposed by Wiedemann (based on real world measurements)
00046 const SUMOReal MSCFModel_Wiedemann::D_MAX = 150;
00047 
00048 
00049 // ===========================================================================
00050 // method definitions
00051 // ===========================================================================
00052 MSCFModel_Wiedemann::MSCFModel_Wiedemann(const MSVehicleType* vtype,
00053         SUMOReal accel, SUMOReal decel,
00054         SUMOReal security, SUMOReal estimation) :
00055     MSCFModel(vtype, accel, decel, 1.0),
00056     mySecurity(security),
00057     myEstimation(estimation),
00058     myAX(vtype->getLength() + 1. + 2. * security),
00059     myCX(25. *(1. + security + estimation)),
00060     myMinAccel(0.2 * myAccel) { // +noise?
00061 }
00062 
00063 
00064 MSCFModel_Wiedemann::~MSCFModel_Wiedemann() {}
00065 
00066 
00067 SUMOReal
00068 MSCFModel_Wiedemann::moveHelper(MSVehicle* const veh, SUMOReal vPos) const {
00069     const SUMOReal vNext = MSCFModel::moveHelper(veh, vPos);
00070     VehicleVariables* vars = (VehicleVariables*)veh->getCarFollowVariables();
00071     vars->accelSign = vNext > veh->getSpeed() ? 1. : -1.;
00072     return vNext;
00073 }
00074 
00075 
00076 SUMOReal
00077 MSCFModel_Wiedemann::followSpeed(const MSVehicle* const veh, SUMOReal speed, SUMOReal gap2pred, SUMOReal predSpeed, SUMOReal /*predMaxDecel*/) const {
00078     return _v(veh, predSpeed, gap2pred);
00079 }
00080 
00081 
00082 SUMOReal
00083 MSCFModel_Wiedemann::stopSpeed(const MSVehicle* const veh, SUMOReal gap) const {
00084     /* Wiedemann does not handle approaching junctions or stops very well:
00085      * regime approaching() fails when dv = 0 (i.e. a vehicle inserted with speed 0 does not accelerate to reach a stop)
00086      * for dv ~ 0 the standard decision tree will switch to following() which
00087      * does a lousy job of closing in on a stop / junction
00088      * hence we borrow from Krauss here
00089      */
00090     return MAX2(getSpeedAfterMaxDecel(veh->getSpeed()), MIN2(krauss_vsafe(gap, 0), maxNextSpeed(veh->getSpeed())));
00091 }
00092 
00093 
00094 SUMOReal
00095 MSCFModel_Wiedemann::interactionGap(const MSVehicle* const , SUMOReal vL) const {
00096     UNUSED_PARAMETER(vL);
00097     return D_MAX;
00098 }
00099 
00100 
00101 MSCFModel*
00102 MSCFModel_Wiedemann::duplicate(const MSVehicleType* vtype) const {
00103     return new MSCFModel_Wiedemann(vtype, myAccel, myDecel, mySecurity, myEstimation);
00104 }
00105 
00106 
00107 SUMOReal
00108 MSCFModel_Wiedemann::_v(const MSVehicle* veh, SUMOReal predSpeed, SUMOReal gap) const {
00109     const VehicleVariables* vars = (VehicleVariables*)veh->getCarFollowVariables();
00110     const SUMOReal dx = gap + myType->getLength(); // wiedemann uses brutto gap
00111     const SUMOReal v = veh->getSpeed();
00112     const SUMOReal vpref = veh->getMaxSpeed();
00113     const SUMOReal dv = v - predSpeed;
00114     const SUMOReal bx = myAX + (1 + 7 * mySecurity) * sqrt(v); // Harding propose a factor of  *.8 here
00115     const SUMOReal ex = 2 - myEstimation; // + RandHelper::randNorm(0.5, 0.15)
00116     const SUMOReal sdx = myAX + ex * (bx - myAX); 
00117     const SUMOReal sdv_root = (dx - myAX) / myCX;
00118     const SUMOReal sdv = sdv_root * sdv_root;
00119     const SUMOReal cldv = sdv * ex * ex;
00120     const SUMOReal opdv = cldv * (-1 - 2* RandHelper::randNorm(0.5, 0.15));
00121     // select the regime, get new acceleration, compute new speed based
00122     SUMOReal accel;
00123     if (dx <= bx) {
00124         accel = emergency(dv, dx);
00125     } else if (dx < sdx) {
00126         if (dv > cldv) {
00127             accel = approaching(dv, dx, bx);
00128         } else if (dv > opdv) {
00129             accel = following(vars->accelSign);
00130         } else {
00131             accel = fullspeed(v, vpref, dx, bx);
00132         }
00133     } else {
00134         if (dv > sdv && dx < D_MAX) { //@note other versions have an disjunction instead of conjunction
00135             accel = approaching(dv, dx, bx);
00136         } else {
00137             accel = fullspeed(v, vpref, dx, bx);
00138         }
00139     }
00140     // since we have hard constrainst on accel we may as well use them here
00141     accel = MAX2(MIN2(accel, myAccel), -myDecel);
00142     const SUMOReal vNew = MAX2(SUMOReal(0), v + ACCEL2SPEED(accel)); // don't allow negative speeds
00143     return vNew;
00144 }
00145 
00146 
00147 SUMOReal
00148 MSCFModel_Wiedemann::fullspeed(SUMOReal v, SUMOReal vpref, SUMOReal dx, SUMOReal bx) const {
00149     SUMOReal bmax = 0.2 + 0.8 * myAccel * (7 - sqrt(v));
00150     // if veh just drifted out of a 'following' process the acceleration is reduced
00151     SUMOReal accel = dx<=2*bx ? MIN2(myMinAccel, bmax * (dx-bx) / bx) : bmax;
00152     if (v > vpref) {
00153         accel = - accel;
00154     }
00155     return accel;
00156 }
00157 
00158 
00159 SUMOReal
00160 MSCFModel_Wiedemann::following(SUMOReal sign) const {
00161     return myMinAccel * sign;
00162 }
00163 
00164 
00165 SUMOReal
00166 MSCFModel_Wiedemann::approaching(SUMOReal dv, SUMOReal dx, SUMOReal bx) const {
00167     // there is singularity in the formula. we do the sanity check outside
00168     return 0.5 * dv * dv / (bx - dx); // + predAccel at t-reaction_time if this is value is above a treshold
00169 }
00170 
00171 
00172 SUMOReal
00173 MSCFModel_Wiedemann::emergency(SUMOReal dv, SUMOReal dx) const {
00174     /* emergency according to A.Stebens
00175     // wiedemann assumes that dx will always be larger than myAX (sumo may
00176     // violate this assumption when crashing (-:
00177     if (dx > myAX) {
00178         SUMOReal accel = 0.5 * dv * dv / (myAX - dx); // + predAccel at t-reaction_time if this is value is above a treshold
00179         // one would assume that in an emergency accel must be negative. However the
00180         // wiedemann formula allows for accel = 0 whenever dv = 0
00181         assert(accel <= 0);
00182         return accel;
00183     } else {
00184         return = -myDecel;
00185     }
00186     */
00187 
00188     // emergency according to C.Werner
00189     return -myDecel;
00190 }
00191 
00192 
00193 SUMOReal
00194 MSCFModel_Wiedemann::krauss_vsafe(SUMOReal gap, SUMOReal predSpeed) const {
00195     if (predSpeed==0&&gap<0.01) {
00196         return 0;
00197     }
00198     const SUMOReal tauDecel = myDecel * myHeadwayTime;
00199     const SUMOReal speedReduction = ACCEL2SPEED(myDecel);
00200     const int predSteps = int(predSpeed / speedReduction);
00201     const SUMOReal leaderContrib = 2. * myDecel * (gap + SPEED2DIST(predSteps * predSpeed - speedReduction * predSteps * (predSteps+1) / 2));
00202     return (SUMOReal)(-tauDecel + sqrt(tauDecel*tauDecel + leaderContrib));
00203 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines