Usando Lua para escrever funções de custo personalizadas para Aimsun Next

Julho de 2024 — Nota técnica nº 88

Tessa Hayman

Especialista em produtos

Você sabia que é possível escrever funções de custo personalizadas para modelos de transporte do Aimsun Next usando Lua  além do Python?  

Lua é uma linguagem de script leve conhecida por sua simplicidade, eficiência e facilidade de integração. Lua foi incluída em nosso software de modelagem desde o lançamento do Aimsun Next versão 22, pois queríamos que os usuários pudessem escrever funções personalizadas e, ao mesmo tempo, permitir tempos de execução mais rápidos para modelos complexos, porque as funções em Lua são avaliadas em paralelo. Lua usa recursos mínimos e foca no desempenho, por isso é bem adequada para essa tarefa. Nesta nota técnica, veremos algumas das funções comuns usadas em funções de custo e como elas podem ser escritas em Lua.  

Note que você ainda pode escrever funções em Python se preferir, e que o Scripting suporta apenas Python. A principal vantagem do Python é a disponibilidade de uma infinidade de bibliotecas, como Pandas ou NumPy. Embora essas bibliotecas não sejam normalmente usadas em funções de custo, deve-se notar que Lua tem bibliotecas limitadas para uso.  

Há várias diferenças importantes entre Python e Lua das quais você deve estar ciente. Há vários artigos listando-as, mas nesta nota técnica cobriremos as principais diferenças para que você possa converter rapidamente suas funções de custo para Lua. 

Variáveis 

Lua trata variáveis ​​de forma diferente de Python. Variáveis ​​são criadas quando são referenciadas em vez de quando seu valor foi definido. Até que um valor tenha sido definido, o valor de uma variável = nil.  

por exemplo  

print (a) à nil 

a = 1 

print (a) -> 1 

Além disso, Lua trata o escopo de variáveis ​​de forma diferente do Python. Por exemplo, em Python, uma variável é local, a menos que seja tornada global explicitamente usando a palavra-chave ‘global’. Lua funciona ao contrário. Por exemplo, variáveis ​​são globais, a menos que explicitamente declaradas como locais usando a palavra-chave ‘local’. 

por exemplo 

Além disso, há uma terceira variedade de variáveis ​​chamada campo de tabela. Ela pode conter qualquer coisa, exceto nil, incluindo funções. No entanto, não é provável que seja usada em funções de custo.  

 

Comentários 

Comentários podem ser adicionados usando –[[texto]] em vez de ”’ OU – em vez de #, 
por exemplo, Lua 

–[[Este é um comentário]] 

por exemplo Python 

#Este é um comentário 

Em Lua # em vez disso, fornece o comprimento de uma variável, por exemplo #comment -> 7 

 

Matrizes 

Em Python, a posição dos objetos em uma lista começa em 0. Entretanto, em Lua a convenção é que os arrays começam com o índice 1.  

por exemplo Lua 

 lista=[0,1,2] 

lista[1] = 0 

 

Python

lista = [0,1,2] 

lista[1] = 1  

 

Funções 

Em Lua para definir uma função você também precisa adicionar uma declaração end no final da função. Por exemplo  

function cost(turn) 

calculatedcost = turn:length2D() 

return calculatedcost 

end 

Observe  que quando uma função de custo é codificada na linguagem Lua, Lua não permite que um nome de variável seja o mesmo que o nome de qualquer função dentro da função de custo. 

 

Classes

Em Python, classes são usadas para definir um grupo de funções que atuam em um objeto em particular. Por exemplo, turn.getName() executa a função getName para o objeto turn para o qual a função foi definida. Em Lua, você precisa usar um : por exemplo, turn:getName().  

 

Exemplo de uma função de custo dinâmica Lua para Aimsun Next 

Vamos agora colocar tudo isso em prática escrevendo uma função de custo completa que calcula um custo generalizado levando em consideração o tempo de viagem, pedágios e custos operacionais.  

<<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>>