Using Lua to Write Custom Cost Functions for Aimsun Next

July 2024 — Technical note #88

Tessa Hayman

Product Specialist

Did you know that you can write custom cost functions for Aimsun Next transport models using Lua in addition to Python?  

Lua is a lightweight scripting language known for its simplicity, efficiency and ease of integration. Lua has been included in our modelling software since the launch of Aimsun Next version 22 as we wanted users to be able to write custom functions while also enabling faster run times for complex models because functions in Lua are evaluated in parallel. Lua uses minimal resources and focuses on performance, so it is well suited to this task. In this technical note we will look at some of the common functions used in cost functions and how these can be written in Lua.  

Note that you can still write functions in Python if you prefer, and that Scripting only supports Python. The main advantage of Python is the availability of a multitude of libraries, such as Pandas or NumPy. Whilst these libraries are not usually used in cost functions, it should be noted that Lua has limited libraries for use.  

There are several important differences between Python and Lua that you should be aware of. There are numerous articles listing these, but in this technical note we will cover the main differences so that you can quickly convert your cost functions to Lua. 

Variables 

Lua treats variables differently to Python. Variables are created when they are referred to rather than when their value has been set. Until a value has been set, the value of a variables = nil.  

e.g.  

print (a) à nil 

a = 1 

print (a) -> 1 

In addition to this, Lua treats the scope of variables differently than Python. E.g. in Python, a variable is local unless made global explicitly using the ‘global’ key word. Lua works the other way around. E.g. variables are global, unless explicitly declared as local using the ‘local’ keyword. 

e.g. 

In addition to this, there is a third variety of variables called a table field. This can hold anything except nil including functions. It is not likely to be used however in cost functions.  

 

Comments 

Comments can be added by using –[[text]] instead of ‘’’ OR – instead of # 
e.g. Lua 

–[[This is a comment]] 

e.g Python 

#This is a comment 

In Lua # instead gives the length of a variable e.g. #comment -> 7 

 

Arrays 

In Python, the position of objects in a list starts at 0. However, in Lua the convention is that arrays start with index 1.  

e.g. Lua 

 list=[0,1,2] 

list[1] = 0 

 

Python 

list = [0,1,2] 

list[1] = 1  

 

Functions 

In Lua to define a function you also need to add an end statement at the end of the function. E.g.  

function cost(turn) 

calculatedcost = turn:length2D() 

return calculatedcost 

end 

Note that when a cost function is coded in Lua language, Lua does not allow a variable name to be the same as the name of any function inside the cost function. 

 

Classes 

In Python classes are used to define a group of functions which act on a particular object. For instance turn.getName() runs the function getName for the object turn for which the function has been defined. In Lua, you need to instead use a : e.g. turn:getName().  

 

Example of a Lua Dynamic Cost Function for Aimsun Next 

Let’s now put all the above in practice by writing a full cost function that computes a generalised cost by taking into account travel time, tolls and operating cost.  

<<code>> 

function distance(context,manager,section,turn,travelTime) 

linkdistance = turn:length2D()+section:length2D() 

return linkdistance 

end 

 

function cost(context, manager, section, turn, travelTime) 

 

— link travel time 

linkcost = turn:getStaTravelT(manager) 

 

— add attractiveness term 

linkcost = linkcost * (1+manager:getAttractivenessWeight()*(1-turn:getAttractiveness()/manager:getMaxTurnAttractiveness())) 

 

—  add user defined term 

linkcost = linkcost + manager:getUserDefinedCostWeight()*section:getUserDefinedCost() 

 

 

VOT = 30 –pence per minute 

VOC = 20 — pence per km 

 

linkdistance=distance(context, manager, section, turn, travelTime) 

 

— make generalised cost 

linkcost = linkcost + (linkdistance *VOC/VOT) +(section:getUserDefinedCost()/VOT) 

 

return linkcost 

 

end 

<<code>> 

 

Aimsun
  • Got a question? Get in touch.

    We are here to help!

SHARE

Cite Aimsun Next

Aimsun Next 24

Aimsun (2024). Aimsun Next 24 User’s Manual, Aimsun Next Version 24.0.0, Barcelona, Spain. Accessed on: April. 16, 2024. [Online].

Available: https://docs.aimsun.com/next/24.0.0/

Aimsun Next 24

@manual {AimsunManual,
title = {Aimsun Next 24 User’s Manual},
author = {Aimsun},
edition = {Aimsun Next 24.0.0},
address = {Barcelona, Spain},
year = {2024. [Online]},
month = {Accessed on: Month, Day, Year},
url = {https://docs.aimsun.com/next/24.0.0},
}​​​​​​​​​​​​​​​

Aimsun Next 24

TY – COMP
T1 – Aimsun Next 24 User’s Manual
A1 – Aimsun
ET – Aimsun Next Version 24.0.0
Y1 – 2024
Y2 – Accessed on: Month, Day, Year
CY – Barcelona, Spain
PB – Aimsun
UR – [In software]. Available:
https://docs.aimsun.com/next/24.0.0/