Basic Scripting¶
Hello World¶
Every programmer starts by writing the same program: to print "Hello World!". In this example we will print it in the Aimsun Next Log window. The steps are:
- Start Aimsun Next.
- Create a new Network.
- Create a new Python Empty Script (from the Project Menu). The new script will appear in the Project Window.
- Open the Python Script (double click over it).
- Write the Hello World application. Note that the editor recognizes the syntax and colors the text.
- Press the Execute button.
- Look in the Log window.
Looking For Everything¶
"Hello World" is merely static text, it is more interesting to take information from the model. This example prints the identifier and name of all the sections in a network. This requires iteration over all the sections.
sectionType = model.getType( "GKSection" )
for types in model.getCatalog().getUsedSubTypesFromType( sectionType ):
for s in types.values():
print("Section ID: %i Name: %s" % (s.getId(), s.getName()))
Aimsun Next has a catalog (GKCatalog) in each model that includes all the objects in it, both graphical and non-graphical, sorted by type and identifier. This catalog is accessible using the GKModel::getCatalog method.
Before iterating over the catalog, the code looks for the type of the objects to be used. In this case, it will be GKSection.
sectionType = model.getType( "GKSection" )
The code then looks for all the types that are, or derived from, GKSection:
for types in model.getCatalog().getUsedSubTypesFromType( sectionType ):
And for each type the code looks for all the objects of that type:
for s in types.values():
In this example, there are two noteworthy points: why to iterate twice, and the array style access.
We need to iterate over all the types that derive from GKSection as it is possible that a developer writing a plug-in can extend the GKSection type by creating a new type based on GKSection. This is part of the object oriented capabilities of C++ and of the extensibility of Aimsun Next. Therefore we should always write code to anticipate this possibility.
The second point is the array style access which is related to how Python deals with mapping objects. The variable types is a map of objects (a dictionary) that uses the id of each object as key. In order to iterate over the objects in the dictionary the values() method is used.
Looking for Something¶
The catalog can also be used to find a particular object by:
- identifier (GKCatalog::find method).
- external identifier (GKCatalog::findObjectByExternalId method).
- or name (GKCatalog::findByName method).
Note that Aimsun Next guarantees that the identifier is unique so a search will find either one object or none, but the name and the external identifier are not necessarily unique so a search might return multiple objects.
Modifying an object¶
This example is a script to reduce the speed of all sections by 10%:
sectionType = model.getType( "GKSection" )
for types in model.getCatalog().getUsedSubTypesFromType( sectionType ):
for section in types.values():
section.setSpeed( section.getSpeed() * 0.9 )
model.getCommander().addCommand( None )
This code extends the previous search to now get the speed of the section with GKSection::getSpeed(), modify it and rewrite it with GKSection::setSpeed(). The new element in this code is this line:
model.getCommander().addCommand( None )
This tells Aimsun Next to clear the undo buffer because a modification that cannot be undone has been executed. In Aimsun Next, only operations performed calling a GKCommand implement methods to revert the modification and thus can be undone (see GKCommand Class Reference for a list). Because the script uses the method setSpeed() to modify the model, this operation doesn’t place a revert command in the undo buffer. In this situation, if an undo operation is performed, it will revert not this modification, but the last undoable one, and will also be operating on a model that has meanwhile been changed. To avoid errors, the undo buffer must therefore be cleared.
All scripts that modify the model should end with this line, unless they perform modifications only using GKCommands.