Aimsun microSDK v8

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 33

Aimsun 8 microSDK Manual

May 2014
© 2005-2014 TSS-Transport Simulation Systems
About this Manual
The present manual describes the Aimsun microSDK. This component,
to be used, requires a license of both Aimsun and the Aimsun
Microsimulator SDK.

Our aim is to keep you informed of any changes so that you can
continue to get the best from Aimsun. As always, please be aware that
product data is subject to change without notice.

TSS-Transport Simulation Systems has made every effort to ensure that


all the information contained within this manual is as accurate as
possible. It should be stressed however, that this is a draft version of
the latest Aimsun microSDK Manual and as such, some of the contents
may be subject to change.

As always, we welcome your feedback (support@aimsun.com) in our


continued improvement and addition of new features to Aimsun

Copyright
Copyright  1992-2014 TSS-Transport Simulation Systems, S.L.

All rights reserved. TSS-Transport Simulation Systems products contain


certain trade secrets and confidential and proprietary information of
TSS-Transport Simulation Systems. Use of this copyright notice is
precautionary and does not imply publication or disclosure.

Trademark
Aimsun and Aimsun NG are trademark of TSS-Transport Simulation
Systems. S.L.
Other brand or product names are trademarks or registered trademarks
of their respective holders.
ABOUT THIS MANUAL .......................................................................................... 2
COPYRIGHT .................................................................................................... 2
TRADEMARK.................................................................................................... 2
1 GENERIC REQUIREMENTS............................................................................. 4
2 STARTER’S GUIDE...................................................................................... 5
2.1 INSTALLATION ........................................................................................ 5
2.2 EDITING .............................................................................................. 6
2.3 COMPILATION......................................................................................... 7
2.4 CHANGING THE NAME OF THE .DLL.................................................................... 8
2.5 MODIFYING THE .XML FILE ............................................................................ 8
2.6 EXAMPLES ............................................................................................ 9
2.7 TESTING THE DIFFERENT EXAMPLES ................................................................. 10
3 DESCRIPTION OF MICROSDK ........................................................................ 11
3.1 THE A2SIMVEHICLE CLASS ......................................................................... 12
3.1.1 Functions relative to the vehicle´s attributes ........................................ 12
3.1.2 Functions relative to the vehicle´s Path ............................................... 14
3.1.3 Functions relative to the localisation of surrounding vehicles ..................... 16
3.1.4 Functions relative to Car-Following ..................................................... 17
3.1.5 Functions relative to Lane-Changing .................................................... 17
3.2 THE A2BEHAVIORALMODEL CLASS .................................................................. 18
3.3 THE A2BEHAVIORALMODELCREATOR CLASS ........................................................ 21
3.4 REGISTERING A NEW MODEL ........................................................................ 22
3.5 WINDOWS NOTES ................................................................................... 22
4 INTERACTION BETWEEN EXTERNAL AND AIMSUN BEHAVIORAL MODELS ................. 23
5 ACTIVATION OF BEHAVIORAL MODELS DURING A SIMULATION ............................. 24
6 EXAMPLE OF MICROSCOPIC MODEL SDK USE.................................................... 25

Draft 3
1 Generic Requirements
The aim of using the microSDK is to enable the integration of new behavioral
models overwriting the models offered by default in Aimsun. The
requirements to do it are the following:

1. Visual C++:

a. The new behavioural models must be built in Visual C++


2005. We provide two projects (microSDKsample1 and
microSDKsample2) that can be taken as the base to your model.

2. Architectural Requirements:

a. Allow the new behavioral models plug-ins to be applied


globally to the whole network or applied locally to a subset of
specific sections (even at lane level, in order to distinguish different
behavioral models in the same section, for instance the behavioral
model of a central lane can be completely different to that for an
on-ramp or off-ramp lane).

b. Allow the plug-in to implement only a subset of behavioral


models overwriting only the models defined by the user and for the
remaining use the default models implemented in Aimsun.

c. Allow the new behavioral models to be dynamically


loaded on simulation start-up using a dynamic library (or
equivalent).

3. Model Requirements:

a. The new behavioral models must be called every


simulation step and for each individual vehicle.

b. Allow to the new behavioral models to add new attributes


to the vehicle object to be stored during the simulation.

c. The new behavioral models must have access to all the


information required to implement the model logic (for instance the
current position and speed of the leader, etc).

Draft 4
2 Starter’s Guide
2.1 Installation
Installing the additional MicroSDK module will create the Aimsun
microSDK directory at the following location: TSS-Transport
Simulation Systems\Aimsun 8.0\programming\

You first need to copy the entire Aimsun microSDK directory into a
Document folder where you have full permissions (for e.g. inside
Documents/).

The Aimsun microSDK directory contains 5 folders:

 docs
 ext
 include
 lib
 sample V2005

The docs folder contains the Aimsun 8 microSDK User Manual.

The ext, include and lib folders contain libraries and declaration
files that will be used to build the .dll files and that you MUST NOT
modify.

Finally, the sample V2005 contains five examples microSDK


projects.

To open a project, you need to have Visual Studio 2005 installed on


your computer. Double click on the microSDKsample.sln file of any
of the examples. The following window pops up. The content of
the project can be viewed by clicking on the cross left to
microSDKsample.

Draft 5
2.2 Editing
The Header and Source Files can be displayed by double clicking on
their name.

Draft 6
2.3 Compilation
To build the .dll file, click on Build->Rebuild microSDKsample.

The output of the compilation appears in the bottom window.


Check for errors and warnings!

Note that you can decide whether to build a Debug or Release .dll.
The Debug .dll should be used for the development of the project
as it allows to use the debugger and follows each step of the
execution. The Release .dll will be executed faster and should be
used during the operational phase.

Draft 7
2.4 Changing the name of the .dll

The output file name can be changed in the microSDKsample


Properties folder accessed from a right click on the cross left of
microSDKsample.

2.5 Modifying the .xml file


The .xml file can be edited with any text editor such as Notepad for
e.g. You should only modify the second line according to the name
of the .dll file to be used:

Draft 8
2.6 Examples
We have prepared five microSDK examples which cover the basic
behavioral model implementations possibilities currently available
in Aimsun 8 microSDK:

1.CarFollowingModel: computes the new value for the speed and


position of all vehicles using the Gipps Car Following Model. All
remaining parts of the model are controlled by Aimsun´s default
model.

2.CarFollowingAccelerationModel: only modifies the acceleration


component of the Car Following Model . Any function returning a
positive (or null) speed can be implemented. All remaining parts of
the model are controlled by Aimsun´s default model.

3.LaneChangingModel: uses the valid lanes defined by Aimsun´s


