Documente Academic
Documente Profesional
Documente Cultură
Trabalho
de
Concluso
de
Curso
apresentado coordenao do curso de
Engenharia de Controle e Automao, do
Instituto Federal de Educao, Cincia e
Tecnologia Fluminense, para obteno do
grau de BACHAREL EM ENGENHARIA DE
CONTROLE E AUTOMAO
Trabalho
de
Concluso
de
Curso
apresentado Coordenao de Engenharia
de Controle e Automao, do Instituto
Federal de Educao, Cincia e Tecnologia
Fluminense Campos dos Goytacazes/RJ,
para obteno do grau de BACHAREL EM
ENGENHARIA
DE
CONTROLE
E
AUTOMAO
BANCA EXAMINADORA
_________________________________________________________
Professor Edson Simes dos Santos, M.Sc.- Orientador
Instituto Federal Fluminense
_________________________________________________________
Professor Fbio Junio dos Santos Coelho
Instituto Federal Fluminense
________________________________________________________
Professor Marcos Moulin Valencia
Instituto Federal Fluminense
AGRADECIMENTOS
RESUMO
PALAVRAS-CHAVE:
Computacional.
Rob
Autnomo.
Processamento
de
Imagem.
Viso
ABSTRACT
Autonomous
Robot.
Image
Processing.
Computer
Vision.
18
Figura 2: RECEPTOR DE RF
19
21
22
26
27
30
31
32
33
33
34
35
36
36
37
37
41
42
LISTA DE SIGLAS
RF
Rdio Frequncia
PID
PD
Proporcional e Derivativo
PI
Proporcional e Integrativo
TX
Transmissor
RX
Receptor
GND
Ground (Terra)
PWM
Vcc
SUMRIO
1 INTRODUO
11
1.1 OBJETIVO
12
12
12
1.2 JUSTIFICATIVA
13
13
2 REVISO DE LITERATURA
15
15
2.2 - ARDUINO
16
17
2.4 Servomotor
20
22
23
3 DESENVOLVIMENTO DO PROJETO
24
24
27
27
28
29
3.3.1 Funes
32
3.3.1.1 Calibra_Cores.m
32
3.3.1.2 captura.m
33
3.3.1.3 varredura.m
34
3.3.1.4 verifica.m
38
3.3.1.5 corrigir.m
38
3.3.1.6 pos_carro.m
38
3.3.1.7 pos_centro.m
38
3.3.1.8 pos_otima.m
39
3.3.1.9 frente_do.m
39
3.3.1.10 encontre_reta.m
39
4 RESULTADOS
40
5 CONSIDERAES FINAIS
43
5.1 CONCLUSO
43
43
6 REFERNCIAS BIBLIOGRFICAS
45
46
53
11
1 INTRODUO
estes
parmetros
ao
microprocessador
da
prpria
plataforma,
possibilitando que cada estudante desenvolva seu prprio algoritmo e insira dentro
12
1.1 OBJETIVO
1.1.1 Objetivo Geral
13
1.2 JUSTIFICATIVA
14
sua evoluo, reas de atuao e definio do conceito IA para que o leitor se sinta
familiarizado com o tema.
15
2 REVISO DE LITERATURA
16
diferentes tipos de parafusos. O algoritmo aplicado por Rudeck (2001), Coelho (2001)
e Canciglieri Jr (2001) descrito da seguinte forma:
Aquisio Pr-processamento Segmentao Identificao do Objeto Reconhecimento de Padres
Na etapa de
2.2 ARDUINO
O conceito Arduino surgiu na Itlia, em 2005, com objetivo de criar um
dispositivo de controle para prottipos construdos de forma menos dispendiosa do
que outras solues disponveis. O quite de desenvolvimento Arduino dito uma
plataforma de computao fsica, em que sistemas digitais, ligados a sensores e a
atuadores, so capazes de medir variveis no ambiente fsico, realizar clculos
numricos e tomar decises lgicas no ambiente computacional e gerar novas
variveis no ambiente fsico. A parte central do kit um microcontrolador, o qual
pode ser entendido como a evoluo de um microprocessador, na qual ele
17
18
por reflexo. Por outro lado, na modulao por frequncia, FM, o comprimento de
onda bem inferior, da ordem de centmetros, o que a torna muito penetrante
apesar de pouco refletida (PEREIRA, 2014, apud, VIEIRA, 2011).
Transmissor:
Modelo: MX-FS-03V;
19
Dimenses: 19 mm x 19 mm;
Antena: 25 cm;
Receptor:
20
Frequncia:433,92MHz;
Modelo:MX-05V;
Tenso: 5VCC;
Corrente: 4 mA;
Sensibilidade: 105db;
Antena: 35 cm;
Dimenses: 30 mm x 17 mm x 7 mm.
2.4 SERVOMOTOR
21
22
23
dispositivos.
A biblioteca SoftwareSerial possui funes que podem ser utilizadas em
conjunto com os mdulos de transmisso e recepo de RF para realizar a
transmisso de dados sem fio. Essas duas funcionalidades trabalham juntas
harmonicamente e no geram conflitos entre si.
24
3 DESENVOLVIMENTO DO PROJETO
Neste captulo ser feita a descrio detalhada dos elementos que constituem
o sistema proposto e desenvolvido neste trabalho. abordado o desenvolvimento de
toda a parte fsica do projeto, incluindo hardware e embarcados, e tambm
abordada toda a parte de programao do projeto.
3.1 DESING DE HARDWARE E ESTRUTURAS
25
utilizando tinta relevo. Aps feita a pintura, a pea foi recortada e inserida na rea de
testes. A bola foi projetada em isopor por ser um material leve e de baixo atrito.
Outros materiais emborrachados e metlicos foram utilizados, porm o isopor se
tornou o material mais apropriado, de acordo com testes prticos realizados. A bola
de isopor foi tingida com tinta para tecido cor verde brilhante. O marcador utilizado
para sinalizar a plataforma robtica no formato de uma estrela de 3 pontas,
tomando-se como base para a criao dessa estrela um tringulo issceles. Este
formato ideal para indicar o sentido no qual se encontra a plataforma robtica, uma
vez que os pontos mais prximos indicam a parte de trs da plataforma, e o ponto
mais distante indica a frente. O marcador foi confeccionado em papel e isopor. O
desenho foi feito utilizando tinta para tecido vermelha, a figura foi fixada em um
pedao retangular de isopor e posicionado em cima de 4 palitos que foram fixados
em 4 pontos da plataforma robtica, a fim de esconder as partes coloridas para no
serem detectadas na captura de imagem, destacando-se assim apenas o marcador.
A plataforma robtica utilizada para a base do carro foi gentilmente cedida
pelo Laboratrio de Automao Inteligente do Instituto Federal Fluminense, e
consiste em uma plataforma fixa
servomotores
26
Fonte: Autor.
A base robtica (4) possui um cano de PVC cortado (1) a fim de direcionar a bola
tangencialmente a circunferncia do cano. O teto com o marcador vermelho (2)
feito de isopor e fixado com palitos de madeira nas extremidades da estrutura de
acrlico (3) que tambm abriga os elementos do circuito. As rodas de plstico (5)
foram adaptadas com elsticos de borracha a fim de melhorar o atrito e evitar
derrapagens.
27
A Figura 6 mostra a bola na cor verde e o gol na cor azul utilizados neste
experimento.
Figura 6: Bola e gol
Fonte: Autor.
28
9600 bits por segundo. Para fins de desenvolvimento, o programa exibe no monitor
serial, caso esteja disponvel, a mensagem que foi recebida via comunicao serial.
Aps receber a informao via comunicao serial, o programa transmite essa
informao atravs do mdulo de transmisso de radio frequncia conectado ao
Arduino. Alm disso, toda vez que uma informao enviada, um led conectado
internamente ao pino 13 do Arduino indica a transmisso de dados. A biblioteca
utilizada
"RadioHead"
est
disponvel
em:
http://www.airspayce.com/mikem/arduino/RadioHead/ (2015)
O programa utilizado como exemplo pode ser encontrado no Apndice A Hardware e Microcontroladores.
29
forma que o timer1 do microcontrolador seja substitudo pelo timer2, pois o timer1
utilizado pela biblioteca Servo.h que controla os motores. No arquivo RH_ASK.cpp,
acrescentar a linha "#define RH_ASK_ARDUINO_USE_TIMER2".
Este programa tambm foi desenvolvido como exemplo e est disponibilizado
no Apndice A - Hardware e Microcontroladores.
30
Fonte: Autor.
31
Fonte: Autor.
1- Asterisco azul utilizado para marcar a base do rob, calculada pelo Matlab.
2- Reta traada entre a base e a frente do rob, com o objetivo de indicar a direo
do rob
3- Asterisco verde utilizado para indicar a frente do rob.
4- Reta traada entre a frente do rob e a posio ideal para acertar a bola.
5- Asterisco verde utilizado para indicar a posio ideal, no qual o rob acerta a bola
em direo ao gol.
6- Asterisco verde indicando o centro da bola.
7- Reta entre a bola e o centro do gol, utilizada para encontrar a posio ideal.
8- Asterisco azul indicando a posio do centro do gol.
32
Fonte: Autor.
1- ngulo formado entre a reta que indica a direo do rob e a reta ideal que passa
pela posio ideal e pela frente do rob.
3.3.1 Funes
Esta seo descreve detalhadamente cada funo que foi criada para a
utilizao no cdigo implementado no Matlab.
3.3.1.1 Calibra_Cores.m
Esta funo efetua a leitura de 3 recortes de imagens com exemplos de cores
e em seguida determina as intensidades de cores que esto compreendidas dentro
daquele espectro para a identificao dos marcadores. Ao exibir uma imagem
colorida, existem intensidades diferentes de cores diferentes que so caractersticos
da imagem. Ao efetuar a mistura dessas cores em intensidades diferentes,
possvel gerar novas cores. A funo Calibra_Cores se encarrega de efetuar a busca
dos valores de intensidade mnimos e mximos para as cores vermelho, verde e
azul, para identificar o carro, a bola e o gol na imagem.
Sendo assim, esta funo gera duas matrizes, uma matriz com os valores
33
BOLA
GOL
VERMELHO
80%
indiferente
indiferente
VERDE
0%
Indiferente
Indiferente
AZUL
10%
indiferente
Indiferente
Fonte: Autor.
BOLA
GOL
VERMELHO
85%
indiferente
indiferente
VERDE
5%
Indiferente
Indiferente
AZUL
20%
indiferente
Indiferente
Fonte: Autor.
34
3.3.1.3 varredura.m
Realiza 8 varreduras em todos os sentidos e direes possveis na imagem, aps
reconhecer o objeto e transformar a imagem em preto e branco de forma a sempre
identificar o primeiro pixel branco. Esta funo foi concebida para encontrar os 3
pontos que caracterizam as extremidades do tringulo marcador do carro. Esta
funo retorna 8 pontos, e no geral, estes 8 pontos possuem 3 valores distintos que
se repetem. A Figura 10 mostra um tringulo.
Figura 10: Tringulo de extremidades 1, 2 e 3.
Fonte: Autor
35
Direo da Varredura
36
Fonte: Autor.
Fonte: Autor.
37
Fonte: Autor.
Fonte: Autor
38
3.3.1.4 verifica.m
A funo verifica.m utilizada para verificar se a funo varredura.m
identificou os 3 pontos distintos referentes ao tringulo marcador do carrinho. Caso a
funo identifique mais ou menos de 3 pontos distintos, a mesma retorna o valor 1
(erro=1). Caso a funo identifique os 3 pontos distintos sem erro, o valor de retorno
0 (erro=0).
3.3.1.5 corrigir.m
Caso sejam capturados mais ou menos de 3 pontos ao tentar identificar o
marcador do carro, a funo corrigir.m poder ser utilizada para aproximar os
parmetros. A funo recebe um vetor contendo 8 pontos, e um raio de ao (em
pixels) como parmetros. Caso pontos muito prximos sejam capturados, possvel
determinar um raio para que todos os pontos encontrados dentro deste raio sejam
substitudos pelo valor mdio entre eles. O valor para o raio de ao ideal
encontrado experimentalmente no sistema implementado pelo autor foi de 10 pixels.
3.3.1.6 pos_carro.m
Esta funo tem o objetivo de substituir o vetor com 8 pontos responsvel por
identificar o carro, que foi obtido atravs da varredura da imagem em todas as
direes, por uma matriz 3x2 que contm apenas os pontos necessrios, no qual
cada linha representa um ponto diferente e cada coluna representa um eixo no plano
(x e y). Em outras palavras, quando o vetor de 8 pontos formado, ele recebe
pontos repetidos. Quando a matriz 3x2 criada pela funo pos_carro, esses pontos
repetidos so eliminados, restando somente os 3 pontos essenciais para a
identificao da posio do carro na imagem.
3.3.1.7 pos_centro.m
Esta funo realiza a varredura em uma imagem preto e branco. Ao identificar
o objeto, a funo calcula o centro a partir dos 8 pontos encontrados aps efetuar a
39
varredura da imagem.
3.3.1.8 pos_otima.m
Esta funo encontra a equao da reta que passa atravs do gol e da bola.
Aps encontrar a equao, a funo calcula a posio ideal para o carro empurrar a
bola em trajetria retilnea at o gol, de forma que a posio ideal um
prolongamento desta reta, acrescido dos parmetros raio da bola e raio do prachoque do carrinho. Para nvel de desenvolvimento, esta funo pode tambm exibir
a reta tima sobre a imagem capturada.
3.3.1.9 frente_do.m
Esta funo compara os trs pontos adquiridos atravs do marcador do carro,
e identifica qual deles representa a frente do carro, atravs da comparao entre as
distncias entre os pontos. Visto que o marcador um tringulo issceles, o ponto
mais distante dos outros dois representa a frente do carro.
3.3.1.10 encontre_reta.m
Esta funo recebe dois pontos como parmetros e retorna a equao da reta
entre esses pontos. utilizada por exemplo para encontrar a reta ideal, que passa
pelo ponto que representa a frente do carro e a posio ideal, ou mesmo a reta que
determina a direo do carro
40
4 RESULTADOS
Alguns problemas ocorreram no desenvolvimento deste projeto. O conflito de
bibliotecas devido a utilizao do mesmo timer do microcontrolador merece
destaque. Este problema foi contornado substituindo-se a biblioteca virtualwire.h
pela biblioteca radiohead.h. Ambas so utilizadas para facilitar a programao do
microcontrolador junto a mdulos de comunicao via rdio frequncia, porm a
biblioteca virtualwire.h conflitava com a biblioteca servo.h pois ambas utilizam o
timer1 para efetuar a temporizao. Esta biblioteca foi substituda pela biblioteca
radiohead.h que possui uma linha de comando interna que pode alterar o seu
funcionamento, de modo que o timer1 seja substitudo pelo timer2. Embora este
problema tenha sido contornado, ele ainda existe de forma que no instante em que
os servomotores esto trabalhando, no possvel utilizar a recepo de dados via
RF. O atraso gerado pelo processamento de imagem lento, fez com que os
parmetros fossem enviados em intervalos de tempo longos, o que permitiu definir
um tempo exato para que o motor permanecesse ligado e depois fosse desligado
para receber os dados. Porm, caso cdigos de processamento de dados mais
eficientes sejam implementados, esta soluo no ser funcional. Sugere-se que
no se utilize a biblioteca servo.h para controlar os servomotores, e seja
implementado o comando atravs do envio de sinal PWM manualmente.
Os servomotores possuem um bom resultado quando submetidos ao controle
proporcional. Porm sua velocidade muito limitada. possvel substituir os
servomotores por motores de corrente contnua, uma vez que a bola utilizada no
jogo constituda de isopor, e no necessita de muita fora para ser deslocada. A
utilizao de motores de corrente contnua tornaria o sistema mais dinmico.
O algoritmo de controle PID foi implementado no mdulo de recepo de
parmetros, porm os ganhos integral e derivativo foram ajustados para zero. Isto se
fez necessrio pois o retardo de transporte devido ao longo intervalo de tempo entre
a aquisio de parmetros impediu a implementao de um controlador PID. Este
algoritmo
de
controle
foi
implementado
sem
utilizao
de
bibliotecas
41
Fonte: Autor.
42
Figura 15 (a)
Figura 15 (b)
Figura 15 (c)
Figura 15 (d)
Figura 15 (e)
Figura 15 (f)
Figura 15 (g)
Fonte: Autor.
43
5 CONSIDERAES FINAIS
Neste captulo so apresentadas as concluses dos resultados obtidos e
sugestes para trabalhos futuros.
5.1 CONCLUSO
A realizao do projeto pode ser considerada um sucesso, em virtude dos
desafios encontrados no decorrer do desenvolvimento. Com o sistema desenvolvido
possvel identificar marcadores em objetos utilizando viso computacional, enviar
dados via rdio frequncia de um computador para um sistema microcontrolado e
aplicar uma estratgia de controle, conforme o sistema proposto inicialmente.
Embora tenha atendido ao propsito inicial, o desenvolvimento do projeto
encontrou dois pontos a serem considerados. O primeiro deles o tempo necessrio
para processar todas as informaes referentes aos parmetros. Uma vez que
clculos complexos so realizados e varreduras de imagem so feitas, a capacidade
de processamento necessria para que o sistema possua uma resposta rpida
aumenta. Com isso foi possvel enviar parmetros a cada intervalo de 1 segundo a 1
segundo e meio.
Outro fator a ser considerado o conflito de bibliotecas, que impediu a
utilizao do controle dos servomotores e o recebimento de parmetros via RF ao
mesmo tempo.
Estes dois itens em conjunto tornaram difcil de se utilizar um controlador PID,
sendo utilizado apenas um controlador proporcional para a demonstrao do
sistema.
44
45
6 REFERNCIAS BIBLIOGRFICAS.
HEINEN, Farlei J.; OSRIO, Fernando Santos. Salo de Iniciao Cientfica. Livro
de
resumos.
Porto
Alegre
UFRGS/PROPESQ,
1999,
Disponvel
em:
RUDEK, Marcelo; COELHO, Leandro dos Santos; CANCIGLIERI JR, Osris. Viso
computacional aplicada a sistemas produtivos: fundamentos e estudo de caso. XXI
Encontro Nacional de Engenharia de Produo-2001, Salvador, 2001.
46
ask_transmitter.pde
-*- mode: C++ -*Simple example of how to use RadioHead to transmit messages
with a simple ASK transmitter in a very simple way.
Implements a simplex (one-way) transmitter with an TX-C1 module
#include <RH_ASK.h>
#include <SPI.h> // Not actually used but needed to compile
RH_ASK driver;
void setup()
{
Serial.begin(9600);
// Debugging only
if (!driver.init())
Serial.println("init failed");
pinMode(13,OUTPUT);
}
void loop()
{
if (Serial.available())
{
char recebido[8]="";
Serial.readBytes(recebido, 8);
Serial.println(recebido);
driver.send((uint8_t *)recebido, strlen(recebido));
driver.waitPacketSent();
digitalWrite(13,1);
delay(200);
digitalWrite(13,0);
}
//char recebido[8]={'1', '2', '3', '4', '5', '6', '7', '8'};
}
47
= -999;
// in steps of 1 degree
// tell servo to go to
// waits 15ms for the servo
// tell servo to go to
// waits 15ms for the servo
case 'f':
Motor_e.write(180);
position in variable 'pos'
Motor_d.write(0);
delay(20);
to reach the position
break;
case 'r':
// tell servo to go to
// waits 15ms for the servo
48
Motor_e.write(0);
position in variable 'pos'
Motor_d.write(180);
delay(20);
to reach the position
break;
//
tell
servo
to
go
to
case 'p':
Motor_e.write(93);
position in variable 'pos'
Motor_d.write(93);
delay(20);
to reach the position
break;
}
}
// tell servo to go to
// waits 15ms for the servo
49
(pid>4) pid=4;
(pid<-4) pid=-4;
(pid>-1 && pid<0) pid=-1;
(pid<1 && pid>0) pid=1;
50
}
void setup()
{
Serial.begin(9600); // Debugging only
Serial.println("setup");
if (!pacote.init())
Serial.println("init failed");
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);
ci=0;
bias=0;
e=0;
e0=e;
t=millis();
t0=t;
}
uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
uint8_t buflen = sizeof(buf);
void loop()
{
51
52
53
verifica.m
%vet_pos=[pos1 pos2
[vert hor]
%vet_pos_V=[pos1(1)
pos8(1)]; %Vetor de
%vet_pos_H=[pos1(2)
pos8(2)]; %Vetor de
54
end
for k=1:1:7
if vet_pos_H(k+1) ~= vet_pos_H(k)
total_de_pontos_H=total_de_pontos_H+1;
end
end
%caso o nmero de parmetros recolhidos do tringulo seja maior que 3,
%um sinal de erro gerado
if total_de_pontos_V >3 || total_de_pontos_H >3;
erro1=1; %erro de aquisio de parmetros
else
erro1=0;
end
varredura_intensiva.m
%Efetua a varredura procurando pixels brancos na imagem, pixels brancos
%possuem valor 1, enquanto pixels pretos possuem valor 0.
%Esta funo recebe como parmetro a imagem e retorna uma matriz com as
%primeiras posies encontradas de acordo com a orientao da varredura
%Cada posio encontrada apagada em um "raio" de pixels ao redor do ponto
%encontrado. Esta funo deve ser utilizada tendo como marcador 3 pontos
%vermelhos.
function [vet_pos] = varredura_intensiva(Im, raio)
tam=size(Im); %Im(1) == Altruta Im(2) == Largura
%Varredura 1
for V=1:1:tam(1, 1)
%Vertical
for H=1:1:tam(1, 2) %Horizontal
if (Im(V,H)== 1)
%pos1 o primeiro ponto branco encontrado.
pos1=[V,H];
Im(V,H)=0;
%Apaga o ponto na Imagem
for(cont1=(V-floor(raio/2)):1:floor((raio/2)))
for(cont2=floor((H-raio/2)):1:floor((raio/2)))
Im(cont1,cont2)=0;
end
end
figure (9)
imshow(Im)
break
end
end
end
%Varredura 2
for V=1:1:tam(1, 1)
%Vertical
for H=1:1:tam(1, 2) %Horizontal
if (Im(V,H)== 1)
55
varredura.m
%Efetua a varredura procurando pixels brancos na imagem, pixels brancos
%possuem valor 1, enquanto pixels pretos possuem valor 0.
%Esta funo recebe como parmetro a imagem e retorna uma matriz com as
%primeiras posies encontradas de acordo com a orientao da varredura
function [vet_pos] = varredura(Im)
tam=size(Im); %Im(1) == Altruta Im(2) == Largura
%Varredura da esquerda para a direita de cima para baixo
for V=1:1:tam(1, 1)
%Vertical
for H=1:1:tam(1, 2) %Horizontal
if (Im(V,H)== 1)
pos1=[V,H];
56
break
end
end
if (Im(V,H)== 1) break;
end
%Mensagem caso no seja detectada a imagem:
if V==tam(1, 1) && H==tam(1, 2);
vet_pos=[0 0 0 0 0 0 0 0];
pos1=[0 0];
pos2=[0 0];
pos3=[0 0];
pos4=[0 0];
pos5=[0 0];
pos6=[0 0];
pos7=[0 0];
pos8=[0 0];
disp('****Imagem no detectada. Erro detectado durante a
varredura.****')
break;
end
end
%pos1 o primeiro ponto branco encontrado.
%Varredura da direita para a esquerda de cima para baixo
for V=1:1:tam(1, 1)
%Vertical
for H=tam(1, 2):-1:1 %Horizontal
if (Im(V,H)== 1)
pos2=[V,H];
break
end
end
if (Im(V,H)== 1) break;
end
end
%Varredura da esquerda para a direita de baixo para cima
for V=tam(1, 1):-1:1
%Vertical
for H=1:1:tam(1, 2) %Horizontal
if (Im(V,H)== 1)
pos3=[V,H];
break
end
end
if (Im(V,H)== 1) break;
end
end
%Varredura da direita para a esquerda de baixo para cima
for V=tam(1, 1):-1:1
%Vertical
for H=tam(1, 2):-1:1 %Horizontal
if (Im(V,H)== 1)
pos4=[V,H];
break
end
end
if (Im(V,H)== 1) break;
end
end
57
pos_otima.m
%Esta funo retorna a posio tima do carrinho para que a bola seja
%atingida e acerte o gol, em coordenadas retangulares com o gol como o
%centro do plano.
58
%A posio ideal dever ser a exteno da reta que passa pelo centro do gol
%e pelo centro da bola. O ponto ideal esta reta acrescida dos valores do
%raio da bola e do raio do para-choque do carrinho.
function [posicao_otima]=pos_otima(gol, bola, raio_carrinho, raio_bola)
end
pos_centro.m
%Esta funo recebe a imagem aps a aplicao dos filtros
%e retorna a posio do centro.
function [pos] = pos_centro(Im)
vet_pos=varredura(Im);
vet_pos_V=vet_pos(1,1)+vet_pos(2,1)+vet_pos(3,1)+vet_pos(4,1)+vet_pos(5,1)+
vet_pos(6,1)+vet_pos(7,1)+vet_pos(8,1);
vet_pos_H=vet_pos(1,2)+vet_pos(2,2)+vet_pos(3,2)+vet_pos(4,2)+vet_pos(5,2)+
vet_pos(6,2)+vet_pos(7,2)+vet_pos(8,2);
pos_V=vet_pos_V/8;
pos_H=vet_pos_H/8;
pos=[pos_H pos_V];
end
59
pos_carro.m
%Esta funo retorna a posio do carrinho com base nos 3 parmetros de
%posio encontrados desde que no haja erro de aquisio de parmetros.
function [posicao]=pos_carro(pos)
posicao(1,1)=pos(1,1);
posicao(1,2)=pos(1,2);
for k=2:1:8
if pos(k,1) ~= posicao(1,1) || pos(k,2) ~= posicao(1,2);
posicao(2,1)=pos(k,1);
posicao(2,2)=pos(k,2);
break
end
end
for k=3:1:8
if (pos(k,1) ~= posicao(1,1) || pos(k,2) ~= posicao(1,2)) &&
(pos(k,1) ~= posicao(2,1) || pos(k,2) ~= posicao(2,2))
posicao(3,1)=pos(k,1);
posicao(3,2)=pos(k,2);
break
end
end
param_carro.m
%Esta funo pega 3 parmetros de posio (triangulo marcador) do carro, e
%1 parametro de posio da bola e retorna a distncia do carro at a bola e
%a angulao do carro em relao a bola.
function [parametros]=param_carro(p_carro, p_bola)
%Encontrando o ponto mais afastado da base do marcador (tringulo issceles
L1=sqrt((p_carro(1,1)-p_carro(2,1))^2 + (p_carro(1,2)-p_carro(2,2))^2);
L2=sqrt((p_carro(1,1)-p_carro(3,1))^2 + (p_carro(1,2)-p_carro(3,2))^2);
L3=sqrt((p_carro(2,1)-p_carro(3,1))^2 + (p_carro(2,2)-p_carro(3,2))^2);
%compara os lados do tringulo, encontra o menor, e atribui ao centro do
%carrinho o valor do ponto oposto ao menor lado.
if L1<L2 && L1<L3
centro(1,1)=p_carro(3,1);
centro(1,2)=p_carro(3,2);
end
if L2<L1 && L2<L3
centro(1,1)=p_carro(2,1);
centro(1,2)=p_carro(2,2);
end
if L3<L1 && L3<L2
centro(1,1)=p_carro(1,1);
centro(1,2)=p_carro(1,2);
end
60
mod_e_ang.m
%Esta funo retorna o valor do mdulo e do ngulo entre 2 pontos
function [parametros]=mod_e_ang(p1, p2)
%Calcula o mdulo
mod= sqrt((p2(1)-p1(1))^2+(p2(2)-p1(2))^2);
%Calcula o ngulo
61
cos_alpha=(p2(1)-p1(1))/mod;
ang=acos(cos_theta);
%Calcula o coeficiente angular
coef_a=(p2(2)-p1(2))/p2(1)-p1(1);
%Calcula o coeficiente linear
coef_l=(p1(2)-coef_a*p1(1)); %b=y-a*x
%Retorno
parametros=[mod ang coef_a coef_l];
end
Loop.m
%Tudo
Calibra_Cores; %gera matrizes com os mximos e os mnimos de cada cor
vid = videoinput('winvideo',1);% abre a conexo com a cmera de video
s1 = serial('COM3'); %conexo serial
fopen(s1);
i=0;
while i<30
i=i+1; %parada aps realizar 10 ciclos
[CARRO BOLA GOL]=captura(vid, mat_max, mat_min);
%imagem_id %Funo utilizada para testes. Efetua a identificao da imagem.
oito_pontos=varredura(CARRO);
if(verifica(oito_pontos))
oito_pontos=corrigir(oito_pontos,10);
end
%"carro" uma matriz 3x2 que contm os 3 pontos do tringulo marcador do
carro
carro=pos_carro(oito_pontos);
%"bola" o ponto do centro da bola
bola=pos_centro(BOLA);
bola=floor(bola); %corta a parte quebrada
%"gol" o ponto do centro do gol
gol=pos_centro(GOL);
gol=floor(gol); %corta a parte quebrada
%Encontra a posio que o carrinho tem que ter para acertar a bola em um
%ponto que faa com que o trajeto da bola seja o gol.
pos_ideal=pos_otima(gol,bola,30,35);
pos_ideal=floor(pos_ideal); %corta a parte quebrada
%Encontra a reta ideal que passa pela frente do carrinho e pela posio
%ideal
frente_do_carro=frente_do(carro);
62
reta_ideal=encontre_reta(frente_do_carro,pos_ideal);
%encontra a reta que d a direo do carro, passando pela frente e pela
%base
base_do_carro=base_do(carro);
reta_carro=encontre_reta(base_do_carro,frente_do_carro);
%Ponto de encontro entre a reta ideal e a reta direo do carro
syms x;
encontro_retas=[solve(reta_carro-reta_ideal)
subs(reta_ideal,x,solve(reta_carro-reta_ideal))];
encontro_retas=sym2poly(encontro_retas);
%Encontrando o angulo ideal em 3 passos:
%1- Transladando a origem do eixo para a base do carrinho
pos_ideal1=[pos_ideal(1)-base_do_carro(1) pos_ideal(2)base_do_carro(2)];
encontro_retas1=[encontro_retas(1)-base_do_carro(1)
encontro_retas(2)-base_do_carro(2)];
%2- Encontra os ngulos entre a origem e posio ideal e origem e
encontro
%de retas
angulo_pos_ideal=atan2(pos_ideal1(2), pos_ideal1(1));
angulo_encontro_retas=atan2(encontro_retas1(2),
encontro_retas1(1));
%3- A subtrao desses ngulos ser o angulo necessrio para o
carrinho
%corrigir a posio.
erro=angulo_encontro_retas-angulo_pos_ideal;
%convertendo o erro de radianos para graus
erro=erro*180/pi;
%Ajustando o sinal do ngulo
%O gol dever estar localizado na parte inferior da imagem para funcionar.
%if frente_do_carro(2)>bola(2);
%
erro=erro*(-1);
%end
%if gol(1)<bola(1);
%
erro=180-erro;
%end
%if erro>=180;
%
erro=-(360-erro);
%end
disp(erro);
%Envia dados via comunicao serial para o arduino
fprintf(s1,'%.2f',erro);
%Plota no desenho
hold on
syms x;
63
plot(frente_do_carro(1),subs(reta_ideal,x,frente_do_carro(1)),'*',pos_ideal
(1),subs(reta_ideal,x,pos_ideal(1)),'*')
plot([frente_do_carro(1) pos_ideal(1)],
[subs(reta_ideal,x,frente_do_carro(1)),subs(reta_ideal,x,pos_ideal(1))])
hold on;
plot(base_do_carro(1),subs(reta_carro,x,base_do_carro(1)),'*',frente_do_car
ro(1),subs(reta_ideal,x,frente_do_carro(1)),'*')
plot([base_do_carro(1) frente_do_carro(1)],
[subs(reta_carro,x,base_do_carro(1)),subs(reta_carro,x,frente_do_carro(1))]
)
end
fclose(s1);
delete(s1);
delete(vid); %fecha a conexo com o canal de vdeo.
imagem_id.m
%Filtra a imagem, subtrai as cores, e indica a imagem filtrada
%em preto e branco, evidenciando o objeto.
%vid = videoinput('winvideo',1);% abre a conexo com a camera de video
%A = getsnapshot(vid); % obtem um quadro do video (figura RGB)
%delete(vid)
[A, MAP1] =
figure(1)
imshow(A)
R = A(:, :,
G = A(:, :,
B = A(:, :,
imread('teste3.png');
1); % Matriz de tons vermelhos
2); % Matriz de tons verdes
3); % Matriz de tons azuis
R1=R-G-B;
G1=G-R-B;
B1=B-R-G;
%figure(2)
%imshow(R1)
CARRO = im2bw(R1, 0.1);%(imagem preto e branco 0 0u 1 mariz nxm)
%figure(3)
%imshow(I1)
%figure(4)
%imshow(G1)
BOLA = im2bw(G1, 0.1);%(imagem preto e branco 0 0u 1 mariz nxm)
%figure(5)
%imshow(I2)
%figure(6)
%imshow(B1)
GOL = im2bw(B1, 0.1);%(imagem preto e branco 0 0u 1 mariz nxm)
%figure(7)
%imshow(I3)
IT=CARRO+BOLA+GOL;
figure(8)
imshow(IT)
64
frente_do.m
%Esta funo recebe os 3 pontos do marcador do carro (tringulo issceles)
%e retorna o ponto que marca a frente do carro (ponto oposto ao menor lado
%do tringulo issceles).
function [frente]=frente_do(p_carro)
%Encontrando o ponto mais afastado da
L1=sqrt((p_carro(2,1)-p_carro(3,1))^2
%mdulo do lado oposto ao ponto p1
L2=sqrt((p_carro(1,1)-p_carro(3,1))^2
%mdulo do lado oposto ao ponto p2
L3=sqrt((p_carro(1,1)-p_carro(2,1))^2
%mdulo do lado oposto ao ponto p3
envia.m
%Esta funo envia dados para o arduino.
function envia(mod, ang)
s1 = serial('COM1');
fopen(s1);
fprint(s1,'%s',mod);
fprint(s1,'%s',ang);
end
encontre_reta.m
%Encontra a equao da reta que passa por 2 pontos
function [eq]=encontre_reta(p1, p2)
65
syms x;
syms y;
A=[x y 1; p1(1) p1(2) 1; p2(1) p2(2) 1];
eq=det(A);
symvar(y);
eq=solve(eq,y);
end
encontre_angulo.m
%Encontra o ngulo entre 2 retas. As variveis devero conter as funes de
%x "f(x)"
function [alpha]=encontre_angulo(reta_1, reta_2)
%m1 e m2 so coeficientes angulares das retas 1 e 2.
syms x;
m1=subs(reta_1,x,1)-subs(reta_1,x,0);
m2=subs(reta_2,x,1)-subs(reta_2,x,0);
alpha=atan(abs((m1-m2)/(1+m1*m2)));
end
corrigir.m
%Esta funo corrige caso diferentes mas muito prximos estejam
%representando o mesmo ponto no vetor. Recebe um vetor com 8 pontos e um
%raio de ao como argumentos. Caso dois pontos sejam encontrados no mesmo
%raio, eles sero substituidos pelo ponto mdio.
function [corrigido] = corrigir(pontos, raio)
%Ordenando os vetores tendo como critrio o primeiro nmero da linha
for k=1:1:7
for i=1:1:7
if pontos(i,1) > pontos(i+1,1);
aux=[pontos(i,1) pontos(i,2)];
pontos(i,1)=pontos(i+1,1);
pontos(i,2)=pontos(i+1,2);
pontos(i+1,1)=aux(1);
pontos(i+1,2)=aux(2);
end
end
end
for k=1:1:7
for i=1:1:7
%Verifica se os pontos esto dentro do raio de busca. Caso
estejam,
%os dois pontos so substituidos pelo valor medio e o valor do
%contador incrementado.
p1=[pontos(i,1); pontos(i,2)];
66
p2=[pontos(i+1,1); pontos(i+1,2)];
mod= sqrt((p2(1)-p1(1))^2+(p2(2)-p1(2))^2);
mod=floor(mod);
if
end
end
end
total_de_pontos=1;
pontos=round(pontos); %Arredonda para nmero inteiro mais prximo.
for i=1:1:7
%Verifica se existem apenas 3 pontos no vetor com oito.
if pontos (i,1) ~= pontos(i+1,1) || pontos (i,2) ~= pontos(i+1,2);
total_de_pontos=total_de_pontos+1;
end
end
if total_de_pontos > 3;
disp('****Erro na correo dos parmetros. Verificar o "raio" na
funo "corrigir"****')
end
corrigido=pontos;
captura.m
%Esta funo faz a leitura da cmera de vdeo e retorna as imagens em preto
%e branco aps aplicao de filtro de cores RGB. vid a varivel "canal"
%de vdeo, que dever ser passada como parmetro para a funo.
function [Img_Red Img_Green Img_Blue] = captura(vid, mat_max, mat_min)
A = getsnapshot(vid);
figure(1)
imshow(A)
%Mascara(:,:,1) representa a imagem do carro
%Mascara(:,:,2) representa a imagem da bola
%Mascara(:,:,3) representa a imagem do gol
Mascara=A(:,:,:)*0;
k=size(A);
x=1; %Limite superior de tolerncia
y=1; %Limite inferior de tolerncia
for i=1:1:3
for L=1:1:k(1,1)
67
for C=1:1:k(1,2)
if A(L,C,1)<mat_max(1,i)*x;
if A(L,C,1)>mat_min(1,i)*y;
if A(L,C,2)<mat_max(2,i)*x;
if A(L,C,2)>mat_min(2,i)*y;
if A(L,C,3)<mat_max(3,i)*x;
if A(L,C,3)>mat_min(3,i)*y;
Mascara(L,C,i)=A(L,C,i);
end
end
end
end
end
end
end
end
end
Img_Red
= im2bw(Mascara(:,:,1), 0.1);
Img_Green = im2bw(Mascara(:,:,2), 0.1);
Img_Blue = im2bw(Mascara(:,:,3), 0.1);
end
Calibra_Cores.m
[Modelo_Bola, MAP1] = imread('bola.png');
[Modelo_Carro, MAP2] = imread('carro.png');
[Modelo_Gol, MAP3] = imread('gol.png');
%Pegando os limites de intensidade dos modelos e organiza os dados em uma
%matriz de mximos e outra matriz de mnimos.
%
%
mat_max
|
mat_min
%
carro bola gol
|
carro bola gol
% r
x
x
x
| r
x
x
x
% g
x
x
x
| g
x
x
x
% b
x
x
x
| b
x
x
x
for i=1:1:3
mat_max(i,1)=max(max(Modelo_Carro(:,:,i)));
mat_min(i,1)=min(min(Modelo_Carro(:,:,i)));
mat_max(i,2)=max(max(Modelo_Bola(:,:,i)));
mat_min(i,2)=min(min(Modelo_Bola(:,:,i)));
mat_max(i,3)=max(max(Modelo_Gol(:,:,i)));
mat_min(i,3)=min(min(Modelo_Gol(:,:,i)));
end
68
base_do.m
%Esta funo recebe os 3 pontos do marcador do carro (tringulo issceles)
%e retorna o ponto que marca a base do carro. O ponto mdio entre os dois
pontos
%opostos a frente do carro.
function [base]=base_do(p_carro)
%Encontrando o ponto mais afastado da
L1=sqrt((p_carro(2,1)-p_carro(3,1))^2
%mdulo do lado oposto ao ponto p1
L2=sqrt((p_carro(1,1)-p_carro(3,1))^2
%mdulo do lado oposto ao ponto p2
L3=sqrt((p_carro(1,1)-p_carro(2,1))^2
%mdulo do lado oposto ao ponto p3
acha_erro.m
%Esta funo retorna o ngulo entre as retas formadas pela posio real do
%carrinho e a posio ideal do carrinho.