controle de um robô movel utilizando a tecnologia zigbee e a visão ...
controle de um robô movel utilizando a tecnologia zigbee e a visão ...
controle de um robô movel utilizando a tecnologia zigbee e a visão ...
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
UNIVERSIDADE FEDERAL DO ESPÍRITO SANTO<br />
CENTRO TECNOLÓGICO<br />
DEPARTAMENTO DE ENGENHARIA ELÉTRICA<br />
PROJETO DE GRADUAÇÃO<br />
CONTROLE DE UM ROBÔ MÓVEL<br />
UTILIZANDO A TECNOLOGIA ZIGBEE<br />
E A VISÃO COMPUTACIONAL<br />
HIGOR D' TALLES COSTA<br />
VITÓRIA – ES<br />
DEZEMBRO/2007
HIGOR D' TALLES COSTA<br />
CONTROLE DE UM ROBÔ MÓVEL<br />
UTILIZANDO A TECNOLOGIA ZIGBEE<br />
E A VISÃO COMPUTACIONAL<br />
Parte escrita do Projeto <strong>de</strong> Graduação do<br />
aluno Higor D' Talles Costa, apresentado<br />
ao Departamento <strong>de</strong> Engenharia Elétrica<br />
do Centro Tecnológico da Universida<strong>de</strong><br />
Fe<strong>de</strong>ral do Espírito Santo, para obtenção<br />
do grau <strong>de</strong> Engenheiro Eletricista.<br />
VITÓRIA – ES<br />
DEZEMBRO/2007
HIGOR D' TALLES COSTA<br />
CONTROLE DE UM ROBÔ MÓVEL<br />
UTILIZANDO A TECNOLOGIA ZIGBEE<br />
E A VISÃO COMPUTACIONAL<br />
COMISSÃO EXAMINADORA:<br />
________________________________________<br />
Prof a . Dr a . Raquel Frizera Vassallo<br />
Orientadora<br />
________________________________________<br />
Prof. Dr. Evandro Ottoni Teatini Salles<br />
Examinador<br />
________________________________________<br />
Prof a . Dr a . Eliete Maria <strong>de</strong> Oliveira Cal<strong>de</strong>ira<br />
Examinadora<br />
Vitória - ES, 21, Dezembro <strong>de</strong> 2007.
DEDICATÓRIA<br />
Aos meus pais, familiares e amigos, por toda a ajuda, incentivo e fé.<br />
i
AGRADECIMENTOS<br />
Agra<strong>de</strong>ço primeiramente a Deus por ter me dado a força, ânimo e<br />
discernimento para concluir este trabalho com êxito.<br />
Aos meus pais, David e Carolina, pelo incessante apoio e força. Gran<strong>de</strong>s<br />
incentivadores. Agra<strong>de</strong>ço pela fé e confiança <strong>de</strong>positadas em mim durante todo o<br />
curso <strong>de</strong> Engenharia Elétrica, e também durante o <strong>de</strong>senvolvimento <strong>de</strong>ste trabalho.<br />
Aos meus irmãos, Érico e Caroline, pelo apoio, fé e amiza<strong>de</strong>.<br />
À Prof a . Raquel Frizera Vassallo, orientadora <strong>de</strong>ste trabalho, pela atenção e<br />
disponibilida<strong>de</strong>. A proposta do trabalho foi bastante <strong>de</strong>safiadora e alinhada com meus<br />
interesses pessoais e profissionais. Não po<strong>de</strong>ria <strong>de</strong>ixar <strong>de</strong> agra<strong>de</strong>cê-la pelo incrível<br />
suporte e conhecimento técnico em Visão Computacional que foram amplamente<br />
aplicados neste trabalho. Por ela tenho enorme admiração, respeito e confiança.<br />
Ao Julio e ao Clebson, estudantes <strong>de</strong> Engenharia <strong>de</strong> Computação, que<br />
gentilmente ce<strong>de</strong>ram os códigos que serviram <strong>de</strong> base para a parte <strong>de</strong> Visão<br />
Computacional.<br />
Ao Christiano, aluno <strong>de</strong> Doutorado, por ter cedido o código do MSP430 que<br />
serviu <strong>de</strong> base para a aplicação <strong>de</strong>senvolvida para o robô.<br />
À Prof a . Carmen, responsável pelo Laboratório <strong>de</strong> Robótica Educacional, por<br />
ter gentilmente aberto as portas <strong>de</strong>sse laboratório para que eu trabalhasse na fase <strong>de</strong><br />
testes. Sem isso, certamente eu não teria atingido os resultados tão rapidamente.<br />
Ao Thierry, monitor do Laboratório <strong>de</strong> Robótica Educacional, pelo apoio,<br />
momentos <strong>de</strong> bate-papo e também pela curiosida<strong>de</strong>, pois isso me fez reavaliar alguns<br />
conceitos aplicados a este trabalho. Essas reflexões foram muito importante para a<br />
tomada <strong>de</strong> alg<strong>um</strong>as <strong>de</strong>cisões <strong>de</strong> projeto.<br />
Finalmente, a todos aqueles cujos nomes não mencionei, embora tenham tido<br />
sua importância em muitos momentos da minha vida acadêmica. Agra<strong>de</strong>ço também<br />
aos que contribuíram direta ou indiretamente para que este trabalho se tornasse<br />
possível.<br />
ii
LISTA DE FIGURAS<br />
1 - PLACA PRINCIPAL DO ROBÔ..................................................................................................................15<br />
2 - ESQUEMA DE LIGAÇÃO DA PLACA PRINCIPAL................................................................................16<br />
3 - ESQUEMA DE LIGAÇÃO DO PC À PLACA PRINCIPAL......................................................................16<br />
4 - CONJUNTO DE DESENVOLVIMENTO DA MAXSTREAM..................................................................19<br />
5 - ANÁLISE DE CONEXÃO COM O X-CTU................................................................................................20<br />
6 - TELA DE CONFIGURAÇÃO DA COMUNICAÇÃO SERIAL.................................................................21<br />
7 - TELA DE TESTES DO X-CTU....................................................................................................................21<br />
8 - TELA DE CONFIGURAÇÃO DO XBEE....................................................................................................22<br />
9 - SINTAXE PARA O MODO DE COMANDO AT.......................................................................................23<br />
10 - EXEMPLOS DE PROGRAMAÇÃO EM MODO DE COMANDO AT.....................................................23<br />
11 - PINAGEM DO MSP430F149.......................................................................................................................26<br />
12 - COMUNICAÇÃO SERIAL ENTRE XBEE E MICROCONTROLADOR.................................................27<br />
13 - ROBÔ E ALVO COM SUAS RESPECTIVAS CORES..............................................................................31<br />
14 - RECONHECIMENTO DE CORES..............................................................................................................31<br />
15 - REFERÊNCIAS DO SISTEMA ÓPTICO....................................................................................................32<br />
16 - FORMAÇÃO DA IMAGEM EM UMA CÂMERA PERSPECTIVA.........................................................35<br />
17 - MODELO DA CÂMERA PERSPECTIVA COM PROJEÇÃO DE PONTO..............................................36<br />
18 - RELAÇÃO DO ERRO COM A TAREFA A SER EXECUTADA..............................................................37<br />
19 - RESPOSTA IDEAL DO CONTROLADOR................................................................................................39<br />
20 - AMBIENTE DE TESTE...............................................................................................................................44<br />
21 - CORES SELECIONADAS COM O SISTEMA EM REPOUSO.................................................................49<br />
22 - CORES SELECIONADAS E RUÍDOS GERADOS COM O SISTEMA EM FUNCIONAMENTO.........49<br />
iii
LISTA DE TABELAS<br />
1 - CARACTERÍSTICAS DO PADRÃO 802.15.4..............................................................................................17<br />
2 - CARACTERÍSTICAS DO XBEE E DO XBEE PRO....................................................................................18<br />
3 - COMPARAÇÃO DE TEMPOS DE RESPOSTA ENTRE ZIGBEE E BLUETOOTH.................................18<br />
iv
GLOSSÁRIO<br />
BSL – BOOTSTRAP LOADER, UTILIZADO PARA PROGRAMAÇÃO DO MSP430.<br />
CAMSHIFT – CONTINUOUSLY ADAPTATIVE MEAN SHIFT. ROBUSTA TÉCNICA INTERATIVA E<br />
NÃO-PARAMÉTRICA PARA ENCONTRAR UM MODO DE DISTRIBUIÇÃO DE<br />
PROBABILIDADE.<br />
DCO – OSCILADOR CONTROLADO DIGITALMENTE.<br />
DI<br />
– DATA IN, PINO DE ENTRADA DE DADOS DO XBEE.<br />
DO – DATA OUT, PINO DE SAÍA DE DADOS DO XBEE.<br />
FRAME – É CADA QUADRO CAPTURADO PELA CÂMERA.<br />
HUE – CANAL DA MATIZ NO SISTEMA DE COR HSV.<br />
HSV – SISTEMA DE COR.<br />
MEAN SHIFT – ALGORÍTMO DE MULTIPROCESSAMENTO DE DADOS GERALMENTE UTILIZADO<br />
EM APLICAÇÕES DE VISÃO COMPUTACIONAL E PROCESSAMENTO DE IMAGENS.<br />
MSP430 – MICROCONTROLADOR FABRICADO PELA TEXAS INSTRUMENTS.<br />
OPENCV – BIBLIOTECA DE PROCESSAMENTO DE IMAGENS DESENVOLVIDA PELA INTEL.<br />
RISC – COMPUTADOR COM CONJUNTO REDUZIDO DE INSTRUÇÕES.<br />
WEBCAM – TIPO DE CÂMERA EM GERAL UTILIZADA EM COMPUTADORES E NÃO COSTUMA<br />
APRESENTAR ALTA QUALIDADE NA CAPTURA DE IMAGENS, ALÉM DE SER UM<br />
DISPOSITIVO QUE REALIZA AJUSTES AUTOMÁTICOS DA IMAGEM SEM A<br />
INTERVENÇÃO DO USUÁRIO.<br />
v
SUMÁRIO<br />
DEDICATÓRIA.........................................................................................................I<br />
AGRADECIMENTOS..............................................................................................II<br />
LISTA DE FIGURAS..............................................................................................III<br />
LISTA DE TABELA...............................................................................................IV<br />
GLOSSÁRIO.............................................................................................................V<br />
SUMÁRIO................................................................................................................VI<br />
RESUMO..............................................................................................................VIII<br />
1 INTRODUÇÃO.......................................................................................................9<br />
1.1 Motivação........................................................................................................9<br />
1.2 Trabalhos Similares.......................................................................................10<br />
1.3 Descrição e Objetivo do Projeto....................................................................11<br />
2 HARDWARE DO SISTEMA...............................................................................14<br />
2.1 Introdução......................................................................................................14<br />
2.2 Placa Principal do Robô.................................................................................14<br />
2.3 Tecnologia ZigBee.........................................................................................17<br />
2.3.1 XBee e suas Características..................................................................17<br />
2.3.2 Programa <strong>de</strong> Configuração e Testes.....................................................19<br />
2.3.3 Métodos <strong>de</strong> Programação.....................................................................22<br />
2.4 O Microcontrolador MSP430.........................................................................24<br />
2.4.1 Principais Características do Microcontrolador....................................25<br />
2.4.2 O Programa do MSP430.......................................................................26<br />
2.5 Conexão do XBee com o MSP430.................................................................27<br />
vi
3 PROCESSAMENTO DE IMAGENS .................................................................29<br />
3.1 Introdução......................................................................................................29<br />
3.2 Técnica Utilizada...........................................................................................29<br />
3.3 Consi<strong>de</strong>rações Iniciais <strong>de</strong> Projeto..................................................................32<br />
3.3.1 Mo<strong>de</strong>lagem Matemática do Sistema Óptico.........................................33<br />
3.3.1 Sistema <strong>de</strong> Orientação..........................................................................39<br />
3.4 Captura e Processamento da Imagem.............................................................40<br />
4 SISTEMA COMPLETO E TAREFA PROPOSTA...........................................42<br />
4.1 Introdução......................................................................................................42<br />
4.2 Montagem do Sistema e Detalhes <strong>de</strong> Funcionamento....................................42<br />
4.3 Tarefa Proposta..............................................................................................44<br />
5 EXPERIMENTO...................................................................................................46<br />
5.1 Introdução......................................................................................................46<br />
5.2 Teste e Análise dos Resultados......................................................................46<br />
6 CONCLUSÃO.......................................................................................................50<br />
6.1 Trabalhos Futuros..........................................................................................51<br />
APÊNDICE A...........................................................................................................52<br />
APÊNDICE B...........................................................................................................57<br />
REFERÊNCIAS BIBLIOGRÁFICAS...................................................................78<br />
vii
RESUMO<br />
Este trabalho aborda a criação <strong>de</strong> <strong>um</strong> sistema <strong>de</strong> <strong>controle</strong> <strong>de</strong> robôs móveis<br />
<strong>utilizando</strong>-se para isso técnicas <strong>de</strong> visão computacional e recursos <strong>de</strong> comunicação<br />
sem fio providos pelo dispositivo XBee que implementa a <strong>tecnologia</strong> ZigBee. O robô<br />
foi também equipado com <strong>um</strong>a placa <strong>de</strong> <strong>controle</strong> com <strong>um</strong> microcontrolador MSP430,<br />
da Texas Instr<strong>um</strong>ents. A tarefa principal <strong>de</strong>ste trabalho visa a movimentação <strong>de</strong> <strong>um</strong><br />
robô em <strong>um</strong> ambiente <strong>utilizando</strong>-se realimentação por imagem e troca <strong>de</strong> informações<br />
à distância. Para isso, foi utilizada <strong>um</strong>a câmera com inclinação e altura conhecidas. A<br />
câmera foi direcionada para o ambiente em que o robô executaria a tarefa, e a<br />
geometria projetiva da cena foi usada para <strong>de</strong>finir o <strong>controle</strong>. O robô e o ponto <strong>de</strong>stino<br />
foram marcados com <strong>um</strong>a indicação colorida para permitir o seguimento <strong>de</strong> cor<br />
durante a movimentação do robô. Com o auxílio <strong>de</strong> alg<strong>um</strong>as relações matemáticas<br />
po<strong>de</strong>-se calcular as velocida<strong>de</strong>s linear e angular <strong>de</strong> tempos em tempos a fim <strong>de</strong><br />
atualizar as velocida<strong>de</strong>s <strong>de</strong> cada roda do robô para que este atingisse o objetivo<br />
proposto.<br />
viii
9<br />
1 INTRODUÇÃO<br />
1.1 Motivação<br />
Muitos trabalhos têm sido <strong>de</strong>senvolvidos para que as habilida<strong>de</strong>s <strong>de</strong> robôs<br />
sejam aperfeiçoadas e ampliadas. Existem robôs para executar tarefas perigosas, como<br />
é o caso <strong>de</strong> trabalhos realizados nas proximida<strong>de</strong>s <strong>de</strong> vulcões em ativida<strong>de</strong>, e robôs<br />
para executar tarefas do dia-a-dia, como é o caso <strong>de</strong> robôs projetados para cuidar <strong>de</strong><br />
crianças e até mesmo para brincar. Esses robôs especializados, e com sensoriamento<br />
variado envolvendo técnicas avançadas tanto <strong>de</strong> eletrônica quanto <strong>de</strong> computação, são<br />
capazes <strong>de</strong> agir sozinhos <strong>de</strong>scobrindo ambientes, apren<strong>de</strong>ndo e até mesmo tomando<br />
<strong>de</strong>cisões.<br />
Mesmo com as diversas possibilida<strong>de</strong>s que as <strong>tecnologia</strong>s atuais permitem,<br />
muitas vezes não é viável utilizar robôs tão avançados em tarefas nem sempre tão<br />
complicadas. Devido a isso, o <strong>de</strong>senvolvimento <strong>de</strong> robôs mais simples, capazes <strong>de</strong> agir<br />
em grupo, tem sido cada vez mais freqüente para aplicações que envolvem diversos<br />
módulos trabalhando em conjunto para atingir <strong>um</strong> objetivo [1, 2]. Esta alternativa<br />
oferece vantagens potenciais em termos <strong>de</strong> flexibilida<strong>de</strong> <strong>de</strong> funcionamento [3, 4].<br />
Existem diversas aplicações em que essa metodologia faz-se necessária, como é o caso<br />
<strong>de</strong> linhas <strong>de</strong> montagem e outras tarefas que exigem o trabalho em equipe, tal como<br />
ocorre com seres h<strong>um</strong>anos.<br />
Alguns trabalhos envolvendo cooperação não só são <strong>de</strong>senvolvidos para que os<br />
componentes do grupo hajam em conjunto, mas também visam o compartilhamento <strong>de</strong><br />
recursos tais como câmeras, dados <strong>de</strong> posicionamento, etc [7]. Esse tipo <strong>de</strong> cooperação<br />
é baseada no comportamento h<strong>um</strong>ano, on<strong>de</strong> nem todos os membros <strong>de</strong> <strong>um</strong>a equipe têm<br />
as mesmas habilida<strong>de</strong>s, embora possam suprir suas necessida<strong>de</strong>s buscando recursos<br />
em outros componentes do grupo.<br />
A visão computacinal po<strong>de</strong> ser aplicada a diversas situações. Hoje em dia tem<br />
sido cada vez mais difundidas aplicações <strong>de</strong>senvolvidas para ambientes inteligentes.<br />
Em geral, aplicações como essas consi<strong>de</strong>ram vários pontos fixos para a observação da
10<br />
cena. No entanto, em alguns casos, as câmeras se movem a fim <strong>de</strong> acompanhar os<br />
objetos a serem seguidos no ambiente.<br />
No que diz respeito a trabalhos <strong>de</strong>senvolvidos por times <strong>de</strong> robôs, em alguns<br />
casos, po<strong>de</strong>-se ter <strong>um</strong> observador da cena que controla os <strong>de</strong>mais membros da equipe<br />
na execução <strong>de</strong> tarefas. Esse papel po<strong>de</strong> ser feito por <strong>um</strong> robô lí<strong>de</strong>r, que também se<br />
locomove no ambiente, ou mesmo por <strong>um</strong> observador fixo. Esse trabalho procura<br />
explorar este fato <strong>utilizando</strong>-se <strong>de</strong> <strong>um</strong> observador fixo para fazer o <strong>controle</strong> <strong>de</strong> <strong>um</strong><br />
robô observado que se locomove no ambiente. Além disso, nessas aplicações é preciso<br />
ter <strong>um</strong> sistema <strong>de</strong> comunicação, que neste caso, isso é feito <strong>utilizando</strong>-se a <strong>tecnologia</strong><br />
ZigBee.<br />
1.2 Trabalhos Similares<br />
Muitos trabalhos já foram <strong>de</strong>senvolvidos a respeito <strong>de</strong> cooperação <strong>de</strong> robôs. As<br />
aplicações mais comuns envolvem robôs que executam tarefas como empurrar caixas,<br />
carregar objetos, realizar formações específicas e agir em sincronia [1, 2, 5].<br />
Em geral, <strong>um</strong> dos meios <strong>de</strong> comunicação mais utilizados é a porta serial, padrão<br />
RS-232, em que as partes se conectam por meio <strong>de</strong> fios sendo <strong>um</strong> para envio <strong>de</strong> dados,<br />
TX, e outro para recebimento, RX. Esse tipo <strong>de</strong> comunicação funciona bem em<br />
sistemas em que o robô tem movimentos bastante limitados ou mesmo em sistemas<br />
articulados com base estática.<br />
Em adição ao sistema <strong>de</strong> comunicação, muitos projetos contam também com o<br />
processamento <strong>de</strong> imagem a fim <strong>de</strong> localizar texturas e objetos no ambiente. Essas<br />
informações são úteis para que o robô consiga se locomover no ambiente e também<br />
para que a tarefa a ser executada seja bem sucedida, pois leva em consi<strong>de</strong>ração<br />
marcações existentes ou propositalmente inseridas no ambiente. Alguns trabalhos<br />
utilizam imagens omnidirecionais [6] enquanto outros utilizam imagens projetivas [8].<br />
Depen<strong>de</strong>ndo do tipo <strong>de</strong> imagem capturada pela câmera, a complexida<strong>de</strong> do problema<br />
po<strong>de</strong> ser a<strong>um</strong>entada ou diminuída significativamente. Imagens omnidirecionais<br />
envolvem complexida<strong>de</strong>s maiores e po<strong>de</strong>m gerar problemas ou imprecisões <strong>de</strong> acordo
11<br />
com tamanho do objeto a ser <strong>de</strong>tectado. Ainda assim, com esse sistema po<strong>de</strong>-se<br />
movimentar o robô levando-o a qualquer ponto visível da imagem [14]. Este tipo <strong>de</strong><br />
imagem tem aplicações mais interessantes quando a câmera é embarcada em sistemas<br />
móveis. Por outro lado, imagens projetivas envolvem complexida<strong>de</strong>s menores e são<br />
mais indicadas para sistemas em que a câmera permanece parada enquanto os robôs se<br />
movimentam em seu campo <strong>de</strong> visão.<br />
Para o caso <strong>de</strong> robôs cooperativos tal como é proposto em [14], é interessante<br />
que os componentes do grupo consigam se comunicar sem a necessida<strong>de</strong> <strong>de</strong> fios e<br />
<strong>de</strong>vido a isso, faz-se necessária a comunicação por <strong>um</strong> meio seguro, veloz e com alta<br />
capacida<strong>de</strong> <strong>de</strong> adição <strong>de</strong> nós ao sistema. A utilização do XBee garante ao sistema toda<br />
a flexibilida<strong>de</strong> e in<strong>de</strong>pendência necessárias para que os robôs se locomovam<br />
livremente ao executar as tarefas.<br />
1.3 Descrição e Objetivo do Projeto<br />
Sistemas como os anteriormente apresentados po<strong>de</strong>m se tornar ainda mais<br />
interessantes quando combinados com módulos <strong>de</strong> comunicação sem fio. Isso confere<br />
maior autonomia aos robôs, já que não estariam sujeitos a limitações impostas por<br />
cabos tais como altos custos <strong>de</strong> instalação, necessida<strong>de</strong> <strong>de</strong> espaço físico a<strong>de</strong>quado, e<br />
também perda <strong>de</strong> informações <strong>de</strong>vido às características intrínsecas do cabo. No<br />
entanto, perdas também po<strong>de</strong>m ocorrer <strong>utilizando</strong>-se comunicação sem fio, mas <strong>de</strong>vido<br />
à facilida<strong>de</strong> <strong>de</strong> instalação estas po<strong>de</strong>m ser minimizadas <strong>utilizando</strong>-se algoritmos<br />
corretores <strong>de</strong> erros. Po<strong>de</strong>-se também utilizar sistemas <strong>de</strong> comunicação multi-rota. Este<br />
tipo <strong>de</strong> sistema po<strong>de</strong> reduzir sensivelmente a ocorrência <strong>de</strong> falhas <strong>de</strong> comunicação.<br />
Para visão computacional, utiliza-se imagens projetivas <strong>de</strong>vido à simplicida<strong>de</strong><br />
<strong>de</strong> processamento quando comparado ao processamento <strong>de</strong> imagens omnidirecionais.<br />
Os robôs são equipados com a placa <strong>de</strong> <strong>controle</strong> criada no projeto [9] e esta tem<br />
como controlador principal o microcontrolador MSP430F149 da Texas Instr<strong>um</strong>ents<br />
(TI). Essa placa conta com diversos módulos funcionais tais como Ponte H, interface<br />
J-Tag, interface <strong>de</strong> programação serial para o programador BSL (BootStrap Loa<strong>de</strong>r),
12<br />
interface <strong>de</strong> <strong>controle</strong> via comunicação serial, entre outros que serão <strong>de</strong>talhados em<br />
outros itens.<br />
Cada robô conta também com <strong>um</strong>a placa <strong>de</strong> <strong>de</strong>senvolvimento contendo <strong>um</strong><br />
módulo <strong>de</strong> comunicação sem fio da <strong>tecnologia</strong> ZigBee. O módulo utilizado foi o XBee<br />
do fabricante MaxStream. Esse módulo possui diversas características a<strong>de</strong>quadas a<br />
operações seguras <strong>de</strong> re<strong>de</strong>s e também <strong>um</strong>a capacida<strong>de</strong> bastante elevada <strong>de</strong><br />
en<strong>de</strong>reçamento <strong>de</strong> nós <strong>de</strong> re<strong>de</strong>. Além disso, trata-se <strong>de</strong> <strong>um</strong> dispositivo com <strong>um</strong><br />
cons<strong>um</strong>o <strong>de</strong> energia extremamente baixo e capaz <strong>de</strong> trabalhar com distâncias bastante<br />
elevadas, cerca <strong>de</strong> 100 metros sem antenas especiais. Este sistema apresenta boas<br />
características <strong>de</strong> transmissão operando na faixa <strong>de</strong> freqüência <strong>de</strong> 2.4 GHz, no Brasil.<br />
Para auxiliar a movimentação dos robô no ambiente, o sistema é também<br />
equipado com <strong>um</strong>a câmera para captura das imagens que serão processadas. Para isso,<br />
é instalada <strong>um</strong>a câmera no ambiente <strong>de</strong> testes e com as imagens capturadas é possível<br />
seguir os robô e movê-lo para os pontos <strong>de</strong> interesse <strong>de</strong>finidos <strong>de</strong> acordo com a tarefa<br />
a ser executada. A biblioteca <strong>de</strong> processamento <strong>de</strong> imagens utilizada neste trabalho é<br />
<strong>de</strong>senvolvida pela Intel e tem código fonte aberto. Ela é chamada OpenCV e possui<br />
diversas funções que tornam mais fácil a <strong>de</strong>tecção e o seguimento <strong>de</strong> cor, tal como é<br />
feito neste trabalho. A versão utilizada é a 1.0.<br />
O robô utilizado neste trabalho é construído em acrílico e utiliza a placa <strong>de</strong><br />
circuito <strong>de</strong>senvolvida em [9]. Suas dimensões são <strong>de</strong> aproximadamente 10x15 cm.<br />
Possui 3 rodas, tração diferencial, e para controlá-lo são enviadas as velocida<strong>de</strong>s<br />
linear, v, e angular, ω, para a porta serial da placa embarcada que controla suas<br />
funções. Internamente, no programa do MSP430, essas velocida<strong>de</strong>s são utilizadas para<br />
compor as velocida<strong>de</strong>s das rodas esquerda e direita. O robô é alimentado por <strong>um</strong>a<br />
bateria <strong>de</strong> ch<strong>um</strong>bo a <strong>um</strong>a tensão <strong>de</strong> 14 volts. A tensão <strong>de</strong> alimentação se sua placa<br />
principal é <strong>de</strong> 9 volts, conseguidos com <strong>um</strong> regulador <strong>de</strong> tensão.<br />
Com tudo <strong>de</strong>vidamente ajustado, é então possível a realização <strong>de</strong> testes. O<br />
principal objetivo <strong>de</strong>ste trabalho é fazer com que <strong>um</strong> robô marcado com duas cores <strong>de</strong><br />
i<strong>de</strong>ntificação, <strong>um</strong>a na parte traseira e outra na dianteira, partindo <strong>de</strong> <strong>um</strong>a orientação<br />
qualquer no plano <strong>de</strong> execução da tarefa, consiga chegar ao ponto marcado como
13<br />
<strong>de</strong>stino, e marcado com <strong>um</strong>a terceira cor. A tarefa é realizada tendo-se como base o<br />
seguimento <strong>de</strong> cor <strong>de</strong>senvolvido com funções da biblioteca OpenCV. Toda a<br />
comunicação é feita do ponto fixo para o robô, isto é, o robô não envia informações.
14<br />
2 HARDWARE DO SISTEMA<br />
2.1 Introdução<br />
A placa <strong>de</strong> circuito principal, que controla as funções do robô foi concebida no<br />
projeto [9]. Apesar <strong>de</strong> ser composta por diversos módulos funcionais, apenas alguns<br />
são relevantes a este projeto. Dentre eles, os principais são:<br />
➢<br />
➢<br />
interface <strong>de</strong> programação via porta serial;<br />
interface <strong>de</strong> <strong>controle</strong> via porta serial;<br />
➢ ponte H.<br />
A placa <strong>de</strong>scrita acima é conectada ao módulo <strong>de</strong> Rádio Freqüência (RF),<br />
XBee, e este é conectado ao MSP430 via porta serial. O módulo RF apresenta muitas<br />
facilida<strong>de</strong>s em relação à comunicação, já que, <strong>um</strong>a vez ajustado, a comunicação é feita<br />
<strong>de</strong> modo transparente e <strong>de</strong>scomplicado. As características <strong>de</strong>sse transceptor po<strong>de</strong>m ser<br />
vistas em [12], no entanto, alg<strong>um</strong>as das suas principais características relevantes a este<br />
projeto são:<br />
➢<br />
➢<br />
➢<br />
operação na freqüência não-licenciada <strong>de</strong> 2.4 GHz;<br />
taxas <strong>de</strong> transmissão relativamente altas quando comparadas a <strong>tecnologia</strong>s<br />
como bluetooth e WiFi;<br />
baixo cons<strong>um</strong>o.<br />
Os <strong>de</strong>talhes funcionais dos circuitos citados, bem como as ligações entre os<br />
módulos e os ajustes necessários para que tudo funcione conforme esperado, são<br />
<strong>de</strong>scritos nos próximos itens.<br />
2.2 Placa Principal do Robô<br />
A placa principal do robô foi <strong>de</strong>senvolvida no projeto [9]. Essa é a placa <strong>de</strong><br />
<strong>controle</strong> do robô e tem como controlador <strong>de</strong> funções o microcontrolador<br />
MSP430F149.
15<br />
Dentre os circuitos funcionais <strong>de</strong>ssa placa, po<strong>de</strong>-se <strong>de</strong>stacar aqueles que são<br />
essenciais para este projeto e que já foram citados acima. Alguns módulos não são<br />
utilizados ou porque não são úteis a este projeto ou porque não foram <strong>de</strong>vidamente<br />
testados e por isso seu uso não foi consi<strong>de</strong>rado, como é o caso do circuito responsável<br />
pela interface J-Tag do MSP430. A placa citada po<strong>de</strong> ser vista na Figura 1 com seus<br />
principais circuitos em <strong>de</strong>staque.<br />
Figura 1: Placa principal do robô.<br />
Devido ao fato <strong>de</strong>ssa placa ainda não contar com <strong>um</strong> manual <strong>de</strong> utilização, fazse<br />
necessário o <strong>de</strong>talhamento do cabo <strong>de</strong> comunicação serial, e também <strong>de</strong> alg<strong>um</strong>as<br />
configurações relativas a pinagem das partes em <strong>de</strong>staque da figura acima. Na Figura<br />
2, po<strong>de</strong>-se ver os <strong>de</strong>talhes necessários da pinagem para que as ligações sejam<br />
realizadas <strong>de</strong> maneira correta. Na Figura 3, po<strong>de</strong>-se ver a configuração do cabo<br />
utilizado para gravação do MSP430 e também para o <strong>controle</strong> da placa.
16<br />
Figura 2: Esquema <strong>de</strong> ligação da placa principal.<br />
Figura 3: Esquema <strong>de</strong> ligação do PC à placa principal.
17<br />
2.3 Tecnologia ZigBee<br />
Hoje em dia tem sido cada vez mais com<strong>um</strong> a busca por técnicas <strong>de</strong> transmissão<br />
<strong>de</strong> dados sem fios. Diversos padrões já foram concebidos e aten<strong>de</strong>m hoje a quase todas<br />
as necessida<strong>de</strong>s tanto <strong>de</strong> clientes resi<strong>de</strong>nciais quando industriais. No entanto, <strong>um</strong><br />
<strong>de</strong>sses padrões, o ZigBee, merece especial <strong>de</strong>staque por suas características. Este<br />
padrão foi criado pela ZigBee Alliance com o intuito <strong>de</strong> prover comunicação sem fio<br />
<strong>de</strong> modo confiável, com baixo cons<strong>um</strong>o e com taxas razoáveis <strong>de</strong> transmissão para<br />
monitoramento e <strong>controle</strong>, além <strong>de</strong> ser <strong>um</strong>a <strong>tecnologia</strong> aberta.<br />
Este padrão possui elevada capacida<strong>de</strong> <strong>de</strong> en<strong>de</strong>reçamento <strong>de</strong> pontos <strong>de</strong> re<strong>de</strong><br />
trabalhando em faixas <strong>de</strong> freqüências abertas e cons<strong>um</strong>indo pouquíssima potência,<br />
tanto em modo <strong>de</strong> operação normal quanto em modo standby. O padrão ZigBee, IEEE<br />
802.15.4, foi homologado em maio <strong>de</strong> 2003. Este padrão tem como foco aplicações <strong>de</strong><br />
rádio freqüência que requerem baixas taxas <strong>de</strong> transmissão <strong>de</strong> dados, baixo cons<strong>um</strong>o<br />
<strong>de</strong> potência e re<strong>de</strong> segura. Este projeto utiliza <strong>um</strong> circuito chamado XBee. Este<br />
circuito utiliza-se <strong>de</strong>ssa <strong>tecnologia</strong> e é <strong>de</strong>senvolvido pela MaxStream.<br />
2.3.1 XBee e suas Características<br />
Como já foi citado, o padrão ZigBee apresenta muitas características<br />
interessantes as quais o tornam muito superior em relação ao padrão Bluetooth, IEEE<br />
802.15.1. Para mais <strong>de</strong>talhes e comparações entre os dois padrões vi<strong>de</strong> [13].<br />
Nas Tabelas 1, 2 e 3, seguem alg<strong>um</strong>as características importantes encontradas<br />
no padrão ZigBee e, em particular, nos dispositivos XBee e XBee Pro [12].<br />
Padrão Freqüências Nº <strong>de</strong> canais Técnica <strong>de</strong> Modulação Taxa <strong>de</strong> dados<br />
802.15.4<br />
2.4 - 2.4835 GHz 16 (11 a 26) DSSS 1 , O-QPSK 250 kbit/s<br />
868 - 870 MHz 1 (0) DSSS, BPSK 20 kbit/s<br />
902 - 928 MHz 10 (1 a 10) DSSS, BPSK 40 kbit/s<br />
Tabela 1: Características do ZigBee, padrão 802.15.4.<br />
1<br />
DSSS (Direct Sequence Spread Spectr<strong>um</strong>), Espalhamento Espectral por Seqüência Direta.
XBee<br />
XBee Pro<br />
Item Características Item Características<br />
Ambiente interno / Urbano 30 m Ambiente interno / Urbano 100 m<br />
Ambiente externo com visada Até 100 m<br />
Ambiente externo com visada Até 1500 m<br />
Potência <strong>de</strong> transmissão 1 mW (0 dBm) Potência <strong>de</strong> transmissão 100 mW (20 dBm) EIRP<br />
Sensibilida<strong>de</strong> <strong>de</strong> transmissão -92 dBm Sensibilida<strong>de</strong> <strong>de</strong> transmissão - 100 dBm<br />
Corrente TX 45 mA (@ 3.3 V) Corrente TX 270 mA (@ 3.3 V)<br />
Corrente RX 50 mA (@ 3.3 V) Corrente RX 55 mA (@ 3.3 V)<br />
Corrente em baixa potência < 10 μA Corrente em baixa potência < 10 μA<br />
Antena acoplada <strong>de</strong> fio - Antena RPSMA 2.4 GHz, 2.1 dBi<br />
Tabela 2: Características do XBee e do XBee Pro.<br />
18<br />
Item<br />
Tempo <strong>de</strong> Resposta<br />
ZigBee<br />
Tempo <strong>de</strong> acesso a re<strong>de</strong> 30 ms 3 s<br />
Tempo <strong>de</strong> transição dos dispositivos escravos dos<br />
estado dormindo para o estado ativo<br />
15 ms 3 s<br />
Bluetooth<br />
Tempo <strong>de</strong> acesso ao canal 15 ms 2 ms<br />
Tabela 3: Comparação <strong>de</strong> tempos <strong>de</strong> resposta entre ZigBee e Bluetooth.<br />
O ZigBee foi concebido para operar em faixas <strong>de</strong> freqüências livres. Na Europa,<br />
a operação é feita em 868 MHz, nos Estados Unidos, em 915 MHz, e em muitas outras<br />
regiões do planeta, incluindo o Brasil, a operação é feita em 2.4 GHz.<br />
A Tabela 1 mostra alg<strong>um</strong>as características <strong>de</strong>pen<strong>de</strong>ntes da freqüência <strong>de</strong><br />
operação. Nessa tabela, po<strong>de</strong>-se ver a relação da freqüência com o números <strong>de</strong> canais<br />
<strong>de</strong> comunicação, técnica <strong>de</strong> modulação suportada bem como as taxas <strong>de</strong> transmissão<br />
que po<strong>de</strong>m ser alcançadas.<br />
Na Tabela 2 po<strong>de</strong>m ser vistas as principais características dos mo<strong>de</strong>los XBee e<br />
do XBee Pro. Como po<strong>de</strong> ser notado, a relação entre distância, potência e taxa <strong>de</strong><br />
transmissão faz do padrão ZigBee <strong>um</strong>a ótima escolha para sistemas <strong>de</strong> monitoramento<br />
remoto, visto que, <strong>um</strong>a simples bateria AA po<strong>de</strong> manter <strong>um</strong> sistema em funcionamento<br />
por milhares <strong>de</strong> horas. A gran<strong>de</strong> eficiência energética do sistema é possível graças a<br />
<strong>um</strong> amplo conjunto <strong>de</strong> comandos capaz <strong>de</strong> colocar e dispositivo em modo <strong>de</strong><br />
economia, fazer medição <strong>de</strong> bateria, nível <strong>de</strong> sinal, entre outros. Com isso, <strong>de</strong>s<strong>de</strong> que o<br />
projeto seja bem <strong>de</strong>senvolvido po<strong>de</strong>-se aproveitar ao máximo suas características.
19<br />
A Tabela 3 mostra informações importantes à respeito <strong>de</strong> tempos <strong>de</strong> resposta.<br />
Para fins <strong>de</strong> comparação, nessa mesma tabela encontram-se os tempos <strong>de</strong> resposta<br />
típicos para o padrão Bluetooth. O ZigBee é superado apenas no tempo <strong>de</strong> acesso ao<br />
canal, mas nos outros dois itens listados sua resposta é muito mais rápida.<br />
A Figura 4 mostra o conjunto <strong>de</strong> <strong>de</strong>senvolvimento da MaxStream utilizado<br />
neste projeto e também os dois chips citados acima.<br />
Figura 4: Conjunto <strong>de</strong> <strong>de</strong>senvolvimento da MaxStream.<br />
2.3.2 Programa <strong>de</strong> Configuração e Testes<br />
No conjunto <strong>de</strong> <strong>de</strong>senvolvimento da MaxStream po<strong>de</strong>-se encontrar também <strong>um</strong><br />
aplicativo chamado X-CTU. Esse aplicativo é utilizado para configurar as<br />
características <strong>de</strong> funcionamento do XBee e também para testar a transmissão e o<br />
recebimento <strong>de</strong> dados. Alg<strong>um</strong>as das principais características <strong>de</strong>sse programa estão<br />
listadas abaixo:<br />
➢<br />
➢<br />
➢<br />
➢<br />
facilida<strong>de</strong> <strong>de</strong> uso em testes <strong>de</strong> loopback a distância;<br />
mostra <strong>um</strong> Indicador <strong>de</strong> Potência do Sinal Recebido (RSSI);<br />
atualização <strong>de</strong> firmware do XBee;<br />
automaticamente <strong>de</strong>tecta o tipo <strong>de</strong> módulo;
➢<br />
➢<br />
20<br />
restaura parâmetros <strong>de</strong> fábrica;<br />
integra-se ao LabView e outras ferramentas <strong>de</strong> teste.<br />
Este aplicativo é muito importante e graças a ele é possível avaliar a intensida<strong>de</strong><br />
do sinal recebido e então criar gráficos e estudos assim como feito em [13]. A Figura 5<br />
abaixo mostra <strong>um</strong>a maneira típica <strong>de</strong> se utilizar o X-CTU em <strong>um</strong> teste <strong>de</strong> loopback.<br />
Figura 5: Análise <strong>de</strong> conexão com o X-CTU.<br />
As Figuras 6 e 7 mostram a tela <strong>de</strong> configuração da comunicação serial e a tela<br />
<strong>de</strong> testes. Na tela <strong>de</strong> configuração, Figura 6, é possível fazer ajustes <strong>de</strong> velocida<strong>de</strong> <strong>de</strong><br />
comunicação, bits <strong>de</strong> parida<strong>de</strong>, entre outros. As configurações utilizadas para este<br />
trabalho po<strong>de</strong>m ser vistas nessa figura. Na tela <strong>de</strong> testes, Figura 7, é mostrada a barra<br />
indicativa da potência do sinal recebido pelo módulo XBee conectado ao computador.<br />
Nesse caso, o transmissor que está conectado ao computador envia o sinal a <strong>um</strong> outro<br />
módulo XBee equipado com <strong>um</strong> conector <strong>de</strong> loopback, e com isso, o sinal volta ao<br />
transmissor e po<strong>de</strong>-se então saber quantos pacotes enviados foram recebidos <strong>de</strong> volta,<br />
e po<strong>de</strong>-se também medir a intensida<strong>de</strong> do sinal entre os módulos <strong>de</strong> comunicação.
21<br />
Figura 6: Tela <strong>de</strong> configuração da comunicação serial.<br />
Figura 7: Tela <strong>de</strong> testes do X-CTU.
22<br />
Na Figura 8, é mostrada a tela <strong>de</strong> configuração do circuito integrado do XBee.<br />
Nesse janela é possível acessar todas as informações do módulo, mudar parâmetros e<br />
até mesmo atualizar o firmware. Caso sejam feitas configurações ina<strong>de</strong>quadas, é<br />
possível também ajustar o dispositivo com os parâmetros originais <strong>de</strong> fábrica.<br />
Figura 8: Tela <strong>de</strong> configuração do XBee.<br />
2.3.3 Métodos <strong>de</strong> Programação<br />
Para modificar parâmetros do módulo RF tais como taxa <strong>de</strong> transmissão, modo<br />
<strong>de</strong> comunicação (broadcast ou ponto-a-ponto), atualização <strong>de</strong> firmware entre outros,<br />
primeiro é necessário colocá-lo em Modo <strong>de</strong> Comando. Po<strong>de</strong>-se fazer isso pelo<br />
programa X-CTU <strong>utilizando</strong>-se o modo Terminal ou mesmo selecionando-se<br />
diretamente os campos que se <strong>de</strong>seja alterar. O Modo <strong>de</strong> Comando é <strong>um</strong> estado em que<br />
todos os caracteres recebidos são interpretados como comandos e não como dados.<br />
Com isso, as informações recebidas servem para alterar diretamente os campos <strong>de</strong><br />
configuração do dispositivo. Há atualmente duas maneiras <strong>de</strong> se programar os módulos<br />
da MaxStream, a primeira é chamada Modo <strong>de</strong> Comando AT e a segunda, Modo <strong>de</strong><br />
Comando API. A maneira mais simples <strong>de</strong> se alterar os parâmetros é pelo Modo <strong>de</strong><br />
Comando AT, já que é mais simplificado e mais direto quando comparado ao outro<br />
modo. Devido a isso, o Modo <strong>de</strong> Comando API não é <strong>de</strong>talhado neste trabalho.<br />
Para entrar em Modo <strong>de</strong> Comando AT, <strong>de</strong>ve-se selecionar a aba “Terminal” do<br />
aplicativo X-CTU. Feito isso, para começar o modo <strong>de</strong> comando basta enviar à porta
23<br />
serial do XBee a seqüência <strong>de</strong> caracteres “+++”, sem as aspas, e em seguida po<strong>de</strong>-se<br />
enviar qualquer comando válido.<br />
No caso <strong>de</strong> envio <strong>de</strong> comandos para o XBee enquanto ele está em modo <strong>de</strong><br />
operação, po<strong>de</strong>-se fazer necessário o envio do comando CT (Command Mo<strong>de</strong><br />
Timeout), que informa ao XBee quanto tempo o módulo <strong>de</strong>verá aguardar por <strong>um</strong><br />
comando até que saia automaticamente do modo <strong>de</strong> comando. Caso isso aconteça, o<br />
módulo retorna automaticamente ao modo <strong>de</strong> operação. Após configurado o CT, os<br />
comandos <strong>de</strong> configuração po<strong>de</strong>m ser enviados pelo usuário. Apesar <strong>de</strong> o módulo<br />
po<strong>de</strong>r sair automaticamente do Modo <strong>de</strong> Programação é possível sair explicitamente<br />
enviando o comando CN (Exit command mo<strong>de</strong>).<br />
A sintaxe dos comandos bem como <strong>um</strong> exemplo <strong>de</strong> programação no Modo <strong>de</strong><br />
Comando AT po<strong>de</strong>m ser vistos nas Figuras 9 e 10, respectivamente.<br />
Figura 9: Sintaxe para o Modo <strong>de</strong> Comando AT.<br />
Figura 10: Exemplos <strong>de</strong> programação em Modo <strong>de</strong> Comando AT.<br />
Os modos <strong>de</strong> comando citados possibilitam a mudança dinâmica dos parâmetros<br />
do dispositivo XBee. Dentre os comandos que po<strong>de</strong>m ser aplicados ao dispositivo,
24<br />
po<strong>de</strong>-se citar alguns <strong>de</strong> extrema importância ao se <strong>de</strong>senvolver projetos mais<br />
elaborados e que fazem valer a adoção <strong>de</strong>sse dispositivo. Alguns comandos com <strong>um</strong>a<br />
breve <strong>de</strong>scrição são listados abaixo:<br />
➢<br />
➢<br />
➢<br />
➢<br />
ND (No<strong>de</strong> discover): <strong>de</strong>scobre e reporta todos os módulos <strong>de</strong> RF encontrados;<br />
PL (Power level): seleciona/lê a potência utilizada para a transmissão;<br />
SM (Sleep mo<strong>de</strong>): configurações para modo <strong>de</strong> baixo cons<strong>um</strong>o;<br />
VR (Firmware version): lê a versão do firmware do módulo RF.<br />
Embora hajam muitas possibilida<strong>de</strong>s para a melhor utilização das<br />
funcionalida<strong>de</strong>s do XBee, este trabalho faz uso dos módulos com suas configurações<br />
ajustadas <strong>de</strong> acordo com o padrão <strong>de</strong> fábrica. Com isso, não é feito uso direto dos<br />
modos <strong>de</strong> comando apresentados, embora essa apresentação tenha sido feita para que o<br />
horizonte <strong>de</strong> aplicações pu<strong>de</strong>sse ser melhor visl<strong>um</strong>brado. Informações mais <strong>de</strong>talhadas<br />
a respeito do conjunto <strong>de</strong> comandos e <strong>de</strong> outras características próprias do dispositivo<br />
da MaxStream po<strong>de</strong>m ser encontradas em [12].<br />
2.4 O Microcontrolador MSP430<br />
Os microcontroladores da Texas Instr<strong>um</strong>ents (TI) são divididos em várias<br />
famílias <strong>de</strong> acordo com parâmetros tais como tipo <strong>de</strong> memória <strong>de</strong> programa e<br />
aplicação. Atualmente existem cinco famílias. São elas:<br />
➢<br />
➢<br />
➢<br />
➢<br />
➢<br />
MSP430x1xx;<br />
MSP430x2xx;<br />
MSP430C3xx;<br />
MSP430x4xx;<br />
MSP430x5xx.<br />
Este trabalho utiliza o MSP430F149, que é <strong>um</strong> dispositivo <strong>de</strong> uso geral dotado<br />
<strong>de</strong> <strong>um</strong>a gran<strong>de</strong> varieda<strong>de</strong> <strong>de</strong> periféricos. Trata-se <strong>de</strong> <strong>um</strong> dispositivo com CPU RISC <strong>de</strong><br />
16 bits, registradores <strong>de</strong> 16 bits e geradores <strong>de</strong> constantes. Estes últimos contribuem
25<br />
para a geração <strong>de</strong> códigos com máxima eficiência. O DCO (Oscilador Controlado<br />
Digitalmente) permite reativar o dispositivo em menos <strong>de</strong> 6 μs. Essa CPU opera em 8<br />
MHz.<br />
A família MSP430F14x ainda tem 2 temporizadores internos <strong>de</strong> 16 bits, <strong>um</strong><br />
rápido conversor Analógico/Digital (A/D) <strong>de</strong> 12 bits, duas interfaces seriais universais<br />
Síncronas/Assíncronas (USART) e ainda 48 pinos <strong>de</strong> Entrada/Saída.<br />
Aplicações típicas incluem sistemas <strong>de</strong> sensoriamento que capturam sinais<br />
analógicos, converte-os para sinais digitais e então os processa e transmite a outro<br />
sistema. Os contadores internos são ainda i<strong>de</strong>ais para aplicações <strong>de</strong> <strong>controle</strong> industrial<br />
tais como <strong>controle</strong> digital <strong>de</strong> motores e medidores portáteis.<br />
2.4.1 Principais Características do Microcontrolador<br />
O MSP430 possui diversas características interessantes e que o diferencia muito<br />
<strong>de</strong> outros microcontroladores. Alg<strong>um</strong>as <strong>de</strong>ssas características estão listadas abaixo:<br />
➢<br />
➢<br />
➢<br />
➢<br />
➢<br />
➢<br />
➢<br />
baixas tensões <strong>de</strong> alimentação (1.8 V a 3.6 V);<br />
baixíssima potência cons<strong>um</strong>ida;<br />
➔<br />
➔<br />
modo ativo: 280 μA a 1 MHz, 2.2 V<br />
modo standby: 1.6 μA<br />
modo <strong>de</strong>sligado (retenção <strong>de</strong> memória RAM): 0.1 μA<br />
interface <strong>de</strong> comunicação serial (USART), que po<strong>de</strong> funcionar como UART ou<br />
mesmo como interface SPI;<br />
memória flash e RAM;<br />
➔<br />
➔<br />
60 KB + 256 B <strong>de</strong> memória flash<br />
2 KB <strong>de</strong> memória RAM<br />
operação em 8 MHz;<br />
alto <strong>de</strong>sempenho dos códigos compilados em C/C++ <strong>de</strong>vido às características<br />
<strong>de</strong> sua arquitetura e também por utilizar memória plana.
26<br />
A Figura 11 mostra a pinagem do mo<strong>de</strong>lo utilizado neste trabalho. Suas<br />
dimensões máximas são 12.20 x 12.20 x 1.20 mm e o encapsulamento é do tipo S-<br />
PQFP-G64.<br />
Figura 11: Pinagem do MSP430F149.<br />
2.4.2 O Programa do MSP430<br />
O programa que controla as funções da placa principal do robô foi escrito em C<br />
e a listagem completa po<strong>de</strong> ser vista no APÊNDICE A. Esse código é <strong>um</strong>a adaptação<br />
do código <strong>de</strong>senvolvido no trabalho [14].<br />
No código original, basicamente foi implementado <strong>um</strong> <strong>controle</strong> dos motores<br />
<strong>utilizando</strong> Modulação por Largura <strong>de</strong> Pulso (PWM), <strong>um</strong> controlador integrador para<br />
ser utilizado com os enco<strong>de</strong>rs e o tratamento <strong>de</strong> interrupções necessário para o<br />
recebimento <strong>de</strong> dados pela porta serial.<br />
Para aten<strong>de</strong>r às necessida<strong>de</strong>s <strong>de</strong>ste trabalho, foram feitas alg<strong>um</strong>as mudanças.<br />
Como os enco<strong>de</strong>rs ainda não estão sendo utilizados, o código relativo a esta função foi
27<br />
<strong>de</strong>sativado. O <strong>controle</strong> do robô passou a ser feito pelo programa <strong>de</strong> visão<br />
computacional, logo, o controlador integrador foi também removido do código. O<br />
programa do MSP sofreu também alg<strong>um</strong>as alterações a fim <strong>de</strong> torná-lo mais simples e<br />
menos exigente em termos <strong>de</strong> processamento. Adicionalmente, <strong>um</strong> código<br />
i<strong>de</strong>ntificador do robô foi inserido ao programa para assegurar que a tarefa seria<br />
executada pelo robô correto, no caso <strong>de</strong> haverem mais robôs envolvidos em <strong>um</strong>a<br />
aplicação.<br />
2.5 Conexão do XBee com o MSP430<br />
Para alcançar os objetivos <strong>de</strong>ste projeto, foi necessário configurar tanto o<br />
conjunto XBee quanto o MSP430 para que ambos pu<strong>de</strong>ssem trabalhar em perfeita<br />
sintonia, aproveitando ao máximo as características particulares <strong>de</strong> cada <strong>um</strong>.<br />
As principais configurações são feitas em relação à comunicação serial, visto<br />
que, o XBee comporta-se como <strong>um</strong> meio físico durante a transmissão e recepção <strong>de</strong><br />
dados. Sendo assim, para que <strong>um</strong> dado seja transmitido pelo XBee basta que o MSP o<br />
direcione este dado a porta serial. O envio ocorre sem complicações e diretamente.<br />
Semelhantemente, para que o XBee receba dados, basta que estes sejam enviados para<br />
seu en<strong>de</strong>reço <strong>de</strong> re<strong>de</strong> por qualquer membro da re<strong>de</strong> autorizado a fazer isso, mas no<br />
caso <strong>de</strong>sse trabalho, isso é feito pelo computador.<br />
A Figura 12 ilustra melhor o processo <strong>de</strong> envio e recebimento <strong>de</strong> dados pelo<br />
XBee.<br />
Figura 12: Comunicação serial entre XBee e Microcontrolador.
28<br />
Como po<strong>de</strong> ser visto na Figura 12, o módulo <strong>de</strong> comunicação XBee é muito<br />
simples <strong>de</strong> ser utilizado, po<strong>de</strong>ndo ser facilmente integrado até mesmo a antigos<br />
processadores <strong>de</strong> 8 bits. O XBee é projetado para oferecer <strong>um</strong> meio <strong>de</strong> comunicação<br />
sem fios e sem complicações, e <strong>de</strong> maneira que seja transparente para o<br />
microcontrolador no que diz respeito ao processo <strong>de</strong> transmissão e aos <strong>de</strong>talhes<br />
particulares da comunicação via RF.<br />
Por padrão, o XBee opera no Modo Transparente. Quando opera nesse modo, o<br />
módulo opera como <strong>um</strong> simples repetidor <strong>de</strong> informações, isto é, todos os dados<br />
recebidos pelo pino <strong>de</strong> entrada <strong>de</strong> dados, DI, são encaminhados para a transmissão em<br />
RF. Quando os dados da transmissão RF são recebidos, eles são direcionados ao pino<br />
<strong>de</strong> saída <strong>de</strong> dados, DO.<br />
Se o módulo não po<strong>de</strong> transmitir os dados imediatamente, no caso <strong>de</strong> já estar<br />
ocupado com o recebimento <strong>de</strong> dados, estes dados recebidos serialmente são<br />
armazenados no buffer <strong>de</strong> DI. Os dados são empacotados e enviados caso o tempo <strong>de</strong><br />
empacotamento chegue ao fim ou caso sejam completados 100 bytes, tamanho<br />
máximo do pacote.<br />
Caso o buffer <strong>de</strong> DI fique completamente cheio, é necessário implementar<br />
alg<strong>um</strong> software ou hardware a fim <strong>de</strong> controlar o fluxo <strong>de</strong> dados para que não ocorra<br />
perda <strong>de</strong> dados por overflow entre o emissor e o receptor. Contudo, é importante notar<br />
que o XBee faz checagem <strong>de</strong> dados por checks<strong>um</strong>, e os pacotes que não passam no<br />
teste são silenciosamente <strong>de</strong>scartados.
29<br />
3 PROCESSAMENTO DE IMAGENS<br />
3.1 Introdução<br />
O processamento <strong>de</strong> imagens é muito utilizado em robótica. Essa técnica agrega<br />
boas possibilida<strong>de</strong>s às funcionalida<strong>de</strong>s dos robôs.<br />
Diversas tarefas po<strong>de</strong>m ser realizadas <strong>utilizando</strong>-se imagens capturadas por <strong>um</strong>a<br />
câmera. Em sistemas assim, a fim <strong>de</strong> complementar os robôs no quesito robustez,<br />
outros tipos <strong>de</strong> sensoriamento po<strong>de</strong>m ser utilizados para se a<strong>um</strong>entar a gama <strong>de</strong><br />
aplicações que esses robôs po<strong>de</strong>m executar e também diminuir a possibilida<strong>de</strong> <strong>de</strong><br />
falhas. Sendo assim, evitam-se limitações <strong>de</strong>correntes <strong>de</strong> situações adversas que<br />
po<strong>de</strong>m ocorrer no ambiente durante as ativida<strong>de</strong>s executadas pelos robôs.<br />
Com o processamento <strong>de</strong> imagem é possível extrair informações do mundo real<br />
em três dimensões (3D) a partir da projeção da imagem em duas dimensões (2D) [1,<br />
6, 8, 9].<br />
3.2 Técnica Utilizada<br />
Dentre as várias técnicas que po<strong>de</strong>m ser utilizadas, optou-se por aquela que<br />
melhor se a<strong>de</strong>quava ao propósito <strong>de</strong>ste trabalho. Sendo assim, fixou-se <strong>um</strong>a câmera a<br />
<strong>um</strong>a altura e inclinação conhecidas em relação ao plano em que o robô executaria a<br />
tarefa, e a partir daí foi feita toda a mo<strong>de</strong>lagem matemática.<br />
É importante ressaltar que foi feita a calibração do foco da câmera a fim <strong>de</strong> se<br />
obter as medidas com maior precisão. O processo <strong>de</strong> calibração consistiu basicamente<br />
na medida <strong>de</strong> <strong>um</strong> objeto, <strong>de</strong> largura conhecida, a várias distâncias da câmera, ambos<br />
sobre <strong>um</strong>a superfície plana. Neste caso, obteve-se duas medidas em centímetros, a<br />
distância da câmera ao objeto e a largura do objeto medido, e <strong>um</strong>a em pixeis, medida<br />
manualmente com o auxílio do programa <strong>de</strong> visão computacional. De posse <strong>de</strong>ssas três<br />
medidas foi possível calcular o foco da câmera em pixeis pela expressão (1):<br />
f = Dd<br />
L<br />
(1)
30<br />
On<strong>de</strong>:<br />
f → foco da câmera, em pixeis;<br />
D → distância entre a câmera e o objeto, em centímetros;<br />
d → largura do objeto, em pixeis;<br />
L → largura do objeto, em centímetros.<br />
Após ajustado o foco da câmera, as imagens foram capturadas e então<br />
processadas pelo programa escrito na linguagem C++ <strong>utilizando</strong> alg<strong>um</strong>as funções da<br />
biblioteca OpenCV. O código utilizado neste trabalho é <strong>um</strong>a adaptação <strong>de</strong> <strong>um</strong>a<br />
aplicação <strong>de</strong>senvolvida por alunos do PET da Engenharia <strong>de</strong> Computação da UFES. O<br />
projeto citado trata <strong>de</strong> <strong>um</strong>a aplicação da visão computacional a futebol <strong>de</strong> robôs cuja<br />
orientadora é a mesma do presente trabalho. As principais funcionalida<strong>de</strong>s <strong>de</strong>sta<br />
aplicação incluem:<br />
➢<br />
➢<br />
➢<br />
➢<br />
➢<br />
marcação da região on<strong>de</strong> os robô executará a tarefa;<br />
seleção das cores do robô e do alvo;<br />
<strong>controle</strong> <strong>de</strong> velocida<strong>de</strong>, orientação e posição no espaço;<br />
seguimento <strong>de</strong> cor;<br />
execução <strong>de</strong> tarefas.<br />
A imagem da Figura 13 mostra o robô e o alvo com suas cores, e a Figura 14<br />
mostra como esses elementos são reconhecidos pelo sistema <strong>de</strong> visão. Note que na<br />
Figura 14 as regiões já estão selecionadas para o sistema <strong>de</strong> seguimento <strong>de</strong> cor.<br />
O sistema <strong>de</strong> seguimento <strong>de</strong> cor foi <strong>de</strong>senvolvido <strong>utilizando</strong>-se alg<strong>um</strong>as funções<br />
da biblioteca OpenCV e é baseado no CAMSHIFT [15]. Com essa técnica é possível<br />
fazer o seguimento <strong>de</strong> cor bastando que para isso seja passada a cor e o histograma <strong>de</strong><br />
cor da imagem. Com o histograma da cor é gerado <strong>um</strong>a tabela <strong>de</strong> projeção da imagem.<br />
Com isso, se o histograma possui <strong>um</strong>a certa distribuição <strong>de</strong> probabilida<strong>de</strong>, então a<br />
tabela <strong>de</strong> cor gerada também terá o mesmo mo<strong>de</strong>lo <strong>de</strong> distribuição. O CAMSHIFT<br />
<strong>de</strong>tecta o mo<strong>de</strong>lo <strong>de</strong> distribuição <strong>de</strong> probabilida<strong>de</strong> aplicando o Mean Shift enquanto<br />
dinamicamente ajusta os parâmetros da distribuição da cor a ser seguida. Note que o<br />
algoritmo do CAMSHIFT segue apenas a cor selecionada. Assim, pela análise <strong>de</strong>
31<br />
probabilida<strong>de</strong> a seleção da cor a ser seguida será atualizada, e servirá como ponto <strong>de</strong><br />
partida para a localização da cor a ser seguida quando <strong>um</strong> novo frame for capturado. A<br />
busca no novo frame é feita levando-se em consi<strong>de</strong>ração as proximida<strong>de</strong>s da região do<br />
frame antigo em que o objeto com a cor a ser seguida se encontrava. Melhores<br />
resultados do seguimento <strong>de</strong> cor <strong>utilizando</strong> o CAMSHIFT são obtidos <strong>utilizando</strong>-se o<br />
canal HUE, do sistema <strong>de</strong> cor HSV, e o histograma da cor.<br />
Figura 13: Robô e alvo com suas respectivas cores.<br />
Figura 14: Reconhecimento <strong>de</strong> cores.
32<br />
A seleção da cor a ser seguida pelo sistema é feita <strong>de</strong> modo manual.<br />
Primeiramente seleciona-se o canto esquerdo inferior e logo após o canto direito<br />
superior. Feito isso, registra-se os pontos e então a região retangular é efetivamente<br />
selecionada. No caso do robô, que neste trabalho é i<strong>de</strong>ntificado por duas cores, após a<br />
seleção das cores os centrói<strong>de</strong>s são conectados.<br />
3.3 Consi<strong>de</strong>rações Iniciais <strong>de</strong> Projeto<br />
Para a mo<strong>de</strong>lagem matemática do sistema óptico, alg<strong>um</strong>as consi<strong>de</strong>rações foram<br />
feitas. Primeiramente, a câmera foi colocada na pare<strong>de</strong> a <strong>um</strong>a altura e ângulo<br />
conhecidos. A partir <strong>de</strong>ssa situação, foram <strong>de</strong>finidas quais seriam as transformações<br />
necessárias para se controlar os robôs no espaço 3D a partir da projeção 2D, capturada<br />
pela câmera.<br />
A Figura 15 ilustra o ambiente <strong>de</strong> testes com os referenciais criados. Uma vez<br />
<strong>de</strong>finidos os referenciais po<strong>de</strong>-se calcular as velocida<strong>de</strong>s angular e linear do robô e<br />
também sua posição <strong>de</strong> maneira bastante simplificada, já que com a mudança <strong>de</strong><br />
coor<strong>de</strong>nadas é possível controlar o robô a partir <strong>de</strong> <strong>um</strong>a única referência.<br />
Figura 15: Referências do sistema óptico.
33<br />
3.3.1 Mo<strong>de</strong>lagem Matemática do Sistema Óptico<br />
Todo o equacionamento do sistema foi feito para que os dados capturados nos<br />
referenciais existentes fossem consi<strong>de</strong>rados no referencial do robô. Com isso, o<br />
<strong>controle</strong> do robô fica muito mais simples e também permite que as velocida<strong>de</strong>s angular<br />
e linear, e conseqüentemente a posição do robô no espaço, sejam controladas<br />
diretamente através do referencial do robô.<br />
Abaixo estão as <strong>de</strong>finições matemáticas do problema, mas antes disso, alg<strong>um</strong>as<br />
<strong>de</strong>finições fazem-se necessárias com relação ao sistema <strong>de</strong> coor<strong>de</strong>nadas adotado.<br />
➢<br />
➢<br />
➢<br />
referencial do mundo → ambiente <strong>de</strong> teste;<br />
referencial da câmera → ponto em que a câmera está afixada consi<strong>de</strong>rando sua<br />
inclinação;<br />
referencial do robô → ponto central da linha que conecta as duas cores do robô.<br />
Posto isso, po<strong>de</strong>-se <strong>de</strong>senvolver a parte matemática do sistema. Para converter<br />
<strong>um</strong> ponto representado no referencial do mundo para sua representação, ou seja,<br />
coor<strong>de</strong>nadas no referencial da câmera, tem-se:<br />
P C<br />
= R X<br />
− P M<br />
P M<br />
= R X<br />
P C<br />
(2)<br />
(3)<br />
R X<br />
− =<br />
[1 0 0 0<br />
1]<br />
0 cos sen 0<br />
0 −sen cos 0<br />
0 0 0<br />
(4)<br />
On<strong>de</strong>: P C → ponto no referencial da câmera;<br />
P M<br />
→ ponto no referencial do mundo;<br />
R X → matrix <strong>de</strong> rotação em torno do eixo X;<br />
ϕ → ângulo <strong>de</strong> inclinação da câmera em relação ao eixo Z.
[<br />
X<br />
C<br />
Y C<br />
Z C<br />
1<br />
]C<br />
Substituindo as matrizes <strong>de</strong> R X , P C e P M encontramos:<br />
Com isso, ao fazermos a multiplicação <strong>de</strong> matrizes acima encontramos os<br />
pontos do mundo no referencial da câmera. :<br />
assim:<br />
=<br />
[1 0 0 0<br />
1]<br />
0 cos sen 0<br />
0 −sen cos 0<br />
0 0 0<br />
X C<br />
= X M<br />
Y C<br />
= Y M<br />
cos Z M<br />
sen<br />
Z C<br />
= −Y M<br />
sen Z M<br />
cos<br />
[<br />
X<br />
M<br />
Y M<br />
Z M<br />
1<br />
]M<br />
A imagem obtida pela câmera é <strong>um</strong>a projeção perspectiva do ambiente. Sendo<br />
34<br />
(5)<br />
(6)<br />
(7)<br />
(8)<br />
x = f<br />
X c<br />
Z C<br />
(9)<br />
y = f<br />
Y c<br />
Z C<br />
(10)<br />
on<strong>de</strong>: f → distância focal em pixeis.<br />
O mo<strong>de</strong>lo da câmera utilizada é o pinhole. Esse mo<strong>de</strong>lo se baseia na passagem<br />
dos raios l<strong>um</strong>inosos por <strong>um</strong> pequeno orifício na entrada da câmera e na sua projeção<br />
em <strong>um</strong>a superfície plana, como mostrado na Figura 16. As câmeras baseadas nesse<br />
princípio são chamadas câmeras perspectivas [8]. O plano R é o plano da imagem, F é<br />
paralelo ao plano R e é chamado <strong>de</strong> plano focal.
35<br />
Figura 16: Formação da imagem em <strong>um</strong>a câmera perspectiva.<br />
temos:<br />
x = f<br />
Para relacionar o ponto na imagem com as coor<strong>de</strong>nadas do ponto 3D no mundo<br />
X M<br />
−Y M<br />
sen Z M<br />
cos <br />
(11)<br />
y = f<br />
Y M<br />
cos Z M<br />
sen<br />
−Y M<br />
sen Z M<br />
cos <br />
(12)<br />
Sabendo-se que os pontos tridimensionais pertencem ao plano Y M = -H, no<br />
referencial do mundo, temos:<br />
x = f<br />
X M<br />
H sen Z M<br />
cos <br />
(13)<br />
y = f Z M<br />
sen − H cos <br />
H sen Z M<br />
cos <br />
(14)<br />
Isolando as variáveis X M e Z M , temos:
36<br />
X M<br />
= x f H sen Z M cos<br />
(15)<br />
Z M<br />
= H<br />
f cos y sen<br />
f sen − y cos<br />
(16)<br />
A Figura 17 ilustra o mo<strong>de</strong>lo da câmera perspectiva com a projeção <strong>de</strong> <strong>um</strong><br />
ponto do mundo no plano da imagem. Normalmente o referencial <strong>de</strong> <strong>um</strong>a imagem é<br />
tomado como sendo o canto superior esquerdo, por isso é necessária <strong>um</strong>a correção nas<br />
coor<strong>de</strong>nadas do ponto na imagem para que esse ponto seja referido ao centro <strong>de</strong><br />
coor<strong>de</strong>nadas on<strong>de</strong> se tem (x o ,y o ). Contudo, neste trabalho o referencial da imagem<br />
capturada é o canto inferior esquerdo. Para isso, as relações utilizadas nos<br />
experimentos para encontrar x e y são <strong>de</strong>scritas pelas expressões (17) e (18).<br />
(17)<br />
x = x img<br />
− x o<br />
y = − y img<br />
− y o<br />
<br />
(18)<br />
Figura 17: Mo<strong>de</strong>lo da câmera perspectiva com projeção <strong>de</strong> ponto.
37<br />
Sendo assim, a partir <strong>de</strong> x e y na imagem po<strong>de</strong>mos obter X M , Z M e Y M , com<br />
Y M = -H, e então po<strong>de</strong>mos calcular o erro <strong>de</strong> posição para o robô. Esse erro é na<br />
verda<strong>de</strong> a distância entre a posição atual do robô e a posição para on<strong>de</strong> ele <strong>de</strong>ve ir a<br />
fim <strong>de</strong> executar a tarefa a ser realizada.<br />
(19)<br />
= Pos <strong>de</strong>sejada<br />
− Pos atual<br />
⇒<br />
Em cada eixo teremos <strong>um</strong> ∆ = ε, como abaixo:<br />
X<br />
= X d<br />
− X<br />
Y<br />
= 0<br />
Z<br />
= Z d<br />
− Z<br />
(20)<br />
(21)<br />
(22)<br />
O ângulo formado entre o eixo Z e a direção em que o robô <strong>de</strong>ve se locomover<br />
po<strong>de</strong> ser calculado com a seguinte expressão:<br />
= arctg X<br />
Z<br />
<br />
(23)<br />
A Figura 18 ilustra a relação do erro |ε| e do ângulo θ calculado <strong>de</strong> acordo com<br />
a tarefa a ser executada.<br />
Figura 18: Relação do erro com a tarefa a ser executada.<br />
Note que o ângulo α é medido em relação ao eixo Z e indica a orientação do<br />
robô. O ângulo ψ é também medido em relação ao eixo Z e é utilizado para medir a
distância angular entre o centrói<strong>de</strong> do robô e o ponto em que se <strong>de</strong>seja chegar.<br />
Finalmente, o ângulo θ é a diferença entre ψ e α, e indica quanto falta para que o robô<br />
se alinhe no sentido do ponto alvo, ou seja, é o erro angular.<br />
De posse do valor <strong>de</strong> θ e do erro <strong>de</strong> posição do robô, Δx e Δz, po<strong>de</strong>-se calcular o<br />
módulo <strong>de</strong> ε, a velocida<strong>de</strong>s linear e a angular.<br />
∣∣= X 2 Z<br />
2<br />
v Z<br />
=∣∣ cos<br />
= k <br />
38<br />
(24)<br />
(25)<br />
(26)<br />
On<strong>de</strong>: v Z = v → velocida<strong>de</strong> linear;<br />
k → constante <strong>de</strong> proporcionalida<strong>de</strong>;<br />
θ → erro angular entre o robô e o ponto alvo.<br />
Finalmente, as expressões necessárias para o <strong>controle</strong> do robô estão<br />
relacionadas nas expressões (27) e (28), sendo v a velocida<strong>de</strong> linear e ω a velocida<strong>de</strong><br />
angular. Foi utilizado <strong>um</strong> controlador hiperbólico <strong>de</strong>vido à sua característica <strong>de</strong><br />
transição suave entre valores positivos e negativos <strong>de</strong> ω. Essa característica é muito<br />
importante para que o robô tenha movimentos mais suaves e assim evita-se erros <strong>de</strong><br />
posição e também problemas <strong>de</strong> tempo <strong>de</strong> resposta dos motores no momento da<br />
inversão do sentido <strong>de</strong> giro. Repare que V max e ω max são escolhidos levando-se em<br />
consi<strong>de</strong>ração resultados práticos. Neste projeto, os valores utilizados para V max e ω max<br />
foram 50% e 5%, respectivamente. O valor é dado em porcentagem pois trata-se <strong>de</strong><br />
valores para o ajuste do PWM, que recebe a porcentagem da potência para a qual o<br />
motor <strong>de</strong>ve ser ajustado.<br />
v = v max<br />
tanh∣∣ cos 2 <br />
= max<br />
tanh<br />
(27)<br />
(28)<br />
A Figura 19 mostra <strong>um</strong> esboço da resposta da velocida<strong>de</strong> angular <strong>de</strong> acordo<br />
com o ângulo θ instantâneo.
39<br />
Figura 19: Resposta i<strong>de</strong>al do controlador.<br />
Como po<strong>de</strong> ser visto, a resposta <strong>de</strong>sse controlador garante <strong>um</strong> movimento<br />
bastante suave para o motor evitando-se mudanças bruscas <strong>de</strong> velocida<strong>de</strong> e também<br />
mudanças bruscas <strong>de</strong> corrente nos motores.<br />
3.3.1 Sistema <strong>de</strong> Orientação<br />
Com o perfeito funcionamento do sistema óptico é possível utilizar as<br />
informações das imagens previamente capturadas e processadas para inferir a<br />
orientação dos robôs no plano <strong>de</strong> ativida<strong>de</strong>.<br />
Como o robô utilizado não é equipado com sensores capazes <strong>de</strong> informar a atual<br />
orientação, optou-se por utilizar duas cores para i<strong>de</strong>ntificá-lo. Com isso, i<strong>de</strong>ntificar a<br />
posição do robô bem como sua orientação no sistema torna-se bastante simples quando<br />
comparado ao método que utiliza apenas <strong>um</strong>a cor por robô. Sendo assim, <strong>um</strong>a cor é<br />
marcada como sendo a parte <strong>de</strong> trás do robô, enquanto a outra é marcada como sendo a<br />
parte da frente. Em seguida, os centrói<strong>de</strong>s são localizados e conectados. A partir <strong>de</strong>stes<br />
pontos, po<strong>de</strong>-se calcular a orientação do robô em relação ao eixo Z e também em<br />
relação ao <strong>de</strong>stino, representado por <strong>um</strong>a terceira cor.
A expressão que avalia tanto a orientação do robô quanto o ângulo entre o eixo<br />
Z e o ponto alvo é <strong>de</strong>scrita pela expressão (29). Note que Ang po<strong>de</strong> ser tanto α quanto<br />
ψ.<br />
Ang = arctg ΔƤ<br />
Δɠ <br />
(29)<br />
Para calcular esses ângulos, foi necessário fazer alg<strong>um</strong>as consi<strong>de</strong>rações para<br />
que o ângulo encontrado estivesse sempre em relação a <strong>um</strong>a única referência. Com<br />
isso, evita-se que ângulos calculados no primeiro e no terceiro quadrantes ou no<br />
segundo e no quarto quadrantes sejam consi<strong>de</strong>rados iguais. Se esse cuidado não fosse<br />
tomado, isso geraria <strong>um</strong> erro no momento em que o robô tivesse que se orientar no<br />
sentido do alvo partindo <strong>de</strong> <strong>um</strong>a orientação aleatória.<br />
Sendo assim, para o cálculo do ângulo, utilizou-se <strong>um</strong>a série <strong>de</strong> relações para<br />
i<strong>de</strong>ntificar em que quadrante encontrava-se o vetor velocida<strong>de</strong> do robô. As relações<br />
levam em consi<strong>de</strong>ração o sinal <strong>de</strong> Δ Ƥ e <strong>de</strong> Δ ɠ, como mostrado abaixo.<br />
➢ Δ Ƥ > 0 e Δ ɠ > 0 → 1 o Quadrante, Angulo = Ang<br />
➢ Δ Ƥ > 0 e Δ ɠ < 0 → 2 o Quadrante, Angulo = Ang + π<br />
➢ Δ Ƥ < 0 e Δ ɠ < 0 → 3 o Quadrante, Angulo = Ang + π<br />
➢ Δ Ƥ < 0 e Δ ɠ > 0 → 4 o Quadrante, Angulo = Ang + 2π<br />
40<br />
Note que Ang é o valor calculado pela expressão (29) e Angulo é o valor<br />
corrigido do ângulo para <strong>um</strong>a referência com<strong>um</strong> e única do sistema, consi<strong>de</strong>rada como<br />
sendo o eixo Z positivo.<br />
3.4 Captura e Processamento da Imagem<br />
Além da captura, no sistema <strong>de</strong> visão foram implementadas funções a fim <strong>de</strong><br />
encontrar o centro dos objetos marcados na imagem. Isso é importante porque permite<br />
que a manipulação do robô no ambiente seja simplificada, já que sua movimentação é<br />
baseada na posição do seu centrói<strong>de</strong>.
41<br />
As funções <strong>de</strong> processamento <strong>de</strong> imagem fazem parte do sistema <strong>de</strong> visão<br />
chamado Sistema Robótico, feito em C++. A manipulação das imagens é bastante<br />
simples quando feita com o auxílio da biblioteca OpenCV da Intel. Embora todas as<br />
funções do programa possam ser vistas na listagem do APÊNDICE B, alg<strong>um</strong>as das<br />
principais funções da biblioteca OpenCV relativas a este trabalho estão <strong>de</strong>scritas<br />
abaixo. São elas:<br />
➢ cvcamGetCamerasCount();<br />
➢<br />
➢<br />
➢<br />
➢<br />
➢<br />
➢<br />
➢<br />
Retorna <strong>um</strong> inteiro com o número <strong>de</strong> câmeras ativas encontradas.<br />
cvcamSetProperty(camIn<strong>de</strong>x, CVCAM_PROP_ENABLE, CVCAMTRUE);<br />
Habilita a câmera especificada em camIn<strong>de</strong>x, sendo 0 o número da primeira.<br />
cvcamSetProperty(camIn<strong>de</strong>x, CVCAM_PROP_RENDER, CVCAMTRUE);<br />
Habilita a digitalização dos frames para a câmera selecionada.<br />
cvcamSetProperty(camIn<strong>de</strong>x, CVCAM_PROP_SETFORMAT, &vidFmt);<br />
Define resolução e quantida<strong>de</strong>s <strong>de</strong> frames que serão capturados por segundo.<br />
Para isso, vidFmt recebe <strong>um</strong>a matriz do tipo {640, 480, 30.0}.<br />
cvcamGetProperty(camIn<strong>de</strong>x, CVCAM_CAMERAPROPS, NULL);<br />
Chama a janela <strong>de</strong> configuração dos parâmetros da câmera.<br />
cvcamInit();<br />
Prepara a câmera com os parâmetros fornecidos.<br />
cvcamStart();<br />
Inicia a captura da imagem.<br />
cvcamStop();<br />
Interrompe a captura da imagem.<br />
➢ cvCreateImage(cvGetSize(frame), frame-><strong>de</strong>pth, 1);<br />
Separa o canal HUE da imagem que está em frame.<br />
Como po<strong>de</strong> ser visto acima, as funções <strong>de</strong>ssa biblioteca fazem boa parte do<br />
trabalho e por isso poupam tempo <strong>de</strong> <strong>de</strong>senvolvimento <strong>de</strong> aplicações. Logo, essa<br />
biblioteca acaba viabilizando aplicações em várias áreas que envolvem processamento<br />
<strong>de</strong> imagens.
42<br />
4 SISTEMA COMPLETO E TAREFA PROPOSTA<br />
4.1 Introdução<br />
O sistema completo é formado por <strong>um</strong> robô equipado com <strong>um</strong>a placa <strong>de</strong><br />
<strong>controle</strong> e com <strong>um</strong> conjunto <strong>de</strong> <strong>de</strong>senvolvimento da MaxStream. O robô possui<br />
também duas placas coloridas em sua parte superior. Essas cores são utilizadas para<br />
que o sistema <strong>de</strong> seguimento <strong>de</strong> cor funcione corretamente e também para possibilitar<br />
a distinção entre os robôs ativos, caso exista mais <strong>de</strong> <strong>um</strong>, e para <strong>de</strong>terminar a direção<br />
do robô.<br />
Nos próximos itens serão abordados os <strong>de</strong>talhes da montagem do robô, da<br />
colocação da câmera no ambiente, da colocação das cores <strong>de</strong> i<strong>de</strong>ntificação do robô, da<br />
região em que a tarefa será executada e também será <strong>de</strong>finida a tarefa que se <strong>de</strong>seja<br />
executar.<br />
4.2 Montagem do Sistema e Detalhes <strong>de</strong> Funcionamento<br />
A montagem da parte física do sistema é bastante simples e apenas alguns<br />
<strong>de</strong>talhes <strong>de</strong>vem ser vistos com maior atenção. Para se evitar problemas, <strong>de</strong>ve-se<br />
remover todos os obstáculos no plano em que o robô se movimenta. Isso <strong>de</strong>ve ser feito<br />
porque nem o robô e nem o sistema <strong>de</strong> seguimento <strong>de</strong> core é capaz <strong>de</strong> <strong>de</strong>tectar<br />
obstáculos. Outro aspecto levado em consi<strong>de</strong>ração é a possibilida<strong>de</strong> <strong>de</strong> existirem<br />
objetos que pu<strong>de</strong>m ter suas cores confundidas com as cores dos robôs, fato que po<strong>de</strong>ria<br />
fazer com que o sistema <strong>de</strong> seguimento <strong>de</strong> cores per<strong>de</strong>sse os robôs.<br />
Em relação à câmera, dois aspectos precisam ser vistos com muita atenção.<br />
Primeiro, o foco da câmera <strong>de</strong>ve ser ajustado, tal como explicado no item 3.2, para que<br />
os cálculos <strong>de</strong> posição sejam feitos corretamente ao converter coor<strong>de</strong>nadas medidas<br />
em pixeis para coor<strong>de</strong>nadas no referencial do mundo, em centímetros. Segundo, a<br />
câmera <strong>de</strong>ve ser afixada a <strong>um</strong>a altura H conhecida e com <strong>um</strong>a inclinação também<br />
conhecida, já que o sistema óptico leva em consi<strong>de</strong>ração todas essas variáveis para<br />
estimar a correta posição do robô.
43<br />
Todo o <strong>controle</strong> do sistema é feito pelo computador com dados do sistema<br />
óptico. No início do processo é necessário selecionar as regiões a serem consi<strong>de</strong>radas<br />
pelo sistema <strong>de</strong> seguimento <strong>de</strong> cor. Com isso, as cores do robô e também a cor do<br />
ponto alvo <strong>de</strong>vem ser selecionadas para que o sistema possa então consi<strong>de</strong>rar essas<br />
cores no momento da execução da tarefa. Para se evitar problemas no sistema <strong>de</strong><br />
<strong>de</strong>tecção e seguimento <strong>de</strong> cor existem dois cuidados básicos que precisam ser<br />
tomados. O primeiro <strong>de</strong>les é em relação às cores, pois não é recomendável utilizar<br />
cores muito semelhantes. O segundo é em relação à aproximação dos corpos coloridos,<br />
que não <strong>de</strong>vem se aproximar muito para evitar que o sistema óptico junte as cores e<br />
passe então a consi<strong>de</strong>rar duas ou mais regiões como sendo apenas <strong>um</strong>a.<br />
Em relação ao funcionamento do sistema, o sistema óptico adquire as imagens<br />
do ambiente, essas imagens são processadas e então o sistema <strong>de</strong> seguimento <strong>de</strong> cor<br />
cuida da movimentação do robô no ambiente <strong>de</strong> acordo com o objetivo da tarefa.<br />
Nesse caso, os dados relevantes ao <strong>controle</strong> do robô, velocida<strong>de</strong> linear e angular, são<br />
transmitidos pelo computador via porta serial, <strong>utilizando</strong>-se também <strong>um</strong> módulo XBee<br />
para enviar mensagens em broadcast. Sendo assim, caso houvessem mais robôs no<br />
sistema, todos receberiam as mesmas informações, mas o programa do MSP430 faz a<br />
checagem para saber qual <strong>de</strong>ve executar os comandos recebidos. Isso é possível<br />
porque quando <strong>um</strong> comando é enviado pelo PC ele vai codificado com a indicação <strong>de</strong><br />
qual robô <strong>de</strong>ve executá-lo, e por outro lado, o programa do MSP430 checa se o código<br />
recebido é o mesmo do robô. Se essa informação coincidir, o robô executa os<br />
comandos.<br />
A Figura 20 mostra o ambiente <strong>de</strong> teste e <strong>um</strong> robô com suas cores <strong>de</strong><br />
i<strong>de</strong>ntificação. Nessa figura po<strong>de</strong>-se ver também o ponto alvo <strong>de</strong> chegada para o robô,<br />
em ver<strong>de</strong> sobre a mesa. Esse ponto alvo é representado por <strong>um</strong> objeto colorido, visto<br />
que o sistema consi<strong>de</strong>ra que o ponto alvo po<strong>de</strong>ria ser na verda<strong>de</strong> <strong>um</strong> outro robô ou<br />
algo que <strong>de</strong>va ser perseguido, como ocorre no projeto <strong>de</strong>senvolvido pelo PET da<br />
Engenharia <strong>de</strong> Computação, em que os robôs <strong>de</strong>vem perseguir <strong>um</strong>a bola colorida.
44<br />
Figura 20: Ambiente <strong>de</strong> teste.<br />
4.3 Tarefa Proposta<br />
A tarefa proposta tem como objetivo testar as funcionalida<strong>de</strong>s do sistema e não<br />
necessariamente visa a realização <strong>de</strong> procedimentos. Testes mais elaborados po<strong>de</strong>m<br />
ser criados e realizados em ambientes e situações mais realistas como aplicações em<br />
chão-<strong>de</strong>-fábrica ou até mesmo aplicações em que os robôs po<strong>de</strong>m ass<strong>um</strong>ir papéis <strong>de</strong><br />
guardas ou observadores mantendo-se sempre atentos a <strong>um</strong> <strong>de</strong>terminado evento.<br />
Para este projeto, a tarefa a ser realizada consi<strong>de</strong>ra a colocação <strong>de</strong> <strong>um</strong> alvo no<br />
ambiente para que o robô o alcance. Para isso, o alvo é i<strong>de</strong>ntificado com <strong>um</strong>a<br />
marcação colorida e o robô com duas outras marcações que indicam sua parte frontal<br />
e traseira.<br />
Na tarefa a ser executada, o procedimento inicial é bastante simples. O<br />
ambiente <strong>de</strong> testes será capturado pela câmera e a área que o programa <strong>de</strong>ve consi<strong>de</strong>rar<br />
para o monitoramento será previamente selecionada na imagem como sendo o campo<br />
<strong>de</strong> ativida<strong>de</strong>. Feito isso, <strong>um</strong> robô será colocado nesse ambiente <strong>de</strong> teste e então, as
45<br />
cores dos robô serão também selecionadas e adicionadas ao sistema <strong>de</strong> seguimento <strong>de</strong><br />
cor. O próximo passo é a marcação do alvo, isto é, o ponto em que os robô <strong>de</strong>ve<br />
chegar ao final da tarefa.<br />
Para fins <strong>de</strong> simplificação, a tarefa proposta consi<strong>de</strong>ra a reorientação dos robôs<br />
na direção e sentido necessário para que o alvo seja atingido. É importante lembrar que<br />
tanto os robô quanto o alvo são consi<strong>de</strong>rados como sendo corpos pontuais<br />
in<strong>de</strong>pen<strong>de</strong>nte <strong>de</strong> suas dimensões físicas ou da área selecionada na imagem.<br />
A realização <strong>de</strong> <strong>um</strong>a tarefa como essa abre caminhos para muitas possibilida<strong>de</strong>s<br />
<strong>de</strong> aplicações. Com isso, embora pareça simples, essa tarefa permite posicionar robôs<br />
frente-a-frente, empurrar caixas, carregar objetos <strong>de</strong> <strong>um</strong> ponto a outro, seguir objetos,<br />
reconhecer marcações e executar tarefas diversas individualmente ou em equipes <strong>de</strong><br />
robôs.
46<br />
5 EXPERIMENTO<br />
5.1 Introdução<br />
A fase <strong>de</strong> testes <strong>de</strong>ste trabalho se mostrou extremamente importante para o<br />
conhecimentos dos problemas, limitações, condições apropriadas aos testes, e também<br />
para reavaliar a possibilida<strong>de</strong> <strong>de</strong> implantar <strong>um</strong> sistema como esse para aplicações<br />
reais.<br />
5.2 Teste e Análise dos Resultados<br />
O que se esperava como resultado era que pelo processamento <strong>de</strong> imagem o<br />
robô se dirigisse ao alvo após receber as velocida<strong>de</strong>s linear e angular, resultado do<br />
processamento <strong>de</strong> imagem baseado no seguimento <strong>de</strong> cor <strong>de</strong> cor. Eram esperados<br />
alguns problemas <strong>de</strong>vido à il<strong>um</strong>inação do ambiente. Com relação ao XBee, não eram<br />
esperados problemas visto que trata-se <strong>de</strong> <strong>um</strong> dispositivo bastante simples <strong>de</strong> usar até<br />
mesmo quando ajustado com as configurações padrão <strong>de</strong> fábrica. Esperava-se também<br />
alguns problemas <strong>de</strong>correntes da projeção da imagem, já que existem alg<strong>um</strong>as<br />
imprecisões do sistema físico quando comparado à mo<strong>de</strong>lagem matemática. As<br />
principais imprecisões foram notadas quando o robô se afastava muito da câmera.<br />
Nessa condição, a orientação do robô não foi realizada <strong>de</strong> maneira muito correta, e<br />
apesar do robô chegar ao ponto alvo, não o fazia com a orientação esperada.<br />
Após iniciados os testes ocorreram <strong>um</strong>a série <strong>de</strong> problemas. O primeiro <strong>de</strong>les<br />
foi <strong>de</strong>vido à origem da imagem capturada pela webcam, que foge dos padrões quando<br />
comparada às outras câmeras utilizadas em [6, 8, 13, 14]. De maneira geral, a origem<br />
da imagem capturada é o ponto esquerdo superior, no entanto, para a webcam utilizada<br />
neste trabalho a origem das imagens capturadas é o ponto esquerdo inferior. Com isso,<br />
<strong>um</strong>a série <strong>de</strong> testes e medidas <strong>de</strong> distâncias foram necessários até que o programa <strong>de</strong><br />
seguimento <strong>de</strong> cor estivesse completamente adaptado a este projeto. O segundo<br />
problema ocorreu <strong>de</strong>vido a <strong>um</strong>a característica da webcam utilizada. Essa câmera ajusta<br />
automaticamente o brilho <strong>de</strong>pen<strong>de</strong>ndo da il<strong>um</strong>inação do ambiente. Isso trouxe sérios
47<br />
problemas aos testes já que o procedimento inicial do processamento <strong>de</strong> imagem<br />
consi<strong>de</strong>ra a captura <strong>de</strong> <strong>um</strong> frame, a conversão para HSV, a separação do canal HUE e<br />
então a subtração do fundo para que as cores <strong>de</strong> i<strong>de</strong>ntificação do robô e do alvo<br />
possam ser <strong>de</strong>tectadas. Quando a il<strong>um</strong>inação variava, por menos que fosse, a câmera<br />
reajustava o brilho automaticamente e então o fundo não era mais o mesmo. Isso fazia<br />
com que aparecessem diversas manchas na imagem. Por isso, é muito importante fazer<br />
os testes em superfície fosca e utilizar cores foscas para o robô e para o alvo. Com<br />
todos esses ruídos, facilmente o sistema <strong>de</strong> seguimento <strong>de</strong> cor perdia os objetos ou<br />
mesmo unia duas ou mais cores como se fossem apenas <strong>um</strong>a, resultando em <strong>um</strong>a falha<br />
total do sistema. Outro problema encontrado, diz respeito à configuração da câmera no<br />
ambiente. Como a câmera capturava o ambiente a <strong>um</strong>a inclinação <strong>de</strong> -30º com a<br />
horizontal, e a mesa <strong>de</strong> testes ficava a cerca <strong>de</strong> 130 cm abaixo da câmera e a <strong>um</strong>a<br />
distância horizontal <strong>de</strong> 180 cm, quando o robô se afastava muito da câmera as regiões<br />
coloridas se tornavam muito pequenas, embora a área da cor selecionada não fosse<br />
redimensionada. Isso fazia com que as regiões se aproximassem muito a<strong>um</strong>entando as<br />
chances <strong>de</strong> que as áreas inicialmente selecionadas se fundissem. Devido à distância,<br />
também foi observado que quando as regiões coloridas se tornavam muito pequenas o<br />
sistema <strong>de</strong> seguimento <strong>de</strong> cor perdia a cor com facilida<strong>de</strong>, pois durante o movimento<br />
do robô muitos ruídos na imagem eram gerados e se o robô se aproximasse <strong>de</strong>sses<br />
ruídos o sistema po<strong>de</strong>ria confundi-los com a cor que estava sendo acompanhada,<br />
resultando na falha do teste.<br />
Nas Figura 21 e 22 po<strong>de</strong>-se ver as imagens do sistema em funcionamento<br />
durante a execução <strong>de</strong> <strong>um</strong>a tarefa. Note que na Figura 21 as cores haviam apenas sido<br />
selecionadas e o robô ainda estava em repouso. Na Figura 22 o robô estava se<br />
locomovendo na direção do alvo. Repare que neste último caso, muitos ruídos<br />
surgiram na imagem e a tarefa po<strong>de</strong>ria falhar com relativa facilida<strong>de</strong> caso o robô<br />
transitasse em regiões com muito ruído.<br />
A respeito dos ruídos gerados na imagem durante a execução da tarefa, alg<strong>um</strong>as<br />
precauções po<strong>de</strong>m ser tomadas a fim <strong>de</strong> minimizar as chances do sistema <strong>de</strong><br />
seguimento <strong>de</strong> cor falhar. São elas:
48<br />
➢<br />
➢<br />
➢<br />
➢<br />
➢<br />
a estrutura do robô e a superfície em que ele se movimenta <strong>de</strong>vem ser foscas;<br />
<strong>de</strong>ve-se evitar que ocorra variação <strong>de</strong> l<strong>um</strong>inosida<strong>de</strong> no ambiente;<br />
vibrações da superfície em que o robô se movimenta e <strong>de</strong> sua própria estrutura<br />
<strong>de</strong>vem ser evitadas ou minimizadas;<br />
a distância entre o robô e a câmera não po<strong>de</strong> ser muito elevada, pois a chance<br />
do sistema <strong>de</strong> seguimento <strong>de</strong> cor per<strong>de</strong>r as cores ou mesmo per<strong>de</strong>r a precisão ao<br />
inferir a orientação do robô a<strong>um</strong>enta significativamente com a distância;<br />
os testes mostraram não ser recomendável o uso <strong>de</strong> webcam em sistemas como<br />
este, pois estas fazem ajuste automático <strong>de</strong> brilho com a mínima variação <strong>de</strong><br />
l<strong>um</strong>inosida<strong>de</strong>, e nesse momento muitos ruídos são inseridos no sistema.<br />
Com base nos itens <strong>de</strong>scritos acima e levando-se em consi<strong>de</strong>ração as condições<br />
em que o teste da Figura 22 foi feito, po<strong>de</strong>-se atribuir os ruídos capturados nessa<br />
imagem à vibração da estrutura do robô, à vibração da mesa em que ele se<br />
movimentava, e também à variação <strong>de</strong> l<strong>um</strong>inosida<strong>de</strong> no momento do teste.<br />
Apesar dos ruídos gerados, a maioria dos testes foi bem sucedida. Ocorreram<br />
problemas apenas nos testes em que os robôs estavam muito distantes da câmera, e<br />
naqueles em que os robôs transitavam nas regiões da imagem com excessivos ruídos<br />
provocados por sobras e por variações intensas <strong>de</strong> l<strong>um</strong>inosida<strong>de</strong>. Falharam também os<br />
testes em que as velocida<strong>de</strong>s linear e angular do robô estavam ajustadas para valores<br />
muito elevados. Com isso, através <strong>de</strong> experimentos chegou-se a valores <strong>de</strong> V max e ω max<br />
iguais a 50% e 5%, respectivamente.
49<br />
Figura 21: Cores selecionadas com o sistema em repouso.<br />
Figura 22: Cores selecionadas e ruídos gerados com o sistema em<br />
funcionamento.
50<br />
6 CONCLUSÃO<br />
O sistema elaborado neste projeto tem como intuito principal a criação <strong>de</strong> <strong>um</strong>a<br />
aplicação capaz <strong>de</strong> movimentar robôs em <strong>um</strong> ambiente <strong>utilizando</strong>-se técnicas <strong>de</strong> visão<br />
computacional e comunicação sem fio pelo padrão 802.15.4, ZigBee. É também <strong>de</strong><br />
interesse que este sistema seja aplicável a tarefas em que os robôs envolvidos possam<br />
trabalhar em cooperação.<br />
Apesar <strong>de</strong> não ter sido feita <strong>um</strong>a aplicação envolvendo mais <strong>de</strong> <strong>um</strong> robô, o<br />
sistema foi preparado para tornar isso possível. No entanto, <strong>um</strong>a aplicação com mais<br />
robôs exigiria a criação <strong>de</strong> <strong>um</strong>a lógica <strong>de</strong> execução <strong>de</strong> tarefas capaz <strong>de</strong> controlá-los <strong>de</strong><br />
modo organizado <strong>de</strong> acordo com a tarefa a ser executada. Assim, seriam necessárias<br />
várias marcações coloridas no ambiente e tarefas personalizadas para quantida<strong>de</strong>s<br />
diferentes <strong>de</strong> robôs, isto é, seria necessário a criação <strong>de</strong> <strong>um</strong>a estratégia mais complexa<br />
<strong>de</strong> execução <strong>de</strong> tarefas.<br />
O padrão ZigBee mostrou-se bastante interessante tanto pela simplicida<strong>de</strong> <strong>de</strong><br />
utilização quando pelas características técnicas que apresenta. A comunicação entre os<br />
dispositivos é feita <strong>de</strong> maneira bastante simplificada e eficiente. Apesar <strong>de</strong> que as<br />
instruções do XBee não tenham sido exploradas a fundo, pelo conjunto <strong>de</strong> instruções<br />
que apresenta po<strong>de</strong>-se ter <strong>um</strong>a idéia da versatilida<strong>de</strong> <strong>de</strong>ste dispositivo. Aplicações<br />
muito complexas po<strong>de</strong>m ser <strong>de</strong>senvolvidas <strong>utilizando</strong>-se alg<strong>um</strong>as poucas funções<br />
como checagem <strong>de</strong> nível <strong>de</strong> bateria, nível <strong>de</strong> sinal, captura <strong>de</strong> informações <strong>de</strong> outros<br />
dispositivos no campo <strong>de</strong> alcance e en<strong>de</strong>reçamento <strong>de</strong> informações a dispositivos<br />
específicos ou em broadcast. Além disso, o ZigBee mostra-se bastante interessante<br />
com relação às técnicas <strong>de</strong> modulação que utiliza e também em relação à segurança<br />
dos dados que trafegam na re<strong>de</strong>.<br />
Embora os resultados tenham sido satisfatórios para este projeto, sistemas como<br />
esse precisam ser muito bem <strong>de</strong>senvolvidos e melhorados para que influências<br />
externas não comprometam tanto seu funcionamento. Com este trabalho conclui-se<br />
que o sucesso do sistema <strong>de</strong>pen<strong>de</strong> <strong>de</strong> muitos quesitos que vão <strong>de</strong>s<strong>de</strong> a maneira como a<br />
parte <strong>de</strong> software é <strong>de</strong>senvolvida até o tipo <strong>de</strong> equipamento que se utiliza. Deve-se<br />
também provi<strong>de</strong>nciar filtros para imagens capazes <strong>de</strong> reduzir os ruídos e então
51<br />
a<strong>um</strong>entar a eficiência e confiabilida<strong>de</strong> do sistema como <strong>um</strong> todo. Isso é <strong>de</strong> extrema<br />
importância, pois nenh<strong>um</strong> sistema funciona em condições <strong>de</strong> isolamento total e falhas<br />
po<strong>de</strong>m ocorrer quando menos se espera, e por isso, o sistema <strong>de</strong>ve estar preparado para<br />
lidar com elas.<br />
6.1 Trabalhos Futuros<br />
Muitas melhorias são planejadas para trabalhos futuros. O atual trabalho ainda<br />
não consi<strong>de</strong>ra sistemas <strong>de</strong> sensoriamento dos robôs e nem mesmo dispositivos que<br />
possibilitem giros calculados e precisos. O sistema <strong>de</strong> seguimento <strong>de</strong> cor é ainda <strong>um</strong><br />
pouco falho e isso po<strong>de</strong> fazer com que o acompanhamento dos robôs seja prejudicado<br />
<strong>de</strong>pen<strong>de</strong>ndo <strong>de</strong> suas velocida<strong>de</strong>s ou mesmo da mudança <strong>de</strong> intensida<strong>de</strong> l<strong>um</strong>inosa no<br />
ambiente, já que a webcam utilizada faz ajustes automáticos diminuindo ou<br />
a<strong>um</strong>entando o brilho da imagem.<br />
Para trabalhos futuros, além da implementação <strong>de</strong> sistemas mais robustos<br />
incluindo sensoriamento e melhorias no sistema <strong>de</strong> seguimento <strong>de</strong> cor, planeja-se<br />
também <strong>um</strong> sistema <strong>de</strong> reconhecimento automático dos robôs ativos na área <strong>de</strong> alcance<br />
do XBee bem como <strong>um</strong> sistema capaz <strong>de</strong> <strong>de</strong>tectar as cores do robôs encontrados sem<br />
que haja necessida<strong>de</strong> <strong>de</strong> intervenção h<strong>um</strong>ana, tal como é feito no presente trabalho.<br />
Outro objetivo para trabalhos futuros é fazer com que os robôs sempre cheguem ao<br />
alvo com <strong>um</strong>a orientação específica em relação ao objeto marcado como alvo,<br />
in<strong>de</strong>pen<strong>de</strong>nte das condições iniciais do sistema.<br />
A respeito do sistema <strong>de</strong> visão como <strong>um</strong> todo, é também <strong>de</strong>sejável que as<br />
funções <strong>de</strong> manipulação <strong>de</strong> imagens possam ser aceleradas, visto que o atual sistema<br />
exige <strong>um</strong>a performance consi<strong>de</strong>rável do computador. Isso ocorre em parte pelo fato <strong>de</strong><br />
que alg<strong>um</strong>as das funções do sistema apresentado nesse projeto po<strong>de</strong>riam ter sido<br />
melhor <strong>de</strong>senvolvidas para otimizá-lo. A biblioteca OpenCV oferece muitos recursos<br />
po<strong>de</strong>rosos que se bem aplicados po<strong>de</strong>m contribuir para a criação <strong>de</strong> sistemas cada vez<br />
mais robustos e mais inteligentes.
52<br />
APÊNDICE A<br />
Para o <strong>controle</strong> do MSP430 foram feitas alg<strong>um</strong>as adaptações no código<br />
<strong>de</strong>senvolvido em [14]. As explicações po<strong>de</strong>m ser encontradas em forma <strong>de</strong><br />
comentários no corpo do programa.<br />
A principal adaptação feita diz respeito à retirada do controlador integrador que<br />
está presente no programa original. Isso foi feito porque todo o <strong>controle</strong> dos robôs<br />
passou a ser realizado pelo programa <strong>de</strong> visão computacional a fim <strong>de</strong> reduzir a carga<br />
<strong>de</strong> processamento <strong>de</strong> cada robô.<br />
Abaixo, segue a listagem completa do código em C.<br />
Arquivo: pwm2_higor.c<br />
#inclu<strong>de</strong> <br />
#inclu<strong>de</strong> <br />
#<strong>de</strong>fine L 19 //distancia entre as rodas, em cm<br />
#<strong>de</strong>fine PWM_PERIOD 400 //60000 // 50<br />
#<strong>de</strong>fine MOTOR_LEFT 0 //en<strong>de</strong>reco do motor esquerdo<br />
#<strong>de</strong>fine MOTOR_RIGHT 1 //en<strong>de</strong>reco do motor direito<br />
#<strong>de</strong>fine MAX_VAL 100 //maximo valor para velocida<strong>de</strong>s<br />
#<strong>de</strong>fine MIN_VAL -100 //minimo valor para velocida<strong>de</strong>s<br />
#<strong>de</strong>fine FRAME_SIZE 5 //quantida<strong>de</strong> <strong>de</strong> bytes para receber/enviar<br />
#<strong>de</strong>fine SEGUIDOR 0 //n<strong>um</strong>ero do seguidor (<strong>de</strong>ve ser mudado para o<br />
//programa <strong>de</strong> cada seguidor)<br />
#<strong>de</strong>fine FROM_SEG 12 //informacao vinda do modulo seguidor (robo),<br />
//apenas confirmacao<br />
#<strong>de</strong>fine FROM_LID 13 //informacao vinda do li<strong>de</strong>r (PC)<br />
int vel_linear = 0;<br />
//velocida<strong>de</strong> linear <strong>de</strong>sejada<br />
int vel_angular = 0;<br />
//velocida<strong>de</strong> angular <strong>de</strong>sejada<br />
int vel_direita = 0;<br />
int vel_esquerda = 0;<br />
int power[2] = {0,0};<br />
//power guarda os valores para ajustar as<br />
//velocida<strong>de</strong> dos motores direito e esquerdo<br />
short int in<strong>de</strong>x_rx = 0; //in<strong>de</strong>x_rx para o buffer_rx<br />
short int buffer_tx = 0; //armazena o byte que sera enviado ao PC<br />
short int buffer_rx[FRAME_SIZE] = { 0, 0, 0, 0, 0 };<br />
//armazena os bytes recebidos do PC<br />
//1 -> sinal da velocida<strong>de</strong> linear<br />
//2 -> modulo da velocida<strong>de</strong> linear<br />
//3 -> sinal da velocida<strong>de</strong> angular<br />
//4 -> modulo da velocida<strong>de</strong> angular<br />
//5 -> seguidor/comando
----------------- CONFERE E AJUSTA VELOCIDADES MAXIMAS --------------//<br />
int limit_range( float value )<br />
{<br />
if ( value < MIN_VAL )<br />
return MIN_VAL;<br />
else if ( value > MAX_VAL )<br />
return MAX_VAL;<br />
else<br />
return value;<br />
}<br />
//-------------------- AJUSTA A POTENCIA DOS MOTORES ------------------//<br />
void alter_power(short int motor_in<strong>de</strong>x)<br />
//ajusta cada motor com o valor <strong>de</strong> PWM calculado para cada roda<br />
{<br />
if (motor_in<strong>de</strong>x == MOTOR_RIGHT)<br />
{<br />
power[ motor_in<strong>de</strong>x ] = limit_range(vel_direita);<br />
if (power[motor_in<strong>de</strong>x] < 0)<br />
{<br />
TBCCR3 = 0;<br />
TBCCR4 = (int)(4 * (-power[motor_in<strong>de</strong>x]));<br />
}<br />
else<br />
{<br />
TBCCR3 = (int)(4 * power[ motor_in<strong>de</strong>x]);<br />
TBCCR4 = 0;<br />
}<br />
}<br />
else if (motor_in<strong>de</strong>x == MOTOR_LEFT)<br />
{<br />
power[ motor_in<strong>de</strong>x ] = limit_range(vel_esquerda);<br />
53<br />
}<br />
}<br />
if (power[motor_in<strong>de</strong>x] < 0)<br />
{<br />
TBCCR1 = (int)(4 * (-power[motor_in<strong>de</strong>x]));<br />
TBCCR2 = 0;<br />
}<br />
else<br />
{<br />
TBCCR1 = 0;<br />
TBCCR2 = (int)(4 * power[motor_in<strong>de</strong>x]);<br />
}<br />
//---------------------- ATUALIZA AS VELOCIDADES ----------------------//<br />
void update_velocities(void)<br />
{<br />
// velocida<strong>de</strong> linear<br />
vel_linear = (short int)buffer_rx[1];<br />
// velocida<strong>de</strong> angular<br />
vel_angular = (short int)buffer_rx[3];<br />
if (buffer_rx[0] == 1)
54<br />
vel_linear = -vel_linear;<br />
if (buffer_rx[2] == 1)<br />
vel_angular = -vel_angular;<br />
// separa as velocida<strong>de</strong>s <strong>de</strong> cada roda a partir da<br />
//velocida<strong>de</strong> angular e linear<br />
vel_direita = vel_linear + (vel_angular * L)/ 2;<br />
vel_esquerda = vel_linear - (vel_angular * L)/ 2;<br />
}<br />
//---------------------- CONTROLE DE VELOCIDADES ----------------------//<br />
// Procedimento principal<br />
void speed_control( void )<br />
//implementa o loop <strong>de</strong> <strong>controle</strong><br />
{<br />
int testeBuffer = 0;<br />
while(1)<br />
{<br />
if ((buffer_rx[4] == SEGUIDOR))<br />
{<br />
update_velocities();<br />
alter_power(MOTOR_LEFT);<br />
alter_power(MOTOR_RIGHT);<br />
testeBuffer = 0;<br />
}<br />
// FROM_SEG = 12, FROM_LID = 13<br />
else if ((buffer_rx[4] == FROM_LID) &&<br />
(buffer_rx[3] == SEGUIDOR) && (testeBuffer == 0))<br />
{<br />
buffer_tx = SEGUIDOR;<br />
U0TXBUF = buffer_tx;<br />
testeBuffer = 1; // <strong>controle</strong> <strong>de</strong> execucao<br />
}<br />
}<br />
}<br />
//--------------------- INICIA COMUNICACAO SERIAL ---------------------//<br />
void initCOM( void ) {<br />
ME1 = URXE0 + UTXE0;<br />
U0CTL = 0;<br />
U0CTL = CHAR + SWRST; // Configura para bit <strong>de</strong> parida<strong>de</strong> 8 bits<br />
//recebidos e en<strong>de</strong>recamento por inativida<strong>de</strong> <strong>de</strong> linha<br />
U0TCTL = SSEL1 + SSEL0; // configura o clock da USART para o SMCLK<br />
//que <strong>de</strong>ve ser <strong>de</strong> 1MHz<br />
//U0RCTL = 0; // configura a interrupcao <strong>de</strong> caracteres<br />
U0MCTL = 0x92; // configura a velocida<strong>de</strong> <strong>de</strong> envio para 9600 bps<br />
U0BR0 = 0x41;<br />
U0BR1 = 0x03;<br />
U0CTL = U0CTL & 0xfe ;<br />
IE1 = URXIE0 + UTXIE0;<br />
}<br />
//---------------------------- INICIA PWM ----------------------------//<br />
void initPWM( void )<br />
{
55<br />
// configuracao do Timer_B para o <strong>controle</strong> do PWM<br />
TBCTL = TBSSEL_2 + ID_0 + MC_1;<br />
TBCCR0 = PWM_PERIOD - 1;// Clock Frequency: 8000000/(ID_X *<br />
//PWM_PERIOD)<br />
TBCCTL1 = OUTMOD_7; // TBCCR1 in output mo<strong>de</strong>: 7 - reset/set<br />
TBCCTL2 = OUTMOD_7; // TBCCR2 in output mo<strong>de</strong>: 7 - reset/set<br />
TBCCTL3 = OUTMOD_7; // TBCCR3 in output mo<strong>de</strong>: 7 - reset/set<br />
TBCCTL4 = OUTMOD_7; // TBCCR4 in output mo<strong>de</strong>: 7 - reset/set<br />
TBCCR1 = 0;<br />
// sem sinal inicial<br />
TBCCR2 = 0;<br />
// sem sinal inicial<br />
TBCCR3 = 0;<br />
TBCCR4 = 0;<br />
}<br />
//-------------------------- ROTINA PRINCIPAL -------------------------//<br />
int main(void)<br />
{<br />
unsigned int i;<br />
// Inicializacoes<br />
WDTCTL = WDTPW + WDTHOLD;<br />
// para o Watchdog Timer<br />
// Turning XT1 (32kHz) on<br />
_BIC_SR (OSCOFF);<br />
// liga XT1<br />
BCSCTL1 &= ~XTS;<br />
// modo LF<br />
for (i = 0xFFFF; i > 0; i--); // tempo para ajuste do oscilador<br />
// XT1 is on<br />
// Turning XT2 (8MHz) on<br />
BCSCTL1 &= ~XT2OFF;<br />
// liga XT2<br />
do<br />
{<br />
IFG1 &= ~OFIFG; // limpa o flag OSCFault<br />
for (i = 0xFF; i > 0; i--); // tempo para ajuste do flag<br />
}<br />
while ((IFG1 & OFIFG) != 0); // o flag OSCFault continua ajustado?<br />
// XT2 is on<br />
BCSCTL2 |= SELM_2 + DIVM_0 + // XT2 e a fonte para MCLK,<br />
// divisor <strong>de</strong> MCLK e 1<br />
SELS + DIVS_0;<br />
// DCO e a fonte para SMCLK,<br />
// divisor <strong>de</strong> SMCLK e 1<br />
BCSCTL1 |= DIVA_0; // divisor para ACLK e 1<br />
// Nesse ponto nos temos a seguinte configuracao <strong>de</strong> clock:<br />
// MCLK e 8 MHz (<strong>de</strong> XT2)<br />
// SMCLK e 8 MHz (<strong>de</strong> XT2)<br />
// ACLK e 32 kHz (<strong>de</strong> XT1)<br />
// Ajustes para pinos <strong>de</strong> E/S<br />
// P1<br />
P1DIR = 0xFF;<br />
P1SEL = 0x00;<br />
// P2<br />
P2DIR = 0xFF;<br />
// nao utilizado (NC)<br />
// todos os pinos como E/S<br />
// nao utilizado (NC)
56<br />
P2SEL = 0x00;<br />
// todos os pinos como E/S<br />
// P3<br />
P3DIR = 0xDB; //<br />
P3SEL = 0x3C; //<br />
// P4<br />
P4DIR = 0xFF;<br />
P4SEL = 0x1E;<br />
// P5<br />
P5DIR = 0xFF;<br />
P5SEL = 0x00;<br />
// P6<br />
P6DIR = 0xFF;<br />
P6SEL = 0x00;<br />
// saidas<br />
// P4.1 a P4.4 como TB1-4, outros como E/S<br />
// nao utilizado (NC)<br />
// todos os pinos como E/S<br />
// nao utilizado (NC)<br />
// todos os pinos como E/S<br />
initCOM();<br />
initPWM();<br />
_EINT();<br />
// habilita interrupcoes<br />
speed_control(); // rotina principal<br />
}<br />
return 0;<br />
//--------------------- TRATAMENTO DE INTERRUPCAO ---------------------//<br />
// Tratamento <strong>de</strong> interrupcoes para recebimento <strong>de</strong> dados pela USART0<br />
#pragma vector = USART0RX_VECTOR<br />
__interrupt void usart0_rx(void)<br />
{<br />
buffer_rx[in<strong>de</strong>x_rx] = U0RXBUF; // armazena na posicao 0 primeiro<br />
}<br />
if (++in<strong>de</strong>x_rx == FRAME_SIZE)<br />
{<br />
in<strong>de</strong>x_rx = 0;<br />
}<br />
// Tratamento <strong>de</strong> interrupcoes para envio <strong>de</strong> dados pela USART0<br />
#pragma vector = USART0TX_VECTOR<br />
__interrupt void usart0_tx(void)<br />
{<br />
/* if (in<strong>de</strong>x_tx < FRAME_SIZE)<br />
{<br />
U0TXBUF = buffer_tx[in<strong>de</strong>x_tx]; // envia a posicao 0 primeiro<br />
in<strong>de</strong>x_tx++;<br />
}<br />
else<br />
{<br />
in<strong>de</strong>x_tx = FRAME_SIZE; // FRAME_SIZE = 5<br />
}<br />
*/<br />
}
57<br />
APÊNDICE B<br />
O programa utilizado para <strong>controle</strong> dos motores e seguimento <strong>de</strong> cor foi<br />
baseado no trabalho <strong>de</strong>senvolvido pelo PET da Engenharia <strong>de</strong> Computação da UFES.<br />
No entanto, o trabalho original consi<strong>de</strong>ra a colocação <strong>de</strong> <strong>um</strong>a câmera sobre a região<br />
em que o futebol <strong>de</strong> robôs é praticado, enquanto que neste trabalho a câmera foi<br />
colocada a <strong>um</strong>a altura, distância e ângulo com a horizontal conhecidos. Com isso,<br />
passou-se a trabalhar com imagens projetivas e por isso alg<strong>um</strong>as adaptações se fizeram<br />
necessárias.<br />
Na lista abaixo estão todos os arquivos utilizados pelo programa completo com<br />
a indicação se passaram ou não por alterações.<br />
Referência Nome do arquivo Modificação<br />
1 RobotSystem.cpp não<br />
2 SistemaRobotico.h não<br />
3 SistemaRobotico.cpp não<br />
4 ComSerial.h sim<br />
5 ComSerial.cpp sim<br />
6 Camera.h não<br />
7 Camera.cpp não<br />
8 CoordSystem.h não<br />
9 CoordSystem.cpp sim<br />
10 <strong>de</strong>fines.h não<br />
11 DadosVisao.h não<br />
12 DadosVisao.cpp não<br />
13 Tempo.h não<br />
14 Tempo.cpp não<br />
15 BasicProcessor.h não<br />
16 BasicProcessor.cpp não<br />
17 SimpleTracker.h não<br />
18 SimpleTracker.cpp não<br />
19 DoubleTracker.h não<br />
20 DoubleTracker.cpp não<br />
21 TeamTracker.h não<br />
22 TeamTracker.cpp não<br />
23 SistemaVisao.h sim<br />
24 SistemaVisao.cpp sim
A seguir, são listados os arquivos alterados e suas respectivas mudanças.<br />
Repare que a n<strong>um</strong>eração na frente <strong>de</strong> cada arquivo listado segue a referência acima.<br />
58<br />
4. ComSerial.h<br />
A este arquivo foi adicionada a função read() e a função setBufferInfoSolicita().<br />
A primeira função é para possibilitar a leitura do buffer quando o MSP430 envia dados<br />
informando o código <strong>de</strong> i<strong>de</strong>ntificação do robô. A segunda, ajusta o buffer a ser enviado<br />
com valores que o MSP430 interpreta como sendo a solicitação do código interno do<br />
robô. Embora este código esteja completamente funcional, não foi implementado no<br />
programa do MSP430 <strong>um</strong>a função capaz <strong>de</strong> utilizá-lo.<br />
#inclu<strong>de</strong> "windows.h"<br />
#<strong>de</strong>fine COMM_BUFFER_SIZE 5<br />
#<strong>de</strong>fine MIN_VAL -100 // valor em porcentagem<br />
#<strong>de</strong>fine MAX_VAL 100<br />
#ifn<strong>de</strong>f COMSERIAL_H // para evitar problema <strong>de</strong> "'class' type re<strong>de</strong>finition"<br />
#<strong>de</strong>fine COMSERIAL_H<br />
class ComSerial<br />
{<br />
DWORD bytes_2_write;<br />
DWORD bytes_2_read;<br />
DWORD bytes_written;<br />
DWORD bytes_read;<br />
HANDLE com1;<br />
DCB dcb;<br />
DCB previous_dcb;<br />
int limit_range(int);<br />
unsigned char ModV; // valores que serao enviados ao microcontrolador<br />
unsigned char SinV;<br />
unsigned char ModW;<br />
unsigned char SinW;<br />
float param; // n<strong>um</strong>ero a ser convertido<br />
float fracpart; // parte fracionaria do n<strong>um</strong>ero<br />
float intpart; // parte inteira do n<strong>um</strong>ero<br />
public:<br />
ComSerial();<br />
~ComSerial();<br />
unsigned char BufferEnvia[COMM_BUFFER_SIZE]; // dados a ser enviado<br />
unsigned char BufferRecebe[1];<br />
unsigned char buffer_recebido[10];
59<br />
int open(); //Abre e configura a porta Com1<br />
int close(); //Fecha a porta e reseta para valores iniciais<br />
void setBuffer(float v,float w, unsigned char s);<br />
void setBufferInfoSolicita(unsigned char s);<br />
void getBuffer(); // le a porta serial<br />
int write(); //escreve o buffer na porta<br />
int read(); //le o buffer da porta<br />
public:<br />
friend class SimpleTracker;<br />
friend class DoubleTracker;<br />
};<br />
#endif<br />
5. ComSerial.cpp<br />
Nesse arquivo, foi implementada a função <strong>de</strong> leitura, read(), e a função <strong>de</strong><br />
ajuste do buffer, setBufferInfoSolicita().<br />
#inclu<strong>de</strong> <br />
#inclu<strong>de</strong> "ComSerial.h"<br />
#inclu<strong>de</strong> <br />
#inclu<strong>de</strong> <br />
using namespace std;<br />
ComSerial::ComSerial() // construtor<br />
{<br />
bytes_2_write = COMM_BUFFER_SIZE;<br />
bytes_2_read = 1;<br />
bytes_written = 0;<br />
bytes_read = 0;<br />
BufferEnvia[0] = 0;<br />
BufferEnvia[1] = 0;<br />
BufferEnvia[2] = 0;<br />
BufferEnvia[3] = 0;<br />
BufferEnvia[4] = 0;<br />
BufferRecebe[0] = 0;<br />
}<br />
ComSerial::~ComSerial() // <strong>de</strong>strutor<br />
{<br />
}<br />
int ComSerial::limit_range(int value)<br />
{<br />
if ( value < MIN_VAL )<br />
return MIN_VAL;<br />
else if ( value > MAX_VAL )<br />
return MAX_VAL;<br />
else<br />
return value;<br />
}<br />
int ComSerial::open()
60<br />
{<br />
TCHAR *pcCommPort = TEXT("COM1");<br />
com1 = CreateFile(pcCommPort, GENERIC_READ | GENERIC_WRITE, 0, NULL,<br />
OPEN_EXISTING, 0, NULL);<br />
if (com1 == INVALID_HANDLE_VALUE) {<br />
cout
61<br />
}<br />
}<br />
return 0;<br />
cout
62<br />
{<br />
SinW = unsigned char(0);<br />
}<br />
else<br />
{<br />
SinW = unsigned char(1);<br />
}<br />
ModW = unsigned char(abs(vel_w));<br />
// coloca os dados no buffer para serem enviados<br />
BufferEnvia[0] = SinV;<br />
BufferEnvia[1] = ModV;<br />
BufferEnvia[2] = SinW;<br />
BufferEnvia[3] = ModW;<br />
BufferEnvia[4] = s;<br />
// <strong>de</strong>finir as estrategias <strong>de</strong> <strong>controle</strong> da<br />
// tafera por robo<br />
}<br />
void ComSerial::setBufferInfoSolicita(unsigned char s)<br />
{<br />
// coloca os dados no buffer para solicitar informacoes<br />
BufferEnvia[0] = 0;<br />
BufferEnvia[1] = 0;<br />
BufferEnvia[2] = 0;<br />
BufferEnvia[3] = s;<br />
BufferEnvia[4] = 13; // informa que o pedido vem do li<strong>de</strong>r<br />
}<br />
void ComSerial::getBuffer()<br />
{<br />
read();<br />
}<br />
9. CoordSystem.cpp<br />
Neste arquivo foi mudada a função transform() para que os pontos capturados<br />
da imagem fossem corrigidos a<strong>de</strong>quadamente em relação ao centro da imagem<br />
capturada pela câmera. Neste ponto <strong>de</strong>ve-se levar em consi<strong>de</strong>ração que para a webcam<br />
utilizada a origem do sistema é o ponto inferior esquerdo.<br />
#inclu<strong>de</strong> "CoordSystem.h"<br />
#inclu<strong>de</strong> <br />
#inclu<strong>de</strong> <br />
Vec2f::Vec2f()<br />
{<br />
x=0;<br />
y=0;<br />
}<br />
// construtor<br />
Vec2f::Vec2f(float a, float b)<br />
{<br />
x=a;<br />
y=b;
63<br />
}<br />
Vec2f::Vec2f(CvPoint P)<br />
{<br />
x = P.x;<br />
y = P.y;<br />
}<br />
Vec2f Vec2f::operator=(const Vec2f& V)<br />
{<br />
x = V.x;<br />
y = V.y;<br />
return *this;<br />
}<br />
Vec2f Vec2f::operator+(const Vec2f& V2)<br />
{<br />
Vec2f result;<br />
// result e <strong>um</strong>a variavel do tipo Vec2f<br />
result.x = x + V2.x; // Atencao: result.x != x != V2.x<br />
result.y = y + V2.y;<br />
}<br />
return result;<br />
Vec2f Vec2f::operator-(const Vec2f& V2)<br />
{<br />
Vec2f result;<br />
result.x = x - V2.x;<br />
result.y = y - V2.y;<br />
}<br />
return result;<br />
float Vec2f::operator*(const Vec2f& V)<br />
{<br />
return x*V.x + y*V.y;<br />
}<br />
Vec2f Vec2f::operator/(const float alfa)<br />
{<br />
Vec2f result;<br />
result.x = x/alfa;<br />
result.y = y/alfa;<br />
return result;<br />
}<br />
void Vec2f::normaliza(float v)<br />
{<br />
float alfa = x*x+y*y;<br />
}<br />
x *= v/alfa;<br />
y *= v/alfa;<br />
float Vec2f::distance(Vec2f& V)<br />
{<br />
return sqrt(pow((x-V.x),2) + pow((y-V.y),2));<br />
}<br />
// pow(7,3) = 7^3
64<br />
float Vec2f::angle(Vec2f& V)<br />
{<br />
static float pi = 3.141592654;<br />
float <strong>de</strong>ltaX, <strong>de</strong>ltaY, ang;<br />
<strong>de</strong>ltaX = V.x - x;<br />
<strong>de</strong>ltaY = V.y - y;<br />
ang = atan(<strong>de</strong>ltaY/<strong>de</strong>ltaX);<br />
}<br />
if(<strong>de</strong>ltaX > 0)<br />
if(<strong>de</strong>ltaY < 0)<br />
return ang + 2*pi;<br />
else<br />
return ang;<br />
else<br />
return ang + pi;<br />
CoordSystem::CoordSystem(Vec2f ref[4])<br />
{<br />
Vec2f aux1, aux2;<br />
float aux3, aux4;<br />
/*Calculo <strong>de</strong> u1*/<br />
aux1 = (ref[1]-ref[0]);<br />
aux2 = (ref[3]-ref[2]);<br />
u1 = (aux1 + aux2)/2;<br />
u1.normaliza(120);<br />
/*Calculo do angulo*/<br />
aux3 = atan(fabs(aux1.y)/fabs(aux1.x));<br />
aux4 = atan(fabs(aux2.y)/fabs(aux2.x));<br />
beta = (aux3 + aux4)/2;<br />
/*Calculo <strong>de</strong> u2*/<br />
aux1 = ref[2]-ref[0];<br />
aux2 = ref[3]-ref[1];<br />
u2 = (aux1 + aux2)/2;<br />
u2.normaliza(70);<br />
}<br />
/*Calculo do centro*/<br />
Centro = (ref[0]+ref[1]+ref[2]+ref[3])/4;<br />
Vec2f CoordSystem::transform(Vec2f &ponto)<br />
{<br />
Vec2f aux;<br />
aux.x = ponto.x - Centro.x;<br />
aux.y = -(ponto.y - Centro.y);<br />
}<br />
return aux;
65<br />
23. SistemaVisao.h<br />
A aplicação principal foi <strong>de</strong>senvolvida <strong>utilizando</strong>-se os arquivos <strong>de</strong><br />
SistemaVisao. Aqui foram inseridas novas funções, novas variáveis e novas <strong>de</strong>finições<br />
para a aplicação. Foram inseridas informações sobre a posição da câmera em relação à<br />
mesa, on<strong>de</strong> os testes foram feitos, e passou-se a comandar a porta serial por esse<br />
arquivo. As novas funções inseridas foram: calcTransf(), calcMove() e calcAngulo().<br />
#pragma once<br />
#inclu<strong>de</strong> "TeamTracker.h"<br />
#inclu<strong>de</strong> "CoordSystem.h"<br />
#inclu<strong>de</strong> "BasicProcessor.h"<br />
#inclu<strong>de</strong> "Tempo.h"<br />
#inclu<strong>de</strong> "../Controle/ComSerial.h"<br />
// Defininicao <strong>de</strong> constantes<br />
#<strong>de</strong>fine FOCO 767 // Foco da câmera em pixels, encontrado<br />
// com experimento<br />
#<strong>de</strong>fine ALTURA_ROBO 115 // Altura entre a camera e a parte superior<br />
// do robo<br />
#<strong>de</strong>fine ALTURA_MESA 130<br />
#<strong>de</strong>fine FI -0.5236 // Inclinacao da camera em relacao ao<br />
// plano do robo (float), 30º = 0.5236<br />
class SistemaVisao<br />
{<br />
float psi;<br />
float alfa;<br />
float teta;<br />
float v;<br />
float w;<br />
float x[10];<br />
float y[10];<br />
float Xc;<br />
float Yc;<br />
float Zc;<br />
float Xm;<br />
float Zm;<br />
float Xd;<br />
float Zd;<br />
float V_MAX;<br />
float W_MAX;<br />
float Xmundo;<br />
float Zmundo;<br />
float ModE;<br />
float xDest;<br />
float yDest;<br />
int infoRobos[10][3];<br />
char statusRobo[10];<br />
protected:<br />
BasicProcessor* basicProc;<br />
CoordSystem *coordSys;<br />
// angulo entre eixo Z e alvo<br />
// angulo da orientacao do robo em relacao a Z<br />
// teta = psi - alfa<br />
// velocia<strong>de</strong> linear<br />
// velocida<strong>de</strong> angular (giro)<br />
// ponto do robo (3D) projetado na imagem (2D)<br />
// pontos da camera<br />
// pontos do robo no referencial do mundo<br />
// ponto em que se <strong>de</strong>seja chegar<br />
// usados para conversoes<br />
// modulo do erro<br />
// guarda posicao do alvo em pixels<br />
// guarda o nome do robo e suas velocida<strong>de</strong>s<br />
// linear e angular<br />
// informa se o robo esta ativo ou nao
66<br />
SimpleTracker* opponents[MAXP];<br />
SimpleTracker* target; // ponto alvo em que os robos <strong>de</strong>vem chegar<br />
DoubleTracker* players[MAXP];<br />
int NO, NP; /*N<strong>um</strong>ero <strong>de</strong> Opponents e Players inseridos*/<br />
TeamTracker *teamTr;<br />
ComSerial* com;<br />
int addRobotsMo<strong>de</strong>;<br />
Vec2f fieldRef[4];<br />
Vec2f mouseClkPos;<br />
CvRect window;<br />
CvRect primaryArea, secondaryArea;<br />
public:<br />
SistemaVisao(void);<br />
public:<br />
~SistemaVisao(void);<br />
public:<br />
DadosVisao* processaFrame(IplImage* F); //Processa frame e retorna<br />
//informacoes dos robos<br />
void calibra();<br />
Camera* iniciaCamera(Vi<strong>de</strong>oProcessor *VP);<br />
protected:<br />
static void mouseCallback(int events,int x,int y,<br />
int flags,void* param);<br />
void printFieldMenu();<br />
void calcPositions();<br />
void calibCoordS();<br />
void calcBackGnd();<br />
void addRobots();<br />
void calcTransf(float,float,int);<br />
void calcMove(int,float,int);<br />
float calcAngulo(float ExT1, float EyT1);<br />
public:<br />
friend class SimpleTracker;<br />
friend class DoubleTracker;<br />
};<br />
24. SistemaVisao.cpp<br />
As mudanças citadas em SistemaVisao.h foram implementadas neste arquivo.<br />
Aqui são <strong>de</strong>scritas as novas funções e também principais adaptações feitas em<br />
addRobots().<br />
A nova função calcTransf() é responsável por fazer a transformação das<br />
coor<strong>de</strong>nadas da imagem, em pixels, para as coor<strong>de</strong>nadas do mundo, em centímetros.<br />
A função calcMove() cuida da movimentação do robô e faz o <strong>controle</strong> <strong>de</strong><br />
execução calculando e enviando as velocida<strong>de</strong>s linear e angular atualizadas. Essa
67<br />
função também envia o comando <strong>de</strong> parada ao robô quando este se encontra à<br />
distância <strong>de</strong>finida em DIST_SEGURA.<br />
A última, calcAngulo(), calcula o ângulo sempre tomando como referência o<br />
eixo Z positivo. Essa função é utilizada para o cálculo <strong>de</strong> ψ, ângulo entre o centrói<strong>de</strong><br />
do robô e o ponto alvo, e <strong>de</strong> θ, ângulo que fornece a orientação do robô em relação ao<br />
eixo Z. A orientação do robô é medida em relação ao vetor formado entre suas duas<br />
cores <strong>de</strong> i<strong>de</strong>ntificação.<br />
Em addRobots(), as principais mudanças foram feitas em relação às<br />
funcionalida<strong>de</strong>s do menu. Com as alterações é possível receber o código dos robôs<br />
ativos, exibir informações tais como velocida<strong>de</strong> linear e angular atuais, executar a<br />
tarefa e também interrompê-la. Esta tornou-se a principal função <strong>de</strong> <strong>controle</strong> <strong>de</strong><br />
execução da aplicação proposta neste trabalho.<br />
#inclu<strong>de</strong> "windows.h"<br />
#inclu<strong>de</strong> <br />
#inclu<strong>de</strong> "cvcam.h"<br />
#inclu<strong>de</strong> "highgui.h"<br />
#inclu<strong>de</strong> <br />
#inclu<strong>de</strong> <br />
#inclu<strong>de</strong> "SistemaVisao.h"<br />
#<strong>de</strong>fine TAM 480<br />
#<strong>de</strong>fine LIDER 13 // codigo para ser interpretado pelo seguidor<br />
#<strong>de</strong>fine DIST_SEGURA 15 // dist min que o robo fica do alvo antes <strong>de</strong> parar<br />
void gotoxy(int x,int y);<br />
void clrscr(void);<br />
SistemaVisao::SistemaVisao(void)<br />
{<br />
coordSys = NULL;<br />
basicProc = NULL;<br />
teamTr = NULL;<br />
NP = 0;<br />
NP = 0;<br />
addRobotsMo<strong>de</strong> = 0;<br />
for (int i = 0; i < 10; i++)<br />
statusRobo[i] = 'a';<br />
}<br />
SistemaVisao::~SistemaVisao(void)<br />
{<br />
}<br />
// construtor<br />
// p = parado, a = ativida<strong>de</strong><br />
// <strong>de</strong>strutor<br />
Camera* SistemaVisao::iniciaCamera(Vi<strong>de</strong>oProcessor *VP)<br />
{<br />
Camera* cam;
68<br />
clrscr();<br />
int ncams = cvcamGetCamerasCount(); // n<strong>um</strong>ero <strong>de</strong> cameras ativas<br />
if(ncams == 1){<br />
cam = new Camera(0);<br />
cam->setProcessor(VP); // quando é <strong>um</strong> objeto iniciado com new<br />
// usa-se esse tipo <strong>de</strong> referencia<br />
}<br />
else<br />
if(ncams > 1){<br />
int n;<br />
}<br />
else{<br />
}<br />
printf("Existem %d cameras. Escolha <strong>um</strong>a:\n(Observe que 0<br />
representa a primeira)",ncams);<br />
gotoxy(35,0);<br />
scanf_s("%d",&n);<br />
cam = new Camera(n);<br />
cam->setProcessor(VP);<br />
printf("Nao existem cameras instaladas.");<br />
return NULL;<br />
char c = 0;<br />
cvNamedWindow("Config");<br />
do{<br />
clrscr();<br />
gotoxy(10,5);<br />
printf("Escolha <strong>um</strong>a das opcoes abaixo:\n\n");<br />
printf(" -1: Escolher resolucao\n -2: Exibir janela <strong>de</strong><br />
configuracao\n -3: Iniciar Captura\n -4: Continuar");<br />
gotoxy(42,5);<br />
switch(c)<br />
{<br />
case '1': cam->vi<strong>de</strong>oFormat();<br />
break;<br />
case '2': cam->configure();<br />
break;<br />
case '3': cam->start();<br />
break;<br />
}<br />
c = cvWaitKey(0);<br />
}while(c != '4');<br />
}<br />
return cam;<br />
void SistemaVisao::calibCoordS()<br />
{<br />
FILE* arq;<br />
for(int i=0; i
69<br />
int y, int flags, void* param))mouseCallback, this);<br />
int comando = 0;<br />
do{<br />
printFieldMenu(); //Imprime menu <strong>de</strong> configuracao do campo<br />
comando = cvWaitKey(0);<br />
}<br />
switch(comando)<br />
{<br />
case '1':<br />
case '2':<br />
case '3':<br />
case '4': fieldRef[comando-'1'] = mouseClkPos;<br />
break;<br />
//Cria sistema <strong>de</strong> coor<strong>de</strong>nadas!!<br />
case '5': coordSys = new CoordSystem(fieldRef);<br />
gotoxy(5,12);<br />
printf("Centro do sistema <strong>de</strong> coor<strong>de</strong>nadas: (%03.0f,<br />
%03.0f)\n",coordSys->Centro.x,<br />
coordSys->Centro.y);<br />
comando = '6';<br />
break;<br />
}<br />
}while(comando != '6');<br />
void SistemaVisao::calcBackGnd()<br />
{<br />
int quant;<br />
basicProc = new BasicProcessor();<br />
clrscr();<br />
gotoxy(1,1);<br />
// printf("Digite o n<strong>um</strong>ero <strong>de</strong> frames que <strong>de</strong>seja usar para<br />
calcular fundo: ");<br />
// scanf_s("%d",&quant);<br />
quant = 2;<br />
basicProc->calcBackGnd(30);<br />
cvNamedWindow("BackGround");<br />
}<br />
gotoxy(5,5);<br />
printf("\nCalculando...\nPressione qualquer tecla apos termino");<br />
cvWaitKey(5000);<br />
cvDestroyWindow("BackGround");<br />
cvNamedWindow("Hue");<br />
void SistemaVisao::addRobots()<br />
{<br />
float cx1 = 0;<br />
float cx2 = 0;<br />
float cy1 = 0;<br />
float cy2 = 0;<br />
float xPosRobo = 0;<br />
float yPosRobo = 0;<br />
float ExT = 0;<br />
float EyT = 0;<br />
char sinal = '0';<br />
// procedimento principal<br />
// guarda posicao do robo em pixels,<br />
// temporario apenas
70<br />
short int temp = 0;<br />
CvPoint centroTarget; // centro do alvo<br />
CvPoint centroRobo; // centro entre as duas cores do robo<br />
int comando = 0;<br />
addRobotsMo<strong>de</strong> = 1;<br />
com = new ComSerial();<br />
teamTr = new TeamTracker(basicProc->getHue());<br />
teamTr->setCoordSystem(coordSys);<br />
cvSetMouseCallback("Config", (void (__c<strong>de</strong>cl *)(int events, int x,<br />
int y, int flags, void* param))mouseCallback, this);<br />
com->open(); // abre porta serial para comunicacao<br />
// centro do campo<br />
float Xo = 0;<br />
float Yo = 0;<br />
do{<br />
clrscr();<br />
gotoxy(0,1);<br />
printf(" -1: Selecione a cor da frente do robo\n -2: Selecione<br />
a outra cor\n -3: Criar jogador\n -4: Selecione a<br />
cor do alvo\n -5: Criar alvo\n -6: Rastrear robos<br />
ativos\n -7: Exibir informacoes dos robos\n -8:<br />
Executar a tarefa programada\n -9: Interrompe a<br />
tarefa (necessario para utilizar os itens do menu)\n<br />
-s: Sair...\n");<br />
gotoxy(5,12);<br />
printf("Regiao Selecionada: (%d, %d, %d, %d)",window.x,<br />
window.y, window.width, window.height);<br />
comando = cvWaitKey(0);<br />
switch(comando)<br />
{<br />
case '1': primaryArea = window;<br />
break;<br />
case '2': secondaryArea = window;<br />
break;<br />
case '3':<br />
players[NP] = new DoubleTracker(basicProc->getHue(),<br />
primaryArea, secondaryArea);<br />
teamTr->addDoubleTracker(players[NP]);<br />
centroRobo = players[NP]->getCenter(); // em pixels<br />
// centro do robo - centro do sistema <strong>de</strong> coor<strong>de</strong>nadas<br />
xDest = centroRobo.x - coordSys->Centro.x;<br />
yDest = -(centroRobo.y - coordSys->Centro.y);<br />
// resultado em Xmundo e Zmundo, em cm<br />
calcTransf(xDest,yDest,ALTURA_ROBO);<br />
gotoxy(5,14);<br />
printf("Posicao central do robo (X,Z), em cm:<br />
(%03.0f,%03.0f)",Xmundo,Zmundo);<br />
NP++;<br />
break;
71<br />
case '4': primaryArea = window;<br />
break;<br />
case '5': // alvo para todos os robos<br />
gotoxy(5,14);<br />
printf("IMPORTANTE! Apenas o último alvo marcado<br />
sera consi<strong>de</strong>rado!");<br />
target = new SimpleTracker(basicProc->getHue(),<br />
primaryArea);<br />
teamTr->addSimpleTracker(target);<br />
// armazena o centro da area do alvo, ponto na<br />
// imagem 2D<br />
centroTarget = target->getCenter();<br />
// centro do robo - centro do sistema <strong>de</strong> coor<strong>de</strong>nadas<br />
xDest = centroTarget.x - coordSys->Centro.x;<br />
yDest = -(centroTarget.y - coordSys->Centro.y);<br />
// converte xDest e yDest para cm e guarda em<br />
// Zmundo e Xmundo<br />
// Calculo <strong>de</strong> Xm,Ym e Zm em centimetros<br />
// resultado em Xmundo e Zmundo, em cm<br />
calcTransf(xDest,yDest,ALTURA_MESA);<br />
gotoxy(5,14);<br />
printf("Ponto central do alvo (X,Z), em cm:<br />
(%03.0f,%03.0f)",Xmundo,Zmundo);<br />
// Zd e Xd, coor<strong>de</strong>nadas do alvo em cm, no mundo<br />
Xd = Xmundo; // Xd no mundo em cm<br />
Zd = Zmundo; // Zd no mundo em cm<br />
break;<br />
case '6': // Rastreamento <strong>de</strong> robos ativos<br />
printf("\n\nRastreando robos...");<br />
// inicia o vetor buffer_recebido[];<br />
for (int i = 0; i < NP; i++)<br />
com->buffer_recebido[i] = '!'; // vazio!<br />
for (int i = 0; i < NP; i++)<br />
{<br />
com->setBufferInfoSolicita(unsigned char(i));<br />
com->write();<br />
cvWaitKey(300);<br />
// espera 300 ms antes <strong>de</strong><br />
// ler, evita problemas <strong>de</strong><br />
// leitura incorreta<br />
com->read();<br />
com->buffer_recebido[i]=com->BufferRecebe[i];<br />
}<br />
printf("\nModulos encontrados (33 indica<br />
inexistente):\n");<br />
for (int i = 0;i < NP; i++)<br />
printf("%d, ",com->buffer_recebido[i]);<br />
cvWaitKey(2000);<br />
break;<br />
case '7': // exibe informações dos robos<br />
printf("\n\nUltimas informacoes dos robos...\n");<br />
if (NP > 0)<br />
{
72<br />
}<br />
else<br />
for (int i = 0; i < NP; i++)<br />
{<br />
printf("\nInformacoes do Robo: %d\n<br />
Velocida<strong>de</strong> Linear: %d\n Velocida<strong>de</strong><br />
Angular: %d\n",infoRobos[i]<br />
[0],infoRobos[i][1],infoRobos[i][2]);<br />
}<br />
printf("\n\nNenh<strong>um</strong> robo foi <strong>de</strong>tectado! Eles<br />
foram adicionados no sistema <strong>de</strong><br />
visao?\n");<br />
printf("\nAperte qualquer tecla para voltar ao<br />
menu...");<br />
cvWaitKey(0);<br />
break;<br />
case '8': // executar a tarefa<br />
printf("\n\nModo <strong>de</strong> execucao...");<br />
do<br />
{<br />
// varredura dos robores<br />
for (int i = 0; i < NP; i++)<br />
{<br />
// operacao normal usando V_MAX = 50 e W_MAX =<br />
// 5, encontradas nos experimentos<br />
calcMove(50,5,i);<br />
}<br />
comando = '1'; // evita lixo em comando!<br />
// INTERVALO DE CONTROLE<br />
comando = cvWaitKey(500);<br />
} while (comando != '9'); // sai do programa<br />
// para todos os robos<br />
for (int i = 0; i < NP; i++)<br />
{<br />
com->setBuffer(0,0,unsigned char(i));<br />
com->write();<br />
}<br />
printf("\n\nSaindo do modo <strong>de</strong> execucao...\n");<br />
cvWaitKey(1500);<br />
break;<br />
}<br />
}while(comando != 's'); // sai do programa e para os robos<br />
// parar todos os robos antes <strong>de</strong> sair do programa<br />
for (int i = 0; i < NP; i++)<br />
{<br />
com->setBuffer(0,0,unsigned char(i)); // carrega buffer<br />
com->write(); // escreve na porta serial<br />
}<br />
}<br />
printf("\n\nSaindo do programa e parando os robos...\n");<br />
cvWaitKey(1500);<br />
com->close(); // fecha porta serial
73<br />
void SistemaVisao::calcPositions()<br />
{<br />
}<br />
void SistemaVisao::calibra()<br />
{<br />
calibCoordS();<br />
calcBackGnd();<br />
addRobots();<br />
}<br />
void<br />
SistemaVisao::mouseCallback(int events,int x,int y,int flags,void* param)<br />
{<br />
SistemaVisao* self = ((SistemaVisao*)param);<br />
y = TAM-y;<br />
if (events == CV_EVENT_LBUTTONUP)<br />
self->mouseClkPos = cvPoint(x,y);<br />
if (self->addRobotsMo<strong>de</strong>)<br />
if (events == CV_EVENT_LBUTTONDOWN){<br />
self->window.x = x;<br />
self->window.y = y;<br />
}<br />
else if (events == CV_EVENT_LBUTTONUP){<br />
self->window.width = x - self->window.x;<br />
self->window.height = y - self->window.y;<br />
}<br />
}<br />
DadosVisao* SistemaVisao::processaFrame(svImagem* F)<br />
{<br />
DadosVisao* dados = NULL;<br />
cvShowImage("Config",F);<br />
if (basicProc != NULL){<br />
basicProc->processNewFrame(F);<br />
if (teamTr != NULL)<br />
dados = teamTr->findPositions(F);<br />
}<br />
if (!basicProc->isProcessing())<br />
cvShowImage("BackGround",basicProc->getBackGnd());<br />
else{<br />
cvShowImage("Hue",basicProc->getHue());<br />
}<br />
}<br />
return dados;<br />
void SistemaVisao::printFieldMenu()<br />
{<br />
Vec2f ponto;<br />
clrscr();<br />
gotoxy(10,2);<br />
printf("\nDigite <strong>um</strong> dos n<strong>um</strong>eros abaixo para modificar <strong>um</strong> dos pontos<br />
<strong>de</strong> referencia: ");<br />
gotoxy(1,5);
printf("-1: Canto inferior esquerdo\n -2: Canto inferior direito\n<br />
-3: Canto superior esquerdo\n -4: Canto superior direito\n -5:<br />
Cria sistema <strong>de</strong> coor<strong>de</strong>nadas e continua...");<br />
for (int i=0;itransform(mouseClkPos);<br />
printf("Original: (%03.0f, %03.0f), Campo: (%03.3f,<br />
%03.3f)",mouseClkPos.x,mouseClkPos.x,ponto.x,ponto.y);<br />
}<br />
gotoxy(40,3);<br />
void clrscr(void) //clear screen<br />
{<br />
CONSOLE_SCREEN_BUFFER_INFO<br />
csbiInfo;<br />
HANDLE hConsoleOut;<br />
COORD Home = {0,0};<br />
DWORD d<strong>um</strong>my;<br />
hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);<br />
GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo);<br />
}<br />
FillConsoleOutputCharacter(hConsoleOut,' ',csbiInfo.dwSize.X *<br />
csbiInfo.dwSize.Y,Home,&d<strong>um</strong>my);<br />
csbiInfo.dwCursorPosition.X = 0;<br />
csbiInfo.dwCursorPosition.Y = 0;<br />
SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition);<br />
void gotoxy(int x,int y)<br />
{<br />
CONSOLE_SCREEN_BUFFER_INFO<br />
csbiInfo;<br />
HANDLE<br />
hConsoleOut;<br />
}<br />
hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);<br />
GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo);<br />
csbiInfo.dwCursorPosition.X = x;<br />
csbiInfo.dwCursorPosition.Y = y;<br />
SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition);<br />
void SistemaVisao::calcTransf(float coordX, float coordY, int altura)<br />
{<br />
// Calculo <strong>de</strong> Xm,Ym e Zm em centimetros<br />
Zmundo = altura * (FOCO * cos(FI) + coordY * sin(FI)) /<br />
(FOCO * sin(FI) - coordY * cos(FI));<br />
//Ymundo = -ALTURA;<br />
Xmundo = (coordX / FOCO) * (altura * sin(FI) + Zmundo * cos(FI));<br />
}
75<br />
// faz os calculos e envia velocida<strong>de</strong>s<br />
void SistemaVisao::calcMove(int V_MAX, float W_MAX, int i)<br />
{<br />
float Ex,Ez;<br />
CvPoint tempRoboTeam;<br />
CvPoint tempRoboOrient;<br />
int distEmp = 0;<br />
float distEmpTemp = 0;<br />
CvPoint Temp = players[i]->getCenter();<br />
xDest = Temp.x - coordSys->Centro.x;<br />
yDest = -(Temp.y - coordSys->Centro.y);<br />
calcTransf(xDest,yDest,ALTURA_ROBO);<br />
// centro entre as duas<br />
// cores do robo, em pixels<br />
// centro do robo - centro<br />
// do sistema <strong>de</strong> coor<strong>de</strong>nadas<br />
// resultado em Xmundo e<br />
// Zmundo, em cm<br />
// Calculo do modulo do erro Ei nas 3 direcoes<br />
// d = <strong>de</strong>stino (alvo)<br />
Ex = Xd - Xmundo;<br />
Ez = abs(Zd) - abs(Zmundo);<br />
// calculo <strong>de</strong> psi, angulo do centro do robo ao alvo<br />
// em relacao ao eixo Z<br />
// psi = atan(Ex/Ez); // original<br />
psi = calcAngulo(Ex,Ez); // (cateto oposto/cateto adjacente)<br />
// Calculo do modulo do erro E, distancia do robo ate o alvo<br />
ModE = sqrt(pow(Ex,2) + pow(Ez,2)); // pow(5,2) = 5^2<br />
// calculo <strong>de</strong> alfa, orientacao do robo em relacao ao eixo Z<br />
tempRoboTeam = players[i]->primaryTr.getCenter();<br />
xDest = tempRoboTeam.x - coordSys->Centro.x;<br />
yDest = -(tempRoboTeam.y - coordSys->Centro.y);<br />
calcTransf(tempRoboTeam.x,tempRoboTeam.y,ALTURA_ROBO);<br />
tempRoboTeam.x = Xmundo;<br />
tempRoboTeam.y = Zmundo;<br />
tempRoboOrient = players[i]->secondaryTr.getCenter();<br />
xDest = tempRoboOrient.x - coordSys->Centro.x;<br />
yDest = -(tempRoboOrient.y - coordSys->Centro.y);<br />
calcTransf(tempRoboOrient.x,tempRoboOrient.y,ALTURA_ROBO);<br />
tempRoboOrient.x = Xmundo;<br />
tempRoboOrient.y = Zmundo;<br />
Ex = tempRoboOrient.x - tempRoboTeam.x; // - tempRoboOrient.x;<br />
Ez = tempRoboOrient.y - tempRoboTeam.y; // - abs(tempRoboOrient.y);<br />
//alfa = atan(Ex/Ez); // alfa original<br />
alfa = calcAngulo(Ex,Ez);<br />
// calculo <strong>de</strong> teta, angulo <strong>de</strong> giro para que o robo se oriente <strong>de</strong><br />
// acordo com o alvo<br />
teta = psi - alfa;<br />
if (statusRobo[i] == 'a')<br />
{<br />
if (ModE
}<br />
}<br />
{<br />
}<br />
else<br />
{<br />
clrscr();<br />
printf("\nO centro do robo '%d' esta a menos <strong>de</strong> %d cm do<br />
alvo e por isso foi parado!",i,DIST_SEGURA);<br />
printf("\nAperte qualquer tecla para continuar...\n");<br />
// para robo i<br />
v = 0;<br />
w = 0;<br />
com->setBuffer(v,w,unsigned char(i));<br />
com->write();<br />
statusRobo[i] = 'p';<br />
// escreve na porta serial<br />
// muda o status do robo <strong>de</strong> ativo<br />
// para parado<br />
cvWaitKey(0);<br />
clrscr();<br />
gotoxy(0,1);<br />
printf(" -1: Selecione a cor da frente do robo\n -2:<br />
Selecione a outra cor\n -3: Criar jogador\n -4:<br />
Selecione a cor do alvo\n -5: Criar alvo\n -6:<br />
Rastrear robos ativos\n -7: Exibir informacoes dos<br />
robos\n -8: Executar a tarefa programada\n -9:<br />
Interrompe a tarefa (necessario para utilizar os<br />
itens do menu)\n -s: Sair...\n");<br />
gotoxy(5,12);<br />
printf("Regiao Selecionada: (%d, %d, %d, %d)",window.x,<br />
window.y, window.width, window.height);<br />
printf("\n\nModo <strong>de</strong> execucao...");<br />
// calculo das velocida<strong>de</strong>s linear e angular<br />
// v = ModE * cos(teta);<br />
// w = K * teta;<br />
// calculo das velocida<strong>de</strong>s linear e angular ja com o<br />
// controlador aplicado<br />
v = V_MAX * tanh(ModE) * cos(teta) * cos(teta);<br />
w = W_MAX * tanh(teta);<br />
com->setBuffer(v,w,unsigned char(i));<br />
com->write(); // escreve na porta serial<br />
}<br />
// guarda informacoes dos robos<br />
infoRobos[i][0] = v;<br />
infoRobos[i][1] = w;<br />
infoRobos[i][2] = i;<br />
76<br />
float SistemaVisao::calcAngulo(float n<strong>um</strong>, float <strong>de</strong>n) //(n<strong>um</strong>,<strong>de</strong>n)<br />
{<br />
float angT1 = atan(n<strong>um</strong>/<strong>de</strong>n);<br />
double pi = 3.1415926535; // 180 graus<br />
float orientacao = 0;<br />
// I<strong>de</strong>ntifica o quadrante em que o robo esta em relacao<br />
// ao centro da regiao <strong>de</strong> testes. O eixo Z positivo e a<br />
// referencia.<br />
if ((n<strong>um</strong> > 0) && (<strong>de</strong>n > 0))<br />
{<br />
orientacao = angT1;<br />
}
77<br />
}<br />
else if ((n<strong>um</strong> > 0) && (<strong>de</strong>n < 0))<br />
{<br />
orientacao = pi + angT1;<br />
}<br />
else if ((n<strong>um</strong> < 0) && (<strong>de</strong>n < 0))<br />
{<br />
orientacao = pi + angT1;<br />
}<br />
else<br />
{<br />
orientacao = 2*pi + angT1;<br />
}<br />
return orientacao;
78<br />
REFERÊNCIAS BIBLIOGRÁFICAS<br />
1. C. Soria, R. Carelli, R. Kelly, J. M. I. Zannatha. Control <strong>de</strong> Robots Cooperativos por<br />
Medio <strong>de</strong> Vision Artificial. XVI Congreso <strong>de</strong> la Asociación Chilena <strong>de</strong> Control Automático,<br />
2004.<br />
2. R. Kelly, R. Carelli, J. M. Zannatha, C. Monroy. Control <strong>de</strong> una pandilla <strong>de</strong> robots<br />
móviles para el seguimiento <strong>de</strong> una contelación <strong>de</strong> puntos objetivo. VI Congreso<br />
Mexicano <strong>de</strong> Robótica, 2004.<br />
3. R. C. Arkin. Behavior-Based Robotics. The MIT Press, 1998.<br />
4. R. R. Murphy. Introduction to AI Robotics. The MIT Press, 2000.<br />
5. J. O. Bragança. Estratégias para Deslocamento <strong>de</strong> Cargas Através <strong>de</strong> Cooperação <strong>de</strong><br />
Robôs Móveis a Rodas. Dissertação <strong>de</strong> Mestrado, UFES, Vitória, ES, 2004.<br />
6. R. F. Vassallo. Cooperação <strong>de</strong> Robôs baseada em Visão Omnidirecional. Projeto<br />
PIBIC 2006-2007, UFES, Vitória, ES, 2006.<br />
7. Inovação Tecnológica. Robôs cooperativos utilizam sensores e equipamentos uns dos<br />
outros. Visitado em 09/12/2007.<br />
http://www.inovacaotecnologica.com.br/noticias/noticia.php?artigo=010180060821<br />
8. R. F. Vassallo. Uma Estratégia <strong>de</strong> Navegação para Robôs Móveis em Ambientes<br />
Interiores. Dissertação <strong>de</strong> Mestrado, UFES, PPGEE, Vitória, ES, 1998.<br />
9. E. Zambon. Uma Plataforma para Desenvolvimento <strong>de</strong> Robôs <strong>de</strong> Baixo Custo com<br />
Alta Capacida<strong>de</strong> Computacional – IROBOT. Projeto <strong>de</strong> Graduação, UFES, Vitória,<br />
ES, 2004.<br />
10. F. Pereira. Microcontroladores MSP430 – Teoria e Prática. 1 a Edição, Editora Érica,<br />
2005.<br />
11. Texas Instr<strong>um</strong>ents. MSP430F149 datasheet. Julho <strong>de</strong> 2000, Revisado em Junho <strong>de</strong><br />
2004.<br />
12. MaxStream. Product Manual v1.xAx - 802.15.4 Protocol. Outubro <strong>de</strong> 2006.<br />
13. A. T. Oliveira, H. T. Costa, e L. C. Maia. ZigBee – Tecnologia e Aplicações. Relatório<br />
apresentado à disciplina <strong>de</strong> Sistemas <strong>de</strong> Telecomunicações, UFES, Vitória, ES, 2006.<br />
14. C. C. Gava. Controle <strong>de</strong> Formação <strong>de</strong> Robôs Móveis Baseado em Visão<br />
Omnidirecional. Tese <strong>de</strong> mestrado, UFES, Vitória, ES, 2007.<br />
15. MFSM. CAMSHIFT Experiments. Visitado em 23/12/2007.<br />
http://mfsm.sourceforge.net/MFSM_0.7/tutorials/Camshift.html