lookahead model to derive whether a lane changing is necessary,
looks for adjacent gap and either performs a lane changing if the
gap is acceptable or adapts to it. All remaining parts of the model
are controlled by Aimsun´s default model.

4.GiveWayModel: uses the giveway information for each vehicle


provided by Aimsun to decide whether to give way or not.

5.FullModel: it is the example described in the User Manual and


that uses all the above.

Draft 9
2.7 Testing the different examples
In order to test the different examples please follow the steps detailed
below:

1. Build the Debug .dll and copy both the .xml and the .dll file into the
following directory: C:\Program Files\TSS-Transport Simulation
Systems\Aimsun 8.0\plugins\aimsun\models
2. Launch Aimsun 8 and open the Network: microSDKtestNetwork.ang
present in the sample V2005 directory.
3. Open the microSDKsample project and put a breakpoint in one of the
functions of the file behavioralModelParticular.cxx.
4. Attach it to the process using: Debug->Attach to Process and select the
Aimsun.exe process.
5. Run the simulation and follows what the .dll is computing.

Draft 10
3 Description of microSDK
Aimsun Platform makes extensive us of the plug-in concept, allowing external
components to be loaded by Aimsun to extend the functionalities of the
application. Each plug-in is coded in C++ as a DLL (Windows) or as a shared
library (Linux, Mac OS X) using the Aimsun platformSDK.

In the same way Aimsun Microscopic Simulator includes an SDK that allow the
modification or replacement of the current models. This microSDK uses the
same mechanism as in the Aimsun Platform although the capabilities of the
plug-in are different.

Aimsun Micro also offers an API (for C, C++ and Python) to access and modify a
simulation as it runs. This API is not the Aimsun microSDK.

The Aimsun microSDK allows the coding of two C++ classes, for the vehicle
and the simulation models used to update such vehicles, and includes the
required functions to register the new model (to replace the current Aimsun
Micro models).

During the simulation Aimsun Micro updates each vehicle using the specified
model. Each vehicle is an instance of the A2SimVehicle class or a class that
derives from it. A model is an instance of the A2BehavioralModel or a class
that derives from it.

An Aimsun Micro developer will subclass both the A2SimVehicle and the
A2BehavioralModel classes.

A plug-in is registered using an XML file (see below) copied into the Aimsun
folder found inside the Plugins folder.

Draft 11
3.1 The A2SimVehicle Class
This class contains all the relevant vehicle data, methods to access it and
methods to update the vehicle every simulation step. We ordered them into
five categories:

3.1.1 Functions relative to the vehicle´s attributes

bool isFictitious() const;


Returns whether the vehicle is real or fictitious (lane-changing shadow,
incidents, giveway, stop, semafore).

bool isTrafficLight() const;


Returns whether the vehicle is a traffic light.

int getId() const;


Returns the Id of the vehicle, 0 if Fictitious and >0 otherwise.

unsigned int getVehType() const;


Returns the Id of the vehicle type if the vehicle.

double getAcceleration( ) const;


Maximum acceleration of the vehicle as specified in the vehicle type
considering local variations.

double getDeceleration( ) const;


Normal deceleration of the vehicle as defined in the vehicle type considering
local variations.

double getDecelerationMax( ) const;


Maximum deceleration of the vehicle as defined in the vehicle type.

double getEstimationOfLeadersDeceleration(A2SimVehicle *leader, double


LeaderSpeed) const;
Estimation of the leader´s deceleration used in the Gipps Model.

double getDecelerationVariationFactor(const bool ImprudentCase)const;


Returns the deceleration factor accepted by the vehicle for imprudent lane
changing case

unsigned int getReactionSteps() const;


Reaction time expressed in number of simulation steps considering local
variations.

double getReactionTime() const;


Reaction time in seconds considering local variations.

Draft 12
double getReactionTimeAtStop() const;
ReactionTime at Stop considering local variations.

double getReactionTimeAtTrafficLight() const;


ReactionTime at Traffic Light considering local variations.

double getLength() const;


Length of the vehicle as defined in the vehicle type.

double getMinimumDistanceInterVeh() const;


Minimum gap in front of the vehicle as defined in the vehicle type.

double getMinimumDistanceInterVeh(A2SimVehicle *leader) const;


Minimum gap in front of the vehicle considering minimum safety distance and
corrected for the vehicle type of the leader (0 if traffic light or incident).

double getFreeFlowSpeed() const;


Maximum Desired Speed of the vehicle for the current lane.

double getSensitivityFactor() const;


Sensitivity Factor to Leader´s deceleration as defined in the vehicle type.

double getMinimumHeadway() const;


Minimum Headway in front of the vehicle as defined in the vehicle type.

bool isUpdated() const;


Returns true if the vehicle has already been updated, false otherwise.

double getPosition( const unsigned int state) const;


Returns the position of the vehicle at time (t – state * simulationStep) (units:
m) from the begining of the current A2KSection.
A2KSections are the sections used by the micro simulator. All positions used in
the micro model refer to the A2KSections!

double getPositionInGKSection( const unsigned int state) const;


Returns the position of the vehicle at time (t – state * simulationStep) (units:
m) from the begining of the current GKSection.
The GKSections are the sections provided by the GUI. If they contain segment
points, they may be cut into different A2KSections at these segment points by
the model.

double getPositionInTargetlane( double X,int targetLane) const;


Returns the position in targetlane, equivalent to X in current lane;

double getSpeed( const unsigned int state) const;


Returns the speed of the vehicle at time (t – state * simulationStep) (units:
m/s).

void getCoordinates( double &xfront, double &yfront, double &xback, double


&yback) const;

Draft 13
It returns the world coordinates of the middle point of a vehicle front bumper
(xfront, yfront) and the world coordinates of the middle point of a vehicle
rear bumper (xback, yback).

double getGap(A2SimVehicle *vehUp,double ShiftUp,A2SimVehicle


*vehDown,double ShiftDw,double &Xup, double &Vup, double &Xdw, double
&Vdw,int time=1)const;
Returns the Gap between vehUp and vehDown, their position and speeds at
time t=t-RTup, t if time=0 or t+dt if time=-1

double getPositionReferenceVeh( const unsigned int state, A2SimVehicle


*vehReference, const unsigned stateVehRef) const;
This function only works for non-ficticious vehicles. It is becoming obsolete
and the getGap function should be favoured!
Get the position of the vehicle at time (t - state * simulationStep), taking the
reference vehicle vehReference(units: m). The vehicle and reference vehicle
do not need to be neither on the same section, nor on the same lane,
although the output does not take the difference in length across the sections
but only along them. If not located in the same section, it returns the shortest
distance between the two vehicle´s fronts.

