Projeto

Geral

Perfil

Planejamento de Tragetória » Histórico » Versão 7

Rebeca Reis, 25/02/2019 02:00 h

1 5 Luciano Barreira
# Planejamento de Trajetória
2 1 Nicolas Oliveira
3 5 Luciano Barreira
Nos utilizamos do algoritmo RRT (Rapidly-Exploring Random Tree) para calcular nossa trajetória. Ele busca uma trajetória a partir de um estado inicial até o objetivo expandindo uma árvore de busca. 
4 2 Nicolas Oliveira
Para isso necessitamos de 3 funções básicas:
5 1 Nicolas Oliveira
6
* Extend(env:enviroment,current:state,target:state,Step:real):state
7
8
Essa função dado um estado atual extende dando um passo em direção ao objetivo, ou em uma direção aleatória. Caso uma colisão ocorra ela retorna um estado vazio (EmptyState).
9
Pseudo código:
10
11 3 Nicolas Oliveira
```c
12
r = (Target - Current)/||Targe-Current|| ; //vetor unitário na direção do target
13
NewState = r*Step + Current ; 
14
if (Colision(NewState)) NewState = EmptyState; //confere se o novo estado vai colidir com algum obstáculo.
15
return NewState;
16
```
17 1 Nicolas Oliveira
18
* Distance(current:state,target:state):real
19
20
Calcula a distância do estado atual ao objetivo, utilizamos a euclidiana nessa implementação.
21
22
* RandomState():state
23
24
Retorna um novo estado uniformemente distribuído no ambiente.
25
26 3 Nicolas Oliveira
```c
27
float random_x;
28
float random_y;
29
random_x = fiel_length*(rand()-0.5); //Random gera um número aleatório uniformemente aleatório distribuído entre 0 e 1
30
random_y = fiel_length*(rand()-0.5); 
31
```
32 1 Nicolas Oliveira
33
Basicamente a função estender pode utilizar como target o objetivo ou um ponto aleátório, o que garante que o algoritmo pode encontrar um caminho sem colidir com nenhum obstáculo. Como na figura abaixo:
34
35
![](rrt.PNG)
36
37
A implementação seguiu o pseudo código abaixo:
38
39
![](pseudocódigo.PNG)
40
41
***A função Nearest garante que sempre extendemos a árvore do nó mais próximo do objetivo, porém ela também demanda muito processamento, já que tem q varrer a árvore toda a cada iteração. Vamos estudar um jeito para resolver isso.***
42 5 Luciano Barreira
Definimos uma árvore de pontos como uma matriz de 4 colunas, onde a primeira é o id do ponto, a segunda a coordenada x, a terceira a coordenada y e a quarta o id do pai. Dessa forma os nós são adicionados com o id sendo incrementado de 1 a cada nó. O id do pai é o id do nó da onde aquale novo ramo foi gerado. Assim quando encontramos um solução podemos fazer o backtracking nessa árvore para reconstruir a trajetória.
43 1 Nicolas Oliveira
44 5 Luciano Barreira
O próximo passo foi implentar a extenção do RRT (ERRT), com memória da última trajetória. Assim na hora de escolhermos um target podemos ir em direção ao objetivo, em uma direção aleatória ou em direção a algum ponto da última trajetória, como na imagem e código abaixo.
45 1 Nicolas Oliveira
46
![](errt.PNG)
47
![](choose.PNG)
48
49 5 Luciano Barreira
Por último implementamos a suavização da trajetória que segue o algoritmo abaixo descrito. Ela auxilia muito na rapidez com que o robô será capaz de seguir a trajetóra.
50 1 Nicolas Oliveira
51
![](suavização.png)
52
53 6 Nicolas Oliveira
## Raio dos Obstáculos
54
55
### Robôs Inimigos
56
57
Para os robôs inimigos agora é considerada a influência da velocidade relativa. Assim o raio do obstáculo é dado por:
58
59
```c
60
radius_enemy + radius_our + bound(0, |speed_enemy-speed_our|*100, 100)
61
```
62
E caso o goal esteja dentro de um obstáculo esse raio é reduzido o suficiente para que um trajetória válida possa ser gerada. O mesmo acontece quando o ponto inicial da trajetória está dentro de um obstáculo, o raio é reduzido afim de ser possível a geração da trajetória.
63
64 1 Nicolas Oliveira
## Implementações futuras e problemas atuais
65 6 Nicolas Oliveira
66
* Tornar os nossos robôs obstáculos, porém com um raio menor.
67
* Tornar as áreas dos goleiros e a parte de trás do gol em obstáculos
68
* Colocar a bola como obstáculo na situação de stop
69
* Tornar o RRT otimizado para diferentes personalidades
70 7 Rebeca Reis
71
# Otimização feita (RRT apenas nos obstáculos)
72
73
Conversando com outras equipes na RoboCup 2018, nos deram uma dica de como poderíamos otimizar nosso planejamento de trajetória. A ideia consiste em traçar uma linha reta entre o ponto atual e o final (objetivo) do robô, identificar possíveis obstáculos que cruzam essa reta e aplicar o RRT apenas na região em que ocorrem esses conflitos, mantendo a linha reta onde não houver problema. Isso é essencial para diminuir o custo de processamento e reduzir os cálculos para gerar nosso path, já que o algoritmo é aplicado numa região muito menor. 
74
75
Pesquisamos o TDP de outras equipes para procurar alguma referência dessa implementação, mas não foi encontrada essa ideia de fazer o RRT apenas nos obstáculos escrita em nenhum deles. Todos os TDPs se baseavam naquele mesmo artigo (autores James Bruce e Manuela Veloso) por onde estudamos o RRT, e não foi encontrado nada diferente daquilo.
76
77
A respeito da implementação:
78
79
* Criei a VI FindColisionPoints, para encontrar a posição dos obstáculos que cruzam a trajetória reta mais simples entre os pontos inicial e final (Simple Path). Ela retorna um vetor com todas as posições de obstáculos nesse caminho.
80
81
* Criei a VI FindStartEndPointsRRT, que serve para encontrar a posição do obstáculo mais distante e do mais próximo do ponto inicial, dentre os que estao no vetor dos pontos de colisão. Em seguida aplica-se um range (por enquanto escolhi o tamanho 200mm pra cada lado) em volta dessas duas extremidades de obstaculos. Essa área interna ao range aplicado é a que será percorrida usando o RRT, e as de fora por uma linha reta. Verifica-se após aplicar o range se o novo ponto cai fora do simple path, o que significa que está muito perto do ponto inicial (ou final) da trajetória, e nesse caso trocamos o ponto gerado que deu problema pelo ponto inicial ou final correspondente. Ou seja, se os pontos encontrados para iniciar ou acabar o RRT forem muito próximos da extremidade (usei um valor de comparação <200mm por enquanto), ou se caírem fora daquele segmento, entao ignora-se a linha reta nesse pequeno caminho e aplica-se o RRT diretamente desde o ponto inicial ou até o ponto destino diretamente.
82
83
* Adaptei a VI RRTPlan para essas modificações. Primeiro, modularizei um grande pedaço onde se fazia o algoritmo do RRT de fato, criando uma subVI chamada RRTAlgorithm, para facilitar a visualização da escolha dos pontos inicial e final de onde aplicaríamos o RRT. Em seguida usei as duas VIs anteriores para gerar os pontos de obstáculos e encontrar os pontos iniciais e finais convenientes no algoritmo, gerando o novo path.
84
85
Durante a implementação, foi perguntado como ficaria o algoritmo quando existem vários obstáculos em sequência ou um outro obstáculo no end point. 
86
87
Resposta: primeiramente eu fiz da forma mais simples, fazendo o RRT em toda a extensão dos obstáculos, desde o primeiro (mais próximo do ponto inicial) até o último (mais perto do ponto final). Optei por essa implementação mais simples a princípio pra verificar se daria certo e observar a trajetória gerada. Depois de debugar e testar dessa maneira, finalmente consegui obter a trajetória desejada pensada dessa forma, e agora posso partir pra implementação mais otimizada ainda: de fazer o rrt em cada obstáculo separadamente (basta fazer um loop no vetor dos obstáculos que eu gerei e tratar os casos de os obstáculos estarem muito próximos e serem aglutinados em apenas 1).
88
89
Seguem agora imagens de como ficou a trajetória gerada nessa implementação mais simples. Vejam que com dois ou mais robôs a trajetória ainda não é a ótima, pois ele calcula o rrt em todo o espaço entre os obstáculos também, e isso é ruim no caso deles estarem muito longes um do outro.
90
91
![](rrt1.png)
92
93
![](rrt2.png)	
94
95
Em seguida, foi finalizada a implementação mais otimizada, com o RRT aplicado apenas nos obstáculos e em cada um por vez. Obtive as seguintes trajetórias:
96
97
![](novorrt1.png)
98
99
![](novorrt3.png)
100
101
Veja que, quando dois obstáculos estão muito próximos um do outro, de forma que não é possível executar a trajetória reta entre eles, estes são algutinados em 1 só, e é aplicado o RRT sobre aquela extensão:
102
103
![](novorrt2.png)
104
105
Iniciou-se a partir daí os testes para medir o tempo que demora para a execução de todo o cálculo e comparar com a implementação anterior para saber se está mais rápido ou não. Foi decidido como seriam os testes: a ideia é que faremos diversos zig zags com um robô e vou medir o tempo máximo de execução da VI RRTPlan pra cada teste desse. Em seguida vou replicar os mesmos zig zags para a outra implementação do RRT e vamos comparar os tempos. As variações entre os zig zags vão ser apenas nas posições e no número dos obstáculos que vão atrapalhar o robô nessa tarefa. Vou deixar cada zig zag rodando por um tempo determinado (Ex: 1 min) e anotar o tempo máximo de execução obtido nesse período.
106
107
Fiz os testes do RRT novo e antigo, para comparar os tempos de execução da VI RRT Plan, que contém todo o cálculo da trajetória e também a parte de suavização. Fiz os testes nas mesmas condições (apenas um robô ligado e posicionamento preciso no grsim com o set position), e obtive os seguintes resultados de tempo e fps durante o tempo de observação (1 min para cada zig zag feito):
108
109
1º) Zig Zag entre os pontos (0,2000) e (0,-2000) SEM obstáculos.
110
111
| RRT antigo |   RRT novo   | 
112
|---         |      ---     |
113
|t=0,0225756s|t=0,000511674s| 
114
|fps=45      |fps=57        | 
115
116
2º) Zig Zag entre os pontos (-4000,0) e (4000,0) SEM obstáculos.
117
118
| RRT antigo |   RRT novo   | 
119
|---         |      ---     |
120
|t=0,0558839s|t=0,000469714s| 
121
|fps=43      |fps=57        | 
122
123
3º) Zig Zag entre os pontos (0,2000) e (0,-2000) 
124
Obstáculo (robô) no ponto (0,0)
125
126
| RRT antigo |   RRT novo   | 
127
|---         |      ---     |
128
|t=0,070037s |t=0,0809514s  | 
129
|fps=50      |fps=57        | 
130
131
132
4º) Zig Zag entre os pontos (-3000,0) e (3000,-0) 
133
Obstáculos (robôs) nos pontos (-1000,0) e (1000,0)
134
135
| RRT antigo |   RRT novo   | 
136
|---         |      ---     |
137
|t=0,0533753s|t=0,0781024s  | 
138
|fps=50      |fps=57        | 
139
140
141
5º) Zig Zag entre os pontos (-3000,0) e (3000,-0) 
142
Obstáculos (robôs) nos pontos (-2000,0) e (2000,0)
143
144
| RRT antigo |   RRT novo   | 
145
|---         |      ---     |
146
|t=0,0809107s|t=0,0846672s  | 
147
|fps=50      |fps=57        | 
148
149
150
Conclusões dos testes:
151
152
* Quando não há obstáculos, o RRT novo é na ordem de 100 vezes mais rápido.
153
* Quando há obstáculos, os dois tempos são de mesma ordem de grandeza, sendo que o RRT antigo é ligeiramente mais rápido: no teste de maior diferença (teste 4), a diferença de tempos foi de 0,0247271s.
154
* Em todos os testes, o código se manteve com fps mais alto no RRT novo. Nos testes em que não havia obstáculos e a trajetória simples podia ser usada, o fps do RRT antigo se mostrou ainda mais baixo que nos outros casos.