Aimsun Next microSDK¶
Aimsun Next microSDK Description¶
The Aimsun Next Platform makes extensive use of the plug-in concept, allowing external components to be loaded to extend the functionalities of the application. The Aimsun Next microSDK provides for coding of two C++ classes, for the vehicle and the simulation models used to replace the vehicle and vehicle behavior, and includes the functions required to register the new behavior model to replace the current Aimsun Next Microsimulation model. During the simulation the microsimulation model 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 Next Microsimulation developer will need to subclass both the A2SimVehicle and the A2BehavioralModel classes. The plug-in generated by the microSDK project is then registered using an XML file (see below) copied into the "plugins" folder found inside the Aimsun Next installation directory.
The A2SimVehicle Class¶
This class contains all the relevant vehicle data, methods to access them, and methods to update the vehicle every simulation step. These are organized into five categories, described below.
Constructor¶
simVehicleParticular ( void * handlerVehicle, unsigned short idhandler, bool isFictitiousVeh, unsigned int vehTypeId = 0 );
The constructor of the vehicle, which is usually called from the behavioral model function named "arrivalNewVehicle". The internal vehicle data are being processed by Aimsun and are not ready to be used, so do not try to use other functions inside the constructor to access data (get functions). If you need to access GKVehicle columns for retrieving custom attributes, use the vehTypeId provided, as shown in the code example.
Functions related to the vehicle attributes¶
bool **isFictitious**() const;
Returns whether the vehicle is real or fictitious (lane-changing shadow, incidents, yield, stop, traffic lights).
bool **isTrafficLight**() const;
Returns whether the vehicle is a traffic light (Traffic lights are simulated with fictional stopped vehicles to ensure the simulated vehicles come to a halt in the same way as they would when joining a queue)
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.
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.
double **getReactionTimeAtStop**() const;
Reaction time at Stop considering local variations.
double **getReactionTimeAtTrafficLight**() const;
Reaction time 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, 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 beginning 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 beginning of the current GKSection.
The GKSections are the sections provided by the GUI. If they contain segment points, they can 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;
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-fictitious vehicles. It will be deprecated and the getGap function should be used instead
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 on the same section, or 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, the function returns the shortest distance between the two vehicle fronts.
Functions related to Vehicle Paths¶
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 a 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) the function returns -1.
unsigned int **getIdNextTurning**() const;
Returns the index of the vehicle's next turn, or current turn if vehicle is in a node. If the next node is a join (very short node not containing any entity) the function returns -1.
bool **isInAReservedLane**() const;
Returns whether the vehicle is in a reserved lane or not
int **getNumberOfMainLanesInCurrentSection**() const;
Returns the number of lanes of the vehicle's current section not taking side lanes into account.
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 (must 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).
enum Type {eNone, eReservedLane, eTurning, eNotAllowedInfluence,eNotAllowed, ePTStopInfluence, eOnRamp, eLaneClosureInfluence,eIncidentInfluence, eLaneClosure, eIncident, ePTStop};
int **getObstacleType**() const;
Gets the type of Obstacle present in the current lane. Uses the enumerated type to return the obstacle type.
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)
Functions related to the Localization 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 * getReflectedVehicle() const;
Returns the vehicle reflected by a Nexo or a Conflict. maxDist serves as a tool for defining a custom visibility distance for the lookup. Not using the maxDist (negative value) will make the algorithm use the default for Gipps.
A2SimVehicle * **getRealLeader**(double &Shift, double maxDist = -1) const;
Returns the current leader (not fictitious) and its offset.
A2SimVehicle * getCooperationLeader(double &Shift) const;
Returns the cooperation leader and its offset.
A2SimVehicle * getTargetGapLeader (double &Shift) const;
Returns the cooperation leader and its offset.
bool hasSimpleLeader() const;
Returns whether the vehicle most restrictive leading condition is another normal vehicle (simple) or is any other road condition (complex) such as stop lines, conflicts, obstacles and the like. The infinity condition (not having leader) is considered simple and would return true.
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).
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 isCooperating() const;
Returns if the vehicle is cooperating with another vehicle to create a gap for it to do a lane change.
bool isTargetingGap() const;
Returns if the vehicle is targeting a gap on another lane, meaning that another vehicle is cooperating with him to let him do a lane change.
Functions related to other API usage¶
bool **hasMandatorySpeed**() const;
Returns if the vehicle has been set by API to have a set speed that is mandatory.
bool **hasModifiedSpeed**() const;
Returns if the vehicle has been set by API to consider using a set speed if conditions allow
double **getAPISpeed**() const;
Returns the speed given to the vehicle by API, either mandatory or modified, returns negative value if no speed set
Functions related to Car-Following¶
bool **applyAimsunCarFollowingModel**()const;
Applies the default car following model for this vehicle.
double **getAimsunCarFollowingSpeed**() const;
Computes the default car following speed for this vehicle.
double **getAccelerationComponentGippsModelSpeed**() const;
Computes the default acceleration speed component for this vehicle with its current characteristics.
double **getAccelerationComponentGippsModelSpeed**(double CurrentSpeed ,double TargetSpeed,double deltaRT) const;
Computes the acceleration speed component for this vehicle and specified input values.
double **getDecelerationComponentGippsModelSpeed**(double Distance2Obstacle) const;
Computes the default 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 deceleration speed component for this vehicle imposed by the vehicle Leader with offset ShiftPre where: .
- 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 set to 1), can be set to 0 if predictions are needed for the time t+RT.
Functions related to Lane-Changing¶
bool **applyAimsunLaneChangingModel**()const;
Applies the default lane changing model for this vehicle.
bool **isLaneChangingPossible**(int targetLane) const;
Returns whether lane changing is possible toward the targetlane (-1 is left, 0 current and 1 is right). Checks for: lack of solid line and that the vehicle is 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 values from 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 the Aimsun algorithms 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 the default Aimsun algorithms 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, int threadId)const;
Performs the Lane Changing toward targetlane. This function includes the gap acceptance.
void **setAsCourtesyVehicle**(const A2SimVehicle *veh2Yield, double ShiftVeh2Yield, int threadId);
Forces the current vehicle to cooperate with veh2Yield. ShiftVeh2Yield is the offset between the beginning of the section of the vehicle and the beginning of section of the leader. The veh2Yield being downstream it is ≥ 0.
The A2BehaviouralModel Class¶
The objective of this class is to update all the vehicles at every simulation step. Some of its virtual methods can be rewritten to fulfil the following requirements:
arrivalNewVehicle¶
This 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 fictitious vehicle is created during the simulation such a conflict or nexo vehicle.
removedVehicle¶
This 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 fictitious vehicle is removed during the simulation such as a conflict or nexo vehicles.
evaluateLaneChanging¶
This method allows re-implementation of a complete 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 default lane changing method. Vehicle functions that can be used in this method include:
- isLaneChangingPossible
- isGapAcceptable
- setAsCourtesyVehicle
- applyLaneChanging
- assignAcceptedGap
- 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.
evaluateCarFollowing¶
This method provide for re-implementation of a complete 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 default Aimsun car following method. The outputs of this function are the new speed and new position of the vehicle. Vehicle functions that can be used in this method include:
- getAimsunCarFollowingSpeed
- getAccelerationComponentGippsModelSpeed
- getDecelerationComponentGippsModelSpeed
- 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 of modifying the key expressions used in the Aimsun Next car-following and lane-changing methods specifically the acceleration and deceleration speed components and the minimum gap used in the gap acceptance. The default implementation is shown as an example.
computeCarFollowingAccelerationComponentSpeed¶
This method and the corresponding computeCarFollowingDecelerationComponentSpeed method overwrite the 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:
- The vehicle chooses the next connection it is going to take.
- The vehicle is involved in a yield calculation being the priority vehicle or vehicle giving way.
- The vehicle estimates whether it can accelerate in a forward gap to perform lane changing.
- The vehicle is evaluating its new velocity with constrains from its current section.
- The vehicle is evaluating its new velocity with constrains from the following turn.
The computeCarFollowingDecelerationComponentSpeed method can be called many times by simulation steps for each vehicles with different input values when:
- When the vehicle is about to enter to check if it can enter behind the last vehicle present in the lane.
- The vehicle selects the next connection it is going to use.
- To check which potential leader is the most restrictive during leader evaluation in current lane or in target lane.
- To Vehicle is evaluating its new velocity taking different kinds of leaders into account such as current leader, BusStop, Obstacles, Priority Vehicle, Cooperation leader, Off ramp leader…
computeMinimumGap¶
This method overwrites the minimumGap criteria for Gap Acceptance throughout the entire simulation.It 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.
isVehicleGivingWay¶
This method overwrites the gap acceptance model at yields. It is called for each pair of yielding vehicle and potential priority vehicle involved in a yield. The yield model is executed before the lane changing and car-following models.
avoidCollision¶
This method is called once per vehicle and per simulation step, after all vehicles have been updated. The default action (obtained by returning false) is to move backwards those vehicles that would overlap with the preceding vehicle.
Simulation Methods¶
virtual double **getSimStep**();
Returns the simulation step.
virtual A2SimVehicle * **arrivalNewVehicle**( void *handlerVehicle, unsigned short idHandler, bool isFictitiousVeh, unsigned int vehTypeId) = 0;
Enters a new vehicle in the external model
virtual void removedVehicle( void *handlerVehicle, unsigned short idHandler, A2SimVehicle * a2simVeh ) = 0;
Removes a vehicle form the external model.
virtual bool **evaluateLaneChanging**( A2SimVehicle *vehicle ) = 0;
Evaluates the new lane and order of the vehicle.
virtual bool **evaluateCarFollowing**(A2SimVehicle *vehicle, double &newpos, double &newspeed) = 0;
Evaluates the new speed and position of the vehicle.
virtual double **computeCarFollowingAccelerationComponentSpeed**(A2SimVehicle *vehicle, double VelActual, double VelDeseada, double RestoCiclo)=0;
Computes 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;
Computes the deceleration component of the speed to be used throughout the entire model. Includes car-following in adjacent lane (aside).
virtual double **computeCarFollowingDecelerationComponentSpeedCore**(A2SimVehicle *vehicle, double speedVehicle, A2SimVehicle *vehicleLeader, double speedLeader, double gap, double leaderDecelerationEstimated)=0;
Computes 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;
Computes 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 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.
virtual int **evaluateLaneSelectionDiscretionary**(A2SimVehicle *vehicle,bool LeftLanePossible,bool RightLanePossible)=0;
Overrides the lane selection model among valid lanes if the vehicle is already in Zone 1.
virtual int **evaluateHasTime2CrossYellowState**(A2SimVehicle *vehicle, double distance2StopLine) = 0;
Called when the red signal behavior has been added (as a vehicle stopped). Return value: -1: no evaluated (and Aimsun Next will evaluate the vehicle following its internal model), 0: the vehicle has no time to cross, 1: the vehicle has time to cross.
The A2BehavioralModelCreator Class¶
This class will create a behavioral model class. The developer must subclass it to return a new model.
class A2BehavioralModelCreator{
public:
A2BehavioralModelCreator();
~ A2BehavioralModelCreator();
virtual A2BehavioralModel * newModel() = 0;
};
Registering a New Model¶
Aimsun Next loads all the plug-ins found in the plug-ins folder, /ProgramFiles/Aimsun/Aimsun Next X.X/plugins/.
Each plug-in is declared using an XML file. The name is not important except that Aimsun Next loads plug-ins in alphabetical order. For this reason it is recommended to number each plug-in to fix 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 Next 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.
When specifying an Experiment in a Dynamic Scenario, the external behavior can be enabled or disabled in the Behavior tab. This means a Scenario can be run with two Experiments, one with and one without the modified behavior and the difference in network behavior compared.
Windows Notes¶
In Windows, symbols must be explicitly exported. To do this, the following code: __declspec(dllexport) must be included. 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();