Atividade #1195
FechadaTestes pré Larc 2019
Descrição
Esta tarefa destina-se a expôr tudo que está sendo testado no pirf nessas duas semanas antes da larc.
Estamos com problema de travamento do código e isso vai ser o foco do nosso trabalho até a competição.
Quando há muitos robôs (ou apenas carenagem) em campo e um robô começa a se mexer, o robô fica descontrolado e várias vezes cai o fps da visão e/ou do while offensive.
Temos dois grandes problemas:
1- FPS de alguma parte do código cai para 40 e fica travado nisso.
2- Mesmo sem cair fps consideravelmente, os robôs ficam descontrolados quando há muitos robôs se mexendo em campo.
Arquivos
Atualizado por Gabriel Borges da Conceição há aproximadamente 5 anos
- Descrição atualizado(a) (diff)
Atualizado por Lucas Germano há aproximadamente 5 anos
Tem alguma versão anterior que não acontecia esse problema? Se tiver, vê quais são as diferenças e tenta identificar o problema
A gnt tem esse mesmo problema faz mt tempo e na RoboCup a gente descobriu que parte dele era por causa do controle (VI's de velocity control etc) o Nicolas já terminou de implementar todas as modificações que a gente fez na RoboCup?
Atualizado por Gabriel Borges da Conceição há aproximadamente 5 anos
Problema 1: Descobrimos que o que estava fazendo o fps do código cair era o RRT. No código antigo, como todos os whiles estavam cascateados, uma queda do while que continha o RRT provocada queda em todo o código.
No código novo conseguimos observar queda apenas do while Offensive, o qual contém o RRT.
Percebemos que o fps caía quando a bola estava muito próxima do robô. Para garantir que o problema era o RRT, colocamos um control que, quando acionado, não executava a VI do RRT. Nas situações com o fps em queda, ao acionar o botão, imediatamente o fps subia.
Conversando com o Nicolas ele me explicou que o algoritmo não é executado a toda iteração. Sempre há duas conferências:
Conferência 1: Verifica se a última trajetória gerada ainda é possível, ou seja, se ainda termina próxima ao destino do robô e se não provoca nenhuma colisão.
Conferência 2: Verifica se a trajetória sendo uma única reta da origem ao destino é possível.
Apenas se as duas conferências retornarem negativamente, o algoritmo é executado para gerar uma nova trajetória. Dessa forma conseguimos fazer com que o processamento não fique sugado tendo que gerar trajetória a toda iteração.
Porém, existem algumas situações que necessitam de calcular a trajetória a toda iteração, dentre elas: muito próximo à bola ou muito próximo ao destino. Isso é feito para que o robô consiga parar em seu destino e chegar bem para chutar a bola (não fique varando até se estabilizar). Justamente nessas situações é que o fps cai. Ou seja, nosso código não suporta executar o RRT a toda iteração por muito tempo.
Fizemos dois testes com o robô físico no pirf:
1- Tirar o recálculo obrigatório quando perto da bola: O fps subiu consideravelmente (de 60 para 80, num máximo de 120 do nosso campo) e não afetou visivelmente o controle e execução do movimento do robô.
2- Tirar o recálculo obrigatório quando perto do destino: Produziu o mesmo efeito de subida de fps, mas causou prejuízo considerável ao movimento do robô.
Nós achamos que essas duas condições seriam redundantes, mas pelo visto não são.
Tirando essas duas obrigatoriedades de recálculo, o fps não caiu mais, mas isso não é solução pois a movimentação do robô fica prejudicada.
O grande problema é que nosso RRT não utiliza a estrutura de dados que deveria, KD-Tree, pois não conseguimos implementar em labview. Usamos vetor linear mesmo e isso piora muito o tempo de execução das buscas. O Nicolas fez testes e percebeu que nosso tempo médio de execução do RRT é maior que o tempo máximo de execução da equipe a qual ele se baseou para montar o algoritmo.
A solução é refazer o RRT em C++, pois será mais fácil implementar o KD-Tree, e importar como .dll para labview.
Como não temos tempo hábil de fazer isso até a larc, encontramos a seguinte solução temporária:
1- Retirar a obrigatoriedade de recálculo perto da bola (mas mantendo perto do destino), o que faz com que o fps caia consideravelmente menos.
2- Se o fps do while que contém o RRT estiver abaixo de determinado valor (70, por exemplo), informar via booleano que deve ser utilizada apenas a única reta como trajetória ao invés de executar o algoritmo. Isso fará com que o código consiga escapar desse poço de fps e não fique travado. Isso pode acabar atrapalhando a movimentação do robô em algumas situações.
Essas duas coisas foram testadas e funcionaram bem. Vamos testar mais nesse fim de semana e ver quais ajustes podemos fazer.
Há ainda duas coisas que podemos fazer para melhorar a situação:
1- O Nicolas disse que foi feita uma evolução do nosso RRT inicial. Antes, era um único cálculo que desviava de todos os obstáculos, essa melhora faz com que ele desvie um por um em vários cálculos separados. Não entendi muito bem ainda, mas o fato é que, pelo o que ele testou, o único cálculo desviando de tudo executa em menos tempo. Então voltar o nosso código a isso ajudaria também.
2- Colocar o RRT do Offensive para executar num while separado. Isso é bom pois uma queda no while do RRT, não interferiria em escolher plays, robôs, gerar destinos e etc. Ainda não testamos isso e pretendemos fazê-lo nesse fim de semana.
Em resumo, conseguimos finalmente identificar qual parte fazia cair o fps do código e achamos soluções temporárias para evitar que isso aconteça. O efeito colateral é que o robô pode acabar tendo sua movimentação um pouco afetada em algumas situações (nas situações de queda de fps) pois passaremos a linha reta, então o robô pode acabar colidindo em alguém e varando um pouco sua posição. Mas, do jeito que estava, nessas situações o fps caía e não voltava, então a movimentação ficava certamente afetada e por tempo indefinido.
Após a larc, o foco será refazer o RRT em C++ e utilizar em nosso código como .dll.
Atualizado por Gabriel Borges da Conceição há aproximadamente 5 anos
Lucas Germano escreveu:
Tem alguma versão anterior que não acontecia esse problema? Se tiver, vê quais são as diferenças e tenta identificar o problema
A gnt tem esse mesmo problema faz mt tempo e na RoboCup a gente descobriu que parte dele era por causa do controle (VI's de velocity control etc) o Nicolas já terminou de implementar todas as modificações que a gente fez na RoboCup?
Todas as atualizações no controle, Kalman e RRT feitas na RoboCup já estão em nosso código atual.
E em relação ao último código que não apresentava esses problemas, é da Larc 2017. De fato, ele não tinha RRT e na visão não tinha o Last AI que tem no atual (o que pesa muito a visão).
Atualizado por Gabriel Borges da Conceição há aproximadamente 5 anos
Problema 2: Conseguimos identificar que o que provoca isso é um acúmulo de pacotes antigos, fazendo com que nossa visão fique defasada. Ou seja, o código trabalha com uma posição não atual dos robôs, logo o planejamento de trajetória e controle realmente não vão fazer sentido.
Primeiramente, percebemos que nenhum fps caía consideravelmente nessas situações, apenas pequenas quedas no while da visão. Estávamos fazendo testes com 11/12 carenagens em campo e 3/4 robôs se mexendo. Após pouco tempo, os robôs já ficavam malucos. Filmamos ao mesmo tempo o nosso desenho do campo e o graphical client e percebemos que nosso desenho estava defasado em alguns segundos. Isso pode ser visto no seguinte vídeo:
A desconfiança era a visão estar pesada ou algo do tipo. Então, a ideia era era reduzir o que desse de processamento nela. Então colocamos o kalman para ser executado apenas para a câmera que está chegando agora ao invés de para as 4. E também retiramos o Last AI que entrava no kalman. Isso era feito para utilizar as velocidades de controle no Kalman, colocando na matriz uk, mas durante a RoboCup o Nicolas percebeu que isso era pior e desabilitou a conta, mas o cluster continuava sendo informado até a VI. Tinha mais informação do que precisávamos usar e nem estávamos mais usando, então retiramos esse Last AI.
Com essas duas modificações, o código deu muito menos problema. Antes de fazermos isso, bastava 10s para os robôs ficarem malucos e pra ter um delay acumulativo na nossa Visão. Com as alterações, testamos por horas e aconteceu apenas 2 vezes, sendo que pausando e rodando o código novamente já funcionava.
Mas, CLARO que isso não era a solução do problema. Ainda acontecia o erro, só que menos. Mas em contrapartida, na competição teremos o dobro de fps e mais que o dobro de robôs se mexendo, o que provavelmente faria ocorrer mais vezes.
Fizemos o seguinte teste no grsim:
Colocamos um wait controlado por um control no while da visão. Deixamos o código rodar com 0 de wait por um tempo, dps forçamos o código a ter fps baixo, deixamos por um tempo e depois voltamos ao normal. Fizemos isso para simular um queda de processamento e analisar como o código se comporta.
O resultado foi que o código ficava com delay cumulativo durante o fps baixo e quando voltava ao fps normal, todo o caminho atrasado era processado rapidamente até que chegava à imagem atualizada. Ou seja, não estavam sendo descartados os pacotes que chegaram há mais tempo. Vídeos sobre isso serão postados daqui a pouco
Funcionamento dessa parte do código (fluxo de uma iteração de while da visão):
Passo 1: Caso a porta mude, fechamos e abrimo a porta UDP com a porta certa. Caso contrário, apenas ficamos lendo da porta que já está aberta. A leitura dos pacotes é transformada de string para um vetor de inteiros (bytes).
Passo 2: Pegamos o vetor de bytes e decodificamos transformando-o em informação do campo e de posição dos robôs e bola.
Passo 3: Pegamos as informações decodificadas, fazemos o filtro de kalman e o código segue (Team and Side, escrever na referência do game e etc).
O problema é que em algumas situações o processamento desse while fica mais lento (quando tem muita informação, muitos robôs se mexendo). Então, para conseguir um pegar novo pacote no passo 1 na próxima iteração de while, temos que esperar os Passos 2 e 3 serem completados na iteração de agora. Com isso, enquanto esse processamento não termina e não conseguimos ler um novo pacote, a própria relação do windows com o labview faz um acúmulo de pacotes no buffer da porta e quando vamos ler um novo pacote, já tem um acúmulo e como só lemos um por vez, pegamos um antigo.
Pra nos garantir de que era isso, mudamos o fato de ficar apenas lendo para abrir-ler-fechar a toda iteração. O problema foi "resolvido" com isso. Quando colocamos wait para forçar queda de fps da visão, o delay era menor e quando o fps voltava ao normal, já atualizava direto pro dado mais atual.
Mas depois de um tempo o labview dava o erro 128. Pesquisamos e vimos que se abrir e fechar a porta mais de 1000 vezes, dá esse erro.
Então a solução que encontramos foi colocar esse método de ler da porta UDP num while separado para que ele nunca seja influenciado por outra parte do código e consiga sempre ler, fazendo com que nunca chegue pacote sem ser lido. O vetor de bytes é passado para o while da visão por referência.
No campo, com fps de câmeras de 120, os fps ficaram:
1- While UDP: 200 - 300
2- While visão sem estimador: 250 - 300
3- while visão com Kalman para as 4 câmeras: 140 - 160
4- while visão com Kalman apenas para a câmera que está chegando: 160 - 170
Esses valores são sem colocar wait.
Todos os outros whiles têm wait para serem forçados a terem fps um pouco abaixo da visão e assim ficaram.
Ainda restam uns probleminhas:
1- Por algum motivo não conseguimos colocar wait no while da leitura UDP, nada roda. Queremos colocar um wait para que esse while rode com fps pouco acima do fps máximo das câmeras.
2- A visão não consegue pegar o tamanho do campo. O ssl-vision não manda as informações do campo em todos os pacotes, manda apenas de tempos em tempos. Daí o que achamos que está acontecendo é: Como o while do udp roda mais rápido que o da visão, a visão não pega todos os vetores que foram escritos na referência e acaba abrindo a referência para ler o vetor de bytes apenas quando o vetor que está escrito é sem o tamanho do campo. Confesso que não conferi se isso ocorre na visão sem estimador, pois nessa situação a visão roda tão rápido quanto o while UDP. No grsim o tamanho do campo é lido sem problemas, acho que deve ser porque o grsim manda isso em todos os pacotes.
Atualizado por Gabriel Borges da Conceição há aproximadamente 5 anos
- Título alterado de Testes pré Larc para Testes pré Larc 2019
Atualizado por Gabriel Borges da Conceição há aproximadamente 5 anos
Em relação a achar que estávamos perdendo pacotes, já descobrimos.
Isso tem a ver com os fps do while do UDP ter ficado tão alto. Nesse while tem uma função buit-in do labview que é a leitura de pacotes da porta. Quando chega nessa parte, o código para e fica eseprando até que chegue um pacote para então seguir. Nós podemos especificar o tempo que queremos que espere, sendo que o máximo é 25 segundos. Ou seja, não tem como essa parte do código rodar mais vezes do que a quantidade de pacotes que chegam.
O erro estava no fato de termos desclonado a Vi, sem querer, por isso estava cagando para muitos pacotes e rodando tão rápido. Corrigindo isso, o fps desse while ficou de fato próximo ao máximo de informação que chega e não tivemos mais problemas para conseguir atualizar o tamanho do campo e receber qualquer pacote.
Atualizado por Gabriel Borges da Conceição há aproximadamente 5 anos
Esses problemas de cair muito o fps devido ao RRT e os robôs ficarem malucos devido ao atrasado da visão parecem estar, de fato, consertados.
Ainda restam alguns problemas. Percebemos ontem que as estimativas de velocidade da bola e do robô não parecem estar boas se comparadas às que estavam no código da robocup. Vamos comparar hoje com o autoref da tigers para ter mais certeza e tentar identificar os problemas.
Restam também alguns errinhos de escolha de personalidades, não identificar chute ou toque em algumas situações, mas sabemos consertar isso e temos tempo hábil. Estamos focando nos problemas que precisam de campo para serem resolvidos.
Atualizado por Luiz Renault Leite Rodrigues há aproximadamente 5 anos
Gabriel Borges da Conceição escreveu:
Problema 1: Descobrimos que o que estava fazendo o fps do código cair era o RRT. No código antigo, como todos os whiles estavam cascateados, uma queda do while que continha o RRT provocada queda em todo o código.
No código novo conseguimos observar queda apenas do while Offensive, o qual contém o RRT.
Percebemos que o fps caía quando a bola estava muito próxima do robô. Para garantir que o problema era o RRT, colocamos um control que, quando acionado, não executava a VI do RRT. Nas situações com o fps em queda, ao acionar o botão, imediatamente o fps subia.
Conversando com o Nicolas ele me explicou que o algoritmo não é executado a toda iteração. Sempre há duas conferências:
Conferência 1: Verifica se a última trajetória gerada ainda é possível, ou seja, se ainda termina próxima ao destino do robô e se não provoca nenhuma colisão.
Conferência 2: Verifica se a trajetória sendo uma única reta da origem ao destino é possível.
Apenas se as duas conferências retornarem negativamente, o algoritmo é executado para gerar uma nova trajetória. Dessa forma conseguimos fazer com que o processamento não fique sugado tendo que gerar trajetória a toda iteração.
Porém, existem algumas situações que necessitam de calcular a trajetória a toda iteração, dentre elas: muito próximo à bola ou muito próximo ao destino. Isso é feito para que o robô consiga parar em seu destino e chegar bem para chutar a bola (não fique varando até se estabilizar). Justamente nessas situações é que o fps cai. Ou seja, nosso código não suporta executar o RRT a toda iteração por muito tempo.
Nestes casos particulars, o RRT não deveria ser usado. Deveria se alternar com cálculo de trajetória convencional. O RRT, ao meu ver serve para estabelecer longos percursos.
Fizemos dois testes com o robô físico no pirf:
1- Tirar o recálculo obrigatório quando perto da bola: O fps subiu consideravelmente (de 60 para 80, num máximo de 120 do nosso campo) e não afetou visivelmente o controle e execução do movimento do robô.
2- Tirar o recálculo obrigatório quando perto do destino: Produziu o mesmo efeito de subida de fps, mas causou prejuízo considerável ao movimento do robô.
Não é o RRT que vai fazer o robô chegar no destino, e sim o controle convencional. O RRT só serve para definir o destino. Uma vez definido, o controle tem que fazer o robô chegar.
Nós achamos que essas duas condições seriam redundantes, mas pelo visto não são.
Tirando essas duas obrigatoriedades de recálculo, o fps não caiu mais, mas isso não é solução pois a movimentação do robô fica prejudicada.
O RRT só deveria ser executado novamente quando o estado do campo se altera, independente da posição do robô na trajetória. Exemplo: quando um outro robô entra na frente. Quando o destino é definido pela posição da bola e esta se altera consideravelmente.
O grande problema é que nosso RRT não utiliza a estrutura de dados que deveria, KD-Tree, pois não conseguimos implementar em labview. Usamos vetor linear mesmo e isso piora muito o tempo de execução das buscas. O Nicolas fez testes e percebeu que nosso tempo médio de execução do RRT é maior que o tempo máximo de execução da equipe a qual ele se baseou para montar o algoritmo.
Qual a dificuldade de implementar o KD-Tree?
A solução é refazer o RRT em C++, pois será mais fácil implementar o KD-Tree, e importar como .dll para labview.
Como não temos tempo hábil de fazer isso até a larc, encontramos a seguinte solução temporária:
Dá tempo de fazer. Inclusive porque não precisa rodar robôs pra isso. Basta utilizar um estado fixo do campo para o desenvolvimento.
1- Retirar a obrigatoriedade de recálculo perto da bola (mas mantendo perto do destino), o que faz com que o fps caia consideravelmente menos.
2- Se o fps do while que contém o RRT estiver abaixo de determinado valor (70, por exemplo), informar via booleano que deve ser utilizada apenas a única reta como trajetória ao invés de executar o algoritmo. Isso fará com que o código consiga escapar desse poço de fps e não fique travado. Isso pode acabar atrapalhando a movimentação do robô em algumas situações.
Essas duas coisas foram testadas e funcionaram bem. Vamos testar mais nesse fim de semana e ver quais ajustes podemos fazer.
Estamos gastando tempo com soluções paliativas. Melhor partir para uma solução definitiva.
Há ainda duas coisas que podemos fazer para melhorar a situação:
1- O Nicolas disse que foi feita uma evolução do nosso RRT inicial. Antes, era um único cálculo que desviava de todos os obstáculos, essa melhora faz com que ele desvie um por um em vários cálculos separados. Não entendi muito bem ainda, mas o fato é que, pelo o que ele testou, o único cálculo desviando de tudo executa em menos tempo. Então voltar o nosso código a isso ajudaria também.
2- Colocar o RRT do Offensive para executar num while separado. Isso é bom pois uma queda no while do RRT, não interferiria em escolher plays, robôs, gerar destinos e etc. Ainda não testamos isso e pretendemos fazê-lo nesse fim de semana.
Em resumo, conseguimos finalmente identificar qual parte fazia cair o fps do código e achamos soluções temporárias para evitar que isso aconteça. O efeito colateral é que o robô pode acabar tendo sua movimentação um pouco afetada em algumas situações (nas situações de queda de fps) pois passaremos a linha reta, então o robô pode acabar colidindo em alguém e varando um pouco sua posição. Mas, do jeito que estava, nessas situações o fps caía e não voltava, então a movimentação ficava certamente afetada e por tempo indefinido.
Após a larc, o foco será refazer o RRT em C++ e utilizar em nosso código como .dll.
Atualizado por Luiz Renault Leite Rodrigues há aproximadamente 5 anos
Gabriel Borges da Conceição escreveu:
Problema 2: Conseguimos identificar que o que provoca isso é um acúmulo de pacotes antigos, fazendo com que nossa visão fique defasada. Ou seja, o código trabalha com uma posição não atual dos robôs, logo o planejamento de trajetória e controle realmente não vão fazer sentido.
Primeiramente, percebemos que nenhum fps caía consideravelmente nessas situações, apenas pequenas quedas no while da visão. Estávamos fazendo testes com 11/12 carenagens em campo e 3/4 robôs se mexendo. Após pouco tempo, os robôs já ficavam malucos. Filmamos ao mesmo tempo o nosso desenho do campo e o graphical client e percebemos que nosso desenho estava defasado em alguns segundos. Isso pode ser visto no seguinte vídeo:
Error executing the video macro (undefined method `find_by_filename' for []:Array Did you mean? find_index)A desconfiança era a visão estar pesada ou algo do tipo. Então, a ideia era era reduzir o que desse de processamento nela. Então colocamos o kalman para ser executado apenas para a câmera que está chegando agora ao invés de para as 4. E também retiramos o Last AI que entrava no kalman. Isso era feito para utilizar as velocidades de controle no Kalman, colocando na matriz uk, mas durante a RoboCup o Nicolas percebeu que isso era pior e desabilitou a conta, mas o cluster continuava sendo informado até a VI. Tinha mais informação do que precisávamos usar e nem estávamos mais usando, então retiramos esse Last AI.
Com essas duas modificações, o código deu muito menos problema. Antes de fazermos isso, bastava 10s para os robôs ficarem malucos e pra ter um delay acumulativo na nossa Visão. Com as alterações, testamos por horas e aconteceu apenas 2 vezes, sendo que pausando e rodando o código novamente já funcionava.
Mas, CLARO que isso não era a solução do problema. Ainda acontecia o erro, só que menos. Mas em contrapartida, na competição teremos o dobro de fps e mais que o dobro de robôs se mexendo, o que provavelmente faria ocorrer mais vezes.
Fizemos o seguinte teste no grsim:
Colocamos um wait controlado por um control no while da visão. Deixamos o código rodar com 0 de wait por um tempo, dps forçamos o código a ter fps baixo, deixamos por um tempo e depois voltamos ao normal. Fizemos isso para simular um queda de processamento e analisar como o código se comporta.
O resultado foi que o código ficava com delay cumulativo durante o fps baixo e quando voltava ao fps normal, todo o caminho atrasado era processado rapidamente até que chegava à imagem atualizada. Ou seja, não estavam sendo descartados os pacotes que chegaram há mais tempo. Vídeos sobre isso serão postados daqui a pouco
Funcionamento dessa parte do código (fluxo de uma iteração de while da visão):
Passo 1: Caso a porta mude, fechamos e abrimo a porta UDP com a porta certa. Caso contrário, apenas ficamos lendo da porta que já está aberta. A leitura dos pacotes é transformada de string para um vetor de inteiros (bytes).
Passo 2: Pegamos o vetor de bytes e decodificamos transformando-o em informação do campo e de posição dos robôs e bola.
Passo 3: Pegamos as informações decodificadas, fazemos o filtro de kalman e o código segue (Team and Side, escrever na referência do game e etc).
O problema é que em algumas situações o processamento desse while fica mais lento (quando tem muita informação, muitos robôs se mexendo). Então, para conseguir um pegar novo pacote no passo 1 na próxima iteração de while, temos que esperar os Passos 2 e 3 serem completados na iteração de agora. Com isso, enquanto esse processamento não termina e não conseguimos ler um novo pacote, a própria relação do windows com o labview faz um acúmulo de pacotes no buffer da porta e quando vamos ler um novo pacote, já tem um acúmulo e como só lemos um por vez, pegamos um antigo.
Pra nos garantir de que era isso, mudamos o fato de ficar apenas lendo para abrir-ler-fechar a toda iteração. O problema foi "resolvido" com isso. Quando colocamos wait para forçar queda de fps da visão, o delay era menor e quando o fps voltava ao normal, já atualizava direto pro dado mais atual.
Mas depois de um tempo o labview dava o erro 128. Pesquisamos e vimos que se abrir e fechar a porta mais de 1000 vezes, dá esse erro.
Então a solução que encontramos foi colocar esse método de ler da porta UDP num while separado para que ele nunca seja influenciado por outra parte do código e consiga sempre ler, fazendo com que nunca chegue pacote sem ser lido. O vetor de bytes é passado para o while da visão por referência.
Ficar abrindo e fechando a porta UDP é uma solução errada já na formulação. Isso não deve ser feito.
Tem que analisar o problema em si, que é: Descartar todas as informações anteriores e processar apenas o último quadro transmitido. Este é o problema. Buscar a solução para ele. Isso pode ser feito através da configuração dos canais.
No campo, com fps de câmeras de 120, os fps ficaram:
1- While UDP: 200 - 300
2- While visão sem estimador: 250 - 300
3- while visão com Kalman para as 4 câmeras: 140 - 160
4- while visão com Kalman apenas para a câmera que está chegando: 160 - 170Esses valores são sem colocar wait.
Todos os outros whiles têm wait para serem forçados a terem fps um pouco abaixo da visão e assim ficaram.
Abandonar esta solução.
Ainda restam uns probleminhas:
1- Por algum motivo não conseguimos colocar wait no while da leitura UDP, nada roda. Queremos colocar um wait para que esse while rode com fps pouco acima do fps máximo das câmeras.
2- A visão não consegue pegar o tamanho do campo. O ssl-vision não manda as informações do campo em todos os pacotes, manda apenas de tempos em tempos. Daí o que achamos que está acontecendo é: Como o while do udp roda mais rápido que o da visão, a visão não pega todos os vetores que foram escritos na referência e acaba abrindo a referência para ler o vetor de bytes apenas quando o vetor que está escrito é sem o tamanho do campo. Confesso que não conferi se isso ocorre na visão sem estimador, pois nessa situação a visão roda tão rápido quanto o while UDP. No grsim o tamanho do campo é lido sem problemas, acho que deve ser porque o grsim manda isso em todos os pacotes.
Atualizado por Luiz Renault Leite Rodrigues há aproximadamente 5 anos
Gabriel Borges da Conceição escreveu:
Esses problemas de cair muito o fps devido ao RRT e os robôs ficarem malucos devido ao atrasado da visão parecem estar, de fato, consertados.
Ao meu ver os problemas permaneces, necessitando de soluções acertadas e definitivas.
Ainda restam alguns problemas. Percebemos ontem que as estimativas de velocidade da bola e do robô não parecem estar boas se comparadas às que estavam no código da robocup. Vamos comparar hoje com o autoref da tigers para ter mais certeza e tentar identificar os problemas.
Restam também alguns errinhos de escolha de personalidades, não identificar chute ou toque em algumas situações, mas sabemos consertar isso e temos tempo hábil. Estamos focando nos problemas que precisam de campo para serem resolvidos.
Atualizado por Nicolas Oliveira há aproximadamente 5 anos
Luiz Renault Leite Rodrigues escreveu:
Nestes casos particulars, o RRT não deveria ser usado. Deveria se alternar com cálculo de trajetória convencional. O RRT, ao meu ver serve para estabelecer longos percursos.
Atualmente isso já acontece, só se usa o RRT quando "n há outras opções".
Não é o RRT que vai fazer o robô chegar no destino, e sim o controle convencional. O RRT só serve para definir o destino. Uma vez definido, o controle tem que fazer o robô chegar.
Isso foi um equívoco nosso em relação ao q estava prejudicando a movimentação (na vdd um erro meu no passado). As ctes de controle já foram revisadas e a movimentação está ok.
O RRT só deveria ser executado novamente quando o estado do campo se altera, independente da posição do robô na trajetória. Exemplo: quando um outro robô entra na frente. Quando o destino é definido pela posição da bola e esta se altera consideravelmente.
O senhor n acha q quando o robo "erra muito" a trajetória, n seria mais prático recalcular uma nova, ao invés de tentar retornar para a antiga? (n entrando no mérito de pq ele iria errar a trajetória.
Qual a dificuldade de implementar o KD-Tree?
Dá tempo de fazer. Inclusive porque não precisa rodar robôs pra isso. Basta utilizar um estado fixo do campo para o desenvolvimento.
Eu particularmente fiquei sem tempo de ajudá-los e eles focaram em encontrar os erros.
Atualizado por Luiz Renault Leite Rodrigues há aproximadamente 5 anos
Nicolas Oliveira escreveu:
O senhor n acha q quando o robo "erra muito" a trajetória, n seria mais prático recalcular uma nova, ao invés de tentar retornar para a antiga? (n entrando no mérito de pq ele iria errar a trajetória.
Está implementado controle de trajetória? Isso é o mais fácil de ser feito e o que melhorará o resultado.
Eu particularmente fiquei sem tempo de ajudá-los e eles focaram em encontrar os erros.
Encontrar os erros é metade do caminho. Agora temos que focar para implementar as soluções de forma eficiente, evitando o desespero antes das partidas.
Atualizado por Nicolas Oliveira há aproximadamente 5 anos
Luiz Renault Leite Rodrigues escreveu:
Ao meu ver os problemas permaneces, necessitando de soluções acertadas e definitivas.
Discordo do senhor pq depois da segmentação do código em verdadeiras threads pudemos no concentrar em ver oq verdadeiramente precisamos fazer.
A parte da decodificação esta correta agr, sem abrir e fechar a porta todo o tempo, mas decodificando todos os pacotes.
Dessa forma a parte da filtragem fica livre pra rodar numa taxa conveniente ao processamento. E os pacotes q n puderem ser usados serão descartados, coisa q n acontecia antes, onde havia um acumulo de pacotes que gerava um delay.
As estimativas e o controle são invariantes as circuntancias do campo, como deve ser, porém n acontecia.
As constantes de controle foram ajustadas, e os novos membros aprenderam o processo.
E principalmente n há mais travamentos, e por mais q possam acontecer, o código está pronto pra isso.
E por fim os novos membros puderam ter um entendimente geral e mais profundo sobre tudo que acontece no código.
Atualizado por Nicolas Oliveira há aproximadamente 5 anos
Luiz Renault Leite Rodrigues escreveu:
Está implementado controle de trajetória? Isso é o mais fácil de ser feito e o que melhorará o resultado.
Isso já esta sendo feito. Por isso o resultado esta melhor rs, toda essa parte foi acertada na ultima robocup.
Encontrar os erros é metade do caminho. Agora temos que focar para implementar as soluções de forma eficiente, evitando o desespero antes das partidas.
Estamos focando nisso.
Atualizado por Gabriel Borges da Conceição há aproximadamente 5 anos
Major, em relação a estarmos encontrando soluções paliativas, concordo em relação ao RRT.
Mas, assim como o Nicolas disse, concordo em pensar que colocar a leitura de pacotes num while separado é uma solução acertada.
O fps desse while estava estranhamente acima dos fps das câmeras por causa de um erro bobo na nossa implementação. Agora o recebimento de pacotes está de fato muito próximo ao que chega do computador da visão.
Agora, o while da visão consegue até rodar mais rápido que o recebimento de pacotes, ou seja, seu processamento está respondendo bem. Mas vamos colocar um limitador levando em conta o atual fps da visão e do recebimento de pacotes para que o while visão rode sempre muito próximo ao recebimento dos pacotes (ligeiramente abaixo).
Em relação a colocar o Kalman apenas para a câmera que chega e fazer estimativas de velocidades de outra forma, temos a completa noção de que isso deve ser mudado o quanto antes. Na verdade, o maior foco do nosso trabalho ao longo desse semestre foi estudar o filtro de Kalman e melhorar a implementação dele à nossa aplicação. Tudo que foi aprendido está na tarefa "Modificar o filtro de Kalman" e agora realmente o entendemos e sabemos como o atacar para melhorar. Chegamos a fazer uma nova implementação que ficou boa no grSim, mas a maior imprecisão das câmeras no campo fez bastante diferença no resultado. Então decidimos focar em identificar os maiores problemas do código no momento (cair fps e delay de visão) devido ao tempo que tínhamos até a competição e focar no Kalman no próximo semestre.
Atualizado por Luiz Renault Leite Rodrigues há aproximadamente 5 anos
Coloque aqui imagem do diagrama de blocos que contém esse recebimento de pacotes que estão comentando. Isso é do UDP?
O que deve acontecer é receber todos os frames via UDP e processar todos estes no estimador. Assim a estimativa fica coerente com o campo e mais precisa.
Porém, só as estimativas que puderem ser utilizadas em função da limitação de processamento deveriam ser recebidas pela inteligência, com as demais descartadas.
Qual limitador vocês pretendem colocar?
Acredito que ainda precisem resolver de forma definitiva o modelo de fila dos frames, de forma a ser mantido disponível para a inteligência apenas o último. Não entendi pela explicação de vocês que isso está acontecendo. Pelo que pude perceber, apenas aumentou a velocidade de processamento. Se for isso, caso haja alguma limitação, ainda manteria a fila e seriam disponibilizados os frames antigos. Me corrijam se isso estiver equivocado.
Atualizado por Luiz Renault Leite Rodrigues há aproximadamente 5 anos
Qual é o planejamento de vocês?
O código atual está jogável com 12 robôs em campo?
O robô consegue chutar para o gol com agilidade?
O controle do robô e de trajetória estão satisfatórios?
Atualizado por Gabriel Borges da Conceição há aproximadamente 5 anos
- Arquivo Separação da visão.png Separação da visão.png adicionado
Luiz Renault Leite Rodrigues escreveu:
Coloque aqui imagem do diagrama de blocos que contém esse recebimento de pacotes que estão comentando. Isso é do UDP?
O que deve acontecer é receber todos os frames via UDP e processar todos estes no estimador. Assim a estimativa fica coerente com o campo e mais precisa.
Porém, só as estimativas que puderem ser utilizadas em função da limitação de processamento deveriam ser recebidas pela inteligência, com as demais descartadas.
Qual limitador vocês pretendem colocar?
![](Separação da visão.png)
Da maneira que está agora, a leitura de pacotes está independente do processamento do resto da visão. Caso haja algum atraso por causa de processamento do visão, a leitura de pacotes não é interferida diretamente e novos pacotes são lidos e escritos na referência, então quando o processamento da visão voltar ao normal, o pacote a ser processado será o mais atual (último escrito na referência).
Antigamente, a leitura de pacotes e processamento dos dados era sequencial, no mesmo loop. Então um novo pacote só era lido quando quando o processamento terminasse. Como só lemos um pacote por iteração e o labview acumulava os pacotes sozinho, isso gerava uma fila.
Não era o nosso código que gerava essa fila, ele apenas lia um pacote da porta. O labview que gerava a fila na porta antes mesmo do nosso processamento.
Acredito que ainda precisem resolver de forma definitiva o modelo de fila dos frames, de forma a ser mantido disponível para a inteligência apenas o último. Não entendi pela explicação de vocês que isso está acontecendo. Pelo que pude perceber, apenas aumentou a velocidade de processamento. Se for isso, caso haja alguma limitação, ainda manteria a fila e seriam disponibilizados os frames antigos. Me corrijam se isso estiver equivocado.
Atualizado por Gabriel Borges da Conceição há aproximadamente 5 anos
Luiz Renault Leite Rodrigues escreveu:
Qual é o planejamento de vocês?
Antes de começarem os testes no campo da competição e percebermos novos possíveis erros, o foco agora é corrigir erros de lógica que deixamos em segundo plano para poder focar nos problemas de acúmulo de pacotes e quedas de fps.
O código atual está jogável com 12 robôs em campo?
Nossos testes no pirf tinham 11/12 carenagens em campo sendo 3/4 robôs se mexendo. Com as alterações feitas no código, não houve mais quedas bruscas de fps e as pequenas quedas na visão (que aconteceram poucas vezes) não provocaram delay na visão e consequentemente os robôs não ficaram descontrolados como acontecia.
O robô consegue chutar para o gol com agilidade?
O controle do robô e de trajetória estão satisfatórios?
Fizemos uma alteração no controle que fez diferença significativa. Colocamos certas ctes PID para quando o robô está a mais de 500mm do destino e outras para quando está a menos que isso. Dessa forma, o robô consegue andar rápido e quando se aproxima do objetivo, é mais preciso e não fica oscilando em torno da posição final.
Atualizado por Luiz Renault Leite Rodrigues há aproximadamente 5 anos
Mandem um video dos robôs se movimentando.
Atualizado por Gabriel Borges da Conceição há quase 5 anos
- Situação alterado de Em andamento para Fechada