Sistema Monitoramento Mapeamento
Sistema Monitoramento Mapeamento
Sistema Monitoramento Mapeamento
Patos de Minas - MG
2019
CÉSAR HELLY SOARES SANTOS JÚNIO
Patos de Minas - MG
2019
CÉSAR HELLY SOARES SANTOS JÚNIO
Banca Examinadora
A robótica móvel é um campo da robótica útil na sociedade atualmente, que surgiu a partir do
crescimento da robótica, uma ciência relativamente recente. Útil por ser necessária em
diversas áreas, como em indústrias de mineração, aeroespacial, agricultura, entre outras. É um
campo que está em desenvolvimento, onde uma das aplicações comuns é de navegar em
ambientes desconhecidos e com isso surge a necessidade de mapeamento territorial, uma vez
é necessário conhecer um local quando se trata de um ambiente de risco, como mapeamento
para segurança em minas, ou quando se deseja adquirir informações de lugares de difícil
acesso humano, como explorações interplanetárias ou marinhas, ou para trabalhos de
inspeção. Este trabalho aborda o mapeamento feito por robô móvel de forma autônoma-
manual, e o seu monitoramento, podendo ser assistido por um usuário, pois mesmo em
mapeamentos exclusivamente autônomo, erros podem ser acometidos, necessitando uma
intervenção humana para corrigir esses erros ou problemas. O mapeamento é feito de forma
simultânea com o monitoramento. Para isso, são usados sensores de velocidade e sensor
ultrassônico, mapeamento métrico por grade, placa de processamento baseado no Arduino e
tecnologia de comunicação Bluetooth. Os resultados demonstram a capacidade do robô em
mapear um ambiente desconhecido de forma satisfatória, levando em conta a utilização de
materiais de baixo custo.
Mobile robotics is a field of robotic useful to the society today, which came from the growth
of robotics, a relatively recent science. Useful because it is necessary in various areas as the
mining, aerospace, agriculture and other industries. It is a field that is in development, where
navigation in unknown environment is a common task. This urges the necessity to have a map
of the territory, once it is necessary to know place when it is a risk environment, such as the
mapping for security in mines, or when information from specific places that is difficult for
humans to access is desired, such as interplanetary or marine explorations, or for inspection
work. This work deals with the mapping process made by a mobile robot in an autonomous-
manual way, and its monitoring, being able to be assisted by a user, since in the autonomous
exclusive mappings errors may occur, requiring a human action to correct these errors or
problems. In this work, the mapping is done simultaneously with the monitoring. For this end,
speed and ultrasonic sensor are utilized along with a grid mapping mode, an Arduino-based
processing board, and a Bluetooth communication technology. Results shown the capacity of
the robot to satisfactory map an unknown environment, taking in account the limitations of a
low-budget platform.
DC Direct Current
FTDI Future Technology Devices International
IDE Integrated Development Environment
IoT Internet of Things
LED Light-Emitting Diode
PC Personal Computer
PWM Pulse Width Modulation
RFID Radio-Frequency Identification
RTC Real Time Clock
SLAM Simultaneous Localization And Mapping
USB Universal Serial Bus
Wi-Fi Wireless Fidelity
SUMÁRIO
1 INTRODUÇÃO........................................................................................................... 17
1.1 TEMA ................................................................................................................... 18
1.2 PROBLEMATIZAÇÃO ........................................................................................ 18
1.3 HIPÓTESES .......................................................................................................... 19
1.4 OBJETIVOS .......................................................................................................... 20
1.4.1 Objetivos gerais............................................................................................. 20
1.4.2 Objetivos específicos ..................................................................................... 20
1.5 JUSTIFICATIVA .................................................................................................. 21
1.6 CONSIDERAÇÕES FINAIS ................................................................................. 22
2 DESENVOLVIMENTO TEÓRICO .......................................................................... 23
2.1 MAPEAMENTO ................................................................................................... 23
2.1.1 Mapeamento topológico ................................................................................ 23
2.1.2 Mapeamento métrico .................................................................................... 26
2.1.3 Comparação entre mapeamento topológico e mapeamento métrico .......... 28
2.2 MAPEAMENTO UTILIZANDO SENSORES ...................................................... 30
2.2.1 Sensor de velocidade (encoder óptico) .......................................................... 31
2.2.2 Sensor de ultrassom ...................................................................................... 31
2.3 MONITORAMENTO ............................................................................................ 33
2.4 PROCESSAMENTO ............................................................................................. 34
2.5 COMUNICAÇÃO ................................................................................................. 36
2.6 CONSIDERAÇÕES FINAIS ................................................................................. 37
3 MATERIAIS E MÉTODOS ....................................................................................... 38
3.1 MATERIAIS E CUSTOS ...................................................................................... 39
3.2 CONSIDERAÇÕES FINAIS ................................................................................. 39
4 DESENVOLVIMENTO ............................................................................................. 40
4.1 CONSTRUÇÃO MECÂNICA ............................................................................... 41
4.2 COMPONENTES ELETRÔNICOS....................................................................... 42
4.2.1 Placa MBZ Pro Mega ................................................................................... 42
4.2.2 Sensor ultrassônico ....................................................................................... 46
4.2.3 Motores ......................................................................................................... 50
4.2.4 Interação entre motores e a estrutura .......................................................... 52
4.2.5 Locomoção do robô ....................................................................................... 54
4.2.6 Interface gráfica no Processing .................................................................... 57
4.2.7 Módulo Bluetooth .......................................................................................... 60
4.3 PROGRAMAÇÃO DO MICROCONTROLADOR ............................................... 61
4.3.1 Implementação do controle manual ............................................................. 62
4.3.2 Lógica de deslocamento no mapa ................................................................. 63
4.3.3 Encoder e implementação da interrupção .................................................... 69
4.3.4 Implementação da lógica de deslocamento no mapa ................................... 71
4.3.5 Implementação do controle automático ....................................................... 76
4.3.6 Implementação da criação de mapas ........................................................... 78
4.4 CONSIDERAÇÕES FINAIS ................................................................................. 83
5 RESULTADOS ........................................................................................................... 84
5.1 DETECÇÃO ESTÁTICA DE OBSTÁCULOS ...................................................... 87
5.2 MOVIMENTAÇÃO E DETECÇÃO DE OBSTÁCULOS ..................................... 89
5.3 EXECUÇÃO EM AMBIENTE REAL DE FORMA REMOTA ............................. 90
5.4 LIMITAÇÕES ENCONTRADAS ......................................................................... 92
6 CONCLUSÃO, CONTRIBUIÇÕES E TRABALHOS FUTUROS .......................... 95
REFERÊNCIAS ................................................................................................................. 97
APÊNDICE I .................................................................................................................... 101
APÊNDICE II .................................................................................................................. 105
17
1 INTRODUÇÃO
1.1 TEMA
1.2 PROBLEMATIZAÇÃO
1.3 HIPÓTESES
1.4 OBJETIVOS
Antes de projetar ou criar um protótipo robótico para suprir o objetivo deste trabalho,
é necessário pesquisar e levantar opções sobre o tema tratado. Pesquisar opções de
mapeamento robótico territorial. Pesquisar estilos de protótipo robótico que economizam
espaço e que sejam viáveis em relação a custo. Pesquisar tipos de comunicação sem fio entre
protótipo e usuário.
criada para esta visualização, nesta interface deve exibir, por meio de preenchimento de cores,
uma representação da área real percorrida pelo protótipo.
1.5 JUSTIFICATIVA
feito por Ramos (2012), mostrou uma otimização do mapeamento, quando fundido aos dados
obtidos por sensores de odometria e sensores inerciais, para compensar os erros de
mapeamento provocados por erros de sensores.
Murphy (2000) também cita modelos probabilísticos para localização de objeto em
uma grade de ocupação usando sonares. Mas este trabalho não possui como foco encontrar
um modelo probabilístico de otimização, mas exercer a aplicação, sendo de forma prática o
mapeamento territorial, mas com adição de capacidade de intervenção humana.
Os trabalhos de mapeamento implementados de forma prática, feitos por Abner e
Yukinobu, exemplificam a capacidade robótica de mapear, um dos objetivos desse trabalho.
Murphy, Ramos e Abner mostram conceitos de mapeamento simultâneo com a localização,
que serão usados para o monitoramento neste trabalho, por usar uma interface que receberá
informações a cada atualização do ciclo de mapeamento local.
Os trabalhos mencionados anteriormente demonstram a abrangência de assuntos
relacionados a este tópico, demonstrando a multidisciplinaridade e a grande possibilidade de
desenvolvimento de pesquisas por meio do protótipo funcional.
2 DESENVOLVIMENTO TEÓRICO
Neste item serão apresentados os principais conceitos teóricos utilizados neste trabalho
e necessários para compreensão do mesmo.
2.1 MAPEAMENTO
Segundo Yukinobu (2010), essas referências podem ter dois tipos de representação,
pontos de referência naturais e artificiais. Pontos de referência naturais são pontos de
referência que não foram construídos para este propósito, mas podem servir como referência
de localização, como por exemplo, casas, lojas, edifícios. No mapeamento por robô móvel
dentro de uma casa seria, por exemplo, móveis, portas, quinas, podendo ser encontrados por
sensores ultrassónicos, ou infravermelho.
Pontos de referência artificiais são pontos de referências que foram que criados para
este propósito de referência, como por exemplo, adesivos refletores em placas de trânsito,
gravuras coloridas, ou seja, características que foram adicionadas propositalmente a um objeto
para sua identificação. No mapeamento por robô móvel, pontos de referência artificiais
seriam, por exemplo, adesivos de uma cor específica colocado em objetos para fácil
identificação por câmera ou utilização de sensores RFID (Radio-Frequency IDentification,
Identificação por Radiofrequência) nas portas de salas onde o robô transita.
O mapa topológico é basicamente desenhado em grafos destacando os pontos de
referências encontrados. Os nós entre as linhas nos grafos representam os pontos de
referência, ou objetos encontrados, denominando o lugar, local ou cômodo. As arestas entre
os nós representam um caminho ou passagem. O método no mapeamento topológico utiliza
de caminhos para ligação de arestas e os nós entre as arestas para representar locais de acesso.
Exemplo de mapa topológico na Figura 2.1 retirado da dissertação de Oliveira (2015).
O mapa da Figura 2.1 representa um escritório. Na Figura 2.1(a) o robô móvel
(representado pelo objeto vermelho) está em sua posição inicial sem movimento, sendo seu
ponto de partida. Os traços saindo do robô representam sua área de obtenção de dados por
sensores. Na Figura 2.1(b), o robô saiu do seu ponto inicial e se dirigiu a outra área, a
varredura pelos sensores delimitam as paredes ou objetos da área.
O primeiro nó representado na figura pelo círculo amarelo “1” indica o local inicial
registrado, o primeiro ponto de referência que denomina um lugar, e também o primeiro nó no
mapa topológico. Na Figura 2.1(c), o robô saiu do local “2” e partiu para outra área, o
segundo local foi registrado e o mapa topológico foi atualizado. Agora com dois nós
interligados por uma aresta, indicando um caminho. Na Figura 2.1(d), o robô saiu do local “3”
e partiu para outra área, o terceiro local foi registrado e o mapa topológico foi atualizado. Os
nós “1”, “2” e “3”, foram interligados por arestas, pois como existe caminho do ponto de
partida “1” para o “2”, e do “2” para o “3”, também é possível um caminho direto do “1” para
o “3”. Na Figura 2.1(e), um novo local é registrado, outro nó é adicionado ao mapa
25
Sua ligação por arestas nesta estratégia demonstra também os caminhos onde há
passagem disponível (porta). A simplicidade de um mapa topológico representado por grafos
não representa a geometria do ambiente, podendo gerar imprecisão no mapeamento.
Figura 2.2 - Mapa topológico.
aquisição de formas geométricas relevantes no para o usuário, no caso, um mapa gerado por
detecção de retas de um corredor.
No artigo de Thrun (1998) foi comparado os dois tipos de mapas, mapa topológico e
mapa métrico, ressaltando vantagens e desvantagens de cada um em relação ao outro. Thrun
destacou algumas vantagens e desvantagens de cada mapa, o que implica nos seus respectivos
mapeamentos e suas facilidades e dificuldades em obter, manter e compreender informações.
O mapeamento métrico por gerar mapas que possuem uma fidelidade maior com o
ambiente físico, considerando células de ocupação e não ocupação em um mapa de grade
possui maior confiabilidade em relação a um mapa de grafos gerado por mapeamento
topológico. Possui uma fácil construção por depender de presença ou ausência espacial, sendo
facilmente representada por células.
A utilização do mapa por células permite uma representação de ambientes em larga
escala com diferentes ocupações, obtendo uma construção de acordo com as variações
geométricas do ambiente. Também possui maior facilidade em sua manutenção, pois sua
construção geralmente (ABNER, 2012) é feita por incremento de célula, com base na
obtenção de dados dos sensores e odometria.
29
Os mapas apresentados nas Figura 2.5 e Figura 2.6, representam os dois tipos de mapa
respectivamente, mapa métrico e mapa topológico. Duas representações de um mesmo
ambiente usando mapas diferentes na robótica.
Os dados obtidos pelo sensor foram usados para determinar a localização do robô no
mapeamento.
refletem no objeto e captam seu o retorno (echo). De acordo com a velocidade de propagação
do som e o tempo de emissão e captação do sensor é possível calcular a distância a um objeto.
Figura 2.8 - Exemplo de atuação de um sensor ultrassom.
grade de ocupação, pois para cada célula na grade, manterá um estado que representa se o
local está ocupado ou vazio (MURPHY, 2000).
Como mostrado na Figura 2.9, a área de visão, pode ser divida em 3 regiões. Região I,
é a região que provavelmente a célula da grade está ocupada, detectado pelo sensor. Região II,
é a região de detecção de células vazias. Região III, é a região de incerteza, pois não possui
confirmação da ocupação ou não das células. A leitura do sensor possui maior chance de estar
correta ao longo do eixo linear originado no ultrassom, do que nas bordas, pois podem existir
obstáculos nas bordas que refletem as ondas emitidas (MURPHY, 2000).
2.3 MONITORAMENTO
Fonte: Autor.
A Figura 2.10, mostra um esquema de SLAM. Nesta figura, os dados obtidos por um
sonar, permitem a construção de um mapa local, ou seja, um mapa limitado pelo alcance do
sonar. Os dados obtidos pelo encoder permitem gerar uma posição estimada do robô. A união
das informações de posição estimada com o mapa local construído permite gerar uma posição
que o robô está situado no mapa local, esta posição do robô é a sua localização. Esta
localização será também a posição de partida do robô para a próxima área que será mapeada
conforme o seu deslocamento.
34
2.4 PROCESSAMENTO
um microcontrolador com a placa que permite o encaixe de módulos, vem com o Software de
programação Arduino IDE e usa linguagem de programação.
A placa de Arduino possui um microcontrolador capaz de processar informações
coletadas pelos sensores para diferentes aplicações. Como por exemplo, para monitoramento,
no artigo de Nasution, Siagian e Tanjung (2018), um Arduino foi usado com um sensor
ultrassônico para monitorar o nível de um rio.
O Arduino consiste de uma placa composta por um microcontrolador Atmel, com
circuitos de entrada/saída e os componentes necessários para funcionamento do
microcontrolador. A placa pode ser facilmente conectada à um computador e programada via
IDE (Integrated Development Environment) utilizando uma linguagem baseada em C/C++,
sem a necessidade de equipamentos adicionais além de um cabo USB (Universal Serial Bus)
e adaptador, caso precise.
Se o Arduino é capaz de ser usado para processar dados de distância do nível de um
rio usando ultrassom, é considerado que a placa também atende as necessidades para
processamento de dados da aplicação desejada de monitoramento e mapeamento.
O tipo de placa Arduino a ser utilizada depende do projeto a ser desenvolvido e
principalmente, do tamanho e do número de portas digitais e analógicas necessárias. As
opções variam desde a placa padrão Uno e suas 14 portas digitais e 6 analógicas, passando por
placas com maior poder de processamento e de portas, como o Arduino Mega, com
microcontrolador ATmega2560 e 54 portas digitais, e o Arduino Due, baseado em
processador ARM de 32 bits (Figura 2.12).
Figura 2.12 - Modelos de placas Arduino
2.5 COMUNICAÇÃO
Em um mapeamento feito por robô à longa distância, uma comunicação sem fio entre
usuário e máquina deve ser escolhida para melhor obtenção de resultados. No artigo de
Alshazly e Hassaballah (2016), foi criado um robô móvel com comunicação Bluetooth, seu
controle é feito por um usuário à distância. Este robô também é capaz de captar informações
de aproximação pelo sensor infravermelho acoplado. A tecnologia Bluetooth usada neste caso
é para objetivos simples de controle de um robô compacto para andar em pequenas regiões.
Outra possibilidade de tecnologia para a comunicação é a utilização do Zigbee,
tecnologia baseada no padrão IEEE 802.15.4. O Zigbee é voltado para aplicações de menos
potência, menor taxa de dados e menor ciclo de trabalho do que Bluetooth. Embora contra
intuitivo, nem todas as aplicações de rede necessitam de muita largura de banda e dos custos
mais altos decorrentes disto. Zigbee define taxas de canal de 20, 40, 100 e 250 Kbits/s,
dependendo da frequência do canal.
Em objetivos de mapeamento que procura uma área de cobertura maior, a tecnologia
de comunicação sem fio deve possuir uma capacidade de transmissão de alcance considerável,
e por tratar na possibilidade de mapeamento em áreas de risco, essa transmissão deve possuir
capacidade de monitoramento não presencial na área de risco.
No artigo de Reddy (2014), ele projetou robôs mestre e escravos por comunicação
wireless, com o intuito da sua aplicação em áreas de risco, destacando principalmente
ambientes de guerra para levar quites médicos, detectar minas terrestres e entrar em áreas de
riscos em geral. Um sistema desse patamar para controlar ou monitorar mais de um robô por
distância, é viável utilizar um sistema com conexão a Internet, como sugestão utilizar Wi-Fi
(Wireless Fidelity). Similar ao sistema de mapeamento, usando comunicação Wi-Fi poderia
controlar inúmeros robores para mapear um local, ou locais distintos pela Internet.
Há diversos padrões 802.11 (Wi-Fi), dentre eles o 802.11 b, n e g. O 802.11g é, de
longe, a tecnologia mais popular e fácil de encontrar. Os padrões 802.11 compartilham muitas
características. Todos usam o mesmo protocolo de acesso ao meio, CSMA/CA, usam a
mesma estrutura de quadro para seus quadros de camada de enlace, têm a capacidade de
reduzir sua taxa de transmissão para alcançar distâncias maiores e permitem a funcionalidade
“modo de infraestrutura” e “modo ad hoc”.
A comunicação feita neste trabalho foi feita inicialmente por comunicação Bluetooth
devido a complexidade do projeto. A comunicação por Wi-Fi será posta como uma meta a ser
37
3 MATERIAIS E MÉTODOS
Pesquisa bibliográfica: A pesquisa foi realizada por meio da leitura de livros, sites e
artigos da área, selecionando as referências mais relevantes e analisando as principais
vantagens e desvantagens de cada tecnologia utilizada.
Avaliação e teste final: Para o teste final do robô, é realizado um teste prático de
mapeamento. Para o teste, a construção do mapa é assistida enquanto o robô explora
de forma autônoma e (ou) manual.
39
Para executar de forma prática o objetivo proposto neste TCC foi necessário a
pesquisa de componentes que atenderiam a demanda do projeto e adquirir os materiais. A lista
dos principais componentes e de seus custos são listados na Tabela 3.1.
Tabela 3.1 - Lista de componentes do projeto e respectivos valores.
Item Preço (R$)
MBZ Pro Mega Wi-Fi Edition 30,00
Sensor Ultrasônico SR05 5,00
Motor Shield L293D Driver Ponte H para Arduino 8,00
Bateria 9V recarregável com carregador 35,00
Estrutura Mecânica em acrílico com motores e sensores HC-020K 45,00
Módulo Bluetooth HC 06 10,00
Módulo Bluetooth para Computador 20,00
Fonte: Autor.
3.2 CONSIDERAÇÕES FINAIS
4 DESENVOLVIMENTO
Fonte: Autor.
A etapa (11) representa o envio dos dados de distância por Bluetooth para uma central.
Neste o mapa gráfico visual é gerado conforme a programação do Arduino em conjunto com
os sensores, atuadores e deslocamento do robô no ambiente. O (12) se refere ao
monitoramento pelo usuário, pela capacidade de assistir o mapeamento em uma interface
gráfica. O (13) refere-se à interação do usuário, caso ele queira dar comandos ao robô.
41
A estrutura mecânica do protótipo não necessitou ser construída, pois feita a aquisição
de uma estrutura de acrílico já com as furações, motores e apoios. Esta estrutura de baixo
custo (Figura 4.2) não possui grande resistência mecânica e nem é recomendada para uso em
terrenos irregulares, mas atende ao propósito do projeto ao fornecer suporte aos motores, aos
discos do encoder e para a eletrônica.
Figura 4.2 – Peças da estrutura de acrílico utilizada no projeto.
As rodas livres (frontal e traseira) servem apenas de apoio para o robô não tombar
durante a sua movimentação e foi considerada que a sua utilização não interfere na
movimentação do robô. O suporte para pilhas foi desconsiderado no projeto, tendo em vista
que foi utilizado uma bateria de 9v para alimentar a placa e os motores.
O protótipo foi construído por etapas, para cada parte do protótipo ser testada
separadamente. A placa de circuito usada no trabalho foi o MBZ Pro Mega Wi-Fi Edition
(Figura 4.4), é uma versão adaptada do Arduino Uno (Figura 4.5). Criada por Marcelo
Maximiano (https://www.blogger.com/profile/06251877058894470676), a placa contém mais
portas comparada com a placa do Arduino Uno, saídas digitais com 3,3 V e uma entrada para
o módulo Wi-Fi ESP-01, é uma placa voltada para projetos de IoT (Internet of Things). Ela
possui o mesmo microcontrolador do Arduino Uno, ATMega328P, e possui áreas próprias
para soldagem (MAXIMIANO, 2016).
Essa placa foi escolhida inicialmente por possuir uma entrada própria para o ESP-01,
para futuramente ser usada com uma comunicação Wi-Fi, mas neste trabalho a comunicação
usada foi o Bluetooth pela sua simplicidade. Uma placa Arduino Uno também poderia ser
usada neste trabalho substituindo a MBZ. O quadro a seguir compara a placa MBZ, com a
placa Arduino Uno (MAXIMIANO, 2016).
43
Figura 4.4 - Diagrama de pinos da placa MBZ Pro Mega Wi-Fi Edition.
Fonte: Autor.
Foi necessário um cabo de dados para conexão do PC com a placa Arduino pelo FTDI.
Para conseguir executar o programa corretamente foi necessário fazer o Download do Driver
FTDI, este para não ocorrer erros de porta na IDE do Arduino quando o FTDI está conectado
a placa de Arduino.
O software Arduino IDE usa o “dialeto” C/C++ (ARDUINO, 2019). Um código
simples parar testar a placa é o “Blink”, disponível nos exemplos do Arduino IDE
45
Fonte: Autor.
Após a verificação da iluminação do LED na placa, outro teste foi imprimir dados na
porta serial (Quadro 4.2). A variável usada, “x”, foi declarada antes da função “setup()” e a
função de impressão foi feita dentro da função “loop()”. O código feito dentro da função
“setup()” foi inicializado para configurar as variáveis, a função é executada apenas uma vez
cada vez que a placa de Arduino é ligada (ARDUINO, 2019). O código feito dentro da função
“loop()” se repete em loop, acontecendo repetições a cada término (ARDUINO, 2019).
A taxa de dados da comunicação serial foi declarada em “Serial.begin()”, entre os
parênteses é colocado a taxa de dados em bits/s. A função frequentemente usada neste
trabalho foi “Serial.println()” que imprime os dados da porta serial e a próxima impressão
segue na próxima linha (ARDUINO, 2019).
46
O teste resultou inúmeros “10” impressos no “Monitor Serial” (Quadro 4.2). Após
sucesso no teste de funcionamento da placa, os itens necessários para o robô também foram
testados de forma separada no decorrer do trabalho.
O sensor ultrasônico utilizado no protótipo foi HC-SR04 (Figura 4.8). Para testar o
sensor, este foi conectado a placa Arduino, os pinos do Arduino “A4” e “A5”, foram
conectados respectivamente aos pinos “Trig” e “Echo” do sensor ultrassônico, os pinos GND
e Vcc do sensor foram conectados aos pinos GND e Vcc do Arduino. Os pinos “GND” e
“Vcc”, são pinos de terra e alimentação respectivamente (o Arduino fornece uma alimentação
de 5V), os pinos “A4” e “A5” são pinos de entrada ou saída analógicas (depende da
programação) (Figura 4.8).
Figura 4.8 - Sensor HC-SR04 real e o diagrama de pinagem utilizada.
m 34000 cm cm
340 = 6
= 0,034 (4.1)
s 10 μs μs
1𝜇𝑠 𝜇𝑠
= 29,4117647059 (4.2)
0,034 𝑐𝑚 𝑐𝑚
O sensor capta a reflexão do pulso, sendo o tempo de reflexão o tempo de ida do pulso
somado com o tempo de retorno do pulso.
A função “void trigPulse() “ faz o sensor ultrassônico emitir ondas sonoras por 10μs,
estes são pulsos ultrassônicos (Quadro 4.4). O “digitalWrite(trig,HIGH)” deixa o pino de
saída “trigger” no nível alto emitindo a onda sonora, durante um delay de 10 μs pelo
“delayMicroseconds(10)” , após este tempo a saída se torna nível baixo, substituindo o
“HIGH” por “LOW”, parando a emissão (REIS, 2018).
Quadro 4.4 - Código da função trigPulse( ).
void trigPulse() //Função para gerar o pulso de trigger para o sensor HC-SR04
{
digitalWrite(trig,HIGH); //Saída de trigger em nível alto
delayMicroseconds(10); //Por 10µs
digitalWrite(trig,LOW); //Saída de trigger volta a nível baixo
} //end trigPulse
Fonte: Autor.
𝑇𝑒𝑚𝑝𝑜 𝑑𝑒 𝑟𝑒𝑓𝑙𝑒𝑥ã𝑜
𝐷𝑖𝑠𝑡â𝑛𝑐𝑖𝑎 𝑎 𝑢𝑚 𝑜𝑏𝑠𝑡á𝑐𝑢𝑙𝑜 = (4.6)
𝑇𝑒𝑚𝑝𝑜 𝑑𝑒 𝑟𝑒𝑓𝑙𝑒𝑥ã𝑜 (1 𝑐𝑚)
𝑇𝑒𝑚𝑝𝑜 𝑑𝑒 𝑟𝑒𝑓𝑙𝑒𝑥ã𝑜
𝐷𝑖𝑠𝑡â𝑛𝑐𝑖𝑎 𝑎 𝑢𝑚 𝑜𝑏𝑠𝑡á𝑐𝑢𝑙𝑜 = (4.7)
58,8235294118 𝜇𝑠
Os cálculos foram feitos no código e a distância foi armazenada em uma variável “H”.
Foi atribuído um valor limite de distância de 70 cm mesmo com o ultrassom captando
distâncias maiores (Quadro 4.6).
Esse valor foi escolhido para que durante a exibição no mapeamento o alcance
máximo do sensor seja pouco menor que cinco vezes o comprimento do robô
(aproximadamente 15 cm). Outro motivo para limitar o valor de medição, é a limitação do
número de dígitos durante a comunicação serial entre robô e PC, quanto mais dígitos mais
retarda a comunicação.
Durante a execução, pulsos constantemente são captados pelo sensor, retornando as
distâncias no “Monitor Serial”. Para conferir se a distância foi medida corretamente, foi
comparada a distância medida pelo sensor com a distância medida por uma régua. Ambas as
medições foram aproximadamente 20 cm, o ultrassom funcionou corretamente.
50
4.2.3 Motores
Para o controle dos motores, uma placa com circuito ponte H foi necessária. O circuito
ponte H serve para controlar o sentido de entrada da corrente DC no motor, assim controlando
o sentido de sua rotação.
No protótipo foi usada a placa Motor Shield L293D Driver Ponte H para Arduino
(Figura 4.9), essa placa possui dois chips de circuito integrado L293D, cada L293D possui
duas pontes H internamente e suporta uma corrente de saída de 600 mA, permitindo a essa
placa uma conexão com até quatro motores DC com até 600mA cada motor. Além de permitir
conexão até quatro motores DC, essa placa possui duas saídas para motor de passo, duas
saídas para servo motor e uma entrada para alimentação externa de até 16 V, embora possa ser
alimentada internamente com a conexão de um jumper.
Figura 4.9 - Motor Shield L293D Driver Ponte H.
Fonte: Autor.
51
Essa placa Driver foi conectada a placa Arduino. Os pinos digitais do Arduino “D4”,
“D5”, “D6”, “D7”, “D8”, “D11”, “D12” e os pinos “Vin”, ”Gnd”, “5v”, “3.3v”, “Rst”, foram
conectados aos pinos correspondentes de mesmo nome da placa Driver (Figura 4.10). Os
pinos digitais “D3”, “D5”, “D6” e “D11”, são pinos para PWM (Pulse Width Modulation),
que podem controlar a velocidade de rotação do motor dependendo da tensão aplicada. Os
pinos “D3”, “D5”, “D6” e “D11”, correspondem aos motores “2”, “3”, “4” e “1”,
respectivamente. Os pinos “D4”, “D7”, “D8”, “D12” são responsáveis para acionamento de
motores DC e motores de passo.
O protótipo robótico possui dois motores DC. Em cada motor possui um par de
conexões (que foram denominadas como A e B), nessas conexões foram soldados jumpers
(Figura 4.11), estes que se conectam aos respectivos pares de canais, “MX” na placa (X
corresponde à numeração de motores de 1 a 4). Durante a montagem física, foram escolhidos
os motores “3” e ”4”. O par de canais “M3” foi conectado ao motor direito (roda direita), e o
par de canais “M4” foi conectado ao motor esquerdo (roda esquerda) (Figura 4.12). A
referência de “esquerda e direita” é feita observando o robô por trás, inverso da visão de
frente.
Figura 4.11 - Solda das conexões no motor.
Fonte: Autor.
Fonte: Autor.
52
Foram feitos testes de acionamento dos motores e análises do sentido das rotações,
para testar corretamente as conexões A e B dos motores. O teste foi feito para manter a
rotação das rodas conforme o tipo de movimento desejado. O código de teste foi baseado no
projeto de automação de Rambo(2016).
O código usa a biblioteca “AFMotor.h”, os motores DC foram declarados como
“motor1” e “motor2”, motor esquerdo e direito respectivamente. Para selecionar os motores
foi usado a função “AF_DCMotor” Para o “AF_DCMotor motor1()”, entre parentes foi
colocado a numeração do canal conectado ao motor, analogamente foi usado “AF_DCMotor
motor2()”, para o motor direito.
Quadro 4.7 - Código referente ao motores.
#include <AFMotor.h>
AF_DCMotor motor1(4);//Seleção do Motor 1
AF_DCMotor motor2(3);//Seleção do Motor 2
void setup() {
}
Fonte: Autor.
O robô possui duas rodas, uma situada no lado esquerdo e outra situada no lado direito
(Figura 4.13), cada motor DC é responsável por girar uma roda diferente. Através do código
usado para girar a roda, foi verificado o sentido de rotação da roda. A função “setSpeed()”
define a velocidade do motor, sendo 0 o valor mínimo e 255 o valor máximo.
Figura 4.13 - Posicionamento das rodas e vista superior do robô.
Fonte: Autor.
Para a roda se mover, foi usado a função “run()”, entre os parênteses foi colocado o
parâmetro desejado para o motor. Os parâmetros são: “FORWARD”, para a roda girar para
“frente”, “BACKWARD” para a roda girar para “trás” (a direção de rotação depende da
fiação) e “RELEASE”, para a roda parar de girar (LEARN.ADAFRUIT, 2019).
Para a roda direita se mover para “frente” conforme a figura 4.15, esta deve rotacionar
em sentido horário (Figura 4.14). Foi usado “motor2.run(FORWARD)” (Quadro 4.8) e
observado se realmente a roda girava em sentido horário conforme a ligação dos fios A e B
53
do motor direito conectado ao par de canais do “M3”, caso girasse anti-horário, as conexões
dos fios no “M3” seriam invertidos para corrigir o sentido de rotação conforme a
programação.
Para a roda esquerda se mover para “frente” conforme a figura 4.15, esta deve
rotacionar em sentido anti-horário (Figura 4.14). Foi usado o código
“motor1.run(FORWARD)”, e verificado o sentido de rotação da roda esquerda (Quadro 4.8).
Rotacionando de modo anti-horário, a conexão A e B no par “M4” está correta, caso contrário
as conexões A e B seriam invertidas. O teste de rotação verificou a conexão correta dos
motores.
Figura 4.14 - Sentido de rotação dos motores.
Fonte: Autor.
Fonte: Autor.
moveram para “trás” (Figura 4.15), e substituindo por “RELEASE” as rodas pararam de se
mover. Com as combinações de rotação das rodas foi possível criar os movimentos do robô.
Para o robô se mover, foram criados cinco tipos de movimento: se mover para frente
normalmente, se mover para trás em ré, girar para direita em torno do próprio eixo, girar para
esquerda em torno do próprio eixo e parar. As combinações de rotações das rodas permitiram
criar estes movimentos.
Estes movimentos foram criados em funções diferentes com o propósito de cada uma
ser usada em situações específicas. Por exemplo, para testar cada uma das funções bastou
retirar o “//” antes da função de movimento desejado (Quadro 4.9). Funções que foram
criadas de acordo com o código de rotação das rodas.
Quadro 4.9 - Código de movimentos do robô.
void robot_forward(); //Função para movimentar robô para frente
void robot_backward();//Função para movimentar robô para trás
void robot_left(); //Função para movimentar robô para esquerda
void robot_right(); //Função para movimentar robô para direita
void robot_stop(); //Função para parar o robô
void setup() {
}
void loop() {
//robot_forward(); //Usado para teste
//robot_left(); //Usado para teste
//robot_backward();//Usado para teste
//robot_right(); //Usado para teste
//robot_stop(); //Usado para teste
}
Fonte: Autor.
Fonte: Autor.
55
Foi notado durante o teste para robô se mover para frente, ao usar a mesma velocidade
para ambos os motores, o robô se deslocava inclinado para direita, deste modo foi observado
que o motor usado para a roda esquerda era mais potente que o motor da direita. Portanto, foi
necessário atribuir um valor menor de velocidade para o motor da esquerda do que o da
direita para calibrar os motores. Em um caso hipotético que ambos os motores funcionam de
mesma forma com a mesma potência, os valores atribuídos de velocidade seriam iguais.
Valores de diferentes velocidades foram atribuídos e testados observando a inclinação
do robô ao se mover para frente, sempre mantendo a velocidade do “motor1” maior que do
“motor2”. Também, para evitar deslizamentos das rodas no solo, consequência da inércia do
robô em uma velocidade alta, e para que também não seja um deslocamento lento, foram
escolhidas as velocidades “205” e “170” para os motores. O valor de diferença “35” entre as
velocidades foi suficiente para manter uma calibração aproximada. A função de movimento
para frente foi modificada (Quadro 4.11).
Quadro 4.11 - Balanceamento da velocidade do robô.
void robot_forward()
{
motor1.setSpeed(170);
motor1.run(FORWARD);
motor2.setSpeed(205);
motor2.run(FORWARD);
} //end robot forward
Fonte: Autor.
Fonte: Autor.
O movimento de girar para a direita em torno do próprio eixo foi possível pela
combinação do movimento da roda esquerda ir para frente e da roda direita ir para trás (Figura
4.18). Para este movimento foi usado o código do Quadro 4.13, criado na função denominada
“robot_right()”.
Figura 4.18 - Ação dos motores para giro do robô para direita.
Fonte: Autor.
O movimento de girar para a esquerda em torno do próprio eixo foi possível pela
combinação do movimento da roda direita ir para frente e da roda esquerda ir para trás (Figura
57
4.19). Para este movimento foi usado o código do Quadro 4.14, criado na função denominada
“robot_left()”.
Figura 4.19 - Ação dos motores para giro do robô para esquerda
Fonte: Autor.
Para monitorar a posição do robô e mapear o local, foi feita a construção de um mapa
visual, exibindo no computador em tempo real o deslocamento do robô, sua posição atual,
distâncias do robô a obstáculos, áreas livres ou com obstáculos e áreas que não foram
exploradas.
Para criar a interface gráfica de mapeamento foi necessário utilizar um software para
esta função. O Processing foi uma das principais ferramentas usadas neste trabalho, assim
como Arduino IDE, este software é usado para programar, com o foco voltado para criar
interfaces gráficas (REAS e FRY, 2010).
58
No Arduino IDE, para inicializar uma comunicação serial com o Processing, dentro da
função “setup()” a porta serial deve ser inicializada com uma taxa de transmissão igual a taxa
usada no Processing: “Serial.begin(9600)” (Quadro 4.20).
Quadro 4.20 - Inicialização da comunicação serial com o Processing.
void setup ( ) {
pinMode(led_pin, OUTPUT);
Serial.begin(9600);
}
Fonte: Autor.
possui algum valor enviado do Processing para a porta serial Para o Arduino enviar os dados
ao Processing, ele envia através do “Serial.println()” ou “Serial.print()”.
Ao receber os dados do Processing o valor é lido e guardado em uma variável
chamada de “state” que acessa as condições de apagar ou acender o LED de acordo com seu
valor. Apaga quando recebe “0”, através do “digitalWrite (led_pin, LOW)”, e o acende
quando recebe “1” através do “digitalWrite (led_pin, HIGH)” (Quadro 4.21).
Quadro 4.21 – Teste de funcionamento da serial com acender e apagar do LED.
if (Serial.available ( ) > 0) { //Verificação
char state = Serial.read ( ); // lendo dados
if(state == '1') // se for 1, acende led
{
digitalWrite (led_pin, HIGH);
}
if (state == '0') { // se for zero, apaga led
digitalWrite (led_pin, LOW);
}
}
Fonte: Autor.
A comunicação serial por Bluetooth pode substituir a comunicação serial via cabo,
porém para a gravação de código na placa Arduino é necessário o cabo de dados. Foi testado
utilizando o “código do potenciômetro” anterior a comunicação Bluetooth entre a placa
Arduino e PC.
O módulo de transmissão Bluetooth usado foi o HC06 (Figura 4.20), as portas “TX” e
“RX” do módulo foram conectadas as portas “RX” e “TX” da placa Arduino respectivamente.
No pino “RX” do módulo foi necessário um fazer um divisor de tensão para converter os 5 V
de entrada em 3,3 V. A placa Arduino foi alimentada por uma bateria de 9 V (Figura 4.21).
Figura 4.20 – Módulo Bluetooth HC06.
Fonte: Autor.
Foi ativada no PC a comunicação por Bluetooth, criando uma porta COM Serial
Bluetooth. O computador usado não possui transmissor Bluetooth, deste modo foi necessário
usar um adaptador Bluetooth USB. O adaptador usado foi o Bluetooth USB Dongle. Este
adaptador usa tecnologia Bluetooth 2.0 e possui alcance de 100 metros.
A porta COM Serial Bluetooth foi usada substituindo a porta “COM” no código do
Processing. O teste permitiu variar as cores da interface pelo potenciômetro e ligar/desligar o
LED à distância. Ao término do teste, para voltar a gravar códigos na placa, o módulo
Bluetooth foi desconectado, pois interfere na gravação.
O controle manual do robô foi feito para que o robô se movimentasse de acordo com
teclas específicas pressionadas no PC. O controle foi criado na Processing, quando o código
está em execução, ao apertar as teclas de seta: “cima”, o robô anda para frente, “baixo”, o
robô anda para trás em ré, “direita”, gira o robô para direita em torno do próprio eixo,
“esquerda”, o gira para esquerda em torno do próprio eixo. Pressionando a tecla “Alt”, o robô
pára o movimento.
Foi usada a função “keyPressed()”, função chamada sempre que alguma tecla é
pressionada. Nesta função as condições de estado de tecla foram determinadas (Quadro 4.22).
Na condição “if(keyCode ==UP){ myPort.write ( '0' ) ;”, se a seta do teclado “cima” for
pressionada, escreve na porta serial “myPort” o dado ‘0’. Na condição “if(keyCode
==DOWN){ myPort.write ( '1' ) ;”, se a seta do teclado “baixo” for pressionada, escreve na
porta serial “myPort” o dado ‘1’. Na condição “if(keyCode ==LEFT){ myPort.write ( '2' ) ;”,
se a seta do teclado “esquerda” for pressionada, escreve na porta serial “myPort” o dado ‘2’.
Na condição “if(keyCode ==RIGHT){ myPort.write ( '3' ) ;”, se a seta do teclado “direita” for
pressionada, escreve na porta serial “myPort” o dado ‘3’. Na condição “if(keyCode ==ALT){
myPort.write ( '4' ) ;”, se a tecla “Alt” for pressionada, escreve na porta serial “myPort” o
dado ‘4’.
Quadro 4.22 - Código para as condições de estado das teclas.
void keyPressed(){
if(key==CODED){
if(keyCode ==UP){ myPort.write ( '0' ) ;
}
if(keyCode==DOWN){myPort.write ( '1' ) ;
}
if(keyCode==LEFT){myPort.write ( '2' ) ;
}
if(keyCode==RIGHT){myPort.write ( '3' ) ;
}
if(keyCode==ALT){myPort.write ( '4' ) ;
}
}}
Fonte: Autor.
robô gira para direita e se for 4 o robô executa a função dos motores que faz o robô parar
(Quadro 4.23).
Quadro 4.23 - Código para cada movimento do robô.
void loop() {
if (Serial.available ( ) > 0) { //
char state = Serial.read ( ); //
if(state == '0') {
robot_forward(); }
if (state == '1') {
robot_backward(); }
if (state == '2') {
robot_left(); }
if (state == '3') {
robot_right(); }
if (state == '4') {
robot_stop(); }
}}
Fonte: Autor.
Fonte: Autor.
robô está se movendo em linha reta para trás, ele é representado como um vetor de sentido
frente até traseira formando um vetor de sentido oposto.
O robô para determinar sua direção, ele gira em torno do próprio eixo de girando para
direita ou girando para esquerda formando um ângulo θ em relação da projeção de um vetor 𝑢
⃗
para frente e um semieixo X positivo. O ângulo cresce no sentido horário e decresce no anti-
horário (Figura 4.23).
Figura 4.23 - Projeção de u e sua relação com o ângulo.
Fonte: Autor.
do vetor 𝑢
⃗ : 𝑢𝑥 = 𝑥, 𝑢𝑦 = 𝑦, fica 𝑢
⃗ 𝑛 = 𝑥𝑛 𝑖̂ + 𝑦𝑛 𝑗̂. Sendo 𝑆𝑛 o vetor resultante da soma
𝑆𝑛 = 𝑆𝑥𝑛 𝑖̂ + 𝑆𝑦𝑛 𝑗̂
Na lógica feita para a programação do robô, as posições X e Y (x e y maiúsculos) que
o robô se encontra são feitas pela soma das componentes dos vetores 𝑢
⃗:
𝑋 = 𝑆𝑥𝑛
(4.10)
𝑌 = 𝑆𝑦𝑛
A cada novo pulso, vai acrescentando no somatório uma nova componente 𝑥𝑛 e 𝑦𝑛 ,
fazendo o resultado do somatório anterior (antes do novo pulso) ser o valor de 𝑆𝑥𝑛−1 e 𝑆𝑦𝑛−1 .
𝑋 = 𝑆𝑥𝑛−1 + 𝑥𝑛
(4.11)
𝑌 = 𝑆𝑦𝑛−1 + 𝑦𝑛
Com 𝑥𝑛 = cos(𝜃𝑛 ), 𝑦𝑛 = sen(𝜃𝑛 ), e 𝜃𝑛 = 𝜃. (A angulação do novo pulso não muda
durante o deslocamento X, Y do robô, a angulação só muda quando o robô gira em torno do
próprio eixo para decidir sua orientação.) Resulta:
𝑋 = 𝑆𝑥𝑛−1 + cos(𝜃)
(4.12)
𝑌 = 𝑆𝑦𝑛−1 + 𝑠𝑒𝑛(𝜃)
66
Deste modo a atualização das posições X e Y a cada novo pulso gerado/captado pode
ter a escrita simplificada como: 𝑋𝑎𝑡𝑢𝑎𝑙 = 𝑋𝑎𝑛𝑡𝑒𝑟𝑖𝑜𝑟 + cos(𝜃) e 𝑌𝑎𝑡𝑢𝑎𝑙 = 𝑌𝑎𝑛𝑡𝑒𝑟𝑖𝑜𝑟 + sen(𝜃).
Caso o robô se movimente dando ré, a nova componente será negativa, então: 𝑋𝑎𝑡𝑢𝑎𝑙 =
𝑋𝑎𝑛𝑡𝑒𝑟𝑖𝑜𝑟 − cos(𝜃) e 𝑌𝑎𝑡𝑢𝑎𝑙 = 𝑌𝑎𝑛𝑡𝑒𝑟𝑖𝑜𝑟 − sen(𝜃).
Por exemplo, o robô se move de um ponto no espaço na coordenada A(0,0) para um
ponto p2. Durante esta deslocamento foram gerados 2 vetores 𝑢
⃗ , passando pelos pontos p1 e
p2 (Figura 4.25).
Figura 4.25 - Exemplo de movimentação do robô e de geração de vetores.
Fonte: Autor.
Se o robô move da posição atual p2 para uma posição p3, girando 30 graus sentido
horário antes de se mover (Figura 4.26), o ângulo se torna 𝜃 = 0° + 30° = 30°. De p2 para
p3, as componentes do vetor 𝑢
⃗ são:
67
𝑥3 = 𝑐𝑜𝑠(30°) = 0.866
(4.14)
𝑦3 = 𝑠𝑒𝑛(30°) = 0.5
Figura 4.26 - Segundo exemplo de movimento do robô e geração de vetores.
Fonte: Autor.
Se o robô move da posição atual p3 para uma posição p4, girando 30 graus no sentido
horário, o ângulo se torna θ=60° (). De p3 para p4, as componentes do vetor u serão:
𝑥4 = 𝑐𝑜𝑠(60°) = 0.5
(4.16)
𝑦4 = 𝑠𝑒𝑛(60°) = 0.866
A soma das componentes resulta na posição p4. As posições X e Y anteriores foram
do ponto p3.
𝑋𝑎𝑛𝑡𝑒𝑟𝑖𝑜𝑟 = 2.866
𝑌𝑎𝑛𝑡𝑒𝑟𝑖𝑜𝑟 = 0.5
𝑋𝑎𝑡𝑢𝑎𝑙 = 𝑋𝑎𝑛𝑡𝑒𝑟𝑖𝑜𝑟 + cos(𝜃) = 2.866 + 0.5 = 3.366 (4.17)
𝑌𝑎𝑡𝑢𝑎𝑙 = 𝑌𝑎𝑛𝑡𝑒𝑟𝑖𝑜𝑟 + sen(𝜃) = 0.5 + 0.866 = 1.366
𝑝4(3.366 ,1.366)
68
Fonte: Autor.
Fonte: Autor.
69
Para obter dados do deslocamento do robô foi necessário utilizar um sensor que
retornasse para a placa Arduino dados que variam de acordo com a movimentação. O sensor
escolhido foi o sensor de velocidade encoder HC-020K (Figura 4.29). O chassi do robô usado
possui encaixe nas rodas para este sensor. Foi utilizado apenas um sensor, este sensor foi
usado para capturar pulsos enquanto o robô se movimenta. A roda ao girar, gera pulsos
proporcionados pela captura de luz no disco perfurado, estes pulsos foram traduzidos em
dados pelo Arduino.
Figura 4.29 - Encoder HC-020K.
O sensor HC-020k possui três fios e um disco perfurado (20 furos) que foi acoplado à
roda do robô. Os fios são: “5V “, “GND” e “OUT , o fio “5V” foi conectando ao pino “Vcc”
do Arduino, “GND” foi conectado ao pino “Gnd” do arduino e “OUT” foi conectado ao pino
“D3” do Arduino (Figura 4.30). Os pino “D3” e “D4” do Arduino são usados para sistemas
que envolvem interrupção (datasheet).
Figura 4.30 - Diagrama da ligação dos pinos para o encoder.
Fonte: Autor.
70
A interrupção é usada em casos que placa de Arduino precise receber vários dados de
forma rápida sem a necessidade terminar o loop de leitura de dados, acessando os dados de
forma paralela enquanto o loop acontece. A interrupção pode ser feita fora do loop, criando
uma função que possa ser acessada de forma independente. O robô precisou de um sistema
que receba vários dados em curto espaço de tempo, sendo necessário usar interrupção, estes
dados são os pulsos gerados. Se os dados fossem lidos dentro da função de loop no Arduino, o
robô não conseguiria contabilizar todos os dados recebidos a tempo, assim geraria um erro de
contagem de pulsos resultando um número menor que o real.
Na programação no Arduino IDE, a interrupção foi colocada no “setup()” quando o
código se inicializa configurando a pinagem e sua operação. A função “attachInterrupt()”
habilita a interrupção de acordo com os parâmetros usados. O primeiro parâmetro usado é o
pino, seguido da função executada sempre que acontece uma interrupção, o terceiro é o modo
que a interrupção acontece.
O pino “D3” foi declarado como entrada, pois o sensor recebe os dados de pulso. No
primeiro parâmetro, foi colocado como “0”, a função reconhece “0” como “D2” e “1” como
“D3”. O segundo parâmetro foi a função criada “ContarAnguloPos()” e o terceiro parâmetro
foi o modo “RISING”, este modo acessa uma interrupção quando o estado do pino vai de
“LOW” para “HIGH” (Quadro 4.24).
Quadro 4.24 - Código de configuração dos pinos do encoder.
pinMode(2, INPUT); // Primeiro pino de interrupção
attachInterrupt(0, ContarAnguloPos, RISING); //
Fonte: Autor.
A lógica vetorial para o deslocamento foi usada para a criação do código no Arduino
IDE para enviar da placa Arduino ao Processing dados das componentes X, Y, e o ângulo θ.
No Processing a matriz de pixels possuem posições X e Y, assim como no plano cartesiano,
porém o eixo Y possui um crescimento invertido. O deslocamento do robô no mapa é a
frequente atualização dos valores de posição.
A mudança dos valores X e Y da posição do robô dependem do encoder. O encoder
enquanto gira, não distingue o sentido de rotação da roda, portanto foi necessário utilizar os
comandos de movimento que são utilizados para controle para também distinguir
separadamente os tipos de dados coletados pelo sensor, se naquele momento está coletando
pulsos enquanto anda para frente, se está coletando enquanto da ré, ou se está coletando
enquanto o robô gira de forma horária ou anti-horária.
As funções void robot_forward() , void robot_backward(), void robot_left(),void
robot_right() (Quadro 4.26), possuem marcadores denominados “mark” estes marcadores
possuem strings de nomes: “frente, “re”, “esquerda”, “direita”, de acordo com os as funções
de movimento que faz o robô ir para frente, trás, girar para esquerda ou girar para direita
respectivamente. Estas funções são acessadas de acordo com o comando de movimento do
robô. Os comandos de movimento podem ser acessados pelo código criado para o controle
manual ou para o controle automático.
Os marcadores servem de condição dentro da função void ContarAnguloPos(), função
acessada por interrupção sempre que o encoder recebe um pulso, nesta função são
armazenados e calculados os valores de X, Y e ângulo θ.
Se o robô vai para frente ou para trás, é enviado o marcador “frente” ou “re”,
respectivamente para a função “ContarAnguloPos()”, a condição acessada do marcador
“frente” e do marcador “re”, armazenam o valor das contagens de pulsos nas variáveis
72
void robot_backward()
{
mark="re";
motor1.setSpeed(170);
motor1.run(BACKWARD);
motor2.setSpeed(205);
motor2.run(BACKWARD);
void robot_left()
{ mark="esquerda";
motor1.setSpeed(120);
motor1.run(BACKWARD);
motor2.setSpeed(155);
motor2.run(FORWARD);
void robot_right()
{ mark="direita";
motor1.setSpeed(120);
motor1.run(FORWARD);
motor2.setSpeed(155);
motor2.run(BACKWARD);
void robot_stop()
{ // sem mark
motor1.setSpeed(0);
motor1.run(RELEASE);
motor2.setSpeed(0);
motor2.run(RELEASE);
Esta limitação foi necessária para que o robô não ultrapasse os valores limites do mapa
para sua exibição. Caso o robô ultrapassasse os limites de desenho no mapa, ele não iria ser
exibido mesmo realizando suas funções normalmente.
As condições “esquerda” e “direita” dentro da função “ContarAnguloPos()”, foram
usadas apenas para a formação do ângulo θ. O robô ao girar para direita o ângulo θ cresce e
ao girar para esquerda o ângulo decresce.
Foi criada uma variável denominada “contadorr” para armazenar uma quantidade de
pulsos durante o giro. O robô ao se mover na condição de “direita”, é somado uma unidade no
“contadorr” a cada novo pulso, e ao se mover na condição de “esquerda” é subtraído uma
unidade a cada novo pulso (Quadro 4.31).
Para o controle automático foi criada uma função (Quadro 4.36) no Processing para
obter uma condição de “state” específica no Arduino. Quando o botão direito do mouse é
clicado envia o número 5 para a porta serial, então o robô adquire a condição “state==’5’” no
Arduino.
Quadro 4.36 - Função de controle automático.
if ( mousePressed && ( mouseButton == RIGHT ) ) { // if the right mouse button is pressed
myPort.write ( '5' ) ; // Send a '5' to the Arduino IDE
}
Fonte: Autor.
função de desvio “decision()” caso se sujeite a uma das seguintes condições: detecte um
obstáculo a menos de 20 centímetros ou uma das componentes X ou Y ultrapassou o valor
limite (Quadro 4.38).
Quadro 4.37 - Atribuição do estado "5", referente ao controle automático.
if (state== '5'){
Auto=5;
}
Fonte: Autor.
Foi testada a tomada de decisão para desvio virando o robô em um sentido específico
quando encontra um obstáculo. Caso robô detecte um obstáculo ou quando chega aos limites
do mapa, este desvia girando o robô para direita (poderia ser para esquerda, mas direita foi o
sentido escolhido).
No começo da função de desvio “decision()”, a variável “contadorNew” é zerada,
significa que sempre que o robô acessar esta função a variável irá começar com o valor igual a
0 (Quadro 4.40). As condições acessadas pelos marcadores “direita” e “esquerda” também
zeram o “contadorNew” quando não estão em modo automático (“Auto=0”) .
Esta variável serve para que o robô possa girar para direita durante a contagem de 19
pulsos. A contagem é feita dentro da condição “direita” ou “esquerda” acessada por
interrupção na função ”ContarAnguloPos()” quando o robô está em modo automático
(“Auto=5”) (Quadro 4.39).
Os 19 pulsos equivalem aproximadamente um quarto dos 78 pulsos necessários para o
robô girar uma volta completa, ou seja, aproximadamente 19 pulsos são necessários para o
robô girar 90°. No código foi colocado o valor de 16, pois durante os testes da execução foi
notado que o robô capta três pulsos a mais ao executar a função, então foi necessário o
número 16 como limite para totalizar os 19 pulsos (Quadro 4.40).
Quadro 4.39 - Ações no contador no estado automático.
if(Auto==5)
contadorNew=contadorNew+1;
else
contadorNew=0;
Fonte: Autor.
78
if (a==1) //
{
do { robot_right();
dist_cm = measureDistance();
Serial.println((String)contadorX+","+contadorY+","+angulo+","+dist_cm);
}while(contadorNew<16);
robot_forward();
} //end if
Fonte: Autor.
Enquanto o robô gira, capta as distâncias dentro da condição “while” e envia para a
porta Serial, os dados: “contadorX”, “contadorY”, “angulo” e “dist_cm”. Ao terminar a
condição o robô se move para frente. A condição “if (a==1)”, foi uma condição criada que
permanece sempre ativa pelo “a=1” no “setup()”. Esta condição foi colocada para inutilizar o
modo automático caso o usuário queria, trocando o valor da variável “a” por um valor
diferente de 1, ou trocando o valor na condição “if (a==1)”.
O mapa foi feito com as dimensões reais aproximadas representadas por números de
pixels na tela da interface formando um mapa de matriz de pixels, na qual um pixel representa
um centímetro. No mapa gerado pelo Processing, fatores como: a posição do robô, a distância
captada pelo ultrassom, as áreas sem obstáculos, as áreas com obstáculos e áreas
inexploradas, foram representados por cores e formatos geométricos diferentes. No mapa as
cores brancas representam espaços vazios sem a presença de obstáculos, as cores pretas
representam a presença de obstáculos, e a cor azul representa a área não explorada.
No Processing, foi criada uma tela interface azul com 500x500 pixels, representando
uma área real de 5x5 metros (Quadro 4.41). Esta tela é o mapa gráfico, onde são desenhados o
robô e os obstáculos. No “size()”, foram colocados as dimensões em pixels, e em
“background()” foi colocado o valor da cor de fundo.
Quadro 4.41 - Parâmetros para criação do mapa.
void setup ( ) {
size (500, 500); // Size of the serial window
background ( 1000 );
Fonte: Autor.
79
O primeiro elemento do vetor “p” foi o dado X, o segundo elemento foi o dado Y, o
terceiro elemento foi o ângulo, e o quarto elemento foi a distância captada pelo ultrassom. Os
dados X, Y são valores de componentes X,Y enviado pelo Arduino, valores resultantes da
quantidade de pulsos gerados/coletados, não significando valores de posições em escala real,
deste modo foi necessária uma conversão destes valores para centímetros.
A circunferência da roda foi calculada, pois ao se mover durante um giro completo das
rodas o robô se move a distância da circunferência:
Um giro completo da roda gera 40 pulsos. Uma unidade enviada pelo Arduino para o
Processing é traduzido para um pixel. O robô ao se mover em linha reta durante 40 pulsos
com a angulação igual a 0° envia 40 unidades da componente X para o Processing assim se
movendo 20,73451151 centímetros no espaço real em um eixo X, o mesmo acontece com o
robô se movendo em linha reta no eixo Y. Portanto uma unidade da componente X ou
componente Y enviada pelo Arduino equivale a 0.51836278784 centímetros.
20,73451151 𝑐𝑚 𝑐𝑚
= 0,51836278784
40 𝑢𝑛𝑖𝑑𝑎𝑑𝑒𝑠 𝑢𝑛𝑖𝑑𝑎𝑑𝑒
(4.26)
1 (𝐴𝑟𝑑𝑢𝑖𝑛𝑜) = 0,51836278784 𝑐𝑚
80
Deste modo o valor das componentes enviadas do Arduino para o Processing foi
multiplicado por 0.51836278784 para converter em centímetros.
𝑋 𝑐𝑚 = 𝑋 (𝐴𝑟𝑑𝑢𝑖𝑛𝑜) × 0,51836278784 𝑐𝑚
(4.27)
𝑌 𝑐𝑚 = 𝑌 (𝐴𝑟𝑑𝑢𝑖𝑛𝑜) × 0,51836278784 𝑐𝑚
Foi criado um objeto de “mira”, este objeto acompanha o robô. A “mira” serve para
indicar a orientação do robô visualmente, mostrando a sua “frente”. O centro do objeto “mira”
foi situado a 10 pixels de distância do centro do robô e gira de acordo com o dado de
angulação recebido. As coordenadas “miraX” e “miraY” são os resultados das projeções do
módulo de 10 pixels, somados com as coordenadas da posição atual do robô.
Acompanhando a “mira”, foi criado o objeto “ultra” que indica a distância do robô a
um obstáculo, se deslocando conforme a angulação, do mesmo modo que a “mira”. Porém
para o cálculo das projeções do “ultra”, o módulo é dado pelo valor da distância captada do
ultrassom (Quadro 4.44).
Quadro 4.44 - Distância do robô até o obstáculo via ultrassom.
miraX=x+10*cos(teta);
miraY=y+10*sin(teta);
ultraX=miraX+estado*cos(teta);
ultraY=miraY+estado*sin(teta);
}
Fonte: Autor.
O objeto “ultra” foi criado para se posicionar na extremidade da “linha”, este objeto
serviu para verificação se contém ou não obstáculos. A diferenciação na presença ou ausência
de obstáculos foi feito através de alteração de cores no mapa. Quando não há obstáculos a
uma distância de 70 centímetros a coloração do objeto “ultra” é branca com a borda vermelha,
e quando detecta um obstáculo há uma distância de 70 centímetros ou menos, a coloração do
82
“ultra” se torna preta com borda verde. Tanto as cores brancas quanto as pretas foram
demarcadas no mapa para diferenciar a presença ou não presença de obstáculos.
No código (Quadro 4.47), a condição “if(estado<70)” é acessada quando o ultrassom
capta uma distância menor que 70 cm, dentro desta condição foram definidas as variáveis para
coloração, “cor=0” (preto) e “cor1=#00ff00” (verde). Sendo a “cor” a variável usada para o
preenchimento e a variável “cor1” para a borda. A condição “else” é acessada quando o
ultrassom capta uma distância maior ou igual a 70 cm, dentro desta condição foram definidas
as variáveis “cor=255” (branco) e “cor1=#ff0000” (vermelho).
Quadro 4.47 - Preenchimento dos obstáculos no mapa.
if(estado<70)
{cor=0;
cor1=#00ff00;}
else
{cor=255;
cor1=#ff0000;}
fill(cor);
stroke(cor1);//
rectMode(CENTER);
rect(ultraX,ultraY,2,2);
Fonte: Autor.
Figura 4.31 - Demonstração do aspecto do robô, mira, extremidade, range e seus estados no mapa.
Fonte: Autor.
O robô ao se mover cria rastros de “clones” no mapa gráfico. Nestes “clones”, as cores
vermelha e verde são indesejadas, pois não possuem significância para diferenciar a presença
ou não de obstáculos, e também pode confundir o usuário na visualização. Foi criada uma
função “apagar()” que substitui a cor vermelha por branca e a cor verde por preta nos rastros
indesejados deixados (Quadro 4.48).
Quadro 4.48 - Remoção das cores indesejadas do mapa.
void apagar()
{
float tamanho;
color white = color(255);
color red = color(#ff0000);
color black = color(0);
color verde = color(#00ff00);
color atual;
tamanho = 1000;
83
Nesta função, o laço “for()” verifica toda a matriz de pixels da interface, armazena
cada cor de pixel em uma variável denominada “atual” e verifica sua cor, se for vermelha, a
transforma em branco, se verde, a transforma em preto. A função responsável “get(i,j)”,
captura a cor do pixel, caso o pixel tenha a cor “red” ou “verde”, as as funções “set(i,j,
black)” e “set(i,j, white)”, atribuem a cor “black” ou “white” a este pixel.
Figura 4.32 - Demonstração do efeito descrito no Quadro 4.48.
Fonte: Autor.
5 RESULTADOS
O aspecto final do protótipo é indicado na Figura 5.1, onde é possível observar a placa
MBZ e com o motor shield na parte traseira do robô, a fixação do sensor de ultrassom na parte
frontal do robô e um protoboard auxiliar para o módulo Bluetooth. A visão geral das conexões
é indicada na Figura 5.2.
Figura 5.1 - Aspecto final do protótipo, com posicionamento do sensor de ultrassom na parte frontal do robô.
Fonte: Autor.
Fonte: Autor.
85
Fonte: Autor.
Para a tela inicial, foi empiricamente estabelecido uma dimensão de 500x500 pixels,
onde cada pixel corresponde aproximadamente a 1 cm no mundo real. As cores representam
os seguintes estados: área não mapeada (azul), área livre de obstáculo (branco), área com
obstáculo (preto), contorno do robô (quadrado vermelho preenchimento branco) e a mira para
indicar para qual lado o sensor e o robô estão apontados (quadrado branco com
preenchimento vermelho).
86
A dimensão do robô foi representada como um quadrado branco com borda vermelha
de 15x15 pixels com uma mira na frente, representado por um quadrado vermelho e borda
branca de 5x5 pixels. A mira possui o centro a 10 pixels de distância do centro do robô. O
alcance do ultrassom foi representado por uma linha branca com 70 pixels de tamanho
máximo com um quadrado de 2x2 pixels na sua extremidade
Figura 5.4 - Indicação dos elementos do mapa, incluindo o robô, a mira e o ambiente.
Fonte: Autor.
Fonte: Autor.
87
Fonte: Autor.
(Figura 5.7) e com a presença de um obstáculo em uma distância relativamente fixa (Figura
5.8).
Figura 5.7 - Teste de giro do robô e suas respectivas leituras com o ambiente livre de obstáculos.
Fonte: Autor.
Figura 5.8 - Teste de giro do robô e suas respectivas leituras com o ambiente com a presença de obstáculos.
Fonte: Autor.
É possível notar na primeira figura que como em volta do robô não possuía obstáculos,
foi demarcado a área em branco, não ultrapassando o alcance máximo do sensor delimitado de
70 centímetros. Na segunda figura, ao inserir o obstáculo em volta do robô a uma distância
próxima, foi demarcado de preto o local que foi detectado do obstáculo. Foi notado que a
distância do robô até os obstáculos era próxima observando a distância dos pixels pretos.
89
Fonte: Autor.
Figura 5.10 - Remoção dos traços indesejados, sem afetar a representação do robô.
Fonte: Autor.
Figura 5.11 - Primeiro exemplo da representação da posição inicial no mapa e seus efeitos.
Fonte: Autor.
Figura 5.12 - Segundo exemplo da representação da posição inicial no mapa e seus efeitos.
Fonte: Autor.
Para testar o robô em campo, por meio da comunicação por Bluetooth, ao pressionar as
teclas de movimento o robô se movimenta de forma correta conforme os comandos dados e
captou a posição dos obstáculos com certa precisão. O teste foi feito em um local controlado
de área pequena devido às limitações do ambiente (Figura 5.13).
Figura 5.13 - Teste em ambiente real com a verificação do mapeamento e de sua exibição na interface.
Fonte: Autor.
92
Problema com a reflexão do ultrassom: A onda sonora refletida se não for captada
pelo ultrassom, durante o mapeamento é mostrada como distância máxima, indicando
caminho livre. Um sensor de distância eficiente poderia suprir este problema.
95
REFERÊNCIAS
BURKE, S. e GREINER, A. These self-flying drones keep a constant eye on your busines.
CNN Tech, New York, 01 maio 2018. Disponível em: <http://money.cnn
.com/2018/05/01/technology/business/self-flying-drones/index.html>. Acesso em: 08 maio
2018.
FRY, B. e REAS, C. Getting Started with Processing. O’Reilly Media, Inc. 1005
Gravenstein Highway North, Sebastopol, CA 95472, Estados Unidos, 2010.
HANZA, A. How to Make Arduino and Processing IDE Communicate. MAKER PRO, 21,
mar. 2018. Disponível em: <https://maker.pro/arduino/tutorial/how-to-make-arduino-and-
processing-ide-communicate>. Acesso em: 15 jul 2019.
KORTENKAMP, D.; BONASSO, R. P.; MURPHY, R., eds. Artificial intelligence and
mobile robots: case studies of successful robot systems. Cambridge, MA, USA: MIT Press,
1998.
RAMBO, W. Vídeo: Robô com motor shield – Parte 2. FILIPEFLOP, 26 jul 2016.
Disponível em: <https://www.filipeflop.com/blog/video-robo-com-motor-shield-parte-2/>.
Acesso em: 15 jul 2019.
ROOSE, K. The Self-Driving Car Industry’s Biggest Turning Point Yet, The New York
Times, 30 mar. 2018. Disponível em: < https://www.nytimes.com/2018/03/30/
technology/self-driving-cars.html>. Acesso em: 06 maio 2018.
THE ROBOTICS BACK-END. Arduino Uno Pins – A Complete Practical Guide. The
Robotics Back-End. Disponível em: <https://roboticsbackend.com/arduino-uno-pins-a-
complete-practical-guide/#Arduino_Uno_pin_diagram>. Acesso em: 05 jun 2019.
THRUN, S. Learning metric-topological maps for indoor mobile robot navigation, Artificial
Inteligence 99(1), 21–71. 1998
100
THRUN, S. et al. A System for Volumetric Robotic Mapping of Abandoned Mines. The
Robotic Institute, Carnegie Mellon University, Pittsburgh, PA (EUA), 2003. Disponível em: <
https://ri.cmu.edu/pub_files/...1/thrun_sebastian_2003_1.pdf>. Acesso em: 07 maio 2018.
APÊNDICE I
Código do Arduino IDE.
#include <AFMotor.h>
AF_DCMotor motor1(4); //Seleção do Motor 1
AF_DCMotor motor2(3); //Seleção do Motor 2
#define trig A4 //Saída para o pino de trigger do sensor
#define echo A5 //Saída para o pino echo do sensor
int a; //Variavel qualquer para entrar em modo automático
int Auto; //Variavel que determina se está em modo automático ou manual
float measureDistance(); //Função para medir, calcular e retornar a distância em cm
void trigPulse(); //Função que gera o pulso de trigger de 10µs
void decision(); //Função para tomada de decisão. Qual melhor caminho?
void ContarAnguloPos();
void robot_forward(); //Função para movimentar robô para frente
void robot_backward(); //Função para movimentar robô para trás
void robot_left(); //Função para movimentar robô para esquerda
void robot_right(); //Função para movimentar robô para direita
void robot_stop(); //Função para parar o robô
float dist_cm; //Armazena a distância em centímetros entre o robô e o obstáculo
float angulo; //Armazena angulo em radiandos do giro do robô
int MaxX; //Armazena a distância X maxima no mapa em centimetros
int MaxY; //Armazena a distância Y maxima no mapa em centimetros
int MaxPixel; //Armazena a largura cm do mapa grafico considerando uma matriz quadrada
float contadorNew; //Contador usado para giro durante o modo automático
float contadorX; //Contador usado para calculo de distância X
float contadorY; //Contador usado para calculo de distância Y
int contadorr; //Contador usado para calculo da angulação em radianos
String mark; //Marca o sentido do robô
void setup() {
// put your setup code here, to run once:
pinMode(trig, OUTPUT); //Saída para o pulso de trigger
pinMode(echo, INPUT); //Entrada para o pulso de echo
digitalWrite(trig, LOW); //Pino de trigger inicia em low
delay(500);
Serial.begin(9600); // Starting the serial communication at 9600 baud rate
// = 0xFF; //Inicia no valor máximo 0xFF
pinMode(2, INPUT); // Primeiro pino de interrupção
attachInterrupt(0, ContarAnguloPos, RISING); //
angulo=0; //Angulo inicial
contadorX=50; //Começa em uma posição X determinada no mapa
contadorY=50; //Começa em uma posição Y determinada no mapa
Auto=0; //Começa em modo manual (0) ou automático (5)
a=1; // 1 para entrar no if usado no modo automatico
MaxPixel=500; //Dimensão máxima do mapa da matriz em cm
MaxX=MaxY=2*(MaxPixel-15);
}
void loop() {
//robot_forward(); //Usado para teste
//robot_left(); //Usado para teste
//robot_backward();//Usado para teste
//robot_right(); //Usado para teste
if (Serial.available ( ) > 0) { // Checking if the Processing IDE has send a value or not
char state = Serial.read ( ); // Reading the data received and saving in the state variable
if(state == '0')
{
Auto=0;
robot_forward();
102
}
if (state == '1') {
Auto=0;
robot_backward();
}
if (state == '2') {
Auto=0;
robot_left();
}
if (state == '3') {
Auto=0;
robot_right();
}
if (state == '4') {
Auto=0;
robot_stop();
}
if (state== '5'){
Auto=5;
}
}
dist_cm=measureDistance();
if(Auto==5){
robot_forward();
if((dist_cm<20) || (contadorX>=MaxX) || (contadorY>=MaxY) || (contadorX<=0) || (contadorY<=0) )
decision();
}
//Serial.println((String)contadorX+","+contadorY+","+anguloA+",,,,,,,,,,,,,,,,,,,"+anguloB); // //Usado para teste
// Serial.println((String)contadorX+","+contadorY+","+dist_cm+",,,,,,,,,yyyy,,,,,,,,"+contadorr); // para teste
Serial.println((String)contadorX+","+contadorY+","+angulo+","+dist_cm);//Deve ir para porta serial
}
contadorX=0;}
if(contadorY>MaxY)
{robot_stop();
contadorY=MaxY;}
if(contadorY<0)
{robot_stop();
contadorY=0;}
}
delayest=millis();
} //end mark frente
}
void robot_forward()
{ mark="frente";
motor1.setSpeed(180);
motor1.run(FORWARD);
motor2.setSpeed(215);
motor2.run(FORWARD);
} //end robot forward
void robot_backward()
{
mark="re";
motor1.setSpeed(180);
motor1.run(BACKWARD);
motor2.setSpeed(215);
motor2.run(BACKWARD);
} //end robot backward
void robot_left()
{ mark="esquerda";
motor1.setSpeed(130);
motor1.run(BACKWARD);
motor2.setSpeed(165);
motor2.run(FORWARD);
} //end robot left
void robot_right()
{ mark="direita";
motor1.setSpeed(130);
motor1.run(FORWARD);
motor2.setSpeed(165);
motor2.run(BACKWARD);
} //end robot right
void robot_stop()
{ // sem mark
motor1.setSpeed(0);
motor1.run(RELEASE);
motor2.setSpeed(0);
motor2.run(RELEASE);
} //end robot stop
105
APÊNDICE II
Código do Processing.
import processing.serial.*; // Importing the serial library to communicate with the Arduino
Serial myPort; // Initializing a vairable named 'myPort' for serial communication
int cor;
int cor1;
String arduino;
float x;
float y;
float miraX;
float miraY;
float estado;
float ultraX;
float ultraY;
float teta;
void setup ( ) {
size (500, 500); // Size of the serial window, you can increase or decrease as you want
background ( 1000 );
myPort = new Serial (this, "COM9", 9600); // Set the com port and the baud rate according to the Arduino
myPort.bufferUntil ( '\n' ); // Receiving the data from the Arduino IDE
}
void serialEvent (Serial myPort) {
arduino = myPort.readStringUntil ( '\n' ) ; // Changing the background color according to received data
float p[] = float(split(arduino, ','));
x=p[0]*0.51836278784; //40*x=6,6pi // x=6,6pi/40 0.51836278784
y=p[1]*0.51836278784;
teta=p[2];
estado=p[3];
miraX=x+10*cos(teta);
miraY=y+10*sin(teta);
ultraX=miraX+estado*cos(teta);
ultraY=miraY+estado*sin(teta);
}
void apagar()
{
float tamanho;
color white = color(255);
color red = color(#ff0000);
color black = color(0);
color verde = color(#00ff00);
color atual;
tamanho = 1000;
for (int i=0; i<tamanho; i++)
{
for (int j=0; j<tamanho; j++)
{
atual = get(i,j);
if (atual == red) {set(i,j, white);}
if (atual == verde) {set(i,j, black);}
}
}
}
void draw ( ) {
apagar();
smooth();
fill(255);
106
stroke(#ff0000);
rectMode(CENTER);
rect(x,y,15,15);
if(estado<70)
{cor=0;
cor1=#00ff00;}
else
{cor=255;
cor1=#ff0000;}
fill(#ff0000); // preenchimento da mira
strokeWeight(2);
stroke(255);
line(miraX,miraY,ultraX,ultraY);
strokeWeight(1);
rectMode(CENTER);
rect(miraX,miraY,5,5);
fill(cor);
stroke(cor1);//
rectMode(CENTER);
rect(ultraX,ultraY,2,2);
print(x);
print("..");
print(y);
print("..");
println(estado);
////////////////estado de click
if ( mousePressed && ( mouseButton == RIGHT ) ) { // if the right mouse button is pressed
myPort.write ( '5' ) ; // Send a '0' to the Arduino IDE
}
}
void keyPressed(){
if(key==CODED){
if(keyCode ==UP){ myPort.write ( '0' ) ;
}
if(keyCode==DOWN){myPort.write ( '1' ) ;
}
if(keyCode==LEFT){myPort.write ( '2' ) ;
}
if(keyCode==RIGHT){myPort.write ( '3' ) ;
}
if(keyCode==ALT){myPort.write ( '4' ) ;
}}}