Projeto

Geral

Perfil

Decisao desvio » Histórico » Versão 9

Ebert Melo, 27/08/2021 19:08 h

1 1 Ebert Melo
h1. Decisao desvio
2
3 2 Ebert Melo
É apenas uma função criada para fins de teste e retorna sempre 1 (Girar para a esquerda). Porém, encontra-se implementada no arquivo turn.py com o nome rotate().
4
5 8 Ebert Melo
O objetivo da função rotate() é retornar o lado que o robô deve girar para desviar do obstáculo:  1 para a esquerda, 2 para a direita e 0 para continuar andando. Para isso,  calcula-se as distâncias do objeto até as bordas e os ângulos de inclinação das retas, e então analisa-se 3 situações: se alguma das distâncias for maior que uma distância mínima d_min para ultrapassá-lo, se uma das retas tiver ângulo agudo maior do que o da outra acrescido de 10º, e se alguma das distâncias for maior que a outra.
6 1 Ebert Melo
7 9 Ebert Melo
Primeiramente, a função obtém a imagem tirada pela câmera, por meio da biblioteca picamera, e a salva no path '/home/pi/image.jpg'. Depois, duas funções são chamadas: xy() e edge(). A primeira utiliza a imagem salva para detectar o obstáculo e retornar as coordenadas (x,y) do centro do objeto. Já a segunda, utiliza a imagem para detectar as bordas laterais mais internas à pista e retornar seus coeficientes de reta em forma de lista (1º termo é o coef. angular e o 2º, coef. linear), junto de um valor j, sendo j = 1 para linha central (as duas bordas foram detectadas), j = 2 para apenas a borda da direita, j = 3 para apenas a borda da esquerda e j = 0 para nenhuma borda detectada.
8 8 Ebert Melo
9 7 Ebert Melo
Se o retorno da função xy() for (0,0), então o robô não detectou obstáculo e retorna 0 (Andar). Caso contrário, analisa-se o valor de j: para j = 1, faz-se a análise das duas bordas, enquanto que para j=2 ou j=3, faz a análise de uma só borda.
10
11 1 Ebert Melo
Antes de prosseguir, é preciso saber que as coordenadas cartesianas utilizadas são diferentes das usuais: o eixo y é invertido de forma que o ponto (0,0) está no canto superior esquerdo da imagem. Então, é feita uma mudança de eixos (x', y') = (y, x) em ambas as retas, de modo que trocar os eixos é equivalente a girar o gráfico 90º à esquerda, transformando-o nos eixos cartesianos usuais.
12 7 Ebert Melo
13 4 Ebert Melo
!mudança_de_eixos.png!
14 1 Ebert Melo
15
Em seguida, é calculado x_linha_left e x_linha_right colocando o valor de x' como y do centro nas equações das retas depois de convertidas nos eixos x' e y'. |x - x_linha_left| = d_left e |x - x_linha_right| = d_right , serão as distâncias das bordas laterais até o centro do obstáculo.
16 7 Ebert Melo
17
!d_left-d_right.png!
18
19
Também é calculado os ângulos agudos de inclinação das retas (ang_left e ang_right) usando a função math.atan()
20
21 1 Ebert Melo
!ang_left-ang_right.png!
22
23 8 Ebert Melo
Depois, os casos são separados para cada valor de j.
24 9 Ebert Melo
* j = 1 (duas bordas detectadas):
25 8 Ebert Melo
** Um dos ângulos é maior que o outro acrescido de 10º:
26
*** A distância da reta até o objeto é maior que d_min: retorna tal lado.
27
*** Caso contrário: O outro lado é escolhido
28
** Os ângulos não são discrepantes um do outro:
29
*** Ambos os lados são maiores que d_min: retorna o lado de maior distância até o objeto
30
*** Apenas um dos lados é maior que d_min: retorna o lado em que a distância é maior que d_min
31
*** Caso contrário: retorna o lado de maior distância até o objeto
32 9 Ebert Melo
* j = 2 ou j = 3 (apenas uma borda foi detectada):
33 1 Ebert Melo
** A distância calculada para o lado é maior que d_min: retorna tal lado.
34 8 Ebert Melo
** Caso contrário: retorna o outro lado.
35 9 Ebert Melo
*j = 0 (nenhuma borda detectada):
36
**Não há nada escrito para este caso. Seria bom implementar algo para evitar bugs.