Professional Documents
Culture Documents
Aimsun microSDK v8
Aimsun microSDK v8
Aimsun microSDK v8
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.
Copyright
Copyright 1992-2014 TSS-Transport Simulation Systems, S.L.
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++:
2. Architectural Requirements:
3. Model Requirements:
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/).
docs
ext
include
lib
sample V2005
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.
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.
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
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:
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:
Draft 12
double getReactionTimeAtStop() const;
ReactionTime at Stop considering local variations.
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).
Draft 14
int getNumberOfLanesInCurrentSection() const;
Returns the total number of lanes of the vehicle´s current section.
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};
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).
bool applyAimsunCarFollowingModel()const;
Applies the Default Aimsun Car Following Model for this vehicle.
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.
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.
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.
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 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.
Draft 20
Removes a vehicle form the external model.
class A2BehavioralModelCreator{
public:
A2BehavioralModelCreator();
~ A2BehavioralModelCreator();
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.
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.
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:
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"
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 (){}
File behavioralModelParticular.h
//-*-Mode: C++;-*-
Draft 25
#ifndef _behavioralModelParticular_h_
#define _behavioralModelParticular_h_
#include "A2BehavioralModelUtil.h"
#include "A2BehavioralModel.h"
#include "simVehicleParticular.h"
private:
int seed;
double p_distance;
public:
behavioralModelParticular();
~behavioralModelParticular();
double computeCarFollowingAccelerationComponentSpeed(A2SimVehicle
*vehicle,double VelActual,double VelDeseada, double RestoCiclo);
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);
};
#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(){}
Draft 27
LaneChangingDirection=0;
} else if (LaneChangingDirection==1 && !RightLanePossible){
LaneChangingDirection=0;
}
if (LaneChangingDirection!=0){
double XPosTargetlane=vehicle->getPositionInTargetlane(vehicle-
>getPosition(0),LaneChangingDirection);
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;
}
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)));
//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;
}
<plugin>
<name>behavioralModelParticular</name>
<lib>behavioralModelParticular</lib>
</plugin>
Draft 33