3.1.2 Functions relative to the vehicle´s Path

unsigned int getIdCurrentLane() const;


Returns the index of the vehicle´s current lane, 1 being the rightmost lane of
the section.

unsigned int getIdCurrentSection() const;


Returns the index of the vehicle´s current section, or next section if vehicle is
in Node.

unsigned int getIdNextSection() const;


Returns the index of the vehicle´s next section.

unsigned int getIdNextJunction() const;


Returns the index of the vehicle´s next junction, or current junction if vehicle
is in a Node. If the next junction is a join (very short node not containing any
entity) it returns -1.

unsigned int getIdNextTurning() const;


Returns the index of the vehicle´s next turning, or current turning if vehicle is
in a Node. If the next node is a join (very short node not containing any
entity) it returns -1.

int getNumberOfMainLanesInCurrentSection() const;


Returns the number of lanes of the vehicle´s current section not taking side
lanes into account.

Draft 14
int getNumberOfLanesInCurrentSection() const;
Returns the total number of lanes of the vehicle´s current section.

int getNumberOfMainLanesInNextSection() const;


Returns the number of lanes of the vehicle´s next section not taking side
lanes into account.

int getNumberOfLanesInNextSection() const;


Returns the total number of lanes of the vehicle´s next section.

bool IsLaneOnRamp(int targetlane) const;


Returns true if targetlane (-1 is left, 0 current and 1 is right) is an entrance
lateral lane.

bool isCurrentLaneInNode() const;


Returns true if the current lane is inside a node.

double getDensity(const int targetLane) const;


Returns the density inside the targetlane (-1 is left, 0 is current, 1 is right) in
veh/m.

double getLaneDensity(const int lane) const;


Returns the density inside the lane (1 is the rightmost lane of the section) in
veh/m.

int getNumberOfVehiclesStoppedInLane(const int lane) const;


Returns the number of vehicles with speed=0 inside the lane (1 is the
rightmost lane of the section) in veh/m.

double getAverageSpeedAHead(const int targetLane, const double


maximumDist, const int maximumNbVehs) const;
Returns the average speed of the first maximumNbVehs vehicles located
within maximumDist (meters) inside the targetlane (-1 is left, 0 is current, 1 is
right) in m/s.

double getAverageLaneSpeedAHead(const int ordenCarril, double


maximumDist, int maximumNbVehs) const;
Returns the average speed of the first maximumNbVehs vehicles located
within maximumDist (meters) inside the lane (1 is the rightmost lane of the
section) in m/s.

void setNextSection(int idNextSection) const;


Sets the vehicle´s next section (needs to be called before entering the node).

void setTargetLaneInDownStreamSection(int idNextSection, int


nextTargetLane) const;
Sets the vehicle´s next lane and next section (needs to be called before
entering the node).

int getObstacleType() const;

Draft 15
Gets the type of Obstacle present in the current lane. Uses the following:
enum Type {eNone, eReservedLane, eTurning, eNotAllowedInfluence,
eNotAllowed, ePTStopInfluence, eOnRamp, eLaneClosureInfluence,
eIncidentInfluence, eLaneClosure, eIncident, ePTStop};

int getObstacleTypeInLane(const int lane) const;


Gets the type of Obstacle present in the lane (1 is the rightmost lane).

double getDistance2Obstacle() const;


Gets the distance to the next Obstacle present in the current lane.

double getDistance2ObstacleInLane(const int lane) const;


Gets the distance to the next Obstacle present in the lane (1 is the rightmost
lane).

double getDistanceOfInfluenceOfObstacleInLane(const int ordenCarril)


const;
Gets the distance of influence to the next Obstacle present in the lane (1 is
the rightmost lane).

int getNbLaneChanges2ReachNextValidLane() const;


Gets the number of lane changes to be made to reach a valid lane (>0 means
right).

3.1.3 Functions relative to the localisation of surrounding


vehicles

A2SimVehicle * getLeader(double &Shift) const;


Returns the current leader (can be fictitious) and its offset. Shift is the offset
between the beginning of the section of the vehicle and the beginning of
section of the leader. The leader being downstream it is >=0.

A2SimVehicle * getRealLeader(double &Shift) const;


Returns the current leader (not fictitious) and its offset.

A2SimVehicle * getFollower(double &Shift) const;


Returns the current follower (can be fictitious) and its offset. Shift is the
offset between the beginning of the section of the vehicle and the beginning
of section of the follower. The follower being upstream it is <=0.

A2SimVehicle * getRealFollower(double &Shift) const;


Returns the current follower (not fictitious) and its offset.

void getUpDown(int targetlane, double shiftPos, A2SimVehicle *&vehUp,


double &shiftUp, A2SimVehicle *&vehDown, double &shiftDown ) const;
Returns the current up and down vehicles (can be fictitious) and their offsets
in the targetlane (-1 is left, 0 current and 1 is right).

Draft 16
void getRealUpDown(int targetlane, double shiftPos, A2SimVehicle
*&vehUpReal, double &shiftUp, A2SimVehicle *&vehDownReal, double
&shiftDown) const;
Returns the current up and down vehicles (can be fictitious) and their offsets
(not fictitious) in the targetlane (-1 is left, 0 current and 1 is right).

3.1.4 Functions relative to Car-Following

bool applyAimsunCarFollowingModel()const;
Applies the Default Aimsun Car Following Model for this vehicle.

double getAimsunCarFollowingSpeed() const;


Computes the Default Aimsun Car Following Speed for this vehicle.

double getAccelerationComponentGippsModelSpeed() const;


Computes the Default Aimsun Gipps Acceleration Speed Component for this
vehicle with its current characteristics.

double getAccelerationComponentGippsModelSpeed(double
VelActual,double VelDeseada,double RestoCiclo) const;
Computes the Aimsun Gipps Acceleration Speed Component for this vehicle
and specified input values.

double getDecelerationComponentGippsModelSpeed(double
Distance2Obstacle) const;
Computes the Default Aimsun Gipps Deceleration Speed Component for this
vehicle imposed by a standing obstacle located a Distance2Obstacle from the
vehicle.

double getDecelerationComponentGippsModelSpeed(const A2SimVehicle


*Leader,double ShiftPre,bool controlDecelMax,bool aside,int time) const;
Computes the Default Aimsun Gipps Deceleration Speed Component for this
vehicle imposed by the vehicle Leader with offset ShiftPre.
-controlDecelMax bounds the result to be compatible with braking
capabilities
-aside uses a special implementation that allows a smoother adaptation in
case of negative gaps if the Leader located in a different lane.
-time (normally sets to 1), can be set 0 if predictions are needed for the
time t+RT.

