/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file MSDriverState.h14/// @author Michael Behrisch15/// @date Tue, 21 Apr 201516///17// A class representing a vehicle driver's current mental state18/****************************************************************************/192021/// @todo: check parameter admissibility in setter methods222324#pragma once25#include <config.h>2627#include <memory>28#include <utils/common/SUMOTime.h>29#include <utils/xml/SUMOXMLDefinitions.h>303132// ===========================================================================33// class definitions34// ===========================================================================35/// @class OUProcess36/// @brief An Ornstein-Uhlenbeck stochastic process37class OUProcess {38public:39/// @brief constructor40OUProcess(double initialState, double timeScale, double noiseIntensity);41/// @brief destructor42~OUProcess();4344/// @brief evolve for a time step of length dt.45void step(double dt);46/// @brief static version of the step()47static double step(double state, double dt, double timeScale, double noiseIntensity);4849/// @brief set the process' timescale to a new value50void setTimeScale(double timeScale) {51myTimeScale = timeScale;52};5354/// @brief set the process' noise intensity to a new value55void setNoiseIntensity(double noiseIntensity) {56myNoiseIntensity = noiseIntensity;57};5859/// @brief set the process' state to a new value60void setState(double state) {61myState = state;62};6364inline double getNoiseIntensity() const {65return myNoiseIntensity;66};6768inline double getTimeScale() const {69return myTimeScale;70};717273/// @brief Obtain the current state of the process74double getState() const;757677static SumoRNG* getRNG() {78return &myRNG;79}8081private:82/** @brief The current state of the process83*/84double myState;8586/** @brief The time scale of the process87*/88double myTimeScale;8990/** @brief The noise intensity of the process91*/92double myNoiseIntensity;9394/// @brief Random generator for OUProcesses95static SumoRNG myRNG;96};979899/// @class MSSimpleDriverState100/// @brief Provides an interface to an error whose fluctuation is controlled101/// via the driver's 'awareness', which can be controlled externally, @see MSDevice_ToC102class MSSimpleDriverState {103104public:105MSSimpleDriverState(MSVehicle* veh);106virtual ~MSSimpleDriverState() {};107108109/// @name Getter methods110///@{111inline double getMinAwareness() const {112return myMinAwareness;113}114115inline double getInitialAwareness() const {116return myInitialAwareness;117}118119inline double getErrorTimeScaleCoefficient() const {120return myErrorTimeScaleCoefficient;121}122123inline double getErrorNoiseIntensityCoefficient() const {124return myErrorNoiseIntensityCoefficient;125}126127inline double getErrorTimeScale() const {128return myError.getTimeScale();129}130131inline double getErrorNoiseIntensity() const {132return myError.getNoiseIntensity();133}134135inline double getSpeedDifferenceErrorCoefficient() const {136return mySpeedDifferenceErrorCoefficient;137}138139inline double getHeadwayErrorCoefficient() const {140return myHeadwayErrorCoefficient;141}142143inline double getFreeSpeedErrorCoefficient() const {144return myFreeSpeedErrorCoefficient;145}146147inline double getSpeedDifferenceChangePerceptionThreshold() const {148return mySpeedDifferenceChangePerceptionThreshold;149}150151inline double getHeadwayChangePerceptionThreshold() const {152return myHeadwayChangePerceptionThreshold;153}154155inline double getAwareness() const {156return myAwareness;157}158159inline double getMaximalReactionTime() const {160return myMaximalReactionTime;161}162163inline double getOriginalReactionTime() const {164return myOriginalReactionTime;165}166167inline double getActionStepLength() const {168return myActionStepLength;169}170171inline double getErrorState() const {172return myError.getState();173};174///@}175176177/// @name Setter methods178///@{179inline void setMinAwareness(const double value) {180myMinAwareness = value;181}182183inline void setInitialAwareness(const double value) {184myInitialAwareness = value;185}186187inline void setErrorTimeScaleCoefficient(const double value) {188myErrorTimeScaleCoefficient = value;189}190191inline void setErrorNoiseIntensityCoefficient(const double value) {192myErrorNoiseIntensityCoefficient = value;193}194195inline void setSpeedDifferenceErrorCoefficient(const double value) {196mySpeedDifferenceErrorCoefficient = value;197}198199inline void setHeadwayErrorCoefficient(const double value) {200myHeadwayErrorCoefficient = value;201}202203inline void setFreeSpeedErrorCoefficient(const double value) {204myFreeSpeedErrorCoefficient = value;205}206207inline void setSpeedDifferenceChangePerceptionThreshold(const double value) {208mySpeedDifferenceChangePerceptionThreshold = value;209}210211inline void setHeadwayChangePerceptionThreshold(const double value) {212myHeadwayChangePerceptionThreshold = value;213}214215inline void setMaximalReactionTime(const double value) {216myMaximalReactionTime = value;217updateReactionTime();218}219220inline void setOriginalReactionTime(const double value) {221myOriginalReactionTime = value;222updateReactionTime();223}224225void setAwareness(const double value);226227inline void setErrorState(const double state) {228myError.setState(state);229};230231inline void setErrorTimeScale(const double value) {232myError.setTimeScale(value);233}234235inline void setErrorNoiseIntensity(const double value) {236myError.setNoiseIntensity(value);237}238///@}239240/// @brief Trigger updates for the errorProcess, assumed gaps, etc241void update();242243244/// @brief Update the assumed gaps to the known objects according to245/// the corresponding perceived speed differences.246void updateAssumedGaps();247248/// @name Methods to obtain the current error quantities to be used by the car-following model249/// @see TCIModel250/// @{251// /// @see myAccelerationError252// inline double getAppliedAcceleration(double desiredAccel) {253// return desiredAccel + myError.getState();254// };255256/// @brief apply perception error to own speed257double getPerceivedOwnSpeed(double speed);258259/// @brief This method checks whether the errorneous speed difference that would be perceived for this step260/// differs sufficiently from the previously perceived to be actually perceived. If so, it sets the261/// flag myReactionFlag[objID]=true, which should be checked just after the call to this method because262/// it will be overwritten by subsequent calls.263double getPerceivedSpeedDifference(const double trueSpeedDifference, const double trueGap, const void* objID = nullptr);264/// @see myHeadwayPerceptionError265double getPerceivedHeadway(const double trueGap, const void* objID = nullptr);266/// @}267268inline void lockDebug() {269myDebugLock = true;270}271272inline void unlockDebug() {273myDebugLock = false;274}275276inline bool debugLocked() const {277return myDebugLock;278}279280private:281// @brief Update the current step duration282void updateStepDuration();283// Update the error process284void updateError();285// Update the reaction time (actionStepLength)286void updateReactionTime();287288private:289290/// @brief Vehicle corresponding to this driver state291MSVehicle* myVehicle;292293/// @brief Driver's 'awareness' \in [0,1]294double myAwareness;295/// @brief Minimal value for 'awareness' \in [0,1]296double myMinAwareness;297/// @brief Initial value for 'awareness' \in [0,1]298double myInitialAwareness;299/// @brief Driver's 'error', @see TCI_Model300OUProcess myError;301/// @brief Coefficient controlling the impact of awareness on the time scale of the error process302double myErrorTimeScaleCoefficient;303/// @brief Coefficient controlling the impact of awareness on the noise intensity of the error process304double myErrorNoiseIntensityCoefficient;305306/// @brief Scaling coefficients for the magnitude of errors307double mySpeedDifferenceErrorCoefficient;308double myHeadwayErrorCoefficient;309double myFreeSpeedErrorCoefficient;310/// @brief Thresholds above a change in the corresponding quantity is perceived.311/// @note In the comparison, we multiply the actual change amount by the current312/// gap to the object to reflect a more precise perception if the object is closer.313double myHeadwayChangePerceptionThreshold;314double mySpeedDifferenceChangePerceptionThreshold;315// // @brief if a perception threshold is passed for some object, a flag is set to induce a reaction to the object316// std::map<void*, bool> myReactionFlag;317318/// @brief Action step length (~current maximal reaction time) induced by awareness level319/// @note This interpolates linearly from myOriginalReactionTime for awareness==1320/// to myMaximalReactionTime for awareness==myMinAwareness321double myActionStepLength;322/// @brief Maximal reaction time (value set for the actionStepLength at awareness=1)323double myOriginalReactionTime;324/// @brief Maximal reaction time (value set for the actionStepLength at awareness=myMinAwareness)325double myMaximalReactionTime;326327/// @name Variables for tracking update instants328/// @see updateStepDuration()329/// @{330/// @brief Elapsed time since the last state update331double myStepDuration;332/// @brief Time point of the last state update333double myLastUpdateTime;334335336/// @brief The assumed gaps to different objects337/// @todo: update each step to incorporate the assumed change given a specific speed difference338std::map<const void*, double> myAssumedGap;339/// @brief The last perceived speed differences to the corresponding objects340std::map<const void*, double> myLastPerceivedSpeedDifference;341/// @}342343/// @brief Used to prevent infinite loops in debugging outputs, @see followSpeed() and stopSpeed() (of MSCFModel_Krauss, e.g.)344bool myDebugLock;345};346347348349350351///** @class MSDriverState352// * @brief An object representing a traffic item. Used for influencing353// * the task demand of the TCI car-following model.354// * @see MSCFModel_TCI355// */356//class MSDriverState {357//358//protected:359// /// @brief base class for VehicleCharacteristics, TLSCharacteristics, PedestrianCharacteristics, SpeedLimitCharacteristics, Junction Characteristics...360// /// @see TrafficItemType, @see MSCFModel_TCI361// struct MSTrafficItemCharacteristics {362// inline virtual ~MSTrafficItemCharacteristics() {};363// };364//365// // @brief Types of traffic items, @see TrafficItem366// enum MSTrafficItemType {367// TRAFFIC_ITEM_VEHICLE,368// TRAFFIC_ITEM_PEDESTRIAN,369// TRAFFIC_ITEM_SPEED_LIMIT,370// TRAFFIC_ITEM_JUNCTION371// };372//373// /** @class MSTrafficItem374// * @brief An object representing a traffic item. Used for influencing375// * the task demand of the TCI car-following model.376// * @see MSCFModel_TCI377// */378// struct MSTrafficItem {379// MSTrafficItem(MSTrafficItemType type, const std::string& id, std::shared_ptr<MSTrafficItemCharacteristics> data);380// static std::hash<std::string> hash;381// MSTrafficItemType type;382// size_t id_hash;383// std::shared_ptr<MSTrafficItemCharacteristics> data;384// double remainingIntegrationTime;385// double integrationDemand;386// double latentDemand;387// };388//389// struct JunctionCharacteristics : MSTrafficItemCharacteristics {390// JunctionCharacteristics(const MSJunction* junction, const MSLink* egoLink, double dist) :391// junction(junction), approachingLink(egoLink), dist(dist) {};392// const MSJunction* junction;393// const MSLink* approachingLink;394// double dist;395// };396//397// struct PedestrianCharacteristics : MSTrafficItemCharacteristics {398// PedestrianCharacteristics(const MSPerson* pedestrian, double dist) :399// pedestrian(pedestrian), dist(dist) {};400// const MSPerson* pedestrian;401// double dist;402// };403//404// struct SpeedLimitCharacteristics : MSTrafficItemCharacteristics {405// SpeedLimitCharacteristics(const MSLane* lane, double dist, double limit) :406// dist(dist), limit(limit), lane(lane) {};407// const MSLane* lane;408// double dist;409// double limit;410// };411//412// struct VehicleCharacteristics : MSTrafficItemCharacteristics {413// VehicleCharacteristics(const MSVehicle* foe, double longitudinalDist, double lateralDist, double relativeSpeed) :414// longitudinalDist(longitudinalDist), lateralDist(lateralDist), foe(foe), relativeSpeed(relativeSpeed) {};415// const MSVehicle* foe;416// double longitudinalDist;417// double lateralDist;418// double relativeSpeed;419// };420//421//422//public:423//424// MSDriverState(MSVehicle* veh);425// virtual ~MSDriverState() {};426//427// /// @name Interfaces to inform Driver Model about traffic items, which potentially428// /// influence the driving difficulty.429// /// @{430// /** @brief Informs about leader.431// */432// virtual void registerLeader(const MSVehicle* leader, double gap, double relativeSpeed, double latGap = -1.);433//434// /** @brief Informs about pedestrian.435// */436// virtual void registerPedestrian(const MSPerson* pedestrian, double gap);437//438// /** @brief Informs about upcoming speed limit reduction.439// */440// virtual void registerSpeedLimit(const MSLane* lane, double speedLimit, double dist);441//442// /** @brief Informs about upcoming junction.443// */444// virtual void registerJunction(MSLink* link, double dist);445//446// /** @brief Takes into account vehicle-specific factors for the driving demand447// * For instance, whether vehicle drives on an opposite direction lane, absolute speed, etc.448// */449// virtual void registerEgoVehicleState();450//451// /** @brief Trigger updates for the state variables according to the traffic situation452// * (present traffic items)453// */454// virtual void update();455// /// @}456//457//458// /// @name Methods to obtain the current error quantities to be used by the car-following model459// /// @see TCIModel460// /// @{461// /// @see myAccelerationError462// inline double getAppliedAcceleration(double desiredAccel) {463// return desiredAccel + myAccelerationError.getState();464// };465// /// @see mySpeedPerceptionError466// inline double getPerceivedSpeedDifference(double trueSpeedDifference) {467// return trueSpeedDifference + mySpeedPerceptionError.getState();468// };469// /// @see myHeadwayPerceptionError470// inline double getPerceivedHeadway(double trueGap) {471// return trueGap + myHeadwayPerceptionError.getState();472// };473// /// @see myActionStepLength474// inline double getActionStepLength(){475// return myActionStepLength;476// };477// /// @}478//479//480//private:481//482// /** @brief Updates the internal variables to track the time between483// * two calls to the state update (i.e., two action points). Needed for a consistent484// * evolution of the error processes.485// */486// void updateStepDuration();487//488// /** @brief Calculates a value for the task difficulty given the capability and the demand489// * and stores the result in myCurrentDrivingDifficulty.490// * @see difficultyFunction()491// */492// void calculateDrivingDifficulty();493//494//495// /** @brief Transformation of the quotient demand/capability to obtain the actual496// * difficulty value used to control driving performance.497// * @note The current implementation is a continuous piecewise affine function.498// * It has two regions with different slopes. A slight ascend, where the capability499// * is larger than the demand and a region of steeper ascend, where the demand500// * exceeds the capability.501// */502// double difficultyFunction(double demandCapabilityQuotient) const;503//504//505// /** @brief Updates the myTaskCapability in dependence of the myTaskDifficulty to model a reactive506// * level of attention. The characteristics of the process are determined by myHomeostasisDifficulty507// * and myCapabilityTimeScale.508// * @todo Review the implementation as simple exponential process.509// */510// void adaptTaskCapability();511//512//513// /// @name Updater for error processes.514// /// @{515// void updateAccelerationError();516// void updateSpeedPerceptionError();517// void updateHeadwayPerceptionError();518// void updateActionStepLength();519// /// @}520//521//522// /// @brief Updates the given error process523// void updateErrorProcess(OUProcess& errorProcess, double timeScaleCoefficient, double noiseIntensityCoefficient) const;524//525// /// @brief Initialize newly appeared traffic item526// void calculateLatentDemand(std::shared_ptr<MSTrafficItem> ti) const;527//528// /// @brief Calculate demand induced by the given junction529// double calculateLatentJunctionDemand(std::shared_ptr<JunctionCharacteristics> ch) const;530// /// @brief Calculate demand induced by the given pedestrian531// double calculateLatentPedestrianDemand(std::shared_ptr<PedestrianCharacteristics> ch) const;532// /// @brief Calculate demand induced by the given pedestrian533// double calculateLatentSpeedLimitDemand(std::shared_ptr<SpeedLimitCharacteristics> ch) const;534// /// @brief Calculate demand induced by the given vehicle535// double calculateLatentVehicleDemand(std::shared_ptr<VehicleCharacteristics> ch) const;536//537// /// @brief Calculate integration demand induced by the given junction538// double calculateJunctionIntegrationDemand(std::shared_ptr<JunctionCharacteristics> ch) const;539// /// @brief Calculate integration demand induced by the given pedestrian540// double calculatePedestrianIntegrationDemand(std::shared_ptr<PedestrianCharacteristics> ch) const;541// /// @brief Calculate integration demand induced by the given pedestrian542// double calculateSpeedLimitIntegrationDemand(std::shared_ptr<SpeedLimitCharacteristics> ch) const;543// /// @brief Calculate integration demand induced by the given vehicle544// double calculateVehicleIntegrationDemand(std::shared_ptr<VehicleCharacteristics> ch) const;545//546// /// @brief Register known traffic item to persist547// void updateItemIntegration(std::shared_ptr<MSTrafficItem> ti) const;548//549// /// @brief Determine the integration demand and duration for a newly encountered traffic item (updated in place)550// /// The integration demand takes effect during a short period after the first appearance of the item.551// void calculateIntegrationDemandAndTime(std::shared_ptr<MSTrafficItem> ti) const;552//553// /// @brief Calculate the integration time for an item approached with the given speed at given dist554// double calculateIntegrationTime(double dist, double speed) const;555//556// /// @brief Incorporate the item's demand into the total task demand.557// void integrateDemand(std::shared_ptr<MSTrafficItem> ti);558//559// /// @brief Called whenever the vehicle is notified about a traffic item encounter.560// void registerTrafficItem(std::shared_ptr<MSTrafficItem> ti);561//562//private:563//564// MSVehicle* myVehicle;565//566// /// @name Variables for tracking update instants567// /// @see updateStepDuration()568// /// @{569//570// /// @brief Elapsed time since the last state update571// double myStepDuration;572// /// @brief Time point of the last state update573// double myLastUpdateTime;574//575// /// @}576//577//578// /// @name Dynamical quantities for the driving performance579// /// @{580//581// /** @brief Task capability (combines static and dynamic factors specific to the driver and the situation,582// * total capability, attention, etc.). Follows myTaskDemand with some inertia (task-difficulty-homeostasis).583// */584// double myTaskCapability;585// double myMinTaskCapability, myMaxTaskCapability;586//587// /** @brief Task Demand (dynamic variable representing the total demand imposed on the driver by the driving situation and environment.588// * For instance, number, novelty and type of traffic participants in neighborhood, speed differences, road curvature,589// * headway to leader, number of lanes, traffic density, street signs, traffic lights)590// */591// double myTaskDemand;592// double myMaxTaskDemand;593//594// /** @brief Cached current value of the difficulty resulting from the combination of task capability and demand.595// * @see calculateDrivingDifficulty()596// */597// double myCurrentDrivingDifficulty;598// /// @brief Upper bound for myCurrentDrivingDifficulty599// double myMaxDifficulty;600// /** @brief Slopes for the dependence of the difficulty on the quotient of demand and capability.601// * @see difficultyFunction();602// */603// double mySubCriticalDifficultyCoefficient, mySuperCriticalDifficultyCoefficient;604//605// /// @}606//607// /// @name Field that reflect the current driving situation608// /// @{609// /// @brief Whether vehicle is driving on an opposite direction lane610// bool myAmOpposite;611// double myCurrentSpeed;612// double myCurrentAcceleration;613// /// @}614//615// /// @name Parameters for the dynamic adaptation of capability (attention) and demand616// /// @{617//618// /** @brief The desired value of the quotient myTaskDemand/myTaskCapability. Influences the fixed point of the619// * process myTaskCapability -> myTaskDemand, @see adaptTaskCapability()620// */621// double myHomeostasisDifficulty;622//623// /** @brief Determines the time scale for the adaptation process of task capability towards the624// * task difficulty.625// */626// double myCapabilityTimeScale;627//628// /** @brief Factor for the demand if driving on an opposite direction lane629// */630// double myOppositeDirectionDrivingDemandFactor;631//632// /// @}633//634//635//636// /** @brief Traffic items in the current neighborhood of the vehicle.637// */638// std::map<size_t, std::shared_ptr<MSTrafficItem> > myTrafficItems;639// std::map<size_t, std::shared_ptr<MSTrafficItem> > myNewTrafficItems;640//641// /// @name Actuation errors642// /// @{643//644// /** @brief Acceleration error. Modelled as an Ornstein-Uhlenbeck process.645// * @see updateAccelerationError()646// */647// OUProcess myAccelerationError;648// /// @brief Coefficient controlling the impact of driving difficulty on the time scale of the acceleration error process649// double myAccelerationErrorTimeScaleCoefficient;650// /// @brief Coefficient controlling the impact of driving difficulty on the noise intensity of the acceleration error process651// double myAccelerationErrorNoiseIntensityCoefficient;652//653// /// @brief Action step length (increases with task difficulty, is similar to reaction time)654// double myActionStepLength;655// /// @brief Proportionality factor of myActionStepLength and driving difficulty656// double myActionStepLengthCoefficient;657// /// @brief Bounds for the action step length658// double myMinActionStepLength, myMaxActionStepLength;659//660// /// @}661//662//663// /// @name Perception errors664// /// @{665//666// /** @brief Error of estimation of the relative speeds of neighboring vehicles667// */668// OUProcess mySpeedPerceptionError;669// /// @brief Coefficient controlling the impact of driving difficulty on the time scale of the relative speed error process670// double mySpeedPerceptionErrorTimeScaleCoefficient;671// /// @brief Coefficient controlling the impact of driving difficulty on the noise intensity of the relative speed error process672// double mySpeedPerceptionErrorNoiseIntensityCoefficient;673//674// /** @brief Error of estimation of the distance/headways of neighboring vehicles675// */676// OUProcess myHeadwayPerceptionError;677// /// @brief Coefficient controlling the impact of driving difficulty on the time scale of the headway error process678// double myHeadwayPerceptionErrorTimeScaleCoefficient;679// /// @brief Coefficient controlling the impact of driving difficulty on the noise intensity of the headway error process680// double myHeadwayPerceptionErrorNoiseIntensityCoefficient;681//682// /// @}683//};684685686687/// @brief Default values for the MSDriverState parameters688struct DriverStateDefaults {689// static double myMinTaskCapability;690// static double myMaxTaskCapability;691// static double myMaxTaskDemand;692// static double myMaxDifficulty;693// static double mySubCriticalDifficultyCoefficient;694// static double mySuperCriticalDifficultyCoefficient;695// static double myHomeostasisDifficulty;696// static double myCapabilityTimeScale;697// static double myAccelerationErrorTimeScaleCoefficient;698// static double myAccelerationErrorNoiseIntensityCoefficient;699// static double myActionStepLengthCoefficient;700// static double myMinActionStepLength;701// static double myMaxActionStepLength;702// static double mySpeedPerceptionErrorTimeScaleCoefficient;703// static double mySpeedPerceptionErrorNoiseIntensityCoefficient;704// static double myHeadwayPerceptionErrorTimeScaleCoefficient;705// static double myHeadwayPerceptionErrorNoiseIntensityCoefficient;706// static double myOppositeDirectionDrivingFactor;707708// for MSSimpleDriverState709static double minAwareness;710static double initialAwareness;711static double errorTimeScaleCoefficient;712static double errorNoiseIntensityCoefficient;713static double speedDifferenceErrorCoefficient;714static double speedDifferenceChangePerceptionThreshold;715static double headwayChangePerceptionThreshold;716static double headwayErrorCoefficient;717static double freeSpeedErrorCoefficient;718static double maximalReactionTimeFactor;719};720721722