22.04.2015 Views

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 ...

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!