3.1.5 Functions relative to Lane-Changing


bool applyAimsunLaneChangingModel()const;
Applies the Default Aimsun Lane Changing Model for this vehicle.

bool isLaneChangingPossible(int targetLane) const;

Draft 17
Returns whether lane changing is possible toward the targetlane (-1 is left, 0
current and 1 is right). Checks for: lack of solid line, vehicle not currently
changing lane.

bool isGapAcceptable(int targetlane,double XposInpEntObj,const


A2SimVehicle *pVehUp,double ShiftUp,const A2SimVehicle *pVehDw,double
ShiftDw)const;
Returns whether the gap between pVehUp and pVehDw is acceptable
according to the CarFollowingDecelerationComponentSpeed.

void assignAcceptedGap(int targetlane,double XPosInpEntObj,const


A2SimVehicle *vehUp,double ShiftUp,const A2SimVehicle *vehDown,double
ShiftDw,int threadId) const;
Puts the vehicle in the list of vehicles to change lane, letting Aimsun decide
whether it is possible in terms of priority with respect to other vehicles
willing to change lane.

void targetNewGap(int targetlane, double XPosInpEntObj, const A2SimVehicle


*vehUpReal, double ShiftUp, const A2SimVehicle *vehDownReal, double
ShiftDw, int threadId)const;
Looks for a new target gap for cooperation around the gap between vehUp
and vehDown.

void assignNewTargetGap (double XPosInpEntObj,const A2SimVehicle


*vehUpReal,double ShiftUp,const A2SimVehicle *vehDownReal,double
ShiftDw,int threadId) const;
Puts the vehicle in the list of vehicles to target the gap between vehUp and
vehDown (vehUp will cooperate depending on the cooperation parameters),
letting Aimsun decide whether it is possible in terms of priority with respect
to other vehicles willing to target the same gap.

void applyLaneChanging(const int targetlane, const A2SimVehicle *pVehUp,


const A2SimVehicle *pVehDw);
Performs the Lane Changing toward targetlane between pVehUp and pVehDw.

void setAsCourtesyVehicle(const A2SimVehicle *veh2Yield);


Forces the current vehicle to cooperate with veh2Yield

3.2 The A2BehavioralModel Class


The objective of this class is to update all the vehicles every simulation step.
The user may rewrite some of its virtual methods to fulfil the following
requirements:

 The arrivalNewVehicle function creates a new vehicle. Usually this


method will return not an instance of A2SimVehicle but an instance of a
subclass of this class. This method is called each time a new vehicle is
generated; either when a real vehicle is generated just before it enters
the network or the virtual queue; or when a ficticious vehicle is created
during the simulation such as conflicts or nexo vehicles.

Draft 18
 The removedVehicle function deletes a vehicle. This method is called
each time a vehicle is removed from the model; either when a real vehicle
exits the network; or when a ficticious vehicle is removed during the
simulation such as conflicts or nexo vehicles.

 The evaluateLaneChanging method allows to re-implement a fully new


Lane-Changing logic and must return a bool set to true if the vehicle is
using it and false if the vehicle is using the Aimsun´s Lane Changing
method. Vehicle´s functions that may be used in this method include:
o isLaneChangingPossible
o isGapAcceptable
o setAsCourtesyVehicle
o applyLaneChanging
o assignAcceptedGap
o applyAimsunLaneChangingModel
This method is called one time per simulation step for each vehicle. It is
called after each vehicle has identified its leader; before any vehicle
changes lane and before the car following method.

 The evaluateCarFollowing method allows to re-implement a fully new


Car-Following logic and must return a bool set to true if the vehicle is
using it and false if the vehicle is using the Aimsun´s Car Following
method. The outputs of this function are the new speed and new position
of the vehicle. Vehicle´s functions that may be used in this method
include:
o getAimsunCarFollowingSpeed
o getAccelerationComponentGippsModelSpeed
o getDecelerationComponentGippsModelSpeed
o applyAimsunCarFollowingModel
This method is called after all vehicles have changed lane and identified
their (new) leader; before any vehicle has updated speed and position.

An alternative to implementing full car-following and/or lane changing


methods consists in modifying the key expressions used in Aimsun´s car-
following and lane-changing methods namely the acceleration and
deceleration speed components and the minimum gap used in the gap
acceptance. The default implementation is shown as an example.

 The computeCarFollowingAccelerationComponentSpeed and


computeCarFollowingDecelerationComponentSpeed methods overwrites
the corresponding expressions of the Gipps model throughout the entire
simulation (affecting the car following but also the lane changing
motivation and gap acceptance).

The computeCarFollowingAccelerationComponentSpeed method can be


called many times by simulation step for each vehicle, with different
input values when:
o The vehicle choses the next connexion it is going to take.

Draft 19
o The vehicle is involved in a giveway calculation being the priority
vehicle or vehicle giving way.
o The vehicle estimates whether it can accelerate in a forward gap to
perform lane changing.
o The vehicle is evaluating its new velocity with constrains from its
current section.
o The vehicle is evaluating its new velocity with constrains from the
following turning.

The computeCarFollowingDecelerationComponentSpeed method can be


called many times by simulation steps for each vehicles with different
input values when:
o When the vehicle is about to enter to check if it can enter behind the
last vehicle present in the lane.
o The Vehicle selects the next connexion it is going to use.
o To check which potential leader is the most restrictive during leader
evaluation in current lane or in target lane.
o To Vehicle is evaluating its new velocity taking different kinds of
leaders into account such as current leader, BusStop, Obstacles,
Prioritary Vehicle, Cooperation leader, Off ramp leader…

 The computeMinimumGap method overwrites the minimumGap criterium


for Gap Acceptance throughout the entire simulation.
This method is called when the vehicle is trying to change lane and
evaluates the minimum gaps required with respect to the up and
downstream vehicles located in the target lane. It is also called when the
vehicle evaluates whether it can adapt to a vehicle requesting cooperation
and to compute the speed behind a leader located in an adjacent lane.

 The isVehicleGivingWay method overwrites the gap acceptance model at


giveways. This method is called for each pair of yielding vehicle and
potential prioritary vehicle involved in a give way. The giveway model is
executed before the lane changing and car-following models.

 The avoidCollision method is called once per vehicle and per simulation
step, after all vehicles have been updated. The Aimsun default (obtained
by returning false) is to move backwards the vehicles that would overlap
with the preceding vehicle.

virtual double getSimStep();


Returns the simulation step.

