Olá Habr! Eu trabalho em uma pequena startup em Berlim que desenvolve pilotos automáticos para carros. Estamos concluindo um projeto para estações de serviço de uma grande montadora alemã e eu gostaria de falar sobre isso: como fizemos, quais dificuldades encontramos e que coisas novas descobrimos. Nesta parte, falarei sobre o módulo de percepção e um pouco sobre a arquitetura da solução como um todo. Sobre o restante dos módulos, talvez, contaremos nas seguintes partes. Ficarei muito feliz em receber feedback e olhar de fora sobre a nossa abordagem.
O comunicado de imprensa do projeto do cliente pode ser encontrado
aqui .
Para começar, vou lhe dizer por que a montadora se voltou para nós e não fez o projeto por conta própria. É difícil para grandes preocupações alemãs alterar processos, e o formato de desenvolvimento de carro raramente é adequado para software - as iterações são longas e requerem um bom planejamento. Parece-me que as montadoras alemãs entendem isso e, portanto, você pode conhecer startups que são fundadas por elas, mas trabalhar como uma empresa independente (por exemplo, AID da Audi e Zenuity da Volvo). Outras montadoras estão organizando eventos como o Startup Autobahn, onde estão procurando empreiteiros em potencial para tarefas e novas idéias. Eles podem solicitar um produto ou protótipo e, após um curto período de tempo, obter o resultado final. Isso pode ser mais rápido do que tentar fazer a mesma coisa, e não custa mais do que seu próprio desenvolvimento em termos de custos. A complexidade das alterações do processo é bem demonstrada pelo número de permissões necessárias para começar a testar um carro com piloto automático nos clientes: consentimento para gravação de vídeo de pessoas (mesmo que não salvemos dados e usamos streaming de vídeo apenas de forma anônima sem identificar pessoas específicas), consentimento para gravação de vídeo territórios, o consentimento do sindicato e o cônsul de trabalho para testar essas tecnologias, o consentimento do serviço de segurança, o consentimento do serviço de TI - essa não é a lista completa.
Desafio
No projeto atual, o cliente quer entender se é possível dirigir carros em centros de serviço usando "AI". O script do usuário é:
- O técnico quer começar a trabalhar com uma máquina que esteja em algum lugar do estacionamento fora da área de teste.
- Ele seleciona o carro no tablet, seleciona a caixa de serviço e clica em "Dirigir".
- O carro entra e para no ponto final (elevador, rampa ou outra coisa).
- Quando o técnico termina o trabalho no carro, ele pressiona um botão no tablet, o carro sai e estaciona em algum espaço vazio do lado de fora.
Características: nem todos os carros têm câmeras. Nas máquinas em que estão, não temos acesso a elas. Os únicos dados na máquina a que temos acesso são sonares e odometria
Sonares e odometriaOs sonares são sensores de distância que são instalados em um círculo em um carro e geralmente parecem pontos redondos; permitem estimar a distância do objeto, mas apenas próximos e com baixa precisão. Odometria - dados sobre a velocidade e a direção reais do carro. Conhecendo esses dados e a posição inicial, você pode determinar com bastante precisão a posição atual da máquina.
Assim, o carro deve ser controlado por sensores externos instalados na área de serviço.
Solução
A arquitetura do produto final é a seguinte:
- Na área de serviço, instalamos câmeras externas, lidares e outras coisas (olá Tesla).
- Os dados das câmeras vão para o Jetson TX2 (três câmeras cada), que estão envolvidos na tarefa de encontrar a máquina e pré-processar imagens das câmeras.
- Além disso, os dados da câmera chegam ao servidor central, orgulhosamente chamado de Torre de Controle, no qual se enquadram nos módulos de percepção, rastreamento e planejamento de caminho. Como resultado da análise, é tomada uma decisão sobre a direção adicional do movimento do carro e é enviada ao carro.
- Nesta fase do projeto, outro Jetson TX2 é colocado no carro, que, usando nosso driver, se conecta ao Vector, que descriptografa os dados do carro e envia comandos. O TX2 recebe comandos de controle de um servidor central e os transmite para o carro.
Para o nível de infraestrutura, o
ROS é usado.
Eis o que acontece depois que um técnico escolhe um carro e clica em "dirigir":
- O sistema está procurando um carro: enviamos um comando ao carro para piscar alarmes, após o qual podemos determinar qual dos carros no estacionamento é selecionado pelo técnico. No estágio inicial de desenvolvimento, também consideramos a opção de determinar a máquina pela chapa de matrícula, mas em algumas áreas do carro estacionado o número pode não ser visível. Além disso, se fizéssemos a determinação do carro pelo número de registro, a resolução das fotos teria que ser bastante aumentada, o que afetaria negativamente a produtividade, e usamos a mesma imagem para pesquisar e dirigir. Esse estágio ocorre uma vez e é repetido apenas se, por algum motivo, perdemos o carro no rastreamento.
- Assim que o carro é encontrado, soltamos as imagens das câmeras que o carro atinge no módulo de percepção, que segmenta o espaço e fornece as coordenadas de todos os objetos, sua orientação e tamanho. Esse processo está em andamento, rodando a cerca de 30 quadros por segundo. Os processos subsequentes também são constantes e são executados até a máquina chegar ao ponto final.
- O módulo de rastreamento recebe informações da percepção, sonares e odometria, mantém na memória todos os objetos encontrados, combina-os, refina a localização, prediz a posição e a velocidade dos objetos.
- Em seguida, o planejador de caminho, dividido em duas partes: planejador de caminho global para a rota global e planejador de caminho local para o local (responsável por evitar obstáculos), cria um caminho e decide para onde ir em nosso carro, envia um comando.
- Jetson pega o comando de carro e o transmite para o carro.
A partida ocorre da mesma maneira que a chegada.
Percepção
Um dos principais e, na minha opinião, o módulo mais interessante é a percepção. Este módulo descreve os dados dos sensores de forma que você possa tomar uma decisão precisa sobre o movimento. Em nosso projeto, fornece as coordenadas, a orientação e os tamanhos de todos os objetos que caem na câmera. Ao projetar este módulo, decidimos começar com algoritmos que permitiriam analisar a imagem de uma só vez. Tentamos:
- VAE desembaraçado . Uma pequena modificação feita no β-VAE nos permitiu treinar a rede para que vetores latentes armazenassem informações da imagem em uma vista esquemática de cima para baixo.
- GAN condicional (a implementação mais famosa é o pix2pix ). Esta rede pode ser usada para construir mapas. Também o usamos para criar uma visão esquemática de cima, colocando dados de uma ou todas as câmeras nele ao mesmo tempo e aguardando uma visão esquemática de cima na saída.
Uma das iterações GAN Condicionais para uma câmera, da esquerda para a direita: imagem de entrada, previsão de rede, resultado esperado
De fato, a idéia dessas abordagens é garantir que a rede final possa entender a localização e a orientação de todos os carros e outros objetos em movimento que caíram na câmera olhando a foto de entrada uma vez. Os dados dos objetos nesse caso serão armazenados em vetores latentes. O treinamento da rede ocorreu nos dados do simulador, que é uma cópia exata do ponto em que a demonstração ocorrerá. E conseguimos atingir certos resultados, mas decidimos não usar esses métodos por vários motivos:
- No tempo alocado, não conseguimos aprender como usar dados de vetores latentes para descrever a imagem. O resultado da rede sempre foi uma imagem - uma vista superior com um layout esquemático de objetos. Isso é menos preciso e temíamos que essa precisão não fosse suficiente para dirigir um carro.
- A solução não é escalável: para todas as instalações subseqüentes e para os casos em que é necessário alterar a direção de algumas câmeras, é necessário reconfigurar o simulador e repetir o treinamento completo.
No entanto, estávamos interessados em entender as possibilidades dessas abordagens e as manteremos em mente para tarefas futuras.
Depois disso, abordamos a tarefa, por outro lado, através de uma pesquisa regular por objetos + uma rede para determinar a posição espacial dos objetos encontrados (por exemplo,
isto ou
aquilo ). Essa opção nos pareceu mais precisa. O único ponto negativo é que ele é mais lento do que as abordagens propostas anteriormente, mas se encaixa em nossa estrutura de atraso possível, já que a velocidade do carro na área de serviço não passa de 5 km / h. O trabalho mais interessante no campo de previsão da posição 3D do objeto nos pareceu
ser esse , que mostra bons resultados no
KITTI . Construímos uma rede semelhante com algumas mudanças e escrevemos nosso próprio algoritmo para determinar a caixa circundante e, para ser mais preciso, um algoritmo para estimar as coordenadas do centro da projeção do objeto no chão - para tomar decisões sobre a direção do movimento, não precisamos de dados sobre a altura dos objetos. A imagem do objeto e seu tipo (carro, pedestre, ..) são alimentados na entrada da rede, e suas dimensões e orientação espacial são exibidas. Em seguida, o módulo avalia o centro de projeção e fornece dados para todos os objetos: as coordenadas do centro, a orientação e as dimensões (largura e comprimento).
No produto final, cada imagem é executada primeiro na rede para procurar objetos; em seguida, todos os objetos são enviados para a rede 3D para prever a orientação e o tamanho. Depois disso, avaliamos o centro de projeção de cada um e enviamos mais adiante os dados de orientação e tamanho. Uma característica desse método é que ele está fortemente vinculado à precisão do limite da caixa de limite da rede de pesquisa de objetos. Por esse motivo, redes como a YOLO não se adequavam a nós. Encontramos o equilíbrio ideal de desempenho e precisão da caixa limite na rede RetinaNet.
Vale a pena notar uma coisa com a qual tivemos sorte neste projeto: o terreno é plano. Bem, isto é, não é tão plano quanto uma comunidade conhecida, mas não há curvas em nosso território. Isso permite o uso de câmeras monoculares fixas para projetar objetos nas coordenadas do plano terrestre sem informações sobre a distância até o objeto. Planos futuros incluem a introdução de previsão de profundidade monocular. Existem muitos trabalhos sobre esse tópico, por exemplo, um dos últimos e muito interessantes que estamos tentando para projetos futuros. A previsão de profundidade permitirá que você trabalhe não apenas em terreno plano, mas potencialmente aumentará a precisão de determinar obstáculos, simplifique o processo de configuração de novas câmeras e elimine a necessidade de rotular cada objeto - não nos importamos com o tipo de objeto, se é algum tipo de obstáculo.
É tudo, obrigado pela leitura e ficarei feliz em responder a perguntas. Como bônus, quero falar sobre um efeito negativo inesperado: o piloto automático não se importa com a orientação do carro, para ele não importa como ir - para a frente ou para trás. O principal é dirigir da melhor maneira e não colidir com ninguém. Portanto, existe uma alta probabilidade de o carro percorrer parte do caminho ao contrário, especialmente em pequenas áreas onde é necessária alta manobrabilidade. No entanto, as pessoas estão acostumadas com o fato de o carro estar avançando principalmente e geralmente esperam o mesmo comportamento do piloto automático. Se uma pessoa de negócios vê um carro que, em vez de andar na frente, dirige para trás, pode considerar que o produto não está pronto e contém erros.
PS Peço desculpas por não haver imagens e vídeos com testes reais, mas não posso publicá-los por motivos legais.