3.7 CONSTRUÇÃO DA SOLUÇÃO
3.7.3 Construção do Algoritmo de Detecção de Obstáculo
A implementação desse algoritmo foi feita iniciando com o posicionamento dos sen- sores de distância ultrassônicos ao redor do VANT, conforme figura 16. Cada sensor aponta em uma direção em um ângulo de 45oem relação ao sensor adjacente. Os sensores estão posi-
cionados na borda do VANT a um raio de 35cm do centro, que representa metade do diâmetro do VANT. Essa distância deve ser considerada na determinação correta do obstáculo detectado. O cone representa a distância e ângulo de alcance de cada sensor, sendo 2m e 25o, respectiva-
mente. A preocupação em colocar os sensores nas extremidades, e não no centro, evita que o sensor detecte o braço do quadro do VANT ou hélices como obstáculos. Em VANTs reais é usada uma cinta, geralmente de alumínio, para fixar sensores como estes.
Quando um obstáculo é detectado, o sensor no V-REP publica os sinais como topics do Sistema Operacional para Robô (ROS) com os dados da detecção do objeto. Os topics ROS possibilitam utilizar um simulador, ou uma linguagem diferente, e.g Lua, C/C++ e Python. Dessa forma permite a troca de dados transparente e o desacoplamento entre processos, fazendo com que não seja necessário alterar o código principal, caso seja necessário substituir algum comportamento. Outra vantagem é a publicação do “topic” via rede, permitindo a transferência de dados entre dispositivos distintos. Por exemplo, é possível substituir o VANT simulado por um VANT real, bastando que o ROS, executando no sistema embarcado, publique o mesmo tipo de sinal.
Cada sensor envia dois topics distintos: um sinal para indicar que um objeto foi iden- tificado e o outro para informar qual distância, permitindo assim identificar no algoritmo de detecção de obstáculo qual sensor disparou, incluindo a distância entre o obstáculo e o sensor. A identificação é feita através do nome do “topic” correspondente com a posição do sensor no VANT. Com o comando ROS “rostopic list | grep Ultrasonic” é possível obter a lista de “topic” que são publicados pelo VANT relacionados aos sensores de distância e suas respec- tivas posições, como mostra a tabela 1: Cada sensor escreve em dois topics. O primeiro sinal, Ultrasonic_<grau>, indicando 1.0 ou 0.0 se o obstáculo foi detectado ou não. Caso detectado o sinal Ultrasonic_<grau>_dist informa a distância.
Figura 16: Posicionamento dos Sensores Ultrassônicos.
Fonte: Autoria própria. Sensores posicionados ao redor do VANT com raio de 35cm do centro. Cada cone
representa o alcance do respectivo sensor.
Tabela 1: Lista de Topics ROS Relacionados Aos Sensores Identificador de Obstáculo
(retorna 0.0 ou 1.0) (retorna valor em metros)Distância do Obstáculo /vrep/Ultrasonic_000 /vrep/Ultrasonic_000_dist /vrep/Ultrasonic_045 /vrep/Ultrasonic_045_dist /vrep/Ultrasonic_090 /vrep/Ultrasonic_090_dist /vrep/Ultrasonic_135 /vrep/Ultrasonic_135_dist /vrep/Ultrasonic_180 /vrep/Ultrasonic_180_dist /vrep/Ultrasonic_225 /vrep/Ultrasonic_225_dist /vrep/Ultrasonic_270 /vrep/Ultrasonic_270_dist /vrep/Ultrasonic_315 /vrep/Ultrasonic_315_dist
Fonte: Autoria própria. “Topics” ROS relacionados aos sensores de distância ao redor do VANT, codificado em linguagem
O processo de detecção de obstáculo é executado periodicamente a cada um segundo, verificando quais sensores foram disparados. Em cada iteração os seguintes passos são execu- tados para cada sensor, (para exemplificar, foi considerado o sensor na posição 45oem relação
à proa do VANT), esses passos estão relacionados ao Algoritmo 3 (apresentado na página 53): • Testar se o sensor detectou um obstáculo, se o “topic” Ultrasonic_045 = 1.0, linha 3.
• Determinar a posição do obstáculo em relação ao VANT: x = (Ultrasonic_045_dist + 0.35).cos(45o)
y = (Ultrasonic_045_dist + 0.35).sen(45o)
Para o sensor posicionado à 90o, é utilizado sen(90o)e cos(90o)e assim por diante
para cada sensor, linhas 4 e 5.
Internamente foram usado os valores em radianos.
• Através de matriz de rotação, é determinada a posição absoluta do obstáculo no espaço, considerando a diferença do ângulo entre a “frame” global e a “frame” do VANT. Esse ângulo é obtido do sinal “topic” Euler z do sensor giroscópico, vindo do VANT, linha 6. O resultado são as coordenadas x,y da posição absoluta do obstáculo no cenário, linha 7 e 8. O valor z é obtido da posição atual do VANT, linha 9.
• Em seguida, verifica-se se existe algum outro obstáculo já armazenado na Lista de Obs- táculos. Devido a precisão dos valores x,y,z, a probabilidade que sejam encontrados exatamente esses valores é muito baixa. A identificação é feita verificando se existe um obstáculo a pelo menos de 10cm, linhas 10 a 14. Para calcular essa distância é usado ál- gebra vetorial: a) obtêm-se a diferença entre os vetores representados pelas coordenadas dos dois obstáculos (o recém detectado e o da lista sendo comparado) e b) obtêm-se a dis- tância d aplicando a equação 7, onde x,y,z são os valores diferenças das coordenadas dos respetivos vetores e kdk representa o módulo (comprimento) do vetor. A distância entre o obstáculo recém detectado e os obstáculos da lista é a diferença entre esse módulos, linha 11.
kdk =px2+y2+z2 (7)
• Se o valor retornado do cálculo realizado no item anterior for maior que 10cm, considera- se um novo obstáculo, incluindo na lista de obstáculos, linha 13. O valor 99 é atribuído ao atributo type para representar um Obstáculo, linha 12.
Algoritmo 3: OBSTACLEDETECTION Entrada: Float Ultrasonic_045,Ultrasonic_045_dist,PosiçãoAtualGPS,ângulo_eulerZ 1 início 2 raioVANT = 0,35 3 se Ultrasonic_045 = 1.0 então 4 obstáculo_Frame_VANT.x=(Ultrasonic_045_dist+raioVANT)*cos(45o) 5 obstáculo_Frame_VANT.y=(Ultrasonic_045_dist+raioVANT)*sen(45o) 6 translação_Frame_Gobal=MatrizTranslação(obstáculo_Frame_VANT, ângulo_eulerZ) 7 obstáculo_Frame_Global.x=translação_Frame_Gobal.x + PosiçãoAtualGPS.x 8 obstáculo_Frame_Global.y=translação_Frame_Gobal.y + PosiçãoAtualGPS.y 9 obstáculo_Frame_Global.z=PosiçãoAtualGPS.z 10 para cada obstáculoDalista de Obstáculos faça
11 se ||obstáculoDalista||-||obstáculo_Frame_Global||> 10cm então 12 obstáculo_Frame_Global.tipo= 99 13 obstáculos.insereNoFinal(obstáculo_Frame_Global) 14 fim 15 fim 16 fim 17 fim
Saída: std :: list < Point > obstáculos