virtual A2SimVehicle * arrivalNewVehicle( void *handlerVehicle, unsigned


short idHandler, bool isFictitiousVeh) = 0;
Enters a new vehicle in the external model

virtual void removedVehicle( void *handlerVehicle, unsigned short idHandler,


A2SimVehicle * a2simVeh ) = 0;

Draft 20
Removes a vehicle form the external model.

virtual bool evaluateLaneChanging( A2SimVehicle *vehicle ) = 0;


Method that evaluates the new lane and order of the vehicle.

virtual bool evaluateCarFollowing(A2SimVehicle *vehicle, double &newpos,


double &newspeed) = 0;
Method that evaluates the new speed and position of the vehicle.

virtual double computeCarFollowingAccelerationComponentSpeed


(A2SimVehicle *vehicle, double VelActual, double VelDeseada, double
RestoCiclo)=0;
Expression of the acceleration component of the speed to be used throughout
the entire model.

virtual double computeCarFollowingDecelerationComponentSpeed


(A2SimVehicle *vehicle, double Shift, A2SimVehicle *vehicleLeader, double
ShiftLeader,bool controlDecelMax=false, bool aside=false,int time=1)=0;
Expression of the deceleration component of the speed to be used throughout
the entire model.

virtual double computeMinimumGap (A2SimVehicle *vehicleUp, A2SimVehicle


*vehicleDown,double Xup,double Vup,double Xdw,double Vdw,double
Gap,bool ImprudentCase=false, bool VehicleIspVehDw=false)=0;
Expression of the minimum gap required between the upstream and
downstream vehicle to ensure continuity.

virtual bool isVehicleGivingWay(A2SimVehicle *vehicleGiveWay, A2SimVehicle


*vehiclePrioritary, yieldInfo *givewayInfo, int &Yield)=0;
Evaluates whether the vehicle vehicleYield should mark a stop to avoid
collision with vehiclePrio or whether it can go.

virtual bool avoidCollision(A2SimVehicle *vehicle,A2SimVehicle


*vehiclePre,double ShiftPre)=0;
Uses the information about the vehicle and its leader and corrects the
position of the vehicle if necessary.

3.3 The A2BehavioralModelCreator Class


This class will create a behavioral model class. The developer will subclass it
to return a new model.

class A2BehavioralModelCreator{

public:
A2BehavioralModelCreator();
~ A2BehavioralModelCreator();

virtual A2BehavioralModel * newModel() = 0;


};

Draft 21
3.4 Registering a New Model
As Aimsun loads all the plug-ins found in the Plugins folder, Aimsun Micro will
load its plug-ins found in the PLUGINS\Aimsun\MODELS folder.

Each plug-in is declared using an XML file. The name is not important except
for the fact that Aimsun loads plug-ins using an alphabetical order. For this
reason it is recommended to number each plug-in (as done in the Plugins
folder) to ensure the loading order.

The XML contains the following tags:


<plugin>
<name>MyModel</name>
<lib>mymodel</lib>
</plugin>

Where name is the unique name of the plug-in using ASCII characters and lib is
the library (without any file extension) that contains the code.

Aimsun will load the plug-in and look for a C function that will create an
instance of the A2BehavioralModelCreator. The C function will be called as
the plug-in name as found in the XML file with the Factory suffix. In the
previous example the plug-in was called MyModel so the function will be
called MyModelFactory.

3.5 Windows Notes


In Windows symbols must be explicitly exported. In order to do so you must
include the following code: __declspec(dllexport). This is true for both classes
and C functions. It is common to use of the following define statements to
deal with this problem (the file A2BehavioralModelUtil.h contains these
statements):
#ifdef _WIN32
#ifdef _A2BehavioralModelUtil_DLL
#define A2BehavioralModelUtil_EXPORT __declspec(dllexport)
#else
#define A2BehavioralModelUtil_EXPORT __declspec(dllimport)
#endif
#else
#define A2BehavioralModelUtil_EXPORT
#endif

The Makefile (or the Visual Settings) will define _A2BehavioralModelUtil_DLL


when compiling the plug-in. And each class and function will be decorated as:

class A2BehavioralModelUtil_EXPORT behavioralModelParticularCreator: public


A2BehavioralModelCreator
{

};

extern "C" A2BehavioralModelUtil_EXPORT A2BehavioralModelCreator * MyModelFactory();

Draft 22
4 Interaction between External and Aimsun Behavioral
Models
During a simulation, when external behavioral models are loaded and
enabled, the update vehicle process is determined by the following
algorithm:

for each Vehicle:


apply external lane changing method if implemented
otherwise apply Aimsun lane-changing model
endfor

for each Vehicle:


apply external car following method if implemented
otherwise apply Aimsun car following model
endfor

for each Vehicle:


Aimsun then updates all vehicles according to
new lane, speed and positions.
endfor

When an external model is active, this algorithm forces to update all


vehicles using the external behavioral models and, in case that the
external model doesn’t update the vehicle, Aimsun applies its default
behavioral models. It assures that every simulation step all vehicles are
updated. This allows to the user update a subset of vehicles and/or by
time and/or by location.

Draft 23
5 Activation of Behavioral Models during a Simulation
The behavioral models registered using XML file located in
PLUGINS/Aimsun/MODELS folder are loaded automatically when Aimsun
starts. In any case during a simulation, running a replication, the user can
enable (that means the external behavioral models are applied) or disable
(the Aimsun behavioral models are applied) the external behavioral models
at level of experiment.

Draft 24
6 Example of Microscopic Model SDK use
In this section we provide examples for the four files that the user
may modify to design a new model:

File simVehicleParticular.h
//-*-Mode: C++;-*-
#ifndef _simVehicleParticular_h_
#define _simVehicleParticular_h_

#include "A2BehavioralModelUtil.h"
#include "A2SimVehicle.h"

class A2BEHAVIORALEXPORT simVehicleParticular: public A2SimVehicle


{
private:
float newAttribute;

public:
simVehicleParticular ( void *handlerVehicle, unsigned short idhandler, bool
isFictitiousVeh );
~ simVehicleParticular ();
const float getnewAttribute() const;
void setnewAttribute ( float avalue);
};

#endif

File simVehicleParticular.cpp
#include "simVehicleParticular.h"

simVehicleParticular:: simVehicleParticular ( void *handlerVehicle, unsigned short


idhandler, bool isFictitiousVeh ) : A2SimVehicle( handlerVehicle, idhandler,
isFictitiousVeh )
{
newAttribute=0;
}

simVehicleParticular::~simVehicleParticular (){}

const float simVehicleParticular::getnewAttribute() const


{
return newAttribute;
}

