UNIVERSIDADE PAULISTA – UNIP
I.C.E.T – INSTITUTO DE CIÊNCIAS EXATAS E ENGENHARIA
GRADUAÇÃO EM ENGENHARIA DA COMPUTAÇÃO
DANILO ARAUJO LUIZ
SISTEMA AUTÔNOMO DE NAVEGAÇÃO COM KINECT E ARDUINO
SÃO PAULO
2011
Danilo Araujo Luiz
SISTEMA AUTÔNOMO DE NAVEGAÇÃO COM KINECT E ARDUINO
Trabalho de Conclusão de Curso para
obtenção do título de Graduação em
Engenharia de Computação apresentado à
Universidade Paulista – UNIP.
Orientador: Prof. Dr. Orlando Del Bianco Filho
São Paulo
2011
Luiz, Danilo Araujo. Sistema autônomo de navegação com Kinect e Arduino. / Danilo Araujo Luiz. - São Paulo, 2011. 59f. : il. color.
Trabalho de conclusão de curso (graduação), apresentado ao
Instituto de Ciências Exatas e Tecnologia da Universidade Paulista, São Paulo, 2011.
Área de concentração: Inteligência Artificial.
“Orientação: Prof. Dr. Orlando Del Bianco Filho.”
1. Driverless car. 2. Lógica Fuzzy. I. Título.
Danilo Araujo Luiz
SISTEMA AUTÔNOMO DE NAVEGAÇÃO COM KINECT E ARDUINO
Trabalho de Conclusão de Curso para
obtenção do título de Graduação em
Engenharia de Computação apresentado à
Universidade Paulista – UNIP.
Aprovado em:
BANCA EXAMINADORA
________________________________________________ ___ /___/___
Professor Orientador Dr. Orlando Del Bianco Filho
________________________________________________ ___ /___/___
Professor Coordenador Dr. Francisco Correa
________________________________________________ ___ /___/___
Professor Ricardo Bacci
DEDICATÓRIA
Dedico este trabalho aos meus pais, à minha namorada, aos meus amigos e
todos aqueles que buscam meios de melhorar o mundo em que vivemos.
AGRADECIMENTOS
Em primeiro lugar agradeço aos meus pais Edinei Luiz e Maria Aparecida
Araujo Luiz que sempre me incentivaram a estudar para conseguir obter o que
desejar na vida.
Em segundo lugar agradeço à minha namorada Flavia Sousa da Silva que me
ajudou e incentivou em todos os momentos.
Também houve alguns amigos que deram apoio à idéia do projeto, tais como
Andrews Regis da Penha Alves, Sandeep Kumtakar e Thiago Marcel Lima.
Devo também agradecer a todos os professores que tive contato durante
todos esses 5 anos cursando Engenharia. Sobretudo os professores do curso
específico de Engenharia de Computação: Flávio Mendonça, José Augusto Pinheiro
Christino, Orlando Del Bianco Filho, Orlando Onofre Junior, Ricardo Bacci e ao
nosso professor Coordenador Francisco Correa.
“Parte da ausência de
humanidade do computador deve-se a
que, competentemente programado e
trabalhando bem, é completamente
honesto.”
(Isaac Asimov)
RESUMO
Após o lançamento da tecnologia do Kinect da Microsoft © surgiram diversas
iniciativas de uso alternativo, uma vez que o mesmo foi projetado para jogos. Essas
deram idéias para projetos que envolviam processamento de imagem em tempo
real.
Uma dessas idéias foi a construção de um sistema autônomo de
navegação utilizando o Kinect pela University of Bundeswehr Munich no projeto:
Kinect-Enabled Autonomous Mini-car Navigation, algo que a Google © Inc. já vinha
trabalhando, porém em grande escala e com outra tecnologia, que também tinha o
mesmo princípio de construir um sistema que permitisse a movimentação de um
carro sem motorista.
Todos esses projetos utilizavam softwares não oficiais da Microsoft para
programação, eram os chamados Kinect Hacks. A partir de 16 de junho de 2011 o
pacote de desenvolvimento do Kinect para Windows foi oficialmente lançada pela
Microsoft.
Este projeto teve como objetivo à criação de um protótipo de um carro capaz
de desviar-se de obstáculos. Diferente da maioria dos projetos existentes utilizou-se
do sensor de profundidade do Kinect invés de sonares.
Além do pacote de desenvolvimento do Kinect para Windows, também se
utilizou de uma plataforma de hardware livre: o Arduino, que atuou diretamente nos
circuitos elétricos.
Palavras chave: driverless car, lógica fuzzy, Kinect, Arduino,
ABSTRACT
After the launching of Kinect technology from Microsoft © Corporation a lot of
initiatives of alternative use has appeared, once the device was designed for game
using. Those initiatives have inspired who wanted to work with real-time image
processing projects.
One of those ideas was the designing of a autonomous navigation system
using Kinect by the University of Bundeswehr Munich with the project: Kinect-
Enabled Autonomous Mini-car Navigation, something that Google © Inc. have been
working in a large scale and using another technology, both have the same principle
to design a driverless car system.
All of the projects which were using non-official software from Microsoft to
programming were called as Kinect Hacks. From June 16th 2011 the official Kinect
software development kit for Windows was launched by Microsoft.
The purpose of this Project was to create a car prototype with an obstacle
avoidance system. Most of the project of this nature is built using sonars, this project
uses the Kinect depth sensor to detect obstacles.
Beyond the Kinect for Windows SDK, the open-source single-board
microcontroller: the Arduino that was acting directly to electrical circuits.
Keywords: driverless car, fuzzy logic, Kinect, Arduino,
SUMÁRIO
1. Introdução ................................................................................................ 9
2. Referencial teórico ................................................................................. 14
2.1 Relação Interdisciplinar ...................................................................... 14
2.2 Kinect ................................................................................................. 15
2.3 Arduino ............................................................................................... 16
3. Metodologia ........................................................................................... 17
4. Projeto ................................................................................................... 18
4.1 Fase I – Programando com o Kinect .................................................. 18
4.2 Fase II – Programando com o Arduino ............................................... 18
4.3 Fase III – Integrando a programação ao carro rádio-controlado ........ 19
4.4 Fase IV – Ajustes de códigos e de circuitos ....................................... 22
5. Considerações finais ............................................................................. 24
Referências......................................................................................................23
Anexos.............................................................................................................32
1. INTRODUÇÃO
Desde os tempos primórdios da civilização humana, o homem tem
desenvolvido ferramentas para facilitar a vida. Grande parte deste conhecimento
adquirido foi perdido através das guerras e durante a época da Idade Média. No
entanto, a partir do século XVIII com a Revolução Industrial e as novas descobertas
no campo da energia elétrica, voltamos a progredir tecnologicamente em uma
velocidade maior. No final do século XIX surgiram primeiros os automóveis e em
seguida no início do século XX, os primeiros aviões. Depois tivemos duas grandes
Guerras Mundiais, onde a tecnologia deu mais um significativo passo com a
introdução dos computadores para cálculos balísticos e popularização dos diversos
meios de transporte.
A partir da segunda metade do século XX houve grandes avanços na
computação. Tivemos a miniaturização dos componentes eletrônicos o que
possibilitou a criação dos circuitos integrados, que por sua vez possibilitaram o
surgimento dos computadores pessoais. Inclusive podemos considerar a criação e a
evolução dos videogames como algo importante para a realização deste projeto, que
também foram possíveis devido ao surgimento destes mesmos circuitos integrados.
Com a popularização do computador pessoal, da internet e dos dispositivos
eletrônicos como celular, GPS, tocadores de áudio, etc, houve duas tendências que
inspiraram à elaboração deste projeto: estudos em robótica e inteligência artificial, e
também a infeliz quantidade de acidentes de trânsito.
Estudos em Robótica e Inteligência Artificial
Enquanto a Robótica constitui-se de estudos de sistemas mecânico-elétricos,
a área de Inteligência Artificial visa criar sistemas capazes de realizar decisões. É
comum que sejam trabalhadas em conjunto, principalmente pela necessidade de
algoritmos e linguagens de programação atuando em sistemas elétricos, o que
ocorre, por exemplo, nos computadores.
Atualmente grande parte do desenvolvimento de robôs tem como fim o uso
militar. Inclusive dados do início de 2011, mostraram que há mais de 2000 robôs no
Afeganistão auxiliando os soldados estadounidenses.
Existem diversos outros usos da Inteligência Artificial, como controlar trens e
metrôs, a exemplo da linha 4 – Amarela do Metrô/ViaQuatro de São Paulo. Também
vemos este tipo de uso de Inteligência Artificial em lançamento de mísseis e naves
espaciais.
Do avanço da tecnologia aos seus malefícios
Apesar de todos os avanços tecnológicos para proporcionar uma qualidade
de vida melhor, bem como facilidades no dia-a-dia, também tivemos muitos efeitos
adversos deste mundo tecnológico.
O homem sempre procurou novas formas de facilitar sua vida, seja por
motivos altruístas ou totalmente egoístas, eis que no desde o final do século XIX
contemplamos à criação do automóvel.
Com toda essa quantidade de inovações tecnológicas foi uma questão de
tempo até a que tecnologia se voltasse contra os homens. Claro que toda tecnologia
pode ser usada para fins destrutivos, como também o mau uso da mesma pode
causar graves desastres.
Desde que os automóveis existem, também existem os acidentes
automobilísticos. E por mais que diversas causas sejam apontadas, a forma que
muitos encontraram para sanar este problema são estudos no campo de sistemas
autônomos de navegação.
Segundo a pesquisa realizada para este projeto, muitos acidentes ocorrem
em boas condições de trânsito, como bom asfalto, durante o dia e clima não
chuvoso. E a maior causa dos acidentes é a falta de atenção, a qual deve estar
sendo maximizada já que atualmente temos na média mais de um celular por
pessoa no Brasil, além disso, o uso da internet vem crescendo nos celulares e
também com a popularização de sistemas de posicionamento global conhecido
comumente como GPS (Global Positioning System) que dentre outras funções
também pode exibir TV Digital.
Outras iniciativas
Existem outros estudos sendo realizados em relação à criação de sistemas
autônomos de navegação, como é o caso da Google Inc. No primeiro episódio da
mini-série Brave New World com Stephen Hawking é possível ver uma
demonstração razoável deste projeto da Google Inc. O projeto consiste na
construção de um sistema autônomo de navegação, é auxiliado por GPS para seguir
uma rota, contudo utiliza-se de outros artifícios para evitar colisões.
Recentemente também foi publicado um estudo do MIT (Massachusetts
Institute of Technology) a respeito de um sistema para auxiliar motoristas. Neste
caso, o sistema é complementar, não substitui um ser humano.
Na China também vem sendo realizado uma pesquisa, pela National
University of Defense Technology, na construção de um sistema autônomo de
navegação que se assemelha muito com o que a Google Inc. vem desenvolvendo.
2. REFERENCIAL TEÓRICO
2.1 Relação Interdisciplinar
Durante a elaboração deste projeto muitos conhecimentos foram adquiridos,
bem como muitos outros conhecimentos adquiridos em classe foram utilizados.
Seguem listadas as matérias e onde ocorreu seu emprego.
Desenho Técnico, na elaboração da caçamba para acomodação do
notebook, circuitos e baterias.
Estatística Descritiva, na análise dos dados obtidos através de diversos
sites, sobretudo do IBGE (Instituto Brasileiro de Geografia e
Estatística).
Eletricidade e Calor, Complementos de Física e Materiais Elétricos que
forneceram as bases necessárias para trabalhar com componentes
eletrônicos.
Análise de Algoritmos e Estrutura de Dados, Arquitetura de
Computadores e Tecnicas de Programação, Engenharia de Software e
Tópicos de Programação Avançada, Linguagens Formais e
Compiladores, Automação de Processos e Controle, Tópicos de
Inteligência Artificial que contribuíram para a elaboração de toda a
programação realizada.
Tratamento Vetorial de Imagens e Processamento de Sinais Digitais
que forneceram as bases para a elaboração de uma lógica baseada
em imagem.
Destacam-se também as matérias de Circuitos Lógico-Digitais,
Microprocessadores e Microcontroladores, e Sistemas Digitais em
Engenharia da Computação, pois foram as matérias fundamentais para
a concretização deste projeto, uma vez que também foram base para
um pré-projeto no final de 2010. Essas matérias fazem toda a ligação
com os conceitos aprendidos em eletricidade e os conceitos
aprendidos em lógicas de programação.
2.2 Kinect
Para a elaboração deste projeto houveram duas principais tecnologias
envolvidas: Kinect e Arduino. Ainda que ambas tecnologias sejam da parte de
hardware, cada uma teve um propósito diferente como veremos a seguir. Nesta
sessão trataremos de uma breve descrição do Kinect.
O Kinect pode ser definido por: um sensor de profundidade. Ele é um
complemento ao console de videogame Xbox 360. Sua principal função é
reconhecer a presença de seres humanos e mapear os movimentos para dentro do
jogo.
Devido ao seu hardware enxuto, surgiram iniciativas para o uso em projetos
de reconhecimento de objetos, reconhecimento de gestos e até mesmo avaliando a
profundidade dos objetos próximos como foi o caso deste projeto.
Para seu funcionamento o Kinect possui um emissor de Infravermelho e um
receptor, além de uma câmera VGA e uma série de 4 microfones dispostos de uma
maneira que pode facilitar o reconhecimento da posição do usuário. A partir do
cálculo do tempo da emissão do Infravermelho e à sua recepção, é possível
mensurar qual é a distância de cada pixel na imagem gerada (neste caso gera-se
uma matriz onde cada ponto da imagem tem uma coordenada X, Y e Z, sendo esta
última a distância).
Com o sucesso dentro e fora dos videogames a Microsoft lançou o pacote de
desenvolvimento de aplicações do Kinect para Windows em junho de 2011. Uma vez
que o uso comercial não fosse o propósito deste pacote de desenvolvimento,
diversos trabalhos envolvendo acessibilidade ou reconhecimento de imagens foram
realizados.
Estima-se que a Microsoft irá lançar uma versão paga do pacote de
desenvolvimento de aplicações do Kinect para Windows em 2012.
2.3 Arduino
Conceitualmente o Arduino é uma plataforma de hardware livre. Consiste-se
numa série de circuitos integrados que são facilmente adaptados para sistemas de
pequeno porte.
Surgiu em 2005 numa tentativa de produzir um hardware que fosse barato e
ao mesmo tempo de fácil programação. Teve grande reconhecimento e
popularização de 2006 em diante.
Possui internamente alguns resistores, regulador de tensão, capacitores e
principalmente um microcontrolador e conversor para interface serial. Atualmente
vem com um conversor FTDI para a comunicação e programação diretamente pela
USB.
Sua praticidade se dá ao fato que além do hardware simplificado e embutido,
possui um ambiente integrado de desenvolvimento de software que trabalha com a
linguagem C e C++.
De modo geral essa plataforma oferece muitas vantagens para os
desenvolvedores, no entanto sua principal vantagem é que trabalha com linguagem
de programação de alto nível.
Além do desenvolvimento contínuo da plataforma, alguns fabricantes montam
módulos para Arduino que realizam operações específicas, tais como adaptador de
rede, adaptador wireless, adaptador de rádio frequência e etc.
3. METODOLOGIA
Este projeto foi organizado em milestones que em inglês significa: marcos. Ainda
que envolva desenvolvimento de hardware e software, existiam dependências entre
algumas fases do projeto.
Podemos definir o projeto em 5 fases que representam esses milestones. A primeira
fase, que será detalhada posteriormente, foi o desenvolvimento do programa
principal que recebe informações do Kinect. A segunda fase foi adaptar este
programa principal para comunicar-se com o Arduino. A terceira fase foi estabelecer
uma ligação entre o Arduino e o Carro rádio-controlado. A quarta fase
conceitualmente foi a fase dedicada a ajustes de software e talvez hardware. A
quina fase é considerada como esta documentação em si.
Devido à espera do lançamento do pacote de desenvolvimento do Kinect para
Windows e sua dependência para as demais fases do projeto, efetivamente, iniciou-
se o projeto em Agosto, depois de muito estudo da plataforma de desenvolvimento.
Havia a possibilidade de trabalhar com bibliotecas não oficiais do Kinect, o que
poderia mudar o sistema operacional e a linguagem de programação.
O cronograma completo está disponível no anexo I.
4. PROJETO
O potencial do Kinect despertou uma série de idéias para trabalhar com
processamento de imagens. No entanto, já faz algum tempo que o interesse por
inteligência artificial e robótica se fazia presente na minha visão de futuro.
Devido à quantidade de tempo de translado do meu local de trabalho até à
minha casa, percebi que dirigir é uma enorme perda de tempo devido ao trânsito
caótico da cidade de São Paulo.
Ainda que defenda o transporte em massa privado – conhecidos como ônibus
fretado – para se locomover do trabalho para casa, há pessoas que prezam pela
individualidade e conforto de seus carros.
De toda forma o avanço da tecnologia tem proporcionado maiores distrações
para os motoristas que insistem em desrespeitar as leis de trânsito utilizando
celulares, GPS com TV Digital, os que dirigem bêbados ou com sono e tantas outras
ações que infringem o código nacional de trânsito.
Pensando nisso, surgiu-se a idéia de automatizar o processo de navegação
dos carros, tirando a responsabilidade do motorista e atribuindo a um sistema
autônomo. Por questões orçamentárias e de tempo, optou-se por construir um
protótipo de um carro capaz de locomover-se autonomamente desviando-se de
obstáculos.
4.1 Fase I – Programando com o Kinect
Esta fase em princípio parecia ser a parte mais difícil da programação. Havia
grandes preocupações por parte de colegas, amigos e professores por conta da
novidade que era a tecnologia.
Após obter muita documentação sobre o Kinect, considerei que estava
aprendendo muito mais inglês do que a programar com o mesmo. No início havia
pouca informação sobre Kinect em português, encontrei apenas um site a respeito,
depois que já havia assistido aos vídeos do site Channel9 da Microsoft que criou
uma seção especial para falar de projetos com Kinect. Outra publicação encontrada
foi uma tradução literal de alguns sites que foi descoberta somente durante a
elaboração da documentação.
Inicialmente tive que entender como funcionava a programação em C#, ainda
que já tivesse programado algo em Visual Basic, ASP, PHP, Java, Delphi, Javascript
e Assembly (para 8051), não sou necessariamente programador.
Quando a Microsoft lançou o pacote de desenvolvimento do Kinect para
Windows, algo que surpreendeu e agradou a todos foi a possibilidade de programar
em diversas linguagens diferentes. Ainda que os exemplos que vieram com este
pacote fossem em C# e C++, a quantidade de código necessário para realizar as
mesmas tarefas eram diferentes nessas duas linguagens. Por isso optei por utilizar o
C#.
Depois de procurar e não encontrar nada a respeito, acabei tendo que
desenvolver um código próprio para determinar a distância de dois pontos da
imagem, um do lado esquerdo e um do lado direito. A maioria dos projetos com
Kinect estava utilizando o sensor de profundidade para reconhecimento de seres
humanos que é o seu foco principal. Depois de algumas tentativas, descobri que
com uma simples linha, conseguia capturar a informação que precisava.
Aproveitei o código principal que ensina a trabalhar com profundidade que
está disponível no Channel9 pelo nome de Working with Depth Data. Adicionei o
monitoramento de um ponto do lado esquerdo e de um ponto do lado direito, e que
me exibisse qual a distância de cada um desses pontos.
Para finalizar a fase I, ainda aprimorei o código criando uma lógica para agir
em relação aos possíveis obstáculos detectáveis. Inicialmente a lógica era baseada
em 4 opções:
Obstáculo do lado esquerdo;
Obstáculo do lado direito;
Obstáculo em ambos os lados;
Nenhum obstáculo detectado.
O problema desta lógica é que era possível atender a duas opções. Quando
algum obstáculo era detectado em um lado e depois no outro lado, a lógica
retornava a mensagem que alcançou obstáculo de um lado e também em ambos os
lados. Este conflito foi corrigido ainda nessa fase.
Então adotei a lógica fuzzy onde uma variável pode pertencer a dois grupos
dependendo do intervalo de tolerância. Em termos práticos, atribuí a minha lógica as
possíveis entradas:
Obstáculo à esquerda;
o Obstáculo somente à esquerda;
o Obstáculo também à direita;
Obstáculo à direita;
o Obstáculo somente à direita;
o Obstáculo também à esquerda;
Nenhum obstáculo.
Para facilitar a compreensão os anexos II e III possuem o código-fonte e o
Diagrama de Blocos respectivamente.
Implementando esta pequena alteração, quando um obstáculo era encontrado
de um lado, observava-se se também estava atingindo o outro lado. Mesmo que um
único obstáculo seja encontrado ao mesmo tempo atingindo os dois pontos
monitorados, por mais que o processamento seja rápido, o mapeamento do
ambiente será feito ponto a ponto e não será simultâneo. Logo, por uma fração de
segundo o sistema pode encontrar o obstáculo primeiro do lado esquerdo e depois
do lado direito ou vice versa. Quaisquer que sejam as respostas, a lógica será capaz
de tratar.
4.2 Fase II – Programando com o Arduino
Devido à quantidade de informação e documentação a respeito de
programação com Arduino, foi fácil encontrar e adaptar um código que pudesse
controlar a direção de um carro. Claro que alguns conceitos em eletrônica como o
uso de portas lógicas e relés foram importantes para determinar uma lógica.
Como havia a necessidade de utilizar um notebook para processar o Kinect e
rodar o Microsoft Visual C# 2010 Express, a lógica atribuída ao Arduino foi realizar a
varredura da porta serial e ler códigos ASCII.
Para cada direção foi atribuído um código ASCII diferente. Basicamente
foram:
Q – À frente e à esquerda;
W – À frente;
E – À frente e à direita;
A – À esquerda;
S – Ré;
D – À direita;
Z – Ré e à esquerda;
P – Desligar todas saídas lógicas.
Maiores detalhes sobre esta lógica estão no anexo V.
Além de atribuir uma lógica ao Arduino, tive de voltar ao programa principal
em C# e adicionar a função de enviar um sinal para a porta serial de acordo com a
resposta gerada. Ou seja, se havia um obstáculo à esquerda, o programa deveria
enviar um sinal ‘e’ para que o Arduino direcionasse os relés de forma a virar o carro
à direita e manter o movimento de tração à frente.
4.3 Fase III – Integrando a programação ao carro rádio-controlado
Ainda que tivessem sido definidos milestones para cada aspecto do projeto,
fossem de software ou hardware, a fase III foi pensada durante a fase II. Afinal a
lógica para o Arduino dependeria diretamente do circuito.
Originalmente a idéia foi abrir o carro e medir correntes e tensões até
descobrir um meio de movimentar o carro. Nesta fase o carro foi levemente
danificado e não realizava curva à direita perfeitamente.
A ausência do esquema elétrico do carro levou à realização destes testes até
que se descobriu que havia quatro pontos que se conectados ao terra do circuito,
realizavam as quatro funções principais de movimentar as rodas dianteiras para
esquerda e direita e as rodas traseiras para frente e para trás.
Para evitar queimas de ambos os lados, criei uma placa intermediária com
apenas quatro relés que isolavam os circuitos do carro e do Arduino. Do lado de
acionamento dos relés, estavam todos ligados ao terra do Arduino e cada um ligado
a uma porta lógica de saída. Do lado de fechamento de circuito dos relés, estavam
todos ligados ao terra do circuito impresso do carro e cada um ligado àqueles quatro
pontos localizados. Apesar de não ter o esquema elétrico dessa primeira versão de
placa, é possível ver fotos desta no anexo VIII.
4.4 Fase IV – Ajustes de códigos e de circuitos
Considerando que a Fase V do projeto é esta documentação, vamos falar
então a última fase do protótipo, que foi mais conturbada do que o esperado.
Infelizmente o circuito do carro queimou-se. A primeira idéia que veio à
cabeça foi substituir o circuito por outro circuito com apenas quatro relés. A maior
parte do desenvolvimento foi pensado de maneira lógica e não considerou-se as
características elétricas dos componentes.
Embora tenha sido simples acionar o movimento de tração para frente ou
para trás utilizando relés, não funcionou muito bem na movimentação da direção. O
controle da direção era realizado com seis fios e mesmo realizando diversas
combinações, nenhuma apresentou um resultado satisfatório e que pudesse ser
reproduzido com os conhecimentos em eletrônica do momento. Fotos também
presentes no anexo VIII.
Uma última tentativa em ressoldar os transístores da placa original resolveu o
problema elétrico. Infelizmente também ocorreu um problema mecânico. A solução
foi comprar outro carro.
Após a compra do outro carro, muito foi pensado numa solução que pudesse
aproveitar a placa intermediária com os quatro relés e que pudesse aproveitar toda
programação do Arduino. Diante dos materiais em vista, percebi que tinha adquirido
um controle a mais.
A solução encontrada foi implementar o acionamento dos relés no controle. E
isto foi feito muito facilmente. O funcionamento do controle é bem simples de modo
mecânico. Quando movimentasse para algum dos lados ou para frente e para trás,
fechasse o circuito com o terra comum. Descoberto isso, soldei os quatro pontos
correspondentes à direção e o terra do circuito do controle.
Aparentemente tudo o que precisava ser feito, estava feito. Paralelamente a
todos esses processos, também trabalhei em duas coisas: a caçamba para carregar
o notebook e um meio de ligar o Kinect com baterias.
A caçamba do notebook foi feita com isopor condensado e rodas genéricas
para cadeiras ou prateleiras. Além disso, foi utilizado cola quente para juntar as
bordas. Por fim, também utilizei palitos de churrasco com fita Silver Tape para
montar o engate ligado ao carrinho que está em detalhe no final do anexo X.
O circuito que faz com que o Kinect funcione a baterias pode ser visto no
anexo VII, aproveitou-se o cabo USB proprietário do Kinect e cortou-se a parte da
fonte que se ligava à tomada. O circuito é bem simples, possui um regulador de
tensão de 12V e dois capacitores para realizar a filtragem. Originalmente ligava-se
as duas baterias de 12V em paralelo com o propósito de fornecer a mesma corrente
por mais tempo. Porém na prática, somente quando coloca-se as duas baterias em
série gerando 24V e passando pelo regulador de 12V é que conseguiu-se ligar o
Kinect. Como essas baterias são genéricas e não possuo informações sobre suas
capacidades elétricas e físicas, conseguiu-se uma autonomia de 10 minutos pelo
menos.
Mesmo tendo soldado a placa intermediária no controle remoto, o sistema
continuava não funcionando de maneira adequada. Também se descobriu que
durante a movimentação do carro, acabava ocorrendo um mau contato entre o
controle e a placa intermediária, e entre o Arduino e a placa intermediária.
Tendo este novo cenário, a solução foi retirar os conectores e soldar o
controle diretamente à placa. E ao invés de ter um duplo contato para ligar no
Arduino, a ponta de ligação no Arduino permaneceu-se igual, contudo a ponta de
ligação à placa, foi soldada diretamente. Essas alterações constam no anexo IX.
Depois deste esforço o sistema continuava não funcionando. Até que se
descobriu que o Arduino não fornecia corrente suficiente para acionar dois relés ao
mesmo tempo. A solução foi adicionar transístores NPN ao circuito e resistores para
evitar a queima do Arduino. Efetivamente a mudança significativa foi que as saídas
do Arduino acionavam somente os transístores que estavam ligados em série com
os respectivos relés. Já esses relés foram ligados diretamente na saída de 5V do
Arduino que ao contrário das saídas lógicas, possuía uma corrente capaz de acionar
os dois relés ao mesmo tempo, enquanto duas portas lógicas acionavam os dois
transístores. Esta versão 2.5 da placa intermediária pode ser vista no início do anexo
X.
Por questões de espaço, a placa intermediária foi remodelada e também
foram adicionados diodos para evitar a queima dos transístores, esses diodos foram
colocados em paralelo aos relés realizando o trabalho de proteção. O esquema
elétrico final da placa intermediária está disponível no anexo VI e as fotos no anexo
X
5. CONSIDERAÇÕES FINAIS
A experiência adquirida neste projeto foi edificante. Foi interessante saber que
às vezes buscamos soluções complexas quando só precisamos de soluções
simples, como foi o caso de integrar o Arduino ao carro rádio-controlado, quando
integrá-lo ao controle remoto foi muito mais simples e o risco de perda muito menor.
Desde o princípio sabia que com determinação e estudo chegaria ao
resultado final, fosse usando o pacote de desenvolvimento do Kinect para Windows
oficial ou usando outras bibliotecas gratuitas. Bem, como sempre soube que o mais
trabalhoso de todo o trabalho seria esta documentação.
Foi excelente contar com meus professores para a orientação do projeto, em
especial ao professor José Augusto Pinheiro Christino que graças à quantidade de
aulas que tivemos neste último semestre, pôde acompanhar de perto os avanços do
projeto.
Igualmente satisfatório foi no final de 2010 quando tivemos que montar um
projeto com o microcontrolador 8051 para os professores Orlando Onofre Junior e
Orlando Del Bianco Filho, que serviu de base para a realização deste projeto.
Inclusive a adoção do Arduino vem de forma a facilitar no cumprimento de prazos, já
que também poderia ter utilizado um 8051 programando em Assembly e fazendo
transmissão de dados via conexão serial.
Acredito que o sucesso do projeto em parte deve-se às aulas que tive durante
esses 5 anos de Engenharia, e até mesmo matérias deste último semestre
acabaram influenciando alguma coisa no projeto. Acredito que todo meu esforço
valeu a pena e quero continuar estudando Inteligência Artificial e Robótica, seja por
hobby ou profissionalmente.
REFERÊNCIAS
A Navigation and Obstacle Avoidance Algorithm for Mobile Robots Operating
in Unknown, Maze-Type Environments. Disponível em:
<http://www.ee.nmt.edu/~wedeward/papers/2004ITEA.pdf>. Acesso em: 05 nov.
2011.
Adding a Kinect to an iRobot Create. Disponível em: <http://www.ros.org/wiki/kinect/Tutorials/Adding%20a%20Kinect%20to%20an%20iRobot%20Create>. Acesso em: 12 nov. 2011.
ANTHONY, Sebastian. Hacked Microsoft Kinect trained to recognize objects.
Disponível em: <http://downloadsquad.switched.com/2010/11/29/hacked-microsoft-
kinect-trained-to-recognize-objects/>. Acesso em: 05 nov. 2011.
Arduino. Disponível em: <http://pt.wikipedia.org/wiki/Arduino>. Acesso em: 06 nov. 2011.
Arduino Uno. Disponível em: <http://arduino.cc/en/Main/ArduinoBoardUno>. Acesso
em: 06 nov. 2011.
AOUDE, Georges; et al. Threat Assessment Design for Driver Assistance System at Intersections. Disponível em: <http://acl.mit.edu/projects/tam.htm>. Acesso em: 12 nov. 2011.
Automóvel. Disponível em:
<http://www.cepa.if.usp.br/energia/energia1999/Grupo4A/automovel.htm>. Acesso
em: 05 nov. 2011.
AXE, David. Um a cada cinquenta soldados no Afeganistão é um robô.
Disponível em: <http://www.gizmodo.com.br/conteudo/um-a-cada-cinquenta-
soldados-no-afeganistao-e-um-robo/>. Acesso em: 12 nov. 2011.
BENNETT, Dylan. RC Car. <http://mboffin.net/category/rc-car/>. Acesso em: 13 nov.
2011.
BOUFFARD, Patrick. Quadrotor Autonomous Flight and Obstacle Avoidance
with Kinect Sensor. Disponível em:
<http://www.youtube.com/watch?v=eWmVrfjDCyw&feature=player_embedded>.
Acesso em: 13 nov. 2011.
BRAIN, Marshall; HARRIS, Tom. Como funcionam os receptores GPS. Disponível em: <http://informatica.hsw.uol.com.br/receptores-gps.htm>. Acesso em: 05 nov. 2011.
Brave New World with Stephen Hawking. Disponível em: <http://www.channel4.com/programmes/brave-new-world-with-stephen-hawking/episode-guide/series-1/episode-1>. Acesso em: 17 out. 2011.
CASTRO, André. Começando a usar o SDK do Kinect. Disponível em: <http://www.100loop.com/destaque/comeando-a-usar-o-sdk-do-kinect/>. Acesso em: 11 ago. 2011.
CAZAN, Vlad. Kinect Fan Control via Arduino. Disponível em: <http://www.vladcazan.com/kinect-hacking/kinect-arduino-control>. Acesso em: 05 nov. 2011.
Celulares aumentam acidentes de trânsito. Disponível em: <http://info.abril.com.br/noticias/tecnologia-pessoal/celulares-aumentam-acidentes-de-transito-08072011-17.shl>. Acesso em: 05 nov. 2011.
Circuito integrado. Disponível em: <http://pt.wikipedia.org/wiki/Circuito_integrado>.
Acesso em: 06 nov. 2011.
CIRIACO, Douglas. O que é Inteligência Artificial? Disponível em:
<http://www.tecmundo.com.br/1039-o-que-e-inteligencia-artificial-.htm>. Acesso em:
05 nov. 2011.
Computador. Disponível em: <http://pt.wikipedia.org/wiki/Computador>. Acesso em:
05 nov. 2011.
Connecting a 12V relay to Arduino. Disponível em: <http://www.instructables.com/id/Connecting-a-12V-Relay-to-Arduino/step6/The-schematic/>. Acesso em: 12 nov. 2011.
Curiosidades e estatísticas sobre acidentes de trânsito. Disponível em:
<http://www.dirigindoseguro.com.br/?p=8>. Acesso em: 05 nov. 2011.
Dados gerais do Brasil - Acidentes de Trânsito. Disponível em:
<www.cesvibrasil.com.br/seguranca/biblioteca_dados.shtm>. Acesso em: 05 nov.
2011.
De 2005 para 2008, acesso à Internet aumenta 75,3%. Disponível em: <http://www.ibge.gov.br/home/presidencia/noticias/noticia_visualiza.php?id_noticia=1517>. Acesso em: 05 nov. 2011. Em 2006, a esperança de vida do brasileiro ao nascer era de 72,3 anos.
Disponível em:
<http://www.ibge.gov.br/home/presidencia/noticias/noticia_visualiza.php?id_noticia=1
043&>. Acesso em: 05 nov. 2011.
ESA desenvolve inteligência artificial. Disponível em: <http://inteligenciaeconomica.com.pt/?p=4147>. Acesso em: 05 nov. 2011.
FAIRHEAD, Harry. China and the rise of the driverless car. Disponível em: <http://www.i-programmer.info/news/105-artificial-intelligence/2876-china-and-the-rise-of-the-driverless-car.html>. Acesso em: 11 ago. 2011.
________________. Sebastian Thrun on Google's driverless car. Disponível em: <http://www.i-programmer.info/news/105-artificial-intelligence/2217-sebasitian-thrun-on-googles-driverless-car.html>. Acesso em: 05 nov. 2011.
________________. Google drives a car. Disponível em: <http://www.i-programmer.info/news/105-artificial-intelligence/1434-google-drives-a-car.html>. Acesso em: 05 nov. 2011.
______________. All About Kinect. Disponível em: <http://www.i-
programmer.info/babbages-bag/2003-kinect-the-technology-.html>. Acesso em: 12
nov. 2011.
FERNANDEZ, Dan. Working with Depth Data. Disponível em: <http://channel9.msdn.com/Series/KinectSDKQuickstarts/Working-with-Depth-Data>. Acesso em: 16 jun. 2011.
Getting started with Microsoft Kinect SDK. Disponível em: <http://www.i-
programmer.info/programming/hardware/2623-getting-started-with-microsoft-kinect-
sdk.html>. Acesso em: 12 nov. 2011.
Getting started with Microsoft Kinect SDK - Depth and Video space. Disponível em: <http://www.i-programmer.info/programming/hardware/2822-getting-started-with-microsoft-kinect-sdk-depth-and-video-space-.html>. Acesso em: 12 nov. 2011.
Getting Started with PC Kinect. Disponível em: <http://www.i-
programmer.info/programming/hardware/1905-getting-started-pc-kinect.html>.
Acesso em: 12 nov. 2011.
GUIMARÃES, Ricardo. Trem descarrila na Linha 4-Amarela da ViaQuatro (Metrô
SP). Disponível em: <http://diariodacptm.blogspot.com/2011/06/trem-descarrila-na-
linha-4-amarela-da.html>. Acesso em: 06 nov. 2011.
Hacked Kinect Enabled Autonomous Mini Robot Car Navigation. Disponível em: <http://www.adafruit.com/blog/2010/12/10/hacked-kinect-enabled-autonomous-mini-robot-car-navigation/>. Acesso em: 13 nov. 2011.
História do Automóvel. Disponível em:
<http://www.historiadetudo.com/automovel.html>. Acesso em: 06 nov. 2011.
Historia do primeiro computador. Disponível em: <https://sites.google.com/site/historiasobreossitesdebusca/Historia-da-tecnologia/historia-do-primeiro-computador>. Acesso em: 06 nov. 2011.
História dos Computadores e Computação. Disponível em: <http://www.lsi.usp.br/~leminski/040907.htm>. Acesso em: 06 nov. 2011.
História dos jogos eletrônicos. Disponível em:
<http://pt.wikipedia.org/wiki/Hist%C3%B3ria_do_videogame>. Acesso em: 06 nov.
2011.
Inteligência artificial. Disponível em:
<http://pt.wikipedia.org/wiki/Inteligencia_artificial>. Acesso em: 05 nov. 2011.
Internet. Disponível em: <http://pt.wikipedia.org/wiki/Internet>. Acesso em: 12 nov.
2011.
iPad- and Kinect-Controlled Car. Disponível em: <http://www.gauravmanek.com/blog/?p=33l>. Acesso em: 12 nov. 2011.
JAMES, Mike. Robot cars - provably uncrashable? Disponível em: <http://www.i-programmer.info/programming/artificial-intelligence/2726-robot-cars-provably-0uncrashable.html>. Acesso em: 13 jul. 2011.
_____________. AI at the Crossroads - predicting who is going to run a red light. Disponível em: <http://www.i-programmer.info/news/105-artificial-intelligence/3413-ai-at-the-crossroads-predicting-who-is-going-to-run-a-red-light.html>. Acesso em: 01 dez. 2011.
____________. Getting started with Microsoft Kinect SDK – Depth. Disponível
em: <http://www.i-programmer.info/programming/hardware/2714-getting-started-with-
microsoft-kinect-sdk-depth.html>. Acesso em: 12 nov. 2011.
____________. Getting started with Microsoft Kinect SDK - Player index. Disponível em: <http://www.i-programmer.info/programming/hardware/2791-getting-started-with-microsoft-kinect-sdk-player-index.html?start=1>. Acesso em: 12 nov. 2011.
Kinect. Disponível em: <http://pt.wikipedia.org/wiki/Kinect>. Acesso em: 12 nov.
2011.
KinectSensor - Análise Geral do Sensor Kinect da Microsoft. Disponível em:
<http://code.google.com/p/kinmob/wiki/KinectSensor>. Acesso em: 12 nov. 2011.
Kinect Enabled Autonomous Mini Robot Car Navigation. Disponível em: <http://www.youtube.com/watch?v=NmnepqAQIlk&feature=player_embedded>. Acesso em: 13 nov. 2011.
Kinect for Windows. Disponível em: <http://kinectforwindows.org/>. Acesso em: 13
nov. 2011.
Kinect for Windows – FAQ. Disponível em:
<http://kinectforwindows.org/resources/faq.aspx>. Acesso em: 13 nov. 2011.
Kinect for Windows - System requirements and Installation instructions.
Disponível em: <http://kinectforwindows.org/download/>. Acesso em: 13 nov. 2011.
MARQUEJANE, André Luiz Fogaça. Brasil já tem 1 celular por pessoa. Disponível
em: <http://www.techguru.com.br/brasil-ja-tem-1-celular-por-pessoa/>. Acesso em:
05 nov. 2011.
MOREIRA, Eduardo. Problemas na rede BlackBerry reduziram drasticamente
acidentes de trânsito nos Emirados Árabes. Disponível em:
<http://www.techtudo.com.br/noticias/noticia/2011/10/problemas-na-rede-blackberry-
reduziram-drasticamente-acidentes-de-transito-nos-emirados-arabes.html>. Acesso
em: 05 nov. 2011.
Microcontrolador. Disponível em: <http://pt.wikipedia.org/wiki/Microcontrolador>.
Acesso em: 06 nov. 2011.
Microprocessador. Disponível em: <http://pt.wikipedia.org/wiki/Microprocessador>.
Acesso em: 06 nov. 2011.
NAN, Hao. Car takes long drive - by itself. Disponível em: <http://www.chinadaily.com.cn/cndy/2011-08/03/content_13037633.htm>. Acesso em: 03 ago. 2011.
NET.2971 - How to use the SerialPort class in WPF. Disponível em: <http://wrb.home.xs4all.nl/Articles_2010/Article_ArduinoWPFSerialPort.htm>. Acesso em: 12 nov. 2011.
O que é um circuito integrado? Disponível em:
<http://elektron.no.sapo.pt/oqueecircuitointegrado1.htm>. Acesso em: 05 nov. 2011.
Obstacle Avoiding Robot using AVR ATmega32 – Part III. Disponível em: <http://extremeelectronics.co.in/robotics/obstacle-avoiding-robot-using-avr-atmega32-%E2%80%93-part-iii/>. Acesso em: 05 nov. 2011.
PEEK, Brian. et al. Kinect for Windows SDK Quickstarts. Disponível em: <http://channel9.msdn.com/Series/KinectSDKQuickstarts>. Acesso em: 16 jun. 2011.
Readme for Kinect for Windows SDK - Beta 2 release. Disponível em:
<http://kinectforwindows.org/download/readme.htm>. Acesso em: 13 nov. 2011.
Revolução Industrial - História da Revolução Industrial. Disponível em:
<http://www.historiadomundo.com.br/idade-moderna/revolucao-industrial.htm>.
Acesso em: 05 nov. 2011.
REYNOLDS, Craig. Steering Behaviors For Autonomous Characters. Disponível
em: <http://www.red3d.com/cwr/steer/>. Acesso em: 06 nov. 2011.
Robótica. Disponível em: <http://pt.wikipedia.org/wiki/Rob%C3%B3tica>. Acesso
em: 05 nov. 2011.
Robot Recipe: Nicholas. Disponível em: <https://decibel.ni.com/content/docs/DOC-8409>. Acesso em: 12 nov. 2011.
SANTOS, Marco Aurélio da Silva. Como surgiu o avião? Disponível em: <http://www.mundoeducacao.com.br/fisica/como-surgiu-aviao.htm>. Acesso em: 05 nov. 2011.
SAXENA, Ashutosh. High Speed Obstacle Avoidance using Monocular Vision
and Reinforcement Learning. Disponível em:
<http://www.cs.cornell.edu/~asaxena/rccar/>. Acesso em: 06 nov. 2011.
SESHI. Fuzzy Logic - Obstacle Avoidance – WPF. Disponível em: <http://www.codeproject.com/KB/recipes/Seshi_FuzzyLogic.aspx>. Acesso em: 13 nov. 2011.
SHARMA, Suhas. [DIY] Kinect AC Power Adapter / Connector for the Old Xbox 360. Disponível em: <http://suhastech.com/xbox-360/homemade-kinect-hack-usb-ac-power-adapter-connector-for-the-xbox-360/>. Acesso em: 13 nov. 2011.
SILVA, Paulo. O potencial do Kinect! Disponível em:
<http://pplware.sapo.pt/pessoal/informatica/o-potencial-do-kinect/>. Acesso em: 13
nov. 2011.
Simple obstacle avoidance code for sumobot? Disponível em: <http://www.societyofrobots.com/robotforum/index.php?topic=8388.0>. Acesso em: 13 nov. 2011.
Sistema de posicionamento global. Disponível em:
<http://pt.wikipedia.org/wiki/Sistema_de_posicionamento_global>. Acesso em: 05
nov. 2011.
SPICER, John. Connect to the Arduino with C#. Disponível em: <http://www.technicana.com/physical-computing/73-connect-to-the-arduino-with-c-.html>. Acesso em: 12 nov. 2011.
Tecnologia Driverless Linha 4 - Amarela do metrô de São Paulo. Disponível em:
<http://www.viaquatro.com.br/>. Acesso em: 06 nov. 2011.
Using Relays with Arduino – Turning on the Lights. Disponível em: <http://www.glacialwanderer.com/hobbyrobotics/?p=9>. Acesso em: 12 nov. 2011.
Xbox. Disponível em: <http://pt.wikipedia.org/wiki/Xbox>. Acesso em: 06 nov. 2011.
What we're driving at. Disponível em:
<http://googleblog.blogspot.com/2010/10/what-were-driving-at.html>. Acesso em: 05
nov. 2011.
ANEXO II
Código-fonte da aplicação em C# para o processamento do Kinect
///////////////////////////////////////////////////////////////////////// // // Arquivo MainWindow.xaml.cs // ///////////////////////////////////////////////////////////////////////// using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using Coding4Fun.Kinect.Wpf; using Microsoft.Research.Kinect.Nui; namespace WorkingWithDepthData public partial class MainWindow : Window public MainWindow() InitializeComponent(); // Prepara o programa para trabalhar com as rotinas do Kinect Runtime nui = new Runtime(); // Carrega todas as funções durante a inicialização do programa private void Window_Loaded(object sender, RoutedEventArgs e) // Cria-se e abre-se a conexão com a porta serial // Envia-se um caractere ‘p’ para resetar todas portas lógicas do Arduino // Este caractere foi previamente configurado no Arduino para esta ação
// Após esta ação a conexão com a porta serial é fechada. var serialPort1 = new SerialPort("COM4", 9600); serialPort1.Open(); serialPort1.Write("p"); serialPort1.Close(); // Iniciam-se as rotinas de uso da câmera, sensor de profundidade e
// de reconhecimento de corpos humanos. nui.Initialize(RuntimeOptions.UseColor | RuntimeOptions.UseDepthAndPlayerIndex | RuntimeOptions.UseSkeletalTracking); nui.VideoFrameReady += new EventHandler<ImageFrameReadyEventArgs>(nui_VideoFrameReady);
// Cria-se um evento para tratar do sensor de profundidade nui.DepthFrameReady += new EventHandler<ImageFrameReadyEventArgs>(nui_DepthFrameReady);
// Abre-se um canal para exibição do vídeo da câmera VGA // e determina-se a resolução de 640 por 480 (largura por altura).
nui.VideoStream.Open(ImageStreamType.Video, 2, ImageResolution.Resolution640x480, ImageType.Color); // Abre-se um canal para processamento do sensor de profundidade
// e determina-se a resolução de 320 por 240 (largura por altura). nui.DepthStream.Open(ImageStreamType.Depth, 2, ImageResolution.Resolution320x240, ImageType.DepthAndPlayerIndex);
// Trata as informações vindas do sensor de profundidade void nui_DepthFrameReady(object sender, ImageFrameReadyEventArgs e) // Converte as informações de profundidade de cada pixel numa matriz
// colorida para representar a distância dos pixels byte[] ColoredBytes = GenerateColoredBytes(e.ImageFrame); // Gera a imagem baseada nas cores das distâncias PlanarImage image = e.ImageFrame.Image; image1.Source = BitmapSource.Create(image.Width, image.Height, 96, 96, PixelFormats.Bgr32, null, ColoredBytes, image.Width * PixelFormats.Bgr32.BitsPerPixel / 8); // Determina uma posição X e Y para monitorar a distância var distanciaR = e.ImageFrame.GetDistance(50, 100); var distanciaL = e.ImageFrame.GetDistance(270, 100); // Mostra na tela do programa aonde qual é a distância de cada ponto monitorado label1.Content = "Próximo obstáculo à direita: \n " + distanciaR; label2.Content = "Próximo obstáculo à esquerda: \n " + distanciaL;
// Declara a criação de uma conexão com a porta serial var serialPort1 = new SerialPort("COM4", 9600);
//Abre a conexão com a porta serial serialPort1.Open();
// Avaliam-se as distâncias do lado direito e esquerdo // para determinar qual ação será tomada // uma vez decidida a ação, um caractere ASCII é enviado a porta serial. // O que cada caractere significa será analisado e interpretado pela // programação existente no Arduino.
// Foi implementada uma lógica fuzzy para tratar da possibilidade de // obstáculos dos dois lados. Sem isso duas ações poderiam ser tomadas // simultaneamente causando um conflito e travando todo o sistema. if (distanciaR <= 1000) if (distanciaL <= 1000) label3.Content = " Parar e voltar!"; serialPort1.Write("z");
else label3.Content = " Obstáculo à direita"; serialPort1.Write("q"); if (distanciaL <= 1000) if (distanciaR <= 1000) label3.Content = " Parar e voltar!"; serialPort1.Write("z"); else label3.Content = "Obstáculo à esquerda"; serialPort1.Write("e"); if (distanciaL > 1000 && distanciaR > 1000) label3.Content = " Caminho livre"; serialPort1.Write("w"); // Fecha a porta serial serialPort1.Close();
// Gera a imagem da câmera de vídeo e mostra na tela void nui_VideoFrameReady(object sender, ImageFrameReadyEventArgs e) PlanarImage imageData = e.ImageFrame.Image; image2.Source = BitmapSource.Create(imageData.Width, imageData.Height, 96, 96, PixelFormats.Bgr32, null, imageData.Bits, imageData.Width * imageData.BytesPerPixel); // Gera o mapa de cores para a profundidade de cada pixel private byte[] GenerateColoredBytes(ImageFrame imageFrame) int height = imageFrame.Image.Height; int width = imageFrame.Image.Width; // Geração da matriz com a profundidade de cada pixel Byte[] depthData = imageFrame.Image.Bits; // colorFrame contém as informações para geração das cores para cada pixel
// na imagem // Geração da matriz com cores para cada pixel Byte[] colorFrame = new byte[imageFrame.Image.Height * imageFrame.Image.Width * 4]; //Constantes para gerar os índices as cores Azul, Verde e Vermelho const int BlueIndex = 0; const int GreenIndex = 1; const int RedIndex = 2;
// Cálculos para chegar na distânia de cada pixel var depthIndex = 0;
for (var y = 0; y < height; y++) var heightOffset = y * width;
for (var x = 0; x < width; x++) var index = ((width - x - 1) + heightOffset) * 4;
var distance = GetDistanceWithPlayerIndex(depthData[depthIndex], depthData[depthIndex + 1]);
// Para distâncias menores a 85 cm, a cor vermelha será mostrada if (distance <= 850) colorFrame[index + BlueIndex] = 0; colorFrame[index + GreenIndex] = 0; colorFrame[index + RedIndex] = 255; // Para distâncias entre 85 e 90 cm, uma coloração laranja escuro
// será mostrada else if (distance < 900) colorFrame[index + BlueIndex] = 0; colorFrame[index + GreenIndex] = 51; colorFrame[index + RedIndex] = 255;
// Para distâncias entre 1 metro e 90 cm, uma coloração laranja // média será mostrada
else if (distance < 1000) colorFrame[index + BlueIndex] = 0; colorFrame[index + GreenIndex] = 102; colorFrame[index + RedIndex] = 255;
// Para distâncias entre 1 e 1,20 metro, uma coloração laranja // clara será mostrada
else if (distance < 1200) colorFrame[index + BlueIndex] = 0; colorFrame[index + GreenIndex] = 153; colorFrame[index + RedIndex] = 255;
// Para distâncias entre 1,20 e 1,50 metro, uma coloração amarela // será mostrada
else if (distance < 1500) colorFrame[index + BlueIndex] = 0; colorFrame[index + GreenIndex] = 255; colorFrame[index + RedIndex] = 255;
// Para distâncias entre 2 metros e 1,50 metro, uma coloração // esverdeada será mostrada
else if (distance < 2000) colorFrame[index + BlueIndex] = 0; colorFrame[index + GreenIndex] = 255; colorFrame[index + RedIndex] = 204;
// Para distâncias superiores a 2 metros uma coloração azul // escura será mostrada
else if (distance > 2000) colorFrame[index + BlueIndex] = 128; colorFrame[index + GreenIndex] = 0; colorFrame[index + RedIndex] = 0; // Coloração do usuário quando detectado if (GetPlayerIndex(depthData[depthIndex]) > 0) colorFrame[index + BlueIndex] = 255; colorFrame[index + GreenIndex] = 255; colorFrame[index + RedIndex] = 255; // Caso pretenda-se realizar ações perante a detecção de um // ser humano, essas ações podem ser adicionadas neste ponto.
// Contudo até onde estudado, não conseguiu-se uma maneira de // des-detectar seres humanos. Durante os testes conseguiu-se // enviar um código para desligamento do sistema após detecção.
depthIndex += 2; return colorFrame;
// Determina quantos seres humanos foram detectados private static int GetPlayerIndex(byte firstFrame) //returns 0 = no player, 1 = 1st player, 2 = 2nd player... //bitwise & on firstFrame return (int)firstFrame & 7;
// Configura os bytes correspondentes a seres humanos e à matrix de pixels private int GetDistanceWithPlayerIndex(byte firstFrame, byte secondFrame) //offset by 3 in first byte to get value after player index int distance = (int)(firstFrame >> 3 | secondFrame << 5); return distance;
// Função de fechamento da janela, o Kinect é desligado e uma última mensagem // é enviada para a porta serial que o Arduino interpretará para desligar todas // as portas lógicas. private void Window_Closed(object sender, EventArgs e) nui.Uninitialize(); var serialPort1 = new SerialPort("COM4", 9600); serialPort1.Open(); serialPort1.Write("p"); serialPort1.Close();
// Modifica o ângulo da câmera e sensores de acordo com a elevação escolhida private void button1_Click(object sender, RoutedEventArgs e) nui.NuiCamera.ElevationAngle = (int)slider1.Value; Código da parte visual do programa em C#. ///////////////////////////////////////////////////////////////////////// // // Arquivo MainWindow.xaml // ///////////////////////////////////////////////////////////////////////// <Window x:Class="WorkingWithDepthData.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="550" Width="909" Loaded="Window_Loaded" Closed="Window_Closed"> <Grid Height="500" Width="859"> <Image Height="240" Width="320" Name="image1" Stretch="Fill" Margin="130,12,409,248" /> <Image Height="240" Width="320" Name="image2" Stretch="Fill" Margin="502,12,78,248" /> <Label Content=" Direita" Height="50" HorizontalAlignment="Right" Margin="0,276,398,0" Name="label1" VerticalAlignment="Top" Width="160" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="354,12,0,0" Name="rectangle2" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="306,12,0,0" Name="rectangle3" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="402,60,0,0" Name="rectangle4" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="354,60,0,0" Name="rectangle5" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="306,60,0,0" Name="rectangle6" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="402,108,0,0" Name="rectangle7" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" />
<Rectangle Height="50" HorizontalAlignment="Left" Margin="354,108,0,0" Name="rectangle8" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="306,108,0,0" Name="rectangle9" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Label Content=" Esquerda" Height="50" HorizontalAlignment="Left" Margin="125,276,0,0" Name="label2" VerticalAlignment="Top" Width="179" /> <Rectangle Height="50" HorizontalAlignment="Right" Margin="0,12,631,0" Name="rectangle10" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="226,12,0,0" Name="rectangle11" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="130,12,0,0" Name="rectangle12" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="226,60,0,0" Name="rectangle13" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="178,60,0,0" Name="rectangle14" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="130,60,0,0" Name="rectangle15" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="226,108,0,0" Name="rectangle16" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="178,108,0,0" Name="rectangle17" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="130,108,0,0" Name="rectangle18" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Label Content=" Estado Atual" Height="43" HorizontalAlignment="Left" Margin="178,341,0,0" Name="label3" VerticalAlignment="Top" Width="243" Foreground="Red" FontSize="24" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="402,156,0,0" Name="rectangle1" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="354,156,0,0" Name="rectangle19" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="306,156,0,0" Name="rectangle20" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="226,156,0,0" Name="rectangle21" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="178,156,0,0" Name="rectangle22" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="130,156,0,0" Name="rectangle23" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> <Slider Height="34" HorizontalAlignment="Left" Margin="567,292,0,0" Name="slider1" VerticalAlignment="Top" Width="205" Interval="1" Minimum="-27" Maximum="27" SmallChange="1" IsSnapToTickEnabled="True" />
<Label Content="Binding Path=Value, ElementName=slider1" Height="42" HorizontalAlignment="Left" Margin="660,315,0,0" Name="label5" VerticalAlignment="Top" Width="53" FontSize="24" /> <Button Content="Ajustar Ângulo" Height="33" HorizontalAlignment="Right" Margin="0,363,87,0" Name="button1" VerticalAlignment="Top" Width="205" Click="button1_Click" /> <Rectangle Height="50" HorizontalAlignment="Left" Margin="402,12,0,0" Name="rectangle24" Stroke="White" StrokeThickness="3" VerticalAlignment="Top" Width="50" /> </Grid> </Window>
Complementar às informações acima, este aplicativo foi desenvolvido numa aplicação WPF em C#.
Além das bibliotecas de referência padrões, também foram utilizadas as bibliotecas
Coding4Fun.Kinect.Wpf.dll e Microsoft.Research.Kinect.dll.
AN
EX
O I
V –
Tela
da a
plic
açã
o e
m C
#
O q
uadro
do la
do e
squerd
o r
epre
senta
a im
age
m g
era
da p
elo
sensor
de p
rofu
nd
idade
;
O q
uadro
do la
do d
ire
ito r
epre
senta
a im
agem
captu
rada p
ela
câm
era
de v
ídeo
.
ANEXO V
Código-fonte da aplicação em C que interpreta as informações para o Arduino e age
nas saídas do mesmo interagindo com o mundo elétrico/físico.
// Prepara todas as saídas que serão utilizadas e configura
qual será a velocidade de bits por segundo na transmissão
serial.
void setup()
pinMode(10, OUTPUT);
pinMode(8, OUTPUT);
pinMode(6, OUTPUT);
pinMode(4, OUTPUT);
Serial.begin(9800);
// Rotina que se repetirá durante toda a execução do programa,
repetindo-se quando chegar ao fim. void loop()
// Verifica se a porta serial está disponível if(Serial.available())
// Declara uma variável e monitora os dados da porta
serial que a preencherão.
int c = Serial.read();
// Caso seja o caractere ASCII que representa a letra
“a”, irá desligar a saída 4 se estiver ligada e ligar
a saída 6. Isto evita conflitos, como virar para a
esquerda e à direita ao mesmo tempo.
// A lógica a seguir também é utilizada para as
demais direções.
if (c == 'a')
digitalWrite(4,LOW);
digitalWrite(6,HIGH);
else if (c == 'q')
digitalWrite(4,LOW);
digitalWrite(6,HIGH);
digitalWrite(8,LOW);
digitalWrite(10,HIGH);
else if (c == 'd')
digitalWrite(6,LOW);
digitalWrite(4,HIGH);
else if (c == 'e')
digitalWrite(4,HIGH);
digitalWrite(6,LOW);
digitalWrite(8,LOW);
digitalWrite(10,HIGH);
else if (c == 's')
digitalWrite(10,LOW);
digitalWrite(8,HIGH);
digitalWrite(6,LOW);
digitalWrite(4,LOW);
else if (c == 'z')
digitalWrite(10,LOW);
digitalWrite(8,HIGH);
digitalWrite(6,HIGH);
digitalWrite(4,LOW);
else if (c == 'w')
digitalWrite(10,HIGH);
digitalWrite(8,LOW);
digitalWrite(6,LOW);
digitalWrite(4,LOW);
else if (c == 'p')
digitalWrite(10,LOW);
digitalWrite(8,LOW);
digitalWrite(6,LOW);
digitalWrite(4,LOW);
ANEXO VI – Esquema elétrico final da placa intermediária
entre o Arduino e o Controle Remoto
Todos os diodos são do tipo 1N4007, todos os relés são de 5V, todos os transístores são NPN
modelo C945 e todos os resistores são de 68Ω. Todos os componentes estão agrupados em 2 pares.
Os circuitos elétricos do controle remoto e do Arduino estão isolados pelos relés.
ANEXO VII – Esquema elétrico de alimentação alternativo
à fonte de 12V para o Kinect
Por motivos de performance e mobilidade, este pequeno circuito teve de ser montado e acoplado ao
cabo USB proprietário do Kinect. A única alteração ao cabo USB original foi cortar o cabo da fonte e
anexá-lo ao fio deste esquema elétrico acima. Para regular a tensão em 12V foi necessário gerar 24V
com duas baterias recarregáveis de 12V e passá-las por um regulador do tipo LM7812C, os
capacitores do esquema realizam o trabalho de filtragem mantendo a mesma corrente e tensão.
Foto do esquema elétrico acima. Do lado esquerdo há dois plugs macho para conectar as baterias de
12V e do lado direito a um plug fêmea para ser conectado ao cabo USB modificado.
Foto do esquema elétrico com detalhe no regulador de tensão e capacitores.
Cabo USB proprietário do Kinect modificado na extremidade onde era localizado a fonte de 12V e
substituída por um plug macho.
Bateria de 12V recarregável com plug fêmea.
ANEXO VIII – Versão original do projeto
Esquema inicial de acoplagem à caçamba. Foi descartado pois a cada frenagem a caçamba chocava-
se com o carro. Além disso, este sistema permitia que a caçamba direcionasse o carro por conta do
peso e flexibilidade do plástico anexado.
Inicialmente foram soldados os contatos dos relés de tração, os contatos que direcionavam o veículo
e o contato do negativo que junto de qualquer outro contato, fechava o circuito e agira na
movimentação do veículo.
Detalhe do resultado final da soldagem dos fios de ligação à placa intermediária.
Detalhe dos fios saindo por fora do carro sem arterar nada em sua estrutura.
Detalhe da ligação do carro à placa intermediária original.
Placa intermediária original: todos os fios eram encaixados nos conectores.
Placa intermediária original: detalhe do verso.
Após queimar o chip do carro, uma nova placa foi criada com apenas 4 relés.
ANEXO IX – Versão 2 do projeto
Placa intermediária na segunda versão, sem conectores, tudo foi soldado para evirar mau contato.
Placa intermediária na segunda versão: detalhe da frente.
ANEXO X – Versão 3 do projeto
Placa intermediária na versão 2.5: foram inseridos diodos, resistores e transístores.
Placa intermediária na versão 2.5: detalhe da frente.
Detalhe da soldagem no controle remote: não houve mudança no circuito do mesmo.
Placa intermediária na versão 3: detalhe de lado.
Placa intermediária na versão 3: detalhe de cima.
Placa intermediária na versão 3: detalhe do verso.
Caçamba montada para carregar o notebook
Novo carro sem circuitos alterados. O Kinect foi colado com fita isolante na parte superior.
Detalhe da diferença de tamanhos.
Detalhe da parte traseira do carro.
Detalhe da parte traseira com o conector da caçamba.
Detalhe do conector acoplado à caçamba.