Há pouco menos de um ano, foi publicada uma
publicação na qual falamos sobre o complexo de treinamento e laboratório (ULK) do trem elétrico ES1 Lastochka desenvolvido por nossa universidade. Então prometi que essa não seria a última publicação sobre esse tópico; em particular, ameacei falar sobre os problemas da criação de visualização tridimensional para esses simuladores e descrever as principais abordagens para resolvê-los.
No ano passado, ficamos satisfeitos com nosso próximo lançamento - o ULK do trem elétrico de alta velocidade Sapsan EVS2, que ocorreu em agosto do ano passado. O complexo educacional e de laboratório deste trem elétrico em si merece uma história separada, mas no contexto desta publicação falaremos sobre a dor - o problema de criar um subsistema adequado de visualização tridimensional, cuja solução nossa equipe abordou de lados diferentes por cerca de dois anos. A liberação do simulador Sapsan é significativa (entre outras coisas) e na medida em que determinou o vetor de desenvolvimento de nossos desenvolvimentos nesta área.
1. Brevemente sobre ULK EVS2 “Sapsan”
Quero enfatizar mais uma vez (o que faço com uma frequência invejável) que os complexos educacionais e laboratoriais de material circulante desenvolvidos em nossa universidade não se destinam à preparação de brigadas de locomotivas. Como
observou com razão
um dos comentaristas do artigo anterior, nossos ULK não são simuladores, mas sim simuladores, onde a ênfase principal está na implementação competente da física do movimento do trem e na simulação da operação dos subsistemas do material circulante que garantem seu movimento e parada. O simulador Sapsan não é uma exceção, na qual as seguintes tarefas são resolvidas:
- Foi implementado um modelo dinâmico da parte mecânica do trem, levando em consideração as forças longitudinais e o perfil da via
- Foi construído um modelo computadorizado detalhado da operação dos principais subsistemas do trem elétrico: circuito elétrico de potência, acionamento elétrico de tração, freios pneumáticos e eletropneumáticos
- Os algoritmos básicos da operação do sistema de controle do trem elétrico em diferentes níveis são reproduzidos.
Além disso, o complexo de treinamento e laboratório inclui um modelo em tamanho real da cabine do trem elétrico, com os principais controles e instalações de exibição de informações. Diferentemente do simulador Swallows, essa cabine não foi fabricada por nós mesmos, mas foi comprada em 2015 em um escritório no país que produz simuladores de treinamento. Portanto, o processo de desenvolvimento do simulador focou na criação de software.
Foto da cabineVista geral do interior da cabine
Vista através do pára-brisa
Exibir dispositivo de segurança para locomotivas integrado (CLUB-U). O vermelho "290" é o limite de velocidade atual obtido da placa eletrônica CLUB-U. Até agora, o limite de velocidade atingido pela Sapsan na Ferrovia de outubro ostenta aqui. No futuro, o cartão eletrônico será implementado como é feito na vida.
Tela principal "Interface homem-máquina"
Indicador do estado do sistema de freio do trem elétrico
Regulador de velocidade e controlador de tração
Controlador de controle de freio de trem elétrico
Chaves de alternação para controle de coletores de corrente e dispositivos de proteção (BV / GV) - chaves de alternância pretas próximas ao regulador de velocidade
Interface de gerenciamento de treinamento - tela Seleção de rota
Tela de controle de volume de efeitos de áudio
Contador de milhas. Uma história engraçada está associada à sua aparência. Quando entregamos nosso primeiro simulador da locomotiva a diesel 2TE116, o representante do cliente brincou com a nossa pergunta quando o ato de conclusão seria assinado: “Bem, vamos fazer como na vida - ao colocar uma nova locomotiva em operação, ela deve passar por uma corrida de 5000 quilômetros. Isso vai passar ... ". O ato, é claro, foi assinado muito antes, mas, avaliando o humor da situação, fizemos um contador semelhante já no simulador do Swallows. O contador pode ser redefinido para "0" digitando a senha de serviço.
Painel acessório direito com manômetros de pressão e válvula de freio de emergência. Nem todos os elementos inerentes a este Sapsan estão instalados aqui - esse controle remoto foi recebido por nós do fornecedor
Portanto, alguns dos controles críticos para nós foram implementados em software, em particular o painel de interruptores de desvio controlados a partir da tela de toque.
O desenvolvimento de software para esse simulador de simulador é uma questão muito ampla, e tentarei (da melhor maneira possível) satisfazer o interesse dos leitores por essas questões no futuro (se houver), mas, por enquanto, vamos voltar ao tópico principal do artigo - visualização tridimensional do processo de movimentação de trens.
2. Antecedentes e tecnologia do passado
Nos comentários do último artigo
, foi feita uma pergunta que, francamente, me divertiu bastante. Sim, de fato, em muitos simuladores ainda em uso hoje, essa abordagem ainda é usada: o vídeo é gravado em uma seção real da ferrovia e depois rola no simulador a uma velocidade proporcional à velocidade do movimento. Isso foi feito apenas porque naqueles tempos distantes em que esses simuladores foram criados, a qualidade dos gráficos tridimensionais deixou muito a desejar, e isso também se aplicava a estações gráficas severas em Unixes comerciais, e não havia dúvida de um PC. Portanto, mesmo os fabricantes de jogos de computador, por exemplo,
este , não hesitaram em usar essa abordagem.
Hoje isso não faz sentido, porque:
- A taxa de quadros insuficiente em baixas velocidades de trem não fornece a suavidade desejada para a atualização da imagem. Teremos os 25 fps estimados apenas na velocidade em que o vídeo foi gravado na cabine do motorista. E essa falha fatal não pode ser superada de forma alguma - nem com uma câmera de alta velocidade (quanto pesa o vídeo gravado a 120 quadros por segundo? Isso é o mesmo ...), nem com a geração programada de quadros intermediários. O último foi realizado por nós usando a tecnologia OpenCV, mas não levou a resultados normais. Esta questão foi repetidamente estudada por todos os lados e, como resultado, concluiu-se que o custo dos recursos para a criação de um sistema desse tipo é muito superior ao desenvolvimento de um sistema similar, mas baseado em gráficos 3D
- Dificuldades com a rolagem suave do vídeo para trás. E mesmo levando em conta que eles serão superados, então para onde correrão os cães que correm na plataforma, achamos que devemos dar o contrário?
- A falta de toda "interatividade". O que fazer com uma mudança nos semáforos, com o movimento de afluências, o movimento de trens que chegam e passam?
Portanto, todos os simuladores e simuladores modernos são criados usando gráficos 3D interativos, pois hoje não há obstáculos do ponto de vista de software ou hardware.
Se tudo estiver muito claro do ponto de vista do hardware - o monitor instalado em vez do para-brisa está conectado a um PC com uma placa de vídeo normal (nem mesmo a topo de linha), do ponto de vista do software, surge a questão de escolher a tecnologia para implementar a tarefa.
3. O mecanismo gráfico versus o mecanismo do jogo ou por que o OpenSceneGraph foi escolhido
Posso estar enganado, mas antecipo comentários com antecedência, que farão uma pergunta completamente lógica: por que, ao analisar as tecnologias existentes, nossa escolha não parou em mastodontes como o Unity ou o Unreal Engine 4? Além disso, responderei a essa pergunta, justificarei minha resposta.
Resumidamente - nem o Unity nem o Unreal Engine atendem aos requisitos da tarefa que está sendo resolvida. Uma resposta mais detalhada fornece, em primeiro lugar, uma lista dos requisitos em questão. O TK, compilado por nós no subsistema de visualização tridimensional, inclui (em ordem decrescente de importância) as seguintes disposições:
- Independência do processo de desenvolvimento de software do subsistema de visualização e do processo de criação de recursos para ele. Os recursos, nesse caso, incluem modelos tridimensionais, texturas e as chamadas rotas . Uma rota é entendida como uma combinação de objetos e recursos de configuração que permitem ao subsistema de vídeo exibir a seção desejada da ferrovia e fornecer simulação do movimento do trem ao longo dela. Isso também inclui a possibilidade de alterar a rota sem reconstruir a parte do software do subsistema de vídeo
- Crie rotas de comprimento ilimitado. Farei uma reserva de que um comprimento ilimitado é, em princípio, inatingível devido a recursos limitados de hardware. Esse requisito deve ser entendido que o comprimento da rota deve estar pelo menos dentro de um “ombro”, ou seja, uma seção da estrada entre os pontos de retorno, e isso, dependendo de vários fatores, é uma distância suficientemente grande, estimada em mais de cem quilômetros. Esse requisito impõe a necessidade de fornecer carregamento / descarregamento dinâmico de recursos do programa com suavidade suficiente com consumo de memória razoável. E é desejável que o mecanismo contenha essa funcionalidade "pronta para uso"
- Integração conveniente com a pilha de tecnologia usada. Tradicionalmente, devido a razões objetivas novamente, nossa equipe usa a linguagem C ++ com estrutura Qt, QtCreator IDE e Git como um sistema de controle de versão para o desenvolvimento de software para ULK PS. Como plataforma ULK PS da plataforma do sistema, um sistema operacional baseado no kernel Linux é usado
O que há de errado com o Unity e o UE? Qual é o fato de que outros mecanismos podem importar recursos de formatos completamente diferentes. No entanto, ao criar um projeto, eles são irreversivelmente convertidos para um formato binário interno, tornando impossível adicionar e alterar recursos sem remontar o projeto. Tecnologias como casas pré-fabricadas e pacotes de ativos disponíveis no Unity não resolvem o problema, pois o editor de mecanismo não é o melhor lugar para criar locais ferroviários, o que requer a extensão do editor, o que leva à necessidade de escrever um "mecanismo dentro do mecanismo". Além disso, a criação de pré-fabricados e pacotes configuráveis é impossível sem o uso do editor do Unity, e isso, como a prática demonstrou, não é muito conveniente, especialmente para modeladores e designers de nível puros. Quanto ao UE, fiz muitas perguntas sobre este e outros recursos ao longo de dois anos sobre como separar o processo de construção de um projeto do processo de adição / alteração de recursos que ele usa e não obtive uma resposta adequada na documentação ou em inveterados "desenvolvedores de jogos. Eu ficaria muito feliz (sem sarcasmo) se estivesse razoavelmente tropeçando em algo que perdi.
Quanto ao segundo requisito, o Unity e o UE parecem fornecer a capacidade de criar locais carregados dinamicamente, mas a pergunta permanece sem resposta: como esses locais podem ser criados independentemente do editor e sem reconstruir o projeto? Existe apenas uma saída - escrever um “mecanismo dentro do mecanismo”, que carregará a geometria e as texturas “brutas” (em qualquer formato de exportação especificado anteriormente dos editores 3D), aplique todos os efeitos necessários a eles e os posicione no espaço com base nos dados descritos por terceiros independente do formato do mecanismo, que ainda precisa ser desenvolvido e ensinado a interpretar o mecanismo.
Em conexão com o exposto, surge a pergunta - se para resolver esse problema, é necessário escrever uma poderosa camada de software sobre o mecanismo de jogo, cuja maior parte das funcionalidades simplesmente não é necessária no problema em consideração, por que precisamos de um mecanismo de jogo?
Talvez o mecanismo gráfico seja suficiente? Fiz essa pergunta à equipe anterior, que resolveu o problema em discussão, contando com o Unity (e naturalmente se fundiu um pouco mais tarde). Em resposta, ele recebeu uma contra-pergunta: "O que você sugere?", Respondendo que, no espírito do texto acima, ele recebeu o sorriso sarcástico de um oponente.
Se você preferir o sarcasmo, a tarefa apresentada é uma tarefa típica de visualização - ela requer apenas uma estrutura para trabalhar com gráficos, pois a física e o subsistema de áudio baseado em física são implementados no lado do servidor. Minha equipe e eu entendemos esse fato, movendo-nos pela inércia de desenvolvedores anteriores, primeiro em direção à Unity, através do UE e tentando fixar o subsistema gráfico de um dos simuladores ferroviários abertos (OpenBVE, que, a propósito, acabou sendo uma muleta temporária)
O OpenSceneGraph é de longe o mecanismo gráfico mais desenvolvido (aberto e gratuito) focado no desenvolvimento de C ++. É amplamente utilizado no exterior precisamente para visualização tridimensional técnica. Esse mecanismo não foi poupado por nenhum tipo de simulador, o mais famoso deles é o
FlightGear . Era uma vez um simulador ferroviário baseado nesse mecanismo - o
Indra , que, no entanto, deixou apenas capturas de tela sem graça do link acima e seu destino futuro é desconhecido para mim.
No contexto da tarefa em questão, o mecanismo gráfico OSG possui as seguintes qualidades positivas:
- Plataforma cruzada, o que possibilita sua aplicação no ecossistema GNU / Linux
- A linguagem de desenvolvimento é C ++ / STL, que possibilita a integração fácil e natural no processo tecnológico estabelecido de desenvolvimento;
- A mais ampla variedade de formatos de recursos é compatível "fora da caixa" - geometria e texturas 3D devido ao sistema de plug-in desenvolvido. Uma interface simples e intuitiva para escrever seus próprios plug-ins para configurar o gerenciador de recursos para formatos fora do padrão, que usamos (escreverei sobre isso abaixo);
- Um sistema de gerenciamento de memória baseado em um modelo proprietário de ponteiros inteligentes (um formato proprietário de ponteiros inteligentes foi usado historicamente, devido ao fato de não haver um mecanismo de ponteiro inteligente no padrão C ++ no início do desenvolvimento);
- Arquitetura modular flexível;
- O gerenciador de objetos de cena que carrega objetos dinamicamente, fornece carregamento e renderização apenas dos objetos que caem na pirâmide de recorte (devido à classe osg :: PagedLOD)
- Capacidade de integração com a estrutura Qt. Graças ao conveniente modelo de "sinais - slots" fornecido pelo Qt, que simplifica e acelera significativamente o desenvolvimento de C ++, usamos amplamente essa estrutura para desenvolver softwares complexos de treinamento. Dessa forma, acumulamos uma base de código significativa reutilizada em diferentes projetos, especialmente no que diz respeito à biblioteca de comunicação interprocessos baseada nos soquetes TCP. Usar os recursos do Qt no projeto do subsistema de vídeo parece ser uma decisão lógica;
- Qualidade de imagem suficiente para a tarefa a ser resolvida.
Foram necessários cerca de seis meses de estudo intensivo dos recursos OSG, a fim de "minuciosamente investigar o terreno" e encontrar abordagens para resolver o problema com esse mecanismo. O que nasceu como resultado merece uma discussão separada.
4. Da arquitetura ao protótipo de trabalho
O subsistema de vídeo dos simuladores de treinamento do material circulante (HTSC) é um aplicativo cliente, rotineiramente chamado de video3d-client, e executa as seguintes funções:
- Uma solicitação para conectar-se à parte do servidor do simulador, autorização no servidor, seguida por uma solicitação periódica para o identificador da rota carregada e, em seguida, a posição atual do trem. Se a conexão for desconectada do lado do servidor, o sistema alternará para o modo de espera para se reconectar;
- Download da rota selecionada, organização do gerenciamento dinâmico do conteúdo da cena renderizada;
- Realizar a cena de acordo com a posição atual do trem na rota
Não que este projeto tenha código aberto, mas o código de uma demonstração de tecnologia com todos os recursos pode ser encontrado
aqui . O projeto consiste nos seguintes módulos:
- filesystem - uma biblioteca para trabalhar com o sistema de arquivos, fornece a geração de caminhos para arquivos de configuração e recursos de aplicativos
- library - uma implementação multiplataforma do carregador dinâmico de bibliotecas. Em geral, uma muleta escrita no momento em que as possibilidades de integração com o Qt (onde existe um módulo da QLibrary pronto para a batalha) ainda eram vagas
- osgdb_dmd - um plug-in para carregar modelos de um formato específico para o mecanismo DGLEngine versão 1.1. Para o que foi necessário, vou explicar um pouco mais
- O loader de rota é uma biblioteca que fornece uma interface abstrata para o loader de rota. É possível carregar rotas de formato arbitrário
- tcp-connection - biblioteca de comunicação entre processos através dos soquetes TCP
- visualizador - o principal módulo executável do programa
- zds-route-loader - plug-in para rotas de carregamento do formato ZDSimulator
Ao projetar o VTPS, surgiu a questão de se desenvolver um formato de rotas independentemente ou usar o formato de rotas existente, bem como rotas prontas de ferrovias domésticas para o simulador ferroviário existente. Felizmente, a solução acabou sendo o produto proprietário fechado
ZDSimulator , que tem a particularidade de ser adaptado ao material circulante doméstico e às especificidades da rede ferroviária. Apesar dos elogios dos autores do projeto, ele apresenta muitas desvantagens significativas, mas ao mesmo tempo possui um formato simples e claro de rotas acessíveis ao público. No primeiro estágio, era um pecado não aproveitar a oportunidade, apesar de a parte gráfica do simulador ser baseada no mecanismo DGLEngine aberto. O problema é que esse mecanismo, embora esteja em desenvolvimento (o estado atual do projeto
pode ser visto aqui ), mas sua segunda versão atual é incompatível com a versão 1.1, na qual o ZDSimulator se baseia.
Os códigos-fonte da versão 1.1 foram perdidos, os links que os levaram desapareceram por um longo tempo.Uma pesquisa minuciosa no arquivo da web tornou possível encontrar os perdidos e salvos, publicando o DGLEngine v1.1 no Gtihub. Este mecanismo usa seu próprio formato específico de modelos 3D. Tendo a fonte do mecanismo, era fácil escrever o plug-in apropriado para OSG.Portanto, a tarefa de criar HTPS foi reduzida à gravação da parte do software no mecanismo OSG. No futuro, está planejado desenvolver nosso próprio formato de rotas, uma vez que o formato atual prevê movimento apenas pelas rotas principais e possui várias desvantagens que não nos permitem recriar uma série de rotas complexas.A hierarquia das principais classes de HTPS é apresentada no diagrama a seguirA hierarquia de classes do carregador de rotas se parece com issoO carregador de qualquer outro formato de rota pode ser gravado como um plug-in que contém uma classe que herda da classe RouteLoader. No início do VTPS, o caminho para o diretório com a rota é transferido para ele, o formato da rota é determinado e o plug-in correspondente é carregado dinamicamente, o que executa o restante do trabalho sujo.Uma nuance de fundamental importância foi a integração do mecanismo OSG e Qt. Essa integração existe e é chamada osgQt . Esta biblioteca não foi usada neste projeto por dois motivos:- Não há necessidade de controles de janela fornecidos pelo Qt. O OSG possui seu próprio sistema de gerenciamento de janelas da GUI bem desenvolvido e não faz sentido cercar a GUI sobre outra GUI, uma vez que o osgQt se destina principalmente à integração do visualizador OSG à GUI baseada em Qt
- o osgQt está sujeito a um erro - operação incorreta com o contexto OpenGL, que em alguns casos não pode ser dividido entre OSG e QGLWidget, devido ao qual a cena é exibida em qualquer lugar, mas não no widget Qt. Além disso, ainda não foi possível descobrir os motivos, pois em alguns sistemas esse bug não se manifesta.
Havia um entendimento de que a integração com o Qt é necessária em termos de uso do conceito de "slots de sinal" para garantir a interação com o subsistema de rede de conexão tcp que usa o Qt e é o padrão de fato em nossos projetos. Eu realmente não queria confiar no sistema de mensagens OSG e reescrever o cliente TCP (e até mesmo entre plataformas). Foi encontrada uma solução elegante, com base no fato de que, se queremos que um objeto envie um sinal que aciona um slot para outro objeto, devemos cumprir três condições:- Herdar classes interagindo de QObject
- Organizar um loop de processamento de sinal
- Crie uma instância da classe QApplication (ou QCoreApplication) que existe na memória durante a operação do aplicativo
Nesse caso, em nenhum caso você deve fazer uma chamada para QApplication :: exec (), que inicia o ciclo regular de processamento de sinal, basta organizar um ciclo no qual é fácil processar sinais chamando QApplication :: processEvents (). O OSG possui esse ciclo (o ciclo no qual a renderização é executada) e é possível criar um manipulador de eventos no qual o evento osgGA :: GUIEventAdapter :: FRAME gerado pelo mecanismo ao processar o próximo quadro é processado. Assim, toda a integração foi reduzida ao códigoqt-events.h#ifndef QT_EVENTS_H #define QT_EVENTS_H #include <osgGA/GUIEventHandler> #include <QtCore/QtCore> class QtEventsHandler : public osgGA::GUIEventHandler { public: QtEventsHandler(){} virtual bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa); protected: }; #endif // QT_EVENTS_H
qt-events.cpp #include "qt-events.h" bool QtEventsHandler::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa) { switch (ea.getEventType()) { case osgGA::GUIEventAdapter::FRAME: { QCoreApplication::processEvents(QEventLoop::AllEvents, 100); break; } default: break; } return false; }
main.cpp #include "main.h"
após o que, as classes herdadas do QObject e seus derivados podem trocar sinais até que o pulso seja perdido.
Todos os itens acima permitiram por dois meses criar o primeiro protótipo funcional do HTPS. Para demonstrar o que aconteceu no final, proponho a seção a seguir de viagens experimentais em rotas reais. Peço desculpas antecipadamente pela qualidade das filmagens - elas não se apossaram da tecnologia inteligente
Conclusão e Conclusões
A principal conclusão, pelo menos para a nossa equipe, foi que não havia "bala cinza" na escolha da tecnologia para implementar o projeto. Mecanismos de jogo agressivamente comercializados nem sempre são adequados para resolver tarefas específicas, que incluem a visualização dos resultados da modelagem de sistemas técnicos. E se eles são adequados, então não são ótimos em termos dos esforços gastos no desenvolvimento e manutenção do projeto.
É uma pena que um mecanismo gráfico OSG muito bom e, mais importante, gratuito, na verdade não tenha uma comunidade em nosso país. Para resolver esse problema, escrevo aqui uma
série de artigos sobre o recurso (lá coletei todos os links para fontes de informação mais ou menos adequadas, inclusive em russo). Além disso, como uma documentação que descreve os princípios básicos do OSG, também posso oferecer
este blog . Espero que alguém ache esta informação útil.
No que diz respeito ao HTSC, o trabalho nessa direção continua. Ainda existem muitas tarefas importantes que precisam ser resolvidas em um futuro próximo.
Obrigado pela atenção!
(c) Centro para o Desenvolvimento de Competências em Inovação