void simVehicleParticular::setnewAttribute ( float avalue)


{
newAttribute=avalue;
}

File behavioralModelParticular.h
//-*-Mode: C++;-*-

Draft 25
#ifndef _behavioralModelParticular_h_
#define _behavioralModelParticular_h_

#include "A2BehavioralModelUtil.h"
#include "A2BehavioralModel.h"
#include "simVehicleParticular.h"

enum Type {eNone, eReservedLane, eTurning, eNotAllowedInfluence, eNotAllowed,


ePTStopInfluence, eOnRamp, eLaneClosureInfluence, eIncidentInfluence,
eLaneClosure, eIncident, ePTStop};

class A2BEHAVIORALEXPORT behavioralModelParticular: public A2BehavioralModel


{

private:
int seed;
double p_distance;

public:

behavioralModelParticular();

~behavioralModelParticular();

bool evaluateCarFollowing( A2SimVehicle *vehicle, double &newpos, double


&newspeed);

bool evaluateLaneChanging( A2SimVehicle *vehicle ,int threadId);

double computeCarFollowingAccelerationComponentSpeed(A2SimVehicle
*vehicle,double VelActual,double VelDeseada, double RestoCiclo);

double computeCarFollowingDecelerationComponentSpeed (A2SimVehicle


*vehicle,double Shift,A2SimVehicle *vehicleLeader,double ShiftLeader,bool
controlDecelMax=false, bool aside=false,int time=1);

double computeMinimumGap(A2SimVehicle *vehicleUp,A2SimVehicle


*vehicleDown,double Xup,double Vup,double Xdw,double Vdw,double Gap,bool
ImprudentCase=false, bool VehicleIspVehDw=false);

bool isVehicleGivingWay( A2SimVehicle *vehicleGiveWay, A2SimVehicle *vehiclePrio,


yieldInfo *givewayInfo, int &Yield);

simVehicleParticular * arrivalNewVehicle( void *handlerVehicle, unsigned short


idHandler, bool isFictitiousVeh);

virtual void removedVehicle( void *handlerVehicle, unsigned short idHandler,


A2SimVehicle * a2simVeh );

bool avoidCollision(A2SimVehicle *vehicle,A2SimVehicle *vehiclePre,double


ShiftPre);

double getGippsAccelerationSpeed (simVehicleParticular *vehicle,double


VelActual,double VelDeseada, double RestoCiclo);

double getGippsDecelerationSpeed (simVehicleParticular *vehicle,double


Shift,simVehicleParticular *vehicleLeader,double ShiftLeader,bool
controlDecelMax=false, bool aside=false,int time=1);

Draft 26
double getGippsMinimumGap(simVehicleParticular* pVehUp,simVehicleParticular*
pVehDw,double Xup,double Vup,double Xdw,double Vdw,double Gap,bool
ImprudentCase=false,bool VehicleIspVehDw=false);
double getIDMAccelerationSpeed (simVehicleParticular *vehicle,double
VelActual,double VelDeseada, double RestoCiclo);

double getIDMDecelerationSpeed (simVehicleParticular *vehicle,double


Shift,simVehicleParticular *vehicleLeader,double ShiftLeader);

double getIDMMinimumGap(simVehicleParticular *vehicle,simVehicleParticular


*leader,double Vup,double Vdw,double Gap);

};

#endif

File behavioralModelParticular.cpp
#include "behavioralModelParticular.h"
#include "simVehicleParticular.h"
#include "AKIProxie.h"
#include "ANGConProxie.h"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
using namespace std;
#define Tolerancia 0.01
#define DBL_MAX 1.7976931348623158e+308

bool UseIDM=false;

behavioralModelParticular::behavioralModelParticular(): A2BehavioralModel()
{
const unsigned short *randomSeedString = AKIConvertFromAsciiString(
"GKReplication::randomSeedAtt" );
seed = ANGConnGetAttributeValueInt( ANGConnGetAttribute( randomSeedString ),
ANGConnGetReplicationId() );
const unsigned short *param0= AKIConvertFromAsciiString(
"GKExperiment::p_distance" );
p_distance = ANGConnGetAttributeValueDouble( ANGConnGetAttribute( param0
),ANGConnGetExperimentId());
}

behavioralModelParticular::~behavioralModelParticular(){}

bool behavioralModelParticular::evaluateLaneChanging(A2SimVehicle *vehicle,int


threadId)
{
//Define Lane Changing Direction
int LaneChangingDirection=vehicle->getNbLaneChanges2ReachNextValidLane();
if (LaneChangingDirection==0){
return false;
}
if (abs(LaneChangingDirection)>1){
LaneChangingDirection=LaneChangingDirection/abs(LaneChangingDirection);
}
bool RightLanePossible=vehicle->isLaneChangingPossible(1);
bool LeftLanePossible=vehicle->isLaneChangingPossible(-1);
if (LaneChangingDirection==-1 && !LeftLanePossible){

Draft 27
LaneChangingDirection=0;
} else if (LaneChangingDirection==1 && !RightLanePossible){
LaneChangingDirection=0;
}

if (LaneChangingDirection!=0){

double XPosTargetlane=vehicle->getPositionInTargetlane(vehicle-
>getPosition(0),LaneChangingDirection);

//Define whether a lane changing attempt is made or not


bool Intentacambio=true;
if (Intentacambio){
//Lane Changing attempt
A2SimVehicle* pVehDw=NULL;
A2SimVehicle *pVehUp=NULL;
double ShiftUp=0,ShiftDw=0;
vehicle->getUpDown(LaneChangingDirection, XPosTargetlane, pVehUp, ShiftUp,
pVehDw, ShiftDw);
bool GapAcceptable=vehicle->isGapAcceptable(LaneChangingDirection,
XPosTargetlane, pVehUp, ShiftUp, pVehDw, ShiftDw);
if(GapAcceptable){
vehicle->assignAcceptedGap(LaneChangingDirection, XPosTargetlane,(const
simVehicleParticular*)pVehUp,ShiftUp,(const
simVehicleParticular*)pVehDw,ShiftDw,threadId);
return true;
}
}

//Target New Gap


if (abs(vehicle->getNbLaneChanges2ReachNextValidLane())>0){
A2SimVehicle * pVehDwReal=NULL;
A2SimVehicle * pVehUpReal=NULL;
double ShiftUpReal=0,ShiftDwReal=0;
vehicle->getRealUpDown( LaneChangingDirection, XPosTargetlane, pVehUpReal,
ShiftUpReal, pVehDwReal, ShiftDwReal);
vehicle->targetNewGap( LaneChangingDirection, XPosTargetlane, pVehUpReal,
ShiftUpReal, pVehDwReal,ShiftDwReal,threadId);
if (pVehUpReal||pVehDwReal){
vehicle->assignNewTargetGap(XPosTargetlane,(const simVehicleParticular*)
pVehUpReal, ShiftUpReal, (const simVehicleParticular*) pVehDwReal, ShiftDwReal,
threadId);
}
}
}
return true;
}

