Interface de Agente Externo¶
A Interface de Agente Externo (EAI) pode introduzir veículos controlados externamente em uma simulação microscópica Aimsun Next. Esses veículos externos podem ser guiados pelas ações de, por exemplo, um motorista humano em um simulador, um controlador de veículo autônomo ou um sistema de controle experimental sendo testado em um ambiente de simulação.
Os dados trocados via EAI são baseados em locais geográficos expressos como coordenadas x e y, em vez da representação simulada da rede de tráfego expressa através de faixas e curvas.
Isso significa que a lógica de controle externo não precisa de conhecimento detalhado sobre como o Aimsun Next modela a rede de tráfego – pode continuar a usar seu próprio modelo de rede. A troca de dados depende unicamente da existência de um sistema compartilhado de coordenadas comuns.
Veículos externos são posicionados na rede de tráfego dentro da simulação. Os outros veículos na simulação – aqueles controlados e atualizados pelo Aimsun Next – irão reagir à presença de veículos externos, seguindo-os, colaborando com suas manobras de troca de faixa e incluindo-os em sua avaliação de lacunas em interseções da mesma forma que reagem a outros veículos 'internos' na simulação.
Observe que em cada passo de tempo simulado, o Aimsun Next envia uma lista de veículos 'internos' (ou seja, veículos na rede Aimsun) ao redor ou próximos a veículos 'externos' no aplicativo externo. A posição desses veículos internos é baseada no centro de seu para-choque dianteiro.
Os semáforos são controlados exclusivamente pelo Aimsun Next em todos os momentos.
Arquitetura de Sistemas¶
A EAI é baseada em uma arquitetura cliente-servidor na qual o Aimsun Next é o servidor, responsável por gerenciar os semáforos e os outros veículos e pedestres na simulação. O cliente é o controlador externo, ou simulador, que recebe informações sobre os objetos dinâmicos na simulação e responde com as posições e direcionamentos atualizados dos veículos controlados externamente.
A EAI fornece o arquivo PROTO que deve ser usado para programar a interface usando uma biblioteca de software derivada diretamente deste arquivo no sistema host e usando a linguagem de programação preferida do cliente. Esta linguagem deve ser suportada pelos protocolos de buffer do Google. Veja Interface de Buffer de Protocolo para mais informações. Use esta opção ao trabalhar com C++, C#, Java, Python ou várias outras linguagens (verifique a lista completa nos Buffer de Protocolo do Google).
O mecanismo de comunicação subjacente é baseado em TCP/IP com dados serializados usando os buffers de protocolo do Google: uma biblioteca de comunicação altamente eficiente e independente de plataforma. A simulação e o controlador podem estar na mesma ou em plataformas de computação diferentes conectadas por uma rede. Isso permite que o aplicativo externo seja desenvolvido em qualquer linguagem de programação, sem a necessidade de conhecimento aprofundado do Aimsun Next.
Os dados serializados devem ser enviados através de um socket TCP/IP. Primeiro, o tamanho da mensagem serializada como um inteiro de 32 bits é enviado na ordem da rede. Em segundo lugar, a mensagem serializada em si é enviada. A frequência dessa comunicação é a mesma que o passo de simulação, que pode ser definido tão baixo quanto 10Hz (0,1s).
A pasta /programming/External Agents Interface inclui uma implementação do mecanismo de conexão. Veja TCPSocket.h e TCPSocket.cpp em Cpp-Sample/AimsunEAConnectorLib para a implementação e Cpp-Sample/AimsunEAConnectorTester para um exemplo de uso em C++.
Como um exemplo de como usar a EAI com uma linguagem que não suporta buffers de protocolo, há um exemplo de integração para MATLAB escrito em C. Você também pode encontrá-lo na pasta /programming/External Agents Interface.
Configuração e Execução do Servidor¶
Configuração da API¶
-
Abra o editor de Cenários, clique na guia APIs do Aimsun Next e marque Extensão de Agente Externo.
-
Dê um duplo clique em Extensão de Agente Externo ou clique em Propriedades.
-
Configure suas propriedades conforme descrito na próxima seção (a captura de tela abaixo serve apenas como exemplo).
Opções de Configuração¶
-
Tempo Limite de Comunicações Inicial: Defina um tempo em segundos pelo qual o Aimsun Next irá aguardar que o controlador externo se conecte. Após esse tempo limite, a simulação começará sem comunicação.
-
Tempo Limite de Mensagem: Defina um tempo em segundos pelo qual a Interface de Buffer de Protocolo aguardará uma resposta. Após esse tempo limite, a comunicação será encerrada.
-
Porta do Servidor: Selecione ou insira o número da porta do servidor.
-
Comunicação Síncrona: Marque esta caixa para sincronizar os relógios do Aimsun Next e do software externo. Esta é a configuração recomendada.
Nota: Quando esta caixa não está marcada, ocorre comunicação assíncrona. Isso significa que não há sincronização de relógio e o Aimsun Next não espera que o agente externo avance o tempo. Você pode usar esta opção para verificar o que acontece se, por qualquer motivo, o software externo não puder rodar pelo menos na velocidade do tempo real. Recomendamos que este teste seja realizado pouco antes da implantação em veículos reais. No entanto, a comunicação síncrona deve cobrir 90% dos testes pré-implantação.
-
Número de Conexões Esperadas: O Aimsun Next pode se conectar a vários clientes. Defina o número de clientes que serão esperados para esta simulação. O servidor parará de esperar novas conexões se este valor for alcançado.
-
Requer Número Esperado de Conexões: Marque esta caixa se a simulação deve ser abortada caso o número de conexões estabelecidas seja menor do que as conexões esperadas.
-
Registrar Mensagens de Entrada: Esta caixa ativa o armazenamento das mensagens que o Aimsun Next recebe de software externo durante a simulação. O arquivo será armazenado como replicationID_connectionID_replay.eai.
-
Registrar Mensagens de Saída: Esta caixa ativa o armazenamento das mensagens que o Aimsun Next envia ao software externo durante a simulação. O arquivo será armazenado como replicationID_connectionID_replay_out.eai.
-
Trajetória Detalhada do Veículo: Marque esta caixa para aplicar suavização visual à posição dos veículos enquanto eles trocam de faixa na visualização principal da interface do Aimsun Next.
-
Tipo de Agente Externo Para Tipo de Veículo/Pedestre: Selecione um dos cinco tipos de veículos, ou a opção Pedestres, para cada tipo de agente externo disponível.
Nota: Nenhum dos parâmetros de comportamento ou parâmetros de roteamento dinâmico definidos para a opção selecionada, que normalmente são usados pelo Aimsun Next, são relevantes para determinar as ações do veículo controlado externamente.
-
Classe de Veículo Para Tipo de Agente Externo: Selecione qual classe de veículo irá representar cada tipo de agente externo. Se nenhuma classe for selecionada, AGENT_NOT_DEFINED será usada como o tipo de agente externo padrão. Se um veículo simulado pertencer a mais de uma classe de veículo com tradução de tipo de agente externo definida, o valor de tipo inferior terá prioridade.
Executando a Simulação¶
-
No Windows, execute o comando:
Aimsun Next.exe --verbose --EVC-host --wait_to_sync --project evc_model.ang
Isso iniciará o Aimsun Next como um Host de Veículo Externo aguardando que um controlador externo se conecte a ele.
-
Separadamente, execute o Controlador de Veículo Externo, que está configurado para se conectar à simulação Aimsun Next. Quando ambos os elementos – simulação e controlador – estiverem em execução, execute a replicação da simulação como de costume. A cada passo de tempo da simulação, a posição dos veículos controlados externamente será atualizada pelo controlador vinculado. Uma opção interessante seria ter um script que execute este aplicativo/external controller e definir esse script como um script de Pré-Execução.
Programação do Cliente ¶
O controlador do cliente é o software que move os veículos controlados externamente. Sua sequência de operações é a seguinte.
-
Criação do modelo:
-
Configura o controlador para que ele use um mapa que corresponda à mesma área que o modelo de simulação. O controlador pode exigir conhecimento detalhado diferente da área. Especificamente, pode precisar de mais conhecimento sobre mobiliário urbano ou sobre guias e rampas onde pode transitar entre áreas de via e pedestres. No entanto, deve corresponder à rede de simulação em termos de topologia de via e do sistema de coordenadas. Os IDs de quaisquer semáforos também devem ser compartilhados entre a simulação e o controlador do cliente.
-
Iniciando o controlador:
-
Abre uma conexão com a simulação.
-
Criar o(s) veículo(s) controlado(s) externamente.
-
A cada passo de tempo:
-
Grava a posição atual do(s) veículo(s) controlado(s) externamente.
-
Lê as novas posições dos agentes simulados (veículos e pedestres) dentro de um raio definido do(s) veículo(s) controlado(s) externamente a partir da simulação.
-
Lê o novo estado dos semáforos dentro desse raio.
-
Lê o novo estado dos painéis de mensagens variáveis (VMS) nesse raio.
-
Apresenta essas informações a um controlador de veículo autônomo ou exibe esses veículos e sinais em um simulador de direção.
-
Atualiza a posição do(s) veículo(s) externo(s) para o próximo passo de tempo.
-
No final da simulação:
-
Encerra a conexão.
-
Desliga o controlador.
A interface pode ser programada no controlador usando:
- protocol buffers em qualquer uma das linguagens suportadas
- para um sistema sem suporte a buffers de protocolo, por exemplo, MATLAB, há um exemplo de implementação como uma biblioteca C.
Diagramas de Sequência¶
Case 1: Aimsun Next finaliza a simulação
Case 3: Aimsun Next cancela a simulação
Interface de Buffer de Protocolo ¶
Se o ponto de partida na codificação da interface do controlador for o arquivo PROTO que define o protocolo de comunicação, então isso permite que a interface seja escrita em uma das várias linguagens, incluindo C++, C# Java e Python – verifique a lista completa nos Buffers de Protocolo do Google.
Ele pode ser compilado em qualquer sistema operacional para atender aos requisitos do software e firmware do controlador.
Usando o arquivo PROTO, um programador também poderá:
- incluir múltiplos veículos controlados externamente
- definir as bolhas (áreas dentro das quais o Aimsun Next enviará informações sobre veículos e semáforos) e controlar seu tamanho e posição
- enviar uma lista de intenções para controlar o movimento dos pedestres.
Para usar o arquivo PROTO:
-
Obtenha o arquivo ExternalAgentsConnector.proto da subpasta de instalação do Aimsun Next, "/programming/External Agents Interface". Observe que este arquivo usa a Protobuf Versão 3.
-
Use as ferramentas fornecidas pelo Google para criar o código fonte. Isso está documentado na página da web Buffers de Protocolo.
-
Adicione este código como parte do processo de construção do projeto, tipicamente editando o Makefile.
Então, ao programar a interface:
-
Inicialização
-
Abra um fluxo de entrada ligando ao endereço IP e à porta EAI do computador que hospeda a simulação.
-
Crie os veículos controlados externamente.
-
A cada passo de tempo
-
Leia a lista de objetos nas bolhas.
-
Avalie as ações do controlador.
-
Atualize as posições no Aimsun Next para os veículos controlados externamente e envie qualquer informação para controlar os pedestres, se necessário.
-
Avance para o próximo passo de tempo.
O código gerado pela Interface de Buffer de Protocolo do Google fornece as estruturas e constantes enumeradas com as quais construir as mensagens e as funções necessárias para enviá-las e recebê-las.
Detalhes do arquivo Proto¶
A partir do Aimsun Next 22, você pode usar três mensagens para controlar o movimento dos pedestres se estiver usando a Interface de Agente Externo para conectar sua simulação externa com o microsimulador do Aimsun Next.
Agora você pode substituir a microsimulação do Aimsun Next e controlar se os pedestres aguardam nas faixas de pedestres, atravessam ou param onde quer que estejam na simulação.
As mensagens que controlam esse comportamento são nomeadas WAIT_AT_CROSSWALK, USE_CROSSWALK e STOP_MOVING. Essas mensagens, quando enviadas, irão substituir o comportamento padrão ou 'típico' dos pedestres e também ignorarão o efeito dos estados dos semáforos.
As duas primeiras são autoexplicativas e a terceira, STOP_MOVING, significa que um pedestre irá desacelerar e parar, mas, se estiver próximo de outros pedestres, ainda poderá se mover se for empurrado e continuará a reagir a obstáculos.
Conector da Interface de Agente Externo para C++¶
Há um exemplo na pasta programmingExternal Agents InterfaceCpp-Sample
para mostrar como usar a interface em C++. Isso deve ser usado como um ponto de partida para um projeto que irá se conectar ao Aimsun Next via Interface de Agente Externo.
Use cmake para configurar e construir o exemplo em C++. O único requisito externo é a biblioteca de buffer de protocolo e as bibliotecas spdlog, idealmente via o gerenciador de pacotes vcpkg.
cd "programmingExternal Agents InterfaceCpp-Sample"
cmake -S . -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE=$env:{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake
cmake --build build
Estrutura¶
- AimsunEAConnectorLib é uma biblioteca que controla a conexão, sincronização e fluxo de execução.
- AimsunEAConnectorTester é um exemplo de como estender esta biblioteca com seu próprio modelo.
Este exemplo é uma ferramenta que fornece um fluxo de trabalho funcional, mas é uma ferramenta criada para que possa ser integrada em projetos maiores ou usada como base.
Gerar Itens Externos¶
Executado automaticamente após estabelecer uma conexão bem-sucedida com o Aimsun Next. Destina-se a ser usado para criar o(s) veículo(s) e modelos para o aplicativo externo.
void generateExternalItems();
Gerenciar Dados Recebidos¶
Em cada passo, destina-se a ser usado para lidar com os dados recebidos da co-simulação do Aimsun Next e configurar o contexto (talvez preenchendo estruturas de dados, logs, imprimindo informações, etc.).
void manageReceivedData( const ExternalAgents::Out * out ) override;
Atualizar Itens Externos¶
Executado imediatamente após gerenciar os dados recebidos, destina-se a ser usado para atualizar o(s) veículo(s) que serão enviados e tomar decisões com o novo contexto.
void updateExternalItems();
Enviar Itens Externos¶
Executado imediatamente após atualizar os itens externos, destina-se a ser usado para enviar o(s) veículo(s), bolhas, intenções de pedestres ou o que quer que a mensagem precise conter. Pode ser usado como um hub para iniciar ferramentas de depuração, armazenar logs, etc.
void sendExternalItems();
Limpar Itens Externos¶
Executado automaticamente após fechar a conexão com o Aimsun Next. Destina-se a ser usado para limpar as estruturas de dados usadas para a execução, uma vez que esse fluxo de trabalho pode ser um pequeno procedimento dentro de um grande programa que continua a ser executado após a co-simulação ser concluída.
void cleanExternalItems();
Conector da Interface de Agente Externo para MATLAB¶
Há um exemplo na pasta programmingExternal Agents InterfaceMATLAB
para mostrar como usar a interface no MATLAB.
Use cmake para configurar e construir o exemplo. Os únicos requisitos externos são a biblioteca de buffer de protocolo e a biblioteca spdlog, idealmente usando o gerenciador de pacotes vcpkg.
cd "programmingExternal Agents InterfaceMATLAB"
cmake -S . -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE=$env:{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake
cmake --build build
Diagramas de Sequência para MATLAB¶
A biblioteca C que implementa a interface para MATLAB tem uma sequência diferente, baseada em funções em vez de mensagens.
Estruturas¶
Informações do Cenário¶
/*! Informações do Cenário */
struct AimsunEACLoadResult
{
int timeStep; // Passo de tempo da simulação no Aimsun Next (ms)
int start; // hora de início (relógio virtual) da simulação em ms desde a época
int duration; // duração da simulação em ms
};
Semáforo ¶
/*! Um semáforo
- nome: nome externo do sinal
- estado:
NOT_DEFINED = 0
OFF = 1
GREEN = 2
YELLOW = 3
RED = 4
FLASHING_YELLOW = 5
FLASHING_RED = 6
YELLOW_BEFORE_GREEN = 7
FLASHING_GREEN_AS_GREEN = 8
FLASHING_RED_AS_RED = 9
FLASHING_YELLOW_AS_YELLOW = 10
YELLOW_AS_GREEN = 11
*/
struct AimsunEACTrafficLightState
{
char name[100]; // O nome externo do sinal
int state; // O estado do sinal
}
Estado do VMS ¶
/*! Um painel de mensagens variáveis (VMS)
- external_id: ID externo do objeto VMS.
- message: A mensagem atual exibida no VMS
*/
struct AimsunEACVMSState
{
char external_id[64];
char message[256];
}
Agente ¶
A estrutura do agente se aplica tanto aos veículos controlados externamente quanto aos veículos da simulação.
/*! Um agente
- id: identificador único do agente
- x, y, z: Posição do veículo (para pedestres, o centro)
- Ao ler do Aimsun Next, corresponde à posição média do para-choque dianteiro
- Ao enviar ao Aimsun Next, envie a posição média do eixo traseiro
- h: direção em radianos com a horizontal
- speed: velocidade do agente em m/s
- length: em metros
- width: em metros
- type:
AGENT_NOT_DEFINED = 0
CAR = 1
BIKE = 2
TRUCK = 3
BUS = 4
PEDESTRIAN = 5
MOTORCYCLE = 6
- brakeLight : Indica se a luz de freio está ativada
- leftTurnSignal: Indica se o sinal de curva à esquerda está ativado
- rightTurnSignal: Indica se o sinal de curva à direita está ativado
- minUpstreamTimeGapForLaneChange: Indica o tempo mínimo necessário para mudar para uma faixa diferente na frente de um veículo a montante
*/
struct AimsunEACAgent
{
int id; // O identificador único do veículo
double x; // A coordenada x do eixo traseiro de um veículo ou da posição do ponto central de um pedestre
double y; // A coordenada y do eixo traseiro de um veículo ou da posição do ponto central de um pedestre
double z; // A coordenada z do eixo traseiro de um veículo ou da posição do ponto central de um pedestre
double h; // A direção em radianos a partir do Leste
double length; // O comprimento do agente em m.
double width; // A largura do agente em m.
double speed; // A velocidade do agente em m/s
bool brakeLight; // Se o agente está com a luz de freio acesa ou não
bool leftTurnIndicator; // Se o agente está com o sinal de curva à esquerda aceso ou não
bool rightTurnIndicator; // Se o agente está com o sinal de curva à direita aceso ou não
int type; // O tipo do agente
double minUpstreamTimeGapForLaneChange; // Indica o tempo mínimo necessário para mudar para uma faixa diferente na frente de um veículo a montante
};
Funções (Biblioteca C)¶
Nota: Esta biblioteca é um exemplo que utiliza o código gerado pelos arquivos PROTO para permitir comunicação com a Interface de Agente Externo. Usando essas funções, pode-se construir um programa que siga a sequência descrita no diagrama MATLAB para executar uma co-simulação.
AimsunEACStart¶
Conecta-se a uma instância do Aimsun Next em execução em um host e com uma porta aberta. Os valores padrão são localhost e 1541. Retorna true
se a conexão foi estabelecida e false
se não.
bool AimsunEACStart( const char * host, int port );
AimsunEACStop¶
Fecha a conexão com a instância do Aimsun Next.
void AimsunEACStop();
AimsunEACLoad¶
Chama a função de carregamento para receber o AimsunEACLoadResult. Retorna true se a conexão ainda estiver aberta, false caso contrário.
bool AimsunEACLoad();
AimsunEACRead¶
Lê os dados do Aimsun Next. Retorna 0
se a conexão for perdida ou o tipo de mensagem tiver sido lido. Os tipos de mensagem são:
-
LoadResult. Use AimsunEACGetLoadResult
-
Out. Use AimsunEACAgentsRead, AimsunEACTrafficLightsRead e AimsunEACVMSStatesRead
-
Close
-
CloseResult
int AimsunEACRead();
AimsunEACCloseReceived¶
Verifica se a simulação foi concluída e a porta fechada. Retorna true
se o Aimsun Next tiver finalizado a simulação.
bool AimsunEACCloseReceived();
AimsunEACGetLoadResult¶
Retorna as informações do cenário. Chame esta função após uma chamada bem-sucedida para AimsunEACRead().
AimsunEACLoadResult * AimsunEACGetLoadResult();
AimsunEACAgentsRead¶
Retorna o número de veículos ao redor do veículo externo. Chame esta função após uma chamada bem-sucedida para AimsunEACRead(). O raio de visibilidade padrão é de 100m.
int AimsunEACAgentsRead();
AimsunEACGetAgent¶
Lê as informações de um veículo, indexado de 0 a (AimsunEACAgentsRead() - 1). Chame esta função após uma chamada bem-sucedida para AimsunEACAgentsRead(). O ponteiro para a estrutura AimsunEACAgent não deve ser liberado ou reatribuído.
struct AimsunEACAgent * AimsunEACGetAgent( int i );
AimsunEACTrafficLightsRead¶
Retorna o número de semáforos ao redor do veículo externo. Chame esta função após uma chamada bem-sucedida para AimsunEACRead().
int AimsunEACTrafficLightsRead();
AimsunEACGetTrafficLightState¶
Lê as informações referentes a um semáforo, indexado de 0 a (AimsunEACTrafficLightsRead() - 1). Chame esta função após uma chamada bem-sucedida para AimsunEACTrafficLightsRead(). O ponteiro para a estrutura AimsunEACTrafficLightState não deve ser liberado ou reatribuído.
struct AimsunEACTrafficLightState * AimsunEACGetTrafficLightState( int i );
AimsunEACVMSStatesRead¶
Retorna o número de estados VMS ao redor do veículo externo. Chame esta função após uma chamada bem-sucedida para AimsunEACRead().
int AimsunEACVMSStatesRead();
AimsunEACGetVMSState¶
Lê as informações de um VMS, indexado de 0 a (AimsunEACVMSStatesRead() - 1). Chame esta função após uma chamada bem-sucedida para AimsunEACVMSStatesRead(). O ponteiro para a estrutura AimsunEACVMSState não deve ser liberado ou reatribuído.
struct AimsunEACVMSState * AimsunEACGetVMSState( int i );
AimsunEACWrite¶
Insere ou atualiza um veículo externo na simulação. A posição e a direção do veículo devem ser definidas na estrutura AimsunEACAgent. Observe que o comportamento do veículo não é modificado pelo Aimsun Next – apenas a posição é atualizada e, portanto, a velocidade do veículo é ignorada. Retorna false
se os dados não puderem ser escritos.
bool AimsunEACWrite( struct AimsunEACAgent *agent );
AimsunEACClose¶
Pede ao Aimsun Next para encerrar a simulação. Retorna true
se este pedido for realizado com sucesso.
bool AimsunEACClose();