Pular para o conteúdo

Basic Scripting

Hello World

Todo programador começa escrevendo o mesmo programa: imprimir "Hello World!". Neste exemplo, vamos imprimi-lo na janela de Log do Aimsun Next. As etapas são:

  1. Inicie o Aimsun Next.
  2. Crie uma nova Rede.
  3. Crie um novo Python Empty Script (a partir do Project Menu). O novo script aparecerá na Project Window.
  4. Abra o Script Python (dê duplo clique sobre ele).
  5. Escreva a aplicação Hello World. Observe que o editor reconhece a sintaxe e colore o texto.
  6. Pressione o botão Execute.
  7. Procure na janela de Log.


Script Hello World

Procurando por tudo

"Hello World" é apenas texto estático; é mais interessante obter informações do modelo. Este exemplo imprime o identificador e o nome de todas as seções em uma rede. Isso requer iteração sobre todas as seções.

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

O Aimsun Next possui um catálogo (GKCatalog) em cada modelo, que inclui todos os objetos nele contidos, tanto gráficos quanto não gráficos, ordenados por tipo e identificador. Esse catálogo é acessível usando o GKModel::getCatalog método.

Antes de iterar sobre o catálogo, o código procura o tipo dos objetos a serem usados. Neste caso, será GKSection.

sectionType = model.getType( "GKSection" )

O código então procura todos os tipos que são, ou derivam de, GKSection:

for types in model.getCatalog().getUsedSubTypesFromType( sectionType ):

E, para cada tipo, o código procura todos os objetos desse tipo:

for s in types.values():

Neste exemplo, há dois pontos dignos de nota: por que iterar duas vezes e o acesso no estilo de array.

Precisamos iterar sobre todos os tipos que derivam de GKSection, pois é possível que um desenvolvedor que esteja escrevendo um plug-in estenda o tipo GKSection criando um novo tipo baseado em GKSection. Isso faz parte das capacidades orientadas a objetos do C++ e da extensibilidade do Aimsun Next. Portanto, devemos sempre escrever código para antecipar essa possibilidade.

O segundo ponto é o acesso em estilo de array, que está relacionado à forma como Python trata objetos de mapeamento. A variável tipos é um mapa de objetos (um dicionário) que usa o id de cada objeto como chave. Para iterar sobre os objetos no dicionário, o values() método é usado.

Procurando Algo

O catálogo também pode ser usado para encontrar um objeto específico por:

  • identificador (método GKCatalog::find).
  • identificador externo (método GKCatalog::findObjectByExternalId).
  • ou nome (método GKCatalog::findByName).

Observe que o Aimsun Next garante que o identificador seja único, portanto uma pesquisa encontrará um objeto ou nenhum, mas o nome e o identificador externo não são necessariamente únicos, de modo que uma pesquisa pode retornar múltiplos objetos.

Modificando um objeto

Este exemplo é um script para reduzir a velocidade de todas as seções em 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 )

Este código estende a busca anterior para agora obter a velocidade da seção com GKSection::getSpeed(), modificá-lo e regravá-lo com GKSection::setSpeed(). O novo elemento neste código é esta linha:

model.getCommander().addCommand( None )

Isso instrui o Aimsun Next a limpar o buffer de desfazer porque foi executada uma modificação que não pode ser desfeita. No Aimsun Next, somente operações realizadas chamando um GKCommand implementam métodos para reverter a modificação e, portanto, podem ser desfeitos (consulte GKCommand Class Reference para obter uma lista). Como o script usa o método setSpeed() para modificar o modelo, esta operação não coloca um comando de reversão no buffer de desfazer. Nessa situação, se uma operação de desfazer for executada, ela não reverterá esta modificação, mas sim a última operação passível de desfazer, e também estará operando sobre um modelo que, entretanto, foi alterado. Para evitar erros, o buffer de desfazer deve, portanto, ser limpo.

Todos os scripts que modificam o modelo devem terminar com esta linha, a menos que realizem modificações apenas usando GKCommands.