bool behavioralModelParticular::evaluateCarFollowing(A2SimVehicle *vehicle, double


&newpos, double &newspeed)
{
newspeed=vehicle->getAimsunCarFollowingSpeed();
double increment=0;
if (newspeed>=vehicle->getSpeed(vehicle->isUpdated())){
increment=newspeed*getSimStep();
}else{
increment=0.5*(newspeed+vehicle->getSpeed(vehicle->isUpdated()))*getSimStep();
}
newpos=vehicle->getPosition(vehicle->isUpdated()) + increment;
return true;

Draft 28
}

double
behavioralModelParticular::computeCarFollowingAccelerationComponentSpeed(
A2SimVehicle *vehicle, double VelActual, double VelDeseada, double RestoCiclo){

double VelPropia = 0;
if (UseIDM){
VelPropia = getIDMAccelerationSpeed( (simVehicleParticular*)vehicle, VelActual,
VelDeseada, RestoCiclo);
}else{
VelPropia = getGippsAccelerationSpeed( (simVehicleParticular*)vehicle, VelActual,
VelDeseada, RestoCiclo);
}
return VelPropia;
}

double
behavioralModelParticular::computeCarFollowingDecelerationComponentSpeed
(A2SimVehicle *vehicle,double Shift,A2SimVehicle *vehicleLeader,double
ShiftLeader,bool controlDecelMax, bool aside,int time){
double VelImpuesta=0;
if (UseIDM){

VelImpuesta=getIDMDecelerationSpeed((simVehicleParticular*)vehicle,Shift,(simVehicl
eParticular*)vehicleLeader,ShiftLeader);
}else{

VelImpuesta=getGippsDecelerationSpeed((simVehicleParticular*)vehicle,Shift,(simVehi
cleParticular*)vehicleLeader,ShiftLeader,controlDecelMax,aside,time);
}
return VelImpuesta;
}

double behavioralModelParticular::computeMinimumGap(A2SimVehicle
*vehicleUp,A2SimVehicle *vehicleDown,double Xup,double Vup,double Xdw,double
Vdw,double Gap,bool ImprudentCase,bool VehicleIspVehDw)
{
double GapMin=0;
if (UseIDM){

GapMin=getIDMMinimumGap((simVehicleParticular*)vehicleUp,(simVehicleParticular*)v
ehicleDown,Vup, Vdw, Gap);
}else{

GapMin=getGippsMinimumGap((simVehicleParticular*)vehicleUp,(simVehicleParticular*
)vehicleDown, Xup, Vup, Xdw, Vdw, Gap, ImprudentCase, VehicleIspVehDw);
}
return GapMin;
}

bool behavioralModelParticular::isVehicleGivingWay(A2SimVehicle *vehicleGiveWay,


A2SimVehicle *vehiclePrio, yieldInfo *givewayInfo, int &Yield){

if (givewayInfo->isVehiclePrioWithinVisibility && (givewayInfo-


>isVehicleGiveWayComingNext || (!givewayInfo-
>isVehiclePrioRealAndReachingConflict && vehiclePrio->getSpeed(0)>0) ||
givewayInfo->isVehiclePrioLeaderOfVehicleGiveWay)){

Draft 29
//Vehicle is passing before Ceda arrives
//or
//Vehicle is fictitious or not coming to this conflict (and not stopped)
Yield=-1;
}else{
bool prioritaryComesNext = (givewayInfo->isVehiclePrioComingNext
|| givewayInfo->isVehiclePrioAfectedByStop
|| givewayInfo->isVehiclePrioAfectedByYellowBox
|| (givewayInfo->isVehiclePrioAfectedByGiveWay && !givewayInfo-
>isVehiclePrioPrioritaryBasedOnWaitingTime) || ((vehiclePrio->getSpeed(0)==0) &&
(givewayInfo->passingTimeVehicleGiveWay <= 0.0)));

if (givewayInfo->isVehiclePrioWithinVisibility && givewayInfo-


>isVehiclePrioRealAndReachingConflict && !prioritaryComesNext){
Yield=1;
}else{
//Vehicle not visibile will not be considered!
//Vehicle not prioritary but stopped
//Ceda is Passing before Prioritary arrives
Yield=0;
}
}
return true;
}

simVehicleParticular * behavioralModelParticular::arrivalNewVehicle( void


*handlerVehicle, unsigned short idHandler, bool isFictitiousVeh){
simVehicleParticular * res = new simVehicleParticular( handlerVehicle, idHandler,
isFictitiousVeh );
if (!isFictitiousVeh) {
res->setnewAttribute(2);
}
return res;
}
void behavioralModelParticular::removedVehicle( void *handlerVehicle, unsigned short
idHandler, A2SimVehicle * a2simVeh )
{

//Gipps
double behavioralModelParticular::getGippsAccelerationSpeed(simVehicleParticular
*vehicle,double VelActual,double VelDeseada, double RestoCiclo)
{
// Calcula l'acceleracio tenint en compte les pendents
double X=VelActual / VelDeseada;
double VelPropia = min(VelDeseada, VelActual + 2.5 * vehicle-
>getAcceleration() * RestoCiclo * (1.0 - X)* sqrt( 0.025 + X));
if (VelPropia<VelActual){
VelPropia=max(VelPropia,max(0.,VelActual + (0.5 * vehicle-
>getDeceleration() * RestoCiclo)));
}
return VelPropia;
}

double behavioralModelParticular::getGippsDecelerationSpeed(simVehicleParticular
*vehicle,double Shift,simVehicleParticular *leader,double ShiftLeader,bool
controlDecelMax,bool aside,int time)
{

Draft 30
double PosAnterior,VelAnterior,PosAnteriorLeader,VelAnteriorLeader;
double GapAnterior=vehicle->getGap( Shift, leader, ShiftLeader, PosAnterior,
VelAnterior, PosAnteriorLeader, VelAnteriorLeader,time);
double RT=vehicle->getReactionTime();
double DecelEstimada=0;
if (VelAnteriorLeader>Tolerancia){
DecelEstimada=vehicle-
>getEstimationOfLeadersDeceleration(leader,VelAnteriorLeader);
}
double bn=vehicle->getDeceleration();
double bnTau=bn*RT;
double VelImpuesta=bnTau;
double factorSqrt=0;
if(VelAnteriorLeader<Tolerancia){
factorSqrt = (bnTau* bnTau) - vehicle->getDeceleration() * (2.0 * GapAnterior -
(VelAnterior * RT));
}else if (VelAnteriorLeader<DBL_MAX){
factorSqrt = (bnTau * bnTau) - vehicle->getDeceleration() * (2.0 *
GapAnterior - (VelAnterior * RT) - ((VelAnteriorLeader * VelAnteriorLeader)/
DecelEstimada));
}else{
VelImpuesta = DBL_MAX;
}
if (factorSqrt>0){
VelImpuesta = bnTau + (double) sqrt(factorSqrt);
}

if (aside){
//SpeedAnterior imposed by Car-Following on side lane > Tolerancia to avoid RT at
stop
double GapMin=getGippsMinimumGap(vehicle, leader, PosAnterior, VelAnterior,
PosAnteriorLeader, VelAnteriorLeader, GapAnterior, false, false);
GapMin=GapAnterior-GapMin;
if (GapMin<0){
double Distance2Obstacle=DBL_MAX;
if (vehicle->getObstacleType()!=eNone){
Distance2Obstacle=vehicle->getDistance2Obstacle()/abs(vehicle-
>getNbLaneChanges2ReachNextValidLane());
Distance2Obstacle=max(0.,Distance2Obstacle-max(VelAnteriorLeader*RT,
leader->getLength()));
}
double minimo = Distance2Obstacle;
double AdaptationDistance=max(vehicle->getFreeFlowSpeed()*RT,vehicle-
>getLength());
if (vehicle->getObstacleType()==eOnRamp){
minimo = min(minimo,3*AdaptationDistance);
}else{
minimo = min(minimo,AdaptationDistance);
}
double maximo = max(VelAnteriorLeader,Tolerancia);
double expParam = 0.5*(1.-VelAnterior/maximo*(1-(GapMin)/minimo));
double expValue = (float)exp( expParam );//la función exp en 32/64 bits retorna
el mismo valor usándola de este modo
VelImpuesta = VelAnterior*expValue;
}
}
if (controlDecelMax){
double VelMin=0;
if (aside){
VelMin=max(0.,VelAnterior+vehicle->getDeceleration()*RT);

Draft 31
}else{
VelMin=max(0.,VelAnterior+vehicle->getDecelerationMax()*RT);
}
if (VelImpuesta<VelMin){
VelImpuesta=VelMin;
}
}
return VelImpuesta;
}

double behavioralModelParticular::getGippsMinimumGap(simVehicleParticular*
pVehUp,simVehicleParticular* pVehDw,double Xup,double Vup,double Xdw,double
Vdw,double Gap,bool ImprudentCase,bool VehicleIspVehDw)
{
double DecelFactorUp=1;
if (VehicleIspVehDw){
DecelFactorUp=pVehDw->getDecelerationVariationFactor(ImprudentCase);
}else{
DecelFactorUp=pVehUp->getDecelerationVariationFactor(ImprudentCase);
}
double tau=pVehUp->getReactionTime();
double GapMin=0;
if (Vdw<0.01){
GapMin=max(0.,0.5*Vup*tau+max(0.,-Vup*Vup/(2*pVehUp-
>getDeceleration())+DecelFactorUp*(1.-0.5*DecelFactorUp)*pVehUp-
>getDeceleration()*tau*tau+(1-DecelFactorUp)*Vup*tau));
if (DecelFactorUp>-Vup/(pVehUp->getDeceleration())*tau){
GapMin=max(0.,0.5*Vup*tau);
}
}else{
double DecelEstimada=pVehUp-
>getEstimationOfLeadersDeceleration(pVehDw,Vdw);
GapMin=max(0.,(Vdw*Vdw)/(2*DecelEstimada)+0.5*Vup*tau+max(0.,-
Vup*Vup/(2*pVehUp->getDeceleration())+DecelFactorUp*(1.-
0.5*DecelFactorUp)*pVehUp->getDeceleration()*tau*tau+(1-DecelFactorUp)*Vup*tau));
if (DecelFactorUp>-Vup/(pVehUp->getDeceleration())*tau){
GapMin=max(0.,(Vdw*Vdw)/(2*DecelEstimada)+0.5*Vup*tau);
}
}
return GapMin;
}

double behavioralModelParticular::getIDMAccelerationSpeed(simVehicleParticular
*vehicle,double VelActual,double VelDeseada, double RestoCiclo)
{
double X=VelActual/VelDeseada;
double acceleration=max(vehicle->getDeceleration(),vehicle->getAcceleration()*(1.-
pow(X,4)));
double speed=max(0.,VelActual+acceleration*RestoCiclo);
return speed;
}

double behavioralModelParticular::getIDMDecelerationSpeed(simVehicleParticular
*vehicle,double Shift,simVehicleParticular *leader,double ShiftLeader)
{
double a=vehicle->getAcceleration();
double VelAnterior,PosAnterior,VelAnteriorLeader,PosAnteriorLeader;

Draft 32
double GapAnterior=vehicle-
>getGap(Shift,leader,ShiftLeader,PosAnterior,VelAnterior,PosAnteriorLeader,VelAnter
iorLeader);
double
DesiredGap=getIDMMinimumGap(vehicle,leader,VelAnterior,VelAnteriorLeader,
GapAnterior);
double X=VelAnterior/vehicle->getFreeFlowSpeed();
double acceleration=a*(1-pow(X,4)-
(DesiredGap/GapAnterior)*(DesiredGap/GapAnterior));
double speed=max(0.,VelAnterior+acceleration*getSimStep());
return speed;
}

double behavioralModelParticular::getIDMMinimumGap(simVehicleParticular*
pVehUp,simVehicleParticular* pVehDw,double VelAnterior,double
VelAnteriorLeader,double GapAnterior)
{
double a=pVehUp->getAcceleration();
double b=-pVehUp->getDeceleration();
double DesiredGap=pVehUp-
>getMinimumDistanceInterVeh()+max(0.,VelAnterior*pVehUp-
>getMinimumHeadway()+VelAnterior*(VelAnteriorLeader-VelAnterior)/(2*sqrt(a*b));
return DesiredGap;
}

bool behavioralModelParticular::avoidCollision(A2SimVehicle *vehicle,A2SimVehicle


*vehiclePre,double ShiftPre)
{
return false;
}

Contents of the XML, located in PLUGINS\Aimsun\MODELS:

<plugin>
<name>behavioralModelParticular</name>
<lib>behavioralModelParticular</lib>
</plugin>

Draft 33

You might also like