CENTRO UNIVERSITÁRIO VILA VELHA
CURSO DE CIÊNCIA DA COMPUTAÇÃO
Alessandro Silveira Gonçalves
Érica de Castro Roque
Frederico da Silva Lamonica
ACIONAMENTO 3D - ESTENDENDO PARA
INTERNET
VILA VELHA
2008
Alessandro Silveira Gonçalves
Érica de Castro Roque
Frederico da Silva Lamonica
ACIONAMENTO 3D - ESTENDENDO PARA
INTERNET
Trabalho de Conclusão de Curso apresentado ao Centro Universitário de Vila Velha
como requisito parcial para a obtenção do
grau de Bacharel em Ciência da Computação.
Orientador: Marcelo Oliveira Camponez
VILA VELHA
2008
Alessandro Silveira Gonçalves
Érica de Castro Roque
Frederico da Silva Lamonica
ACIONAMENTO 3D - ESTENDENDO PARA
INTERNET
BANCA EXAMINADORA
Prof. Msc. Marcelo Oliveira Camponez
Centro Universitário Vila Velha
Orientador
Prof. Msc. Marcelo Brunoro
Centro Universitário Vila Velha
Prof. Msc. Otacílio José Pereira
Centro Universitário Vila Velha
Trabalho de Conclusão de Curso
aprovado em 26/11/2008.
Aos meus pais pelo incentivo e carinho, a todos os meus familiares, a
todos os meus colegas/amigos que torceram para mim e a todos os
professores que me ajudaram na elaboração do trabalho.
AGRADECIMENTOS
Primeiramente agradeço a Deus por ter feito com que nós estivéssemos aqui para
a conclusão de mais uma etapa de nossas vidas. Agradeço também a nossos pais,
mães e familiares que na hora do descanso nos deram a motivação maior de continuar
este trabalho. Agradeço também aos meus colegas de classe que nos ajudaram de
forma direta e indireta na conclusão do curso. E não poderia deixar de agradecer a
todos os professores, coordenadores, monitores e outros.
Faço um agradecimento em especial ao meu coordenador de monografia, Marcelo
Oliveira Camponez, por ter orientado o caminho para a elaboração do trabalho de
conclusão de curso.
A ciência pode construir o computador, mas não o operador."
Dr. Werner
LISTA DE TABELAS
1
CAMADAS E PROTOCOLOS.
. . . . . . . . . . . . . . . . . . . . . . .
15
2
COMPARATIVO ENTRE AS ENGINES . . . . . . . . . . . . . . . . . . .
20
3
COMPARATIVO ENTRE EDITORES . . . . . . . . . . . . . . . . . . . .
21
4
COMPARATIVO ENTRE O RS-232 E O RS-485. . . . . . . . . . . . . .
25
5
DISTRIBUIÇÃO DOS PONTOS ELÉTRICOS. . . . . . . . . . . . . . . .
39
6
CUSTO MATERIAL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
39
7
CUSTO MÃO-DE-OBRA. . . . . . . . . . . . . . . . . . . . . . . . . . .
40
LISTA DE FIGURAS
1
Utilização dos protocolos TCP/IP para formar a estrutura de comunicação de rede (correio-eletrônico), compartilhamento de arquivos. . . .
15
2
Estrutura de rede TCP/IP conectada a Internet. . . . . . . . . . . . . . .
16
3
Computação Gráfica e subáreas. . . . . . . . . . . . . . . . . . . . . . .
17
4
Coordenada da câmera. . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
5
Esquema de camadas do projeto. . . . . . . . . . . . . . . . . . . . . .
26
6
Diagrama de seqüência. . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
7
Funcionamento do protocolo TCP/IP. . . . . . . . . . . . . . . . . . . . .
32
8
Comunicação com o socket. . . . . . . . . . . . . . . . . . . . . . . . . .
33
9
Código. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35
10
Diagrama de classe. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35
11
HAL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
12
Comunicação RS-232. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37
13
Comunicação RS-485. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
37
14
Dispositivo AMP-12. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
SUMÁRIO
RESUMO
1 INTRODUÇÃO
11
2 REFERENCIAL TEÓRICO
14
2.1 TCP/IP (Transmission Control Protocol / Internet Protocol) . . . . . . . .
14
2.1.1 Protocolo TCP . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
2.1.2 Protocolo IP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
2.2 Computação Gráfica . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
2.3 Engine 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
2.4 Editores 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
2.5 Banco de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21
2.6 RS-232 e RS-485
23
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3 Desenvolvimento
26
3.1 Cliente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
3.1.1 TCP/IP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31
3.2 Servidor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33
3.3 Banco de dados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
3.4 Hal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
3.5 Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
4 FINANCEIRO
39
5 CONCLUSÃO
41
6 TRABALHOS FUTUROS
42
ANEXO A -- Anexo A - Código desenvolvido do Cliente
43
ANEXO B -- Anexo B - Código desenvolvido do Servidor
68
RESUMO
Neste projeto é desenvolvida uma aplicação cliente-servidor, no qual parte-se de uma
interface 3D (modelo 3D do ambiente controlado) instalada em seu computador pessoal. O usuário será capaz de controlar o ambiente, acionando equipamentos elétricos (lâmpadas, ventiladores, motores, etc.) através da Internet. Esta aplicação é uma
continuação de um TCC (Trabalho de Conclusão de Curso) feito anteriormente, no
qual cliente e servidor eram executados na mesma máquina. Neste trabalho, cliente e
servidor ficam situados em computadores diferentes interligados por uma rede TCP/IP.
Palavras-chave: Computação Gráfica, redes de computadores, banco de dados, RS
232, RS 485 e RS 422.
11
1
INTRODUÇÃO
A Internet surgiu em meados dos anos 1960 e 1970 durante a Guerra Fria. Importantes informações eram armazenadas em servidores que se localizavam em quartéis
generais estratégicos, e o medo de perdê-las no caso de um ataque a esses estabelecimentos era enorme. Nesse momento nos Estados Unidos, a ARPA (Agência de
Projetos de Pesquisas Avançadas) criou a primeira rede - ARPAnet - com o objetivo
de conectar os computadores dos seus departamentos de pesquisa.
Com o passar dos anos, as universidades e outras instituições que faziam trabalhos relativos à defesa tiveram permissão para se conectar a ARPAnet. A rede havia
crescido tanto que seu protocolo de comutação de pacotes, o NPC, tornou-se inadequado tendo que mudar para um novo protocolo chamado TCP/IP.
Em meados dos anos 1990, a Internet deixou de ser uma instituição de natureza
apenas acadêmica e passou a ser explorada comercialmente. Foi criado o primeiro
browser para a web, fazendo com que a Internet se popularizasse cada vez mais e
começasse a fazer parte do cotidiano de pessoas comuns.
Atualmente há vários tipos de serviços disponíveis na Internet, desde uma simples
compra em um site, jogos virtuais e até mesmo cirurgias. Isso é possível graças a
enorme expansão da Internet e das tecnologias que a usam, como softwares (usados
para as conexões entre os clientes / servidores e para o controle dos dispositivos) e
hardwares (usados como a parte física, no caso de uma cirurgia seriam as mãos e
ferramentas do médico).
Uma das tecnologias mais usadas na Internet é o comércio eletrônico (E-Commerce).
Em 1995, surgiu a primeira empresa de e-commerce, a americana Amazon.com, e
cinco anos mais tarde essa tecnologia veio para o Brasil. O ato de comprar e vender
pela Internet foi tão bem aceito pela sociedade, que em 2005 houve um movimento
de R$ 12,5 bilhões em compras on-line no Brasil. E não para por ai, a estimativa para
2010 é de R$ 100,90 milhões. (Gazeta Mercantil, 04.01.2006) De acordo com o site
12
WNews no ano de 2005, cientistas australianos da Universidade de Queensland realizaram a primeira cirurgia a laser via Internet para operar células que estavam em
San Diego, na Califórnia. Eles utilizaram um software chamado de RoboLase para
produzir furos com menos de um milésimo de milímetro em células humanas. Os dois
laboratórios precisaram de um link de um gigabyte por segundo para garantir a precisão da operação. Além disso, conseguiram operar ferramentas como pinças a laser
para imobilizar um espermatozóide em movimento.
Atualmente, uma prática que vem se tornando mais comum pela Internet são os
jogos onlines. Na Internet há milhares de gêneros (ação, estratégia, tiro, etc). Como
exemplos podemos citar: Quake, Counter-Strike e Second Life. Esses simulam um
ambiente onde o usuário é um personagem que interage com outros jogadores. Todos os usuários têm a aplicação em funcionamento no próprio computador e estão
conectados a Internet. A conexão é feita da seguinte forma: tendo a aplicação do
jogo iniciada, ela se conecta ao servidor via Internet e faz a integração com os outros
usuários.
Uma vertente que utiliza a internet e vem se destacando cada vez mais no mercado mundial é a domótica, também conhecida como edifícios inteligentes. Com a
finalidade de trazer mais conforto, comodidade e segurança para a vida agitada das
pessoas, essa área tem como característica controlar aparelhos eletrônicos por meio
de uma central computadorizada. Esse tipo de aplicação tem atraído olhares de empresas e clientes particulares e tem sido utilizada não só pela comodidade e conforto,
mas também pela economia de energia elétrica. Usando computadores, telefones
móveis e outros meios que se conectam a Internet, os usuários podem controlar todos os equipamentos de sua casa como luz, cortinas, ar condicionado, entre outros
aparelhos eletrônicos.
A domótica está presente na aplicação que será desenvolvida neste TCC, de forma
que um usuário através de seu computador pessoal (cliente) entrará na aplicação que
simulará uma casa em 3D, e através dela acionará dispositivos (lâmpadas, motores e
etc) de sua casa real. Ao selecionar o acionamento / desacionamento, a aplicação automaticamente se conectará ao computador servidor via Internet e passará o comando
de acionamento da carga especifica. A casa 3D será uma réplica virtual da casa real,
para facilitar os controles de acionamento. Serão necessários alguns dispositivos para
realizar os acionamentos, pois eles servirão de forma intermediária entre o computador servidor e os motores, lâmpadas e outras cargas.
13
Esse projeto é a continuação de uma aplicação desenvolvida no ano de 2007,
quando foi criado um software que executado em um computador pessoal, era capaz
de controlar em uma residência itens como: lâmpadas, motores, entre outros aparelhos eletrônicos. Para interface com o usuário foi desenvolvido um modelo em 3D,
que é uma réplica do ambiente real. A interação acontece semelhante a um jogo em
primeira pessoa. O acionamento da carga elétrica se dá a partir de dispositivos diretamente ligados ao computador pessoal através de um conversor RS-232. O projeto
atual é semelhante ao anterior, porém usa a Internet como mediadora do acionamento.
O objetivo deste TCC é separar a interface 3D que controla o ambiente do computador servidor, tendo a mesma, sua localização no computador pessoal do usuário.
Serão feitas mudanças na aplicação para que quando o usuário acionar alguma carga
no ambiente 3D seja enviado o comando para o servidor. Esse envio será feito através
da Internet.
O servidor deverá ser modificado para aceitar conexões vindas do cliente, interpretar o comando recebido, se comunicar com um banco de dados e com os dispositivos
de acionamentos.
14
2
REFERENCIAL TEÓRICO
Neste item será feita uma revisão teórica dos principais conceitos e tecnologias
que serão utilizados, como por exemplo: TCP/IP, engines, editores, banco de dados,
entre outros.
2.1 TCP/IP (Transmission Control Protocol / Internet Protocol)
A história do TCP/IP começa com a ARPANET. Nesse período universidades e
repartições públicas se conectavam a ela através de uma linha telefônica. Com a
evolução da tecnologia, redes de rádio e satélite começaram a usar a ARPANET,
porém surgiram problemas com os protocolos já existentes e isso forçou a criação
de uma nova arquitetura de referência. Em 1974, foi criado por Cerf e Kahan o Modelo
de Referência TCP/IP.
De acordo com Tanenbaum (2001), o TCP/IP é uma arquitetura flexível capaz de
se adaptar a aplicações com necessidades diferentes, como por exemplo: transações
bancárias e transmissão de Voip (voz sobre IP). Ela é dividida em cinco camadas:
• Camada física: define a organização da estrutura de conexão física entre o sistema computacional e a rede. Usa estruturas como conectores, cabeamento e
etc.
• Camada de enlace: tem a função de fazer a transmissão de informações entre
computadores, desde que haja um meio físico conectando-os.
• Camada de rede: trata da comunicação entre as máquinas. Ela é responsável
pelo roteamento dos dados desde a origem até o destino desejado.
• Camada de transporte: responsável por pegar os dados enviados da camada de
15
aplicação e enviá-los à camada de rede. Ele conecta programas, diferente das
camadas que conectam equipamentos.
• Camada de aplicação: fornece uma interface direta com os aplicativos do usuário,
fazendo a comunicação entre os aplicativos.
A Tabela.1 relaciona os principais protocolos de cada camada
CAMADAS
Física
Enlace
Rede
Transporte
Aplicação
PROTOCOLOS
RDIS, RS-232, EIA-422, RS-449, USB
Ethernet, 802.11 WIFI, IEEE 802.1 Q,
802.11g, HDLC, PPP, Token Ring, Frame Relay
IP (Ipv4, Ipv6), ARP, RARP, ICMP, IPSec
TCP, UDP
FTP, Telnet , SMTP , DNS , HTTTP, POP3, RDP
Tabela 1: CAMADAS E PROTOCOLOS.
Seguem nas Figura.1 e Figura.2 alguns exemplos de aplicações de arquiteturas
distintas de rede baseadas em TCP/IP, por exemplo, redes internas de empresas
baseadas em transporte TCP/IP, serviços de redes de empresas online e provedores
de acesso a Internet.
Figura 1: Utilização dos protocolos TCP/IP para formar a estrutura de comunicação
de rede (correio-eletrônico), compartilhamento de arquivos.
16
Figura 2: Estrutura de rede TCP/IP conectada a Internet.
2.1.1 Protocolo TCP
Protocolo que especifica o formato dos dados e das confirmações que dois computadores trocam, e os procedimentos para assegurar que os dados cheguem corretamente.
O protocolo TCP divide o processo de comunicação em três fases:
• O cliente envia segmento tipo SYN (pedido de conexão).
• O servidor reconhece o pedido de conexão enviando segmento tipo SYN com bit
de reconhecimento (ACK) ligado para o cliente.
• A transferência de dados e o encerramento da conexão podem ser iniciados
tanto pelo cliente como pelo servidor enviando um segmento FIN (sinalizando
fim da conexão).
2.1.2 Protocolo IP
É o protocolo responsável pelo roteamento entre redes em uma estrutura de rede
TCP/IP, provendo a capacidade de comunicação entre cada elemento componente da
rede para permitir o transporte de uma mensagem da origem até o destino.
17
2.2 Computação Gráfica
Segundo a ISO (International Organization for Standardization), Computação Gráfica pode se definir como: um conjunto de ferramentas e técnicas para converter dados
de um dispositivo gráfico através do computador. [Azevedo, Eduardo]
Em 1950, com finalidades acadêmicas e militares, foi criado o primeiro computador
com recursos gráficos, o Whirlwind I, desenvolvido pelo MIT. Porém, só em 1959 que
surgiu o termo Computer Graphics (Computação Gráfica), criado por Verne Hudson.
Para gerar uma imagem por computador é necessário entender a base da computação gráfica, que pode ser dividida em três grandes subáreas:
• Síntese de imagens, que representa objetos criados a partir de especificações
geométricas;
• Processamento de imagens, que seria a forma digital de melhorar uma imagem;
• Análise de imagens, onde é feita uma análise da imagem para a obtenção das
características desejadas.
O diagrama da Figura.3 ilustra o relacionamento da Computação Gráfica e suas
subáreas.
Figura 3: Computação Gráfica e subáreas.
Neste TCC, o foco na utilização da Computação Gráfica está na síntese de imagens, principalmente em 3D. Por este motivo, o texto a partir deste ponto se aprofundará apenas nesta subárea, sendo descrito a partir da visão do usuário final.
Existem vários softwares chamados de editores gráficos, que auxiliam na manipulação e na criação de imagens e cenas. No mercado existem vários tipos de editores,
18
porém quanto mais especifico for o software para a criação, mais real será a imagem
final.
As cores de uma imagem projetada na tela do computador são compostas por
clusters. Um cluster é composto de três pixels (pontos que compõem uma imagem),
sendo cada um de uma cor (vermelho, azul e verde, que ao serem projetadas se misturam opticamente). Esse espaço de cor projetado é chamado de RGB (Red, Green,
Blue). Os desenvolvedores, a fim de obter uma representação gráfica virtual realista,
precisam trabalhar diretamente ou indiretamente com a manipulação de pontos de um
gráfico matricial (pixels). [Corrigan, John]
Para a representação e manipulação de imagens são usados gráficos vetoriais
(imagens formadas por cálculos matemáticos executados pelo computador) e gráficos
matriciais (imagens formadas pelo preenchimento de uma matriz de pixels)[Azevedo,
Eduardo]. As características das imagens, sejam matriciais ou vetoriais, são:
Imagens Matriciais:
• Formadas por uma grade matricial composta por pixels;
• Por ser baseada em pixels, geralmente são usadas para imagens desenvolvidas
em um programa de pintura ou para processar imagens fotográficas;
• São exemplos de imagens criadas com os programas Corel Photopaint e Adobe
Photoshop.
Imagens Vetoriais:
• Constituídas por linhas e curvas definidas matematicamente, de espessura e cor
constante;
• Por ter a definição matemática, a imagem pode se movida, redimensionada ou
rotacionada como um objeto independente;
• São exemplos de imagens criadas pelos programas Corel Draw e Adobe Ilustrador.
A geração de imagens 3D pelo computador é dada a partir da descrição dos elementos que compõe uma cena. Uma imagem é composta por três tipos diferentes de
elementos: os objetos, as fontes de luz e as câmeras. Geralmente são eles que são
visualizados na imagem final.
19
Um objeto, ou um nó como é descrito nos editores 2D e 3D, é um desenho que
compõe uma cena e pode ser caracterizado por dois tipos de atributos: os ópticos
e os geométricos. O primeiro está associado a características como cor, textura,
transparência e brilho. O segundo se baseia na sua forma geométrica e no espaço
em que ocupa.
A iluminação de uma cena é dada a partir das fontes luminosas que a compõe.
São elas que permitem que o objeto seja visto. Existem vários tipos, como:
• Ambiente: representada por uma iluminação uniforme;
• Pontual: representada por um ponto de luz, que é introduzido em todas as direções;
• Spot: definida por um cone de iluminação;
O último elemento que compõe a síntese de uma imagem é a câmera. Ela é
responsável pela projeção de um plano de imagem bidimensional em um plano tridimensional. O plano tridimensional é controlado pelas posições x, y e z. Podemos
citar como elementos o ponto de observação, a orientação e o foco. Ponto de observação é representado pela localização da câmera dentro da cena. O foco representa
para onde a mesma está apontando. A orientação é controlada pela posição x, y, z,
pelo foco e pelo vetor que indica a vista superior da cena 3D.[Azevedo, Eduardo]. A
Figura.4 representa os elementos de uma câmera.
Figura 4: Coordenada da câmera.
Para fazer a animação das imagens criadas pelos editores 3D são usadas APIs
gráficas, que são conjuntos de rotinas e padrões utilizados por programas aplicativos,
os quais fazem a comunicação entre o modelo 3D, o software e o hardware das placas
de vídeo. Os mais conhecidos hoje em dia são o DirectX e o OpenGL.
20
2.3 Engine 3D
O desenvolvimento de aplicações com imagens 3D utilizando DirectX e OpenGL,
que são APIs complexas por serem chamadas rotinas de baixo nível, não possibilita
uma boa produtividade, o que estimulou os desenvolvedores a criarem engines 3D
(encapsulamento das APIs de baixo nível).
Em meados da década de 90, eram utilizadas engines para auxiliar o programador
na criação de ambientes 3D. O uso dessas bibliotecas de código se tornou mais freqüente depois da criação dos jogos Quake e Doom. Ao invés dos programadores
começarem a desenvolver um novo jogo do início, eles utilizavam rotinas já prontas.
Em 1998, essa prática era tão comum que se pagava muito caro por uma licença do
código.
Existem várias ferramentas no mercado, como por exemplo, Irrlicht, Agar, 3D Coding BlackHole Engine, 3DgameStudio, entre outros. Cada biblioteca possui características próprias como ferramentas especificas, funcionalidades suportadas, APIs gráficas encapsuladas, linguagens de programação disponível, plataformas, som e vídeo,
recursos gráficos como iluminação, sombreamento, malhas e texturas. Cabe ao desenvolvedor escolher a engine que mais se adapta ao sistema a ser criado. A Tabela.2
mostra um comparativo entre diversas engines no mercado.
Engines
Irrlicht
C4 Engine
Torque Game Engine
Reality Factory
TV3D SDK 6.5
3DGameStudio
OGRE
Open
Source
X
X
Uso
Comercial
X
X
X
X
X
APIS
Gráficas
OpenGl | Directx
OpenGl
OpenGl | Directx
OpenGl | Directx
Directx
Directx
OpenGl | Directx
Linguagem de
Programação
C/C++,ASP.Net
C/C++
C/C++
C/C++
C/C++,ASP.Net
C/C++,Delphi
C/C++
Tabela 2: COMPARATIVO ENTRE AS ENGINES
2.4 Editores 3D
São ferramentas usadas para o desenvolvimento de objetos, personagens, cenários,
entre outras coisas em três dimensões. Existem vários tipos de editores, como:
3D Studio Max, Rhinoceros 3D, LightWave 3D, IrrEdit, Maya, Cinema 4d, SketchUp,
21
ZBrush, Blender, L3P, Wings 3D, AutoCad, QC Pro, Promob, Corel Bryce, entre outros.
A Tabela.3 mostra uma pequena comparação entre os editores mais populares.
Editores
Desenvolvida por
3D Studio Max
IrrEdit
Maya
Blender
Discreet,Kinetix
Ambiera
Alias
Blender Foundantion
Usada para
desenvolvimento de
Personagens
Cenários
Cenários
Objetos
Extensões
.3ds, .dxf, .dwg
.bsp, .irr, .irrmesh
.rpm, .ma
.dxf,.x,.flt, .dae,.ply
Tabela 3: COMPARATIVO ENTRE EDITORES
2.5 Banco de dados
Os sistemas de banco de dados surgiram na década de 60, como uma evolução
dos sistemas de informação baseados em arquivos em discos magnéticos. No início
da computação, o armazenamento de dados ocorria dentro dos programas. Com o
surgimento dos discos magnéticos, os dados passaram a ser armazenados de forma
distinta do código executável dos programas. [C. J. Date, 2004]
Para resolver o problema de armazenamento e recuperação de informações são
usados bancos de dados. Esse sistema de armazenamento deve ser usado quando
um conjunto de informações possui muitas variáveis interligadas entre si. Essas funcionalidades, como por exemplo: cadastro, recuperação e relacionamento entre dados, muitas vezes não são encontradas em sistemas de arquivos comuns. A seguir é
mostrada a diferença entre usar um banco de dados e um sistema de arquivo.
Sistema de banco de dados
• Dados e metadados: dados e descrições são armazenados na base e gerenciados pelo SGBD.
• Independência de dados: a modificação de um campo não afeta o programa.
• Redundância: único repositório de dados, eliminando o problema de redundância.
Sistema de arquivos
22
• Dados e Meta-Dados: Dados são armazenados através de interação com aplicações.
• Independência de Dados: Modificação de um campo afeta o programa.
• Redundância: Gasto de espaço e necessidades de esforços para manter consistência.
Ao longo do tempo foi criada uma arquitetura para sistemas de banco de dados,
com o objetivo de separar o banco de dados físico das aplicações com o usuário, por
meio de três níveis de esquemas [C. J. Date, 2004]:
• Esquema interno: descreve a estrutura física de armazenamento do banco de
dados, a organização de arquivos e seus métodos de acesso.
• Esquema conceitual: descreve a estrutura do banco de dados representando os
dados que vão ser utilizados, escondendo os detalhes de armazenamento.
• Esquema externo: descreve os dados, ou parte dos dados, que mais interessam
aos usuários.
Como exemplo de modelos de bancos de dados, podemos citar: banco de dados
relacional, orientado a objeto, hierárquico, entre outros. Neste texto descreveremos
dois modelos, o orientado a objeto e o relacional.
• Banco de dados relacional: no modelo relacional, o banco organiza os dados em
relações. Cada relação pode ser vista como uma tabela, na qual cada coluna
corresponde a atributos da relação, e as linhas correspondem a registros ou elementos da relação. O relacionamento entre tabelas é feito a partir de chaves.
Uma chave é um conjunto de um ou mais atributos que determinam a unicidade
de cada registro. Temos dois tipos: chave primária, que é a chave com a função
de identificar cada registro dando-lhe unicidade (nunca se repetirá), e chave estrangeira, formada através de um relacionamento com a chave primária de outra
tabela.
• Banco de dados orientado a objeto: neste modelo as informações são armazenadas
em forma de objetos. Os dados só podem ser manipulados pelos métodos
definidos pela classe a que estes objetos pertencem. O acesso aos dados pode
ser rápido, já que as junções geralmente não são necessárias pois um objeto
pode ser obtido diretamente sem busca, seguindo os ponteiros [Kim, Won, 1990].
23
Um fator que leva à adoção do banco de dados orientado a objetos no lugar do
banco de dados relacional, é que no relacional a dificuldade em manipular dados
complexos é maior. Outro fator se encontra na manipulação dos dados, que é feita
através de uma aplicação, tendo seu código a necessidade de ser traduzido entre a
representação do dado e os registros da tabela relacional, o que consome tempo.
Um sistema de banco de dados pode ser utilizado em vários tipos de aplicações.
Uma delas é uma aplicação cliente - servidor. Quando uma aplicação para o ambiente
cliente - servidor é projetada, ela estará fisicamente separada do banco de dados por
várias camadas de componentes. [MELO, Rubens; SILVA, Sidney; TANAKA, Asterio,
1997]
Seu funcionamento se baseia no seguinte esquema: o usuário do sistema, através
da aplicação cliente, envia o pedido de requisição a aplicação servidor, que por sua
vez devolve ao cliente os resultados solicitados. As aplicações rodam sobre o controle
do sistema operacional que coordena todos os recursos do sistema computacional
utilizado.
2.6 RS-232 e RS-485
No início da década de 1960, o RS-232 foi criado para a conexão de modens e impressoras nos computadores da IBM e era definido como o único meio para aumentar
a distância de comunicação serial à baixa taxa de baund (velocidade em que os dados
são enviados através de um canal) [Tanenbaum, Andrew S., 2001].
As principais limitações do RS-232 são: ele é ponto a ponto, que é uma restrição
severa quando vários instrumentos são necessários, e a distância máxima de 15 metros, que é curta para a maioria dos sistemas de controle.
No RS-232, os sinais são representados por níveis de tensão referentes ao fioterra, possuindo um fio para transmissão e outro para recepção.
A especificação do RS-232 define:
• Sinais elétricos característicos;
• Características mecânicas da interface;
• Descrição funcional dos circuitos.
24
O RS-232 é popular e bastante utilizado, apesar de possuir muitas limitações. Em
conseqüência, outras interfaces que superam algumas dessas limitações têm sido
bastante utilizadas, como o RS-485 e o RS-422. As mesmas são interfaces seriais
comumente confundidas uma com a outra, muito bem sucedidas em aplicações industriais e no controle das aplicações, onde é necessária a comunicação entre elas,
mesmo não sendo diretamente compatíveis.
No começo dos anos 70 foi introduzida a interface RS-422, que é usada por um
sistema de dois fios separados para cada sinal. Isso permite uma grande transmissão
de dados e minimiza os problemas de variação do potencial do solo, já que o mesmo
não é usado como referência de voltagem, como o RS-232.
O RS-485 é o mais versátil entre as interfaces RS citadas, tendo semelhanças com
a RS-422. Permiti uma grande distância de comunicação e uma grande velocidade de
transferência de dados. Além disso, aumenta o número de transmissões e recebimentos na linha, o que o torna muito útil quando o sistema usa vários instrumentos ou
controladores que podem ser conectados na mesma linha [John Park, Steve Mackay
e Edwin Wright, 2003].
A maior diferença entre eles é que o RS-485 é usado por um sistema de dois fios
multidrop, que transmite dados em uma única direção por vez em um canal bidirecional
e o RS-422 é usado por um sistema de quatro fios ponto a ponto, que transmite dados
em um canal em duas direções simultaneamente.
O RS-232 e o RS-485 são comumente confundidos um com o outro. A Tabela.4
mostra as principais diferenças entre o RS-232 e o RS-485:
25
TRANSMISSOR
Modo de operação
Max. no. de
drivers e receptores
Tamanho do cabo recomendado
Taxa máxima de
transferência de dados
Voltagem máxima
Sinal do driver
de saída
Programa de carga
Sensibilidade
do receptor
Resistência do
receptor de entrada
RS-232
Desequilibrado
1 driver e
1 receptor
15 metros
20 Kbps
RS-485
Diferencial
32 drivers e
32 receptores
1200 metros
10 Mkps
+20V a -20V
+- 5.0V mínimo
+- 25V máximo
>3 ohm
+- 3.0 V
+1V a -1V
+- 1.5V mínimo
+- 6.0V máximo
120 ohm
+- 200 mV
-12V <= Vem <= 12V
> 12 kiloohm
3 kiloohm a
7 kiloohm
Tabela 4: COMPARATIVO ENTRE O RS-232 E O RS-485.
26
3
Desenvolvimento
A solução proposta para este TCC foi dividida em 5 camadas. Para cada camada é
desenvolvida uma aplicação própria, tornando possível a transferência de informações
desde um computador cliente, passando pelo servidor e chegando até o acionamento
de uma carga. Na Figura.5 abaixo, são mostradas as cinco camadas e o relacionamento entre elas:
Figura 5: Esquema de camadas do projeto.
A primeira camada será a do cliente, onde o usuário terá o controle de sua casa,
interagindo com uma interface 3D. A segunda camada, a do servidor, terá uma aplicação desenvolvida para o controle das informações vindas do cliente. A camada de
banco de dados conterá todas as informações da casa (quartos, localização das lâmpadas e etc), o estado em que as cargas estão (acionadas ou não), e o comando
que acionará a carga específica. Uma quarta camada, apelidada de HAL (Hardware
27
Abstraction Layer), será a intermediária entre o banco de dados e a camada de hardware. A última camada é a de hardwares. É nessa camada que se encontram os
dispositivos RS-232, RS-485 e o conversor, os quais controlarão fisicamente o acionamento de cargas. Os dispositivos e o conversor usados neste projeto serão fornecidos
pela empresa KRL Tecnologia. Na Figura.6 é mostrado o diagrama de seqüência da
aplicação.
Figura 6: Diagrama de seqüência.
3.1 Cliente
O projeto é iniciado no computador do cliente, onde existirá uma aplicação simulando o ambiente que será controlado, dada na forma de uma interface em três dimensões. A aplicação será uma réplica fiel do ambiente, por exemplo, de um apartamento.
Ela será criada a partir da ferramenta irrEdit.
IrrEdit é uma ferramenta que edita ambientes em três dimensões e a luminosidade
dos mesmos. Nela foi criado um protótipo de um quarto para que fosse possível
simular a funcionalidade do projeto. Ao ser criado o quarto estará somente com sua
moldura, faltando então adicionar objetos tais como: lâmpadas, interruptores e etc.
A inserção desses objetos é dada através de engines, dentre elas a IrrLitch que foi
usada neste TCC.
A IrrLitch foi usada como editor de objetos do ambiente e a integração deles com
o sistema. Ela funciona através da linguagem C++, sendo a codificação feita dentro
do compilador DevC++. Cada objeto no código é dado em forma de uma figura na
cena. Tanto a IrrEdit quanto a IrrLitch foram utilizadas para a criação e modelagem
28
do ambiente, e para o posicionamento dos objetos na cena. Sendo um projeto de
continuidade, estas ferramentas serão utilizadas também com o fim de modificar o
ambiente atual e a ação dos objetos em cena.
A diferença entre este TCC e o antigo é o comportamento dos objetos. Antes,
ao clicarmos em um interruptor, a própria aplicação implementada se conectava aos
dispositivos para o acionamento da lâmpada. Hoje, a conexão com os dispositivos é
feita pelo servidor, cabendo então ao cliente informar ao servidor qual lâmpada deverá
ser acionada.
Neste projeto, o principal foco foi separar a aplicação 3D, que está no computador
do cliente, do acionamento das cargas presentes no servidor, que se encontra no
ambiente controlado. A comunicação e a troca de informações entre eles serão dadas
pela Internet, através do protocolo TCP. Tanto o computador cliente quanto o servidor
deverão estar conectados a Internet, para que a troca de informações seja realizada.
Se um dos dois não estiver devidamente conectado a troca de informações será falha,
e o sistema retornará um erro de falha na conexão.
A aplicação Cliente foi desenvolvida no paradigma de orientação a objetos. Nesse
caso, o programa foi modelado em quatro objetos: CMainMenu, Serial, CAmbiente,
Main
A Classe CMainMenu é formada por:
• CMainMenu() - O construtor da classe é iniciado com os parâmetros em que o
menu deve aparecer, com a engine que será usada, o endereço IP, a porta TCP,
e se a tela aparecerá em modo fullscreen.
• Bool run (bool outFullscreen, bool outCom1, bool outCom2, vídeo :: E_DRIVER_TYPE
outDriver) - Método que requisita as funções responsáveis pela criação do menu.
Nele são passadas como parâmetro as variáveis alteradas ou não do bloco principal. Ele é responsável pela criação dos objetos que, por exemplo, tratam a
parte gráfica da aplicação, gerenciam todos os nós adicionados à cena, e outros
objetos que manipulam dados úteis para a construção do aplicativo 3D.
• virtual bool OnEvent(SEvent event) - Usado para tratar eventos vindos do clique
do mouse ou quando teclas do teclado são pressionadas. Neste caso, é usado
este método para tratar os itens selecionados.
• void setTransparency() - Função que aplica transparência no menu.
29
• gui::IGUIButton* startButton - O nome da variável que é informada sobre o pressionamento do botão "START".
• IrrlichtDevice *device - Variável principal. É a partir dela que tudo é criado.
• s32 selected - Aonde é definido o renderizador escolhido pelo usuário.
Na classe Main estão definidas as variáveis que representam as opções de fullscreen
e de porta de comunicação apresentadas no menu principal. São definidos também
os comandos de chamada para os objetos CMainMenu e CAmbiente. A biblioteca
OPENGL é responsável pela criação do menu na classe CMainMenu e do ambiente
na classe CAmbiente.
Os outros objetos são estruturados de forma diferente. Eles possuem métodos,
funções e variáveis necessárias para a criação objetivo. No CMainMenu, é implementado o menu. Ele será composto por duas guias: uma fornecendo algumas opções da
aplicação para o usuário, e a outra que irá exibir um texto sobre o projeto. Dessa forma,
é necessário criar um controlador de guias. Nessas guias são fornecidas opções para
o usuário como: o tipo de renderizador gráfico, a opção de fullscreen e a porta de comunicação. A engine IrrLicht disponibiliza alguns renderizadores gráficos. Esses renderizadores são listados no menu para que atenda aos diferentes usuários de acordo
com suas preferências. Depois que o usuário escolheu as opções desejadas, a interação com o ambiente 3D é feita pressionando o botão "Start".
Ao selecionar o botão "Start", a aplicação inicia o objeto CAmbiente. Ele possui
os métodos responsáveis pela criação do ambiente, os nós responsáveis pela criação
da cena, as funções que tratam a parte gráfica da aplicação como textura e cores, e
o gerenciador de cena. Estes três nós criados anteriormente são a estrutura básica
para qualquer aplicação que utiliza a engine IrrLicht. A partir daí, basta carregar o
ambiente criado no editor IrrEdit usando o método LOADSCENE, pois é um arquivo
de extensão .irr. Para carregar a cena criada é necessário usar dois nós, sendo um nó
responsável pelo ambiente e outro pela iluminação. É preciso extrair o nó ambiente
para aplicá-lo à técnica de detecção de colisão no ambiente. A técnica de detecção
de colisão é necessária para que quando for criado qualquer objeto dentro de uma
cena como, por exemplo, uma parede, um teto, um carro ou móveis, o usuário não os
atravesse, dando assim a idéia de estar num ambiente real.
Depois de criado o ambiente, uma câmera é necessária para a visualização e
navegação dentro da cena. A câmera adicionada é controlada pelas teclas de dire-
30
cionamento e pelo mouse. Para que a câmera não atravesse os objetos dentro da
interface é necessário criar um animador de desenhos, pois é ele que irá responder se
houve ou não a colisão. Depois deve-se ligá-lo ao nó em que se deseja que a colisão
seja feita, que neste caso, é a câmera.
Também é necessário criar alguns objetos que participarão do acionamento de
dispositivos como, por exemplo, lâmpadas, e outros para dar um pouco de vida ao
ambiente. Primeiramente, criamos duas lâmpadas. Uma delas será posicionada no
teto, e outra na parede. Estas lâmpadas terão dois estados: apagada e acesa, que
serão definidos através de texturas. Para simular o acionamento virtual das lâmpadas,
precisa-se criar uma fonte de luz para cada lâmpada e assim como interruptores. E
para uma melhor simulação do ambiente real criam-se alguns objetos como janela,
porta, quadros, entre outros. Esses objetos serão representados através de texturas.
Para identificarmos o alvo da câmera, iremos criar um billboard. Um billboard é um
ponto luminoso, geralmente usado para explosões, fogos, e semelhantes. Neste caso,
o billboard seguirá o cursor do mouse. Isto é necessário pois o usuário precisa saber
aonde estará clicando com o mouse para poder fazer o acionamento das lâmpadas
através dos interruptores. Posteriormente criaremos um vetor que indicará o ponto de
interseção entre o alvo da câmera e o objeto que ela estará olhando. Para obter esse
ponto de interseção, precisamos do ponto de colisão entre o alvo e o objeto que estará
sendo observado.
O último método escrito no CAmbiente é utilizado para o acionamento dos dispositivos. Este método captura o clique do mouse. Se o usuário clicar com o botão
esquerdo em cima de um interruptor, uma lâmpada se acenderá e o objeto Serial será
criado. Se o usuário clicar com o botão direito em cima de um interruptor, essa lâmpada se apagará e o objeto Serial será criado. Quando um interruptor for acionado,
será mostrada na tela uma lâmpada sendo acesa para que o usuário tenha conhecimento que a conexão com o servidor foi feita e a lâmpada foi acesa no ambiente
controlado.
A conexão criada é a Cliente / Servidor que foi feita através do protocolo TCP. O
cliente se conecta ao servidor e envia uma palavra indicando qual das lâmpadas ou
motores tem de ser acionado. Após o envio ter sido realizado, com sucesso ou não, a
conexão é destruída, ficando disponível a abertura de novas conexões.
31
3.1.1 TCP/IP
A comunicação entre o computador cliente e o computador servidor é feita através
do protocolo TCP/IP. TCP/IP, que significa Transmission Control Protocol - Internet
Protocol (Protocolo de Controle de Transmissão - Protocolo de Internet), é um protocolo de comunicação entre computadores em rede. A comunicação pelo protocolo
é feita através da Internet, obrigando os computadores cliente e servidor a estarem
conectados à mesma.
A escolha do protocolo TCP/IP foi feita pelo fato dele ser o mais usado em redes. O
TCP fornece um serviço de transporte orientado à conexão, e o IP fornece um serviço
de rede não-orientado à conexão. Outro fator que facilitou a escolha do TCP/IP foi o
fato dele ter arquitetura aberta e qualquer fabricante poder adotar a sua própria versão TCP/IP em seu sistema operacional, sem necessidade de pagamento de direitos
autorais a ninguém. Com isso, todos os fabricantes de sistemas operacionais acabam
adotando o TCP/IP, transformando-o em um protocolo universal, possibilitando que
todos os sistemas possam se comunicar sem dificuldade.
Uma das vantagens do TCP/IP em relação aos outros protocolos pesquisados é
que ele é roteável, isto é, podem existir vários caminhos para o dado atingir o computador de destino.
A escolha de um protocolo de comunicação se deu através de dois outros protocolos, o TCP/IP e o UDP, tendo como finalista o primeiro. A decisão foi baseada na
principal diferença entre os dois protocolos e mostrou-se ideal para o projeto:
• O TCP é um protocolo orientado à conexão, que inclui vários mecanismos para
iniciar e encerrar a conexão, negociar tamanhos de pacotes e permitir a retransmissão de pacotes corrompidos. No TCP tudo isso é feito com muito cuidado,
para garantir que os dados realmente cheguem inalterados, apesar de todos os
problemas que possam existir na conexão;
• O UDP transmite dados pouco sensíveis, como streaming de áudio e vídeo. No
UDP não existe checagem nem confirmação. Os dados são transmitidos apenas
uma vez. Os pacotes que chegam corrompidos são simplesmente descartados,
sem que o emissor sequer saiba do problema. A idéia é justamente transmitir
dados com o maior desempenho possível, eliminando dos pacotes quase tudo
que não sejam dados.
32
Na Figura.7 é mostrada uma visão geral do funcionamento do protocolo TCP/IP
na implementação do projeto, dada da seguinte forma:
Figura 7: Funcionamento do protocolo TCP/IP.
O protocolo TCP foi implementado no cliente e servidor a partir de sockets. O
socket (porta de um canal de comunicação) permite a um processo (executado em um
computador) enviar/receber mensagens para/de outro processo que pode estar sendo
executado no mesmo computador ou num computador remoto. A Figura.8 mostra as
camadas de uma aplicação por sockets.
A aplicação no servidor foi implementada começando pela criação de um socket.
Em seguida é atribuída a esse, a porta por onde a aplicação cliente solicitará a
conexão. O socket é colocado em modo de escuta para poder aceitar pedidos de
conexão dirigidos ao mesmo.
A aplicação no cliente foi implementada criando-se um socket com os dados de
Porta e IP do servidor para realizar a conexão.
A conexão é feita quando o cliente cria uma chamada ao servidor através do
socket. O servidor, que está executando no modo de escuta, estabiliza a conexão
solicitada pela aplicação cliente e cria um canal de comunicação entre os sockets.
33
Figura 8: Comunicação com o socket.
Com a conexão estabelecida, a aplicação cliente envia a informação para o servidor.
Recebida a confirmação de recebimento do servidor, o cliente encerra a conexão e o
servidor continua no modo de escuta, esperando novas conexões.
3.2 Servidor
O servidor foi desenvolvido para ficar executando no ambiente real sem parar, esperando que conexões sejam realizadas pelo computador cliente. Mesmo quando a
conexão com o cliente é encerrada, o servidor continua executando, esperando novas conexões. O servidor só para de funcionar se ele for desligado ou se não houver
conectividade com a Internet. Quando a conexão entre o cliente e servidor é estabelecida, é realizado o envio via Internet de uma palavra por parte do cliente. O
servidor executa uma comparação entre a palavra enviada e as cargas que desejam
ser acionadas. Feita a comparação, o servidor envia um comando de update para o
banco de dados, fazendo uma alteração no estado da carga.
Após a alteração, o servidor procura no banco de dados o comando necessário
para o acionamento, que se encontra junto ao estado alterado. O comando é enviado
através da porta serial, para o acionamento da carga.
O envio do comando é feito por um código que se encontra dentro do servidor.
Esse código assegura que o dispositivo está conectado com o computador servidor,
abre as portas necessárias para o acionamento, as configura e, depois de tudo configurado, a palavra está pronta para ser transmitida. Quando termina a transmissão,
34
as portas seriais utilizadas devem ser fechadas para dar acesso à outra solicitação.
3.3 Banco de dados
Para o desenvolvimento do servidor de banco de dados, foi usado o MySQL. O
MySQL é uma ferramenta de banco de dados relacional gratuita e desenvolvida pela
Sun. Tem como usuários a NASA, o Banco Bradesco, a HP, a Nokia, entre outras empresas. Esse servidor foi escolhido porque possui compatibilidade com a linguagem
C++ usada neste projeto, excelente desempenho e estabilidade quando há necessidade de busca de dados, suporte para vários tipos de tabelas e pouco exige quanto a
recursos de hardware.
O MySQL no computador servidor ficará rodando até que o computador cliente
envie uma palavra. Isto acontece quando o usuário através de uma interface 3D clica
em um interruptor situado no ambiente virtual. O computador cliente interpreta o posicionamento do click e envia uma palavra indicando o interruptor clicado. Quando a
palavra chega ao servidor, é feita uma comparação com a chave primária da tabela
"Objetos", identificando qual carga (lâmpada, ventilador, ar condicionado, etc), deve
ser acionada. Feita a comparação, é alterado seu estado na tabela, em seguida o
HAL envia o acionamento para os dispositivos ligando ou desligando o motor.
A implementação é realizada no DevC++. Na Figura.9, é mostrado o momento da
conexão com o servidor após ter sido acionado o interruptor. Esta conexão acontece
na primeira linha. Quando realizada e verificado qual a palavra foi enviada, é feito um
update no banco para que em seguida seja enviado um comando para os dispositivos.
Caso ocorra uma falha na conexão é informado o tipo de erro.
No banco de dados existirá dois tipo de tabelas: a do objeto, e do cômodo. Na
primeira são encontradas as identificações do objeto como chave primária da tabela, a
identificação do cômodo, a descrição do objeto, o status informando se está desligado
ou ligado, o comando e o endereço MAC. E na segunda encontra-se a identificação
do cômodo dita com chave primária da sua tabela e da sua descrição. Na Figura.10
são mostradas as tabelas e suas relações:
35
Figura 9: Código.
Figura 10: Diagrama de classe.
36
3.4 Hal
Para realizar a comunicação entre o banco de dados e os dispositivos, foi implementada uma aplicação chamada de HAL (Hardware Abstraction Layer). Essa aplicação ficará rodando no servidor com intervalos de poucos segundos até que uma
carga seja modificada no banco de dados. Quando isto acontece, a palavra é comparada com o banco existente e seu estado é alterado em seguida. Após este procedimento, o servidor recolhe o comando de acionamento e envia para os dispositivos.
Este comando é formado por 8 bits, contendo o endereço MAC do dispositivo 485 e
qual a saída a ser acionada.
Na Figura.11 é mostrado como acontece o recebimento e o envio da palavra.
Figura 11: HAL.
3.5 Hardware
Quando há alteração no banco de dados, a aplicação envia o comando através
de um conjunto de bits para os dispositivos. O comando passa pela interface serial
RS-232 instalada no computador, porém a RS-232 possui diversas limitações prejudicando o desempenho da aplicação desenvolvida. Sua implementação é simples
e de baixo custo, estando disponível na maioria dos computadores. Na Figura.12 é
mostrada a comunicação RS 232 simples.
É necessário utilizar um conversor RS-232 para RS-485 a fim de aumentar a distância de comunicação do sistema serial RS-232. Esse conversor permite a comunicação de equipamentos RS-232 com equipamentos RS 485, além de tudo ele faz
o isolamento elétrico dos sistemas. A saída do conversor possui dois fios, onde são
37
Figura 12: Comunicação RS-232.
montadas as interfaces seriais RS-485 fazendo uma rede de comunicação entre elas.
O RS-485 foi escolhido para esta aplicação, pois a mesma tem o enfoque principal
na comunicação em rede, onde com apenas uma par de fios é possível se comunicar
com diversos equipamentos em rede usando o mesmo barramento. Outra característica é que, de maneira extremamente confiável, ela permite a comunicação em distâncias de até 1200 metros. A Figura.13 mostra a comunicação RS 232 e a rede de
dispositivos RS 485.
Figura 13: Comunicação RS-485.
O protocolo RS 485 é do tipo half-duplex, onde há um dispositivo transmissor e
outro dispositivo receptor, ambos podendo transmitir e receber dados não simultaneamente. Por exemplo, um dispositivo A pode transmitir dados e outro dispositivo B
receber dados, ou vice e versa. Nas Figura.14 é visualizado o dispositivo AMP-12
usado nesse projeto.
Na Figura.14 é visualizado o dispositivo AMP-12 aberto. Dentro, é encontrado o
MAC (A), as portas de entrada e saída do dispositivo (B), o relé de acionamento (C),
o drive do barramento RS-485 (D), o microcontrolador (E), entre outros.
38
Figura 14: Dispositivo AMP-12.
39
4
FINANCEIRO
Para que o projeto seja utilizado em um ambiente, é necessário ao final do projeto
acrescentar um custo para a instalação da aplicação. Pode-se citar como exemplo
uma casa de 200 metros quadrados com três quartos, dois banheiros, uma cozinha e
uma sala, onde a aplicação foi instalada em vinte e quatro pontos elétricos. A Tabela.5
mostra a distribuição de pontos elétricos dentro da casa.
Cômodos
Quarto 1
Quarto 2
Quarto 3
Banheiro 1
Banheiro 2
Sala
Cozinha
Lâmpada
3
3
2
1
1
5
4
Ar Condicionado
1
1
0
0
0
1
0
Ventilador
0
0
1
0
0
0
1
Tabela 5: DISTRIBUIÇÃO DOS PONTOS ELÉTRICOS.
Os dispositivos AMP-12 são confeccionados pela empresa KRL e possuem o valor
de R$ 250,00. Considerando que cada dispositivo habilita oito pontos elétricos, serão
necessários três dispositivos para realizar a instalação, totalizando um valor de R$
750,00. A Tabela.6 mostra a quantidade de material necessário para a instalação
segura e com sucesso da aplicação na casa.
Material
Cabo
Dispositivo
Fonte
Valor Unitário
R$ 1,00 por metro
R$ 250,00
R$ 120,00
Quantidade Necessária
650 metros
3 unidades
1 unidade
Valor Total
R$ 625,00
R$ 750,00
R$ 120,00
Tabela 6: CUSTO MATERIAL.
Para uma casa de 200 metros quadrados serão necessários 625 metros de cabo.
Levando em consideração que cada metro de cabo tem o custo de R$ 1,00, o valor
40
total do cabeamento será de R$ 625,00. Considera-se que em cada metro quadrado
de um ambiente serão gastos 2,5 metros de cabo.
Para a ligação dos dispositivos na rede elétrica da casa serão necessárias fontes
de energia. O valor de cada fonte no mercado é de R$ 120,00. Levando em consideração que uma fonte alimenta 30 dispositivos e a casa em questão necessita de três
dispositivos, então será utilizada uma fonte, totalizando um valor de R$ 120,00.
A Tabela.7 mostra os custos com a mão-de-obra especializada que acrescentará
valor no projeto final.
Mão-de-obra
Instalação física
Modelagem 3D
Adequação programa
Valor
R$ 500,00
R$ 900,00
R$ 900,00
Tabela 7: CUSTO MÃO-DE-OBRA.
O projeto final terá um custo total de R$ 3.795,00. Tendo o ambiente citado como
exemplo, uma casa de 200 metros quadrados com 24 pontos instalados, cada ponto
terá um valor em média de R$ 158,00. Conclui-se então que o software desenvolvido
é viável financeiramente.
No mercado já existe esse tipo de aplicação, porém o custo para a aquisição e
instalação ainda é muito alto. A ONID Limited é uma empresa do Reino Unido, que instala e cria sistemas inteligentes para residências. Cada casa inteligente é desenhada
de acordo com o ambiente construído, dando ênfase a sistemas personalizados.
Nossa aplicação é semelhante a ONID, porém ainda falta desenvolver algumas
características, como por exemplo, segurança para que se transforme em um produto
comercial.
41
5
CONCLUSÃO
A partir do desenvolvimento do trabalho, conclui-se que é possível visualizar um
projeto que possibilita ao usuário, através de seu computador pessoal (cliente), entrar
numa aplicação que simula uma casa em 3D e, através dela, acionar cargas de sua
casa real via da Internet.
Tendo em vista a extensão deste projeto, foi preciso separá-lo em etapas: a
primeira, consiste no desenvolvimento de uma interface 3D que controle o ambiente
real, executada no computador servidor. Após essa etapa, foi desenvolvido um código
que permitirá ao computador cliente, através da Internet, o controle desse ambiente.
A etapa final será sobre o desenvolvimento de novos tipos de controles.
A aplicação foi criada exatamente como proposta, onde o usuário, através de seu
computador pessoal, possa interagir com a interface 3D, navegando no ambiente igual
ao da sua casa. A partir de um click em um dos interruptores da casa, é enviado ao
servidor uma palavra. O servidor fica rodando até que uma palavra seja enviando
pelo cliente. Quando isso acontece, é feita uma comparação com a chave primária da
tabela objeto do banco de dados. Feito a comparação, é alterado no banco o estado
da carga e enviado automaticamente o comando para os dispositivos, acionando o
motor elétrico.
O projeto é viável tecnologicamente, tecnicamente e financeiramente, pois, hoje
já existem tecnologias capazes de controlar cargas e conectar-se pela Internet. Os
custos dos dispositivos e mão-de-obra para a construção do projeto não são abusivos, facilitando o acesso para pessoas das mais diversas classes sociais e renda.
A implementação não é difícil, pois qualquer programador com conhecimentos em
programação orientado a objetos e protocolo TCP / IP é capaz de modificar o projeto.
O projeto pode se tornar viável comercialmente. Para isso, é necessário que o
mesmo tenha algumas melhorias nos quesitos de segurança, tecnologias compatíveis
e modificação do ambiente 3D.
42
6
TRABALHOS FUTUROS
Após a conclusão do protótipo, serão necessárias algumas atualizações para tornálo mais acessível ao cliente quanto às questões de segurança. São elas referentes às
senhas e logins; as opções de cenário e objetos pré-existentes que facilitarão a interação dos usuários; a criação de outros tipos de controle, já que os acionamentos
provêm de bancos de dados; uma possível aplicação via bluetooth e o desenvolvimento de outras aplicações para que o cliente tenha mais diversidade de controle em
sua residência.
43
ANEXO A -- Anexo A - Código desenvolvido
do Cliente
// Classe que cria o AMBIENTE
#include <conio.h>
#include "CAmbiente.h"
#include "Serial.h"
#include <process.h>
#include <errno.h>
#include <stdio.h>
// Método construtor
CAmbiente::CAmbiente()
{}
// Método destrutor
CAmbiente::~CAmbiente()
{}
/* Método que chama as funções responsáveis pela criação do AMBIENTE.
Nele é passado como parâmetro as opções selecionadas no MENU.
*/
int CAmbiente::run(video::E_DRIVER_TYPE driverType, bool fullscreen)
{
// Como ja dito anteriormente, este é o nó principal, é a partir dele que
toda a cena será criada.
IrrlichtDevice* dispositivo = createDevice(driverType,
core::dimension2d<s32>(640, 480),16,fullscreen,false,false,this);
44
if (dispositivo == 0)
return 1;
// É necessário criar um nó responsável pelas funções que tratam a parte
gráfica da aplicação, como texturas, cores, etc.
video::IVideoDriver* driver = dispositivo->getVideoDriver();
// Agora temos que criar o gerenciador de cena, que vai gerencias todos os
nós criados dentro da cena.
cena = dispositivo->getSceneManager();
/* Estes três nós criados anteriormente é a estrutura básica para qualquer
aplicação que utiliza a engine IrrLicht. Praticamente todos os programas terão
que criar um dispositivo, um driver gráfico e um gerenciador de cena. A partir
daí, fica por conta do programador. Neste caso, iremos carregar o ambiente
criado no editor IrrEdit, usando o método LOADSCENE, pois é um arquivo de
extensão .irr. No caso de carregar um outro ambiente de uma outra extensão,
criado por outro editor, este método não suportará (com exceção .3DS), tendo que
utilizar um outro método.
Carregando a cena criada no irredit.
*/
cena->loadScene("../../media/example.irr");
/* A cena criada no editor IrrEdit, é composta por 2 nós. O ambiente
propriamente dito (de nome MESH), e uma luz de baixa intensidade, que simula uma
iluminação ambiente. Então devemos extrair o nó do ambiente para posteriormente
ser aplciado a técnica de detectado a colisão apenas no ambiente. Isso é feito
da seguinte forma:
*/
scene::ISceneNode* no = cena->getSceneNodeFromType(scene::ESNT_MESH,NULL);
io::IAttributes* atributo =
dispositivo->getFileSystem()->createEmptyAttributes();
no->serializeAttributes(atributo);
core::stringc nome = atributo->getAttributeAsString("Mesh");
atributo->drop();
scene::IAnimatedMesh* mesh = cena->getMesh(nome.c_str());
45
/* Agora, para fazer a detecção de colisão, devemos criar um seletor de
triângulos para o ambiente. Quando criamos qualquer coisa dentro de uma cena
como, por exemplo, uma parede, um teto, um carro, móveis, e etc, estes objetos
não existem fisicamente dentro do mundo virtual, ou seja, todos eles podem
ocupar o mesmo espaço, permitindo que um atravesse o outro, sem que haja colisão
entre eles. Sendo assim, um seletor de triângulos irá dar um estado físico para
um determinado objeto (nó), sendo que cada objeto pode ter seu própiro seletor
de triângulos. Neste caso, iremos criar um seletor de triângulos para o
ambiente, para que possa ser feito a detecção de colisão nas paredes, no piso e
no teto.
*/
scene::ITriangleSelector* seletor = 0;
if (no){
seletor = cena->createTriangleSelector(mesh->getMesh(0),no);
no->setTriangleSelector(seletor);
seletor->drop();}
/* Agora que a cena já está fisicamente criada, temos que criar uma câmera
para visualizar e navegar dentro dela. A câmera que iremos adicionar dentro da
cena é controlada pelas teclas de direcionamento e pelo mouse.
*/
scene::ICameraSceneNode* camera = cena->addCameraSceneNodeFPS(0, 70.0f,
40.0f, -1, 0, 0, true);
camera->setPosition(core::vector3df(-5,23,-50));
/* Para que a colisão entre 2 objetos (nós) seja detectada, devemos criar um
animador de desenhos, pois é ele que irá responder se houve ou não a colisão.
Depois devemos ligá-lo
neste caso, é a câmera.
ao nó em que desejamos que a colisão seja feita, que
*/
scene::ISceneNodeAnimator* animador =
cena->createCollisionResponseAnimator(seletor,camera,core::vector3df(10,10,10),
core::vector3df(0,-0.1,0),core::vector3df(0,30,0));
camera->addAnimator(animador);
animador->drop();
/* Nos próximos bolocos iremos criar alguns objetos que participarão do
46
acionamento de dispositivos como, por exemplo, lâmpadas. E outros para dar um
pouco de vida ao ambiente. Em primeiro passo, iremos criar uma lâmpada e
colocá-la no centro do teto do ambiente. Esta lâmpada terá dois estados: apagada
e acesa, que serão definitos através de texturas.
*/
lampada =
cena->addCubeSceneNode(15.0f,0,-1,core::vector3df(0,0,0),core::vector3df(0,0,0),
core::vector3df(1.5f,0.1f,1.5f));
lampada->setPosition(core::vector3df(-10,58,10));
lampada->setMaterialFlag(video::EMF_LIGHTING,false);
lampada->setMaterialTexture(0,driver->getTexture("../../media/luz_apagada.jpg"));
// Carregando as texturas da lampada
acesa1 = driver->getTexture("../../media/luz_acesa.jpg");
apagada1 = driver->getTexture("../../media/luz_apagada.jpg");
// Agora vamos criar um interruptor para esta lâmpada e posicioná-lo na
parade.
interruptor1 = cena->addCubeSceneNode(5.0f,0,-1,core::vector3df(0,0,0),
core::vector3df(-4,60,0),core::vector3df(0.6f,1.0f,0.0f));
interruptor1->setPosition(core::vector3df(44,20,56));
interruptor1->setMaterialFlag(video::EMF_LIGHTING,false);
interruptor1->setMaterialTexture(0,driver->getTexture("../../media/inter.bmp"));
interruptor1->setID(1);
int id = interruptor1->getID();
v1 = interruptor1->getPosition();
i1x=v1.X; i1y=v1.Y; i1z=v1.Z;
// Para simular o acionamento virtual da lâmpada, temos que criar uma fonte
de luz para representá-la
luz_central = cena->addLightSceneNode(0,
core::vector3df(-10,45,10),video::SColorf(1.0f,1.0f,1.0f,1.0f),3.5f);
luz_central->setVisible(false);
47
/* Vamos criar uma outra lâmapda para o ambiente, que será do tipo arandela,
posicinada na parede. Esta arandela também terá 2 estados: apadada e acesa, que
também serão definidos através de texturas.
*/
arandela = cena->addCubeSceneNode(13.0f,0,-1,core::vector3df(0,0,0),
core::vector3df(0,7,0),core::vector3df(0.7f,0.7f,0.7f));
arandela->setPosition(core::vector3df(-55,38,-35));
arandela->setMaterialFlag(video::EMF_LIGHTING,false);
arandela->setMaterialTexture(0,driver->
getTexture("../../media/arandela_apagada.jpg"));
// carregando as texturas da arandela
acesa2 = driver->getTexture("../../media/arandela_acesa.jpg");
apagada2 = driver->getTexture("../../media/arandela_apagada.jpg");
// Agora temos que criar um outro interruptor para a arandela.
interruptor2 = cena->addCubeSceneNode(5.0f,0,-1,core::vector3df(0,0,0),
core::vector3df(-4,60,0),core::vector3df(0.6f,1.0f,0.0f));
interruptor2->setPosition(core::vector3df(48,20,50));
interruptor2->setMaterialFlag(video::EMF_LIGHTING,false);
interruptor2->setMaterialTexture(0,driver->getTexture("../../media/inter.bmp"));
interruptor2->setID(2);
int id2 = interruptor2->getID();
v3 = interruptor2->getPosition();
i2x=v3.X; i2y=v3.Y; i2z=v3.Z;
// Da mesma forma da lâmapda central, vamos criar uma fone de luz para a
arandela
luz_parede = cena->addLightSceneNode(0,
core::vector3df(-35,55,-35),video::SColorf(1.0f,1.0f,1.0f,1.0f),2.5f);
luz_parede->setVisible(false);
/* Para simular mais ainda um ambiente real, vamos criar algumas objetos
como janela, porta quadros, entre outros. Esses objetos serão representados
48
através de texturas. criando uma janela.
*/
scene::ISceneNode* janela =
cena->addCubeSceneNode(15.0f,0,-1,core::vector3df(0,0,0),core::
vector3df(-5.9,5,1),core::vector3df(3.0f,3.0f,0.3f));
janela->setPosition(core::vector3df(0,38,63.5));
janela->setMaterialFlag(video::EMF_LIGHTING,false);
janela->setMaterialTexture(0,driver->getTexture("../../media/janela3.jpg"));
// Criando um quadro
scene::ISceneNode* quadro =
cena->addCubeSceneNode(15.0f,0,-1,core::vector3df(0,0,0),
core::vector3df(9,0.5,0),core::vector3df(3.0f,3.0f,0.3f));
quadro->setPosition(core::vector3df(0,35,-66.5));
quadro->setMaterialFlag(video::EMF_LIGHTING,false);
quadro->setMaterialTexture(0,driver->getTexture("../../media/mona.jpg"));
// Criando uma porta
scene::ISceneNode* porta =
cena->addCubeSceneNode(15.0f,0,-1,core::vector3df(0,0,0),
core::vector3df(-3,57,0),core::vector3df(2.5f,5.0f,0.3f));
porta->setPosition(core::vector3df(65,20,25));
porta->setMaterialFlag(video::EMF_LIGHTING,false);
porta->setMaterialTexture(0,driver->getTexture("../../media/portamadeira.jpg"));
/* Para identificarmos o alvo da câmera, iremos criar um billboard. Um
billboard é um ponto luminoso, geralmente usado para explosões, fogos, e coisas
do tipo. Neste caso, o billboard seguirá o cursor do mouse. Isso é necessário
pois o usuário precisa saber aonde estará clicando com o mouse para poder fazer
o acionamento das lampadas através dos interruptores.
*/
bill = cena->addBillboardSceneNode();
bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
bill->setMaterialTexture(0,driver->getTexture("../../media/particle.bmp"));
bill->setMaterialFlag(video::EMF_LIGHTING,false);
bill->setMaterialFlag(video::EMF_ZBUFFER,false);
49
bill->setSize(core::dimension2d<f32>(10.0f,10.0f));
video::SMaterial material;
// Função utilizada para esconder a seta do mouse
dispositivo->getCursorControl()->setVisible(false);
// Inteiro para contar os frames por segundo da aplicação.
int lastFPS = -1;
/* Pronto, o MENU está criado. Agora o que devemos fazer é colcoar o
dispositivo para funcionar, chamando o método RUN. Este método vai colocar o
dispositivo em loop infinito até que o usuário termine a aplicação fechando a
janela ou pressionando ALT+F4.
*/
while(dispositivo->run())
// Esta função é opcional, mas sem ela, o dispositivo não garante que o
cursor do mouse
// seja iniciado no centro da janela.
if (dispositivo->isWindowActive()){
driver->beginScene(true, true, video::SColor(0,200,200,200));
// Para desenhar realmente o AMBIENTE na tela, temos que extrair todos os
métodos e funções
// utilizados para este propósito. Para isso, utilizamos a função DRAWALL.
cena->drawAll();
/* Este bloco trata da posição do billboard para que este siga o alvo da
câmera em tempo Em primeiro passo, temos que criar um linha que inicia na
posição da câmera e vai até seu alvo.
*/
core::line3d<f32> linha;
linha.start = camera->getPosition();
linha.end = linha.start + (camera->getTarget() linha.start).normalize()*1000.0f;
50
// Agora vamos criar um vetor que indicará o ponto de interseção entre o
alvo da câmera
// e o objeto em que ela está olhando.
core::vector3df intersecao;
core::triangle3df triangulo;
// Para obter esse ponto de interseção, nós precisamos do ponto de colisão
entre o alvo
// e o objeto que está sendo observado. Para isto usamos o seguinte
bloco:
if (cena->getSceneCollisionManager()->getCollisionPoint
(linha,seletor,intersecao,triangulo));{
bill->setPosition(intersecao);
driver->setTransform(video::ETS_WORLD,core::matrix4());
driver->setMaterial(material);
//driver->draw3DTriangle(triangulo,video::SColor(255,255,255,255));
}
driver->endScene();
int fps = driver->getFPS();
// Para saber quantos frames por segundo o programa está sendo rodado e
exibí-lo no
// título da janela, nós utilizamos o seguinte bloco:
if (lastFPS != fps)
{
core::stringw str = L"Frederico,Erica e Alessandro e sua Casa 3D[";
str += driver->getName();
str += "] FPS:";
str += fps;
dispositivo->setWindowCaption(str.c_str());
lastFPS = fps;
51
}
}
// Função usada para descarregar todos os nós depois que a aplicação é
terminada.
dispositivo->drop();
return 0;
}
/* Este é método utilizado para fazer o acionanemto dos dispositivos. Este
método captura clique
do mouse. Se o usuário clicar com o botão esquerdo em cima de um interruptor,
uma lâmpada se
acenderá. Se o usuário clicar com o botão direito em cima de um interruptor,
essa lâmpada se
apagará.
*/
bool CAmbiente::OnEvent(SEvent evento)
{
int chamada;
if (evento.EventType == irr::EET_MOUSE_INPUT_EVENT)
{
v2 = bill->getPosition();
bx=v2.X; by=v2.Y; bz=v2.Z;
switch (evento.MouseInput.Event)
{
case irr::EMIE_LMOUSE_LEFT_UP:
// botao esquerdo é
apertado
if(x != 1){
if((bx>=43 && bx<=45)&&(by>=19 &&
by<=21)&&(bz>=55 && bz<=57)){
lampada->setMaterialTexture(0,acesa1);
printf("\n\nLampada acesa!");
52
luz_central->setVisible(true);
cliente c;
c.run("LMP2");
c.~cliente();
x=1;y=2;}
}
if(w != 1){
if((bx>=47 && bx<=49)&&(by>=19 &&
by<=21)&&(bz>=49 && bz<=51)){
arandela->setMaterialTexture(0,acesa2);
printf("\n\nArandela acesa!");
luz_parede->setVisible(true);
cliente c;
c.run("LMP0");
c.~cliente();
w=1;z=2;}
} break;
case irr::EMIE_RMOUSE_LEFT_UP:
// botao direito é apertado
if(y != 1){
if((bx>=43 && bx<=45)&&(by>=19 &&
by<=21)&&(bz>=55 && bz<=57)){
lampada->setMaterialTexture(0,apagada1);
printf("\n\nLampada apagada!");
luz_central->setVisible(false);
cliente c;
53
c.run("LMP1");
c.~cliente();
y=1;x=2;}
}
if(z != 1){
if((bx>=47 && bx<=49)&&(by>=19 &&
by<=21)&&(bz>=49 && bz<=51)){
arandela->setMaterialTexture(0,apagada2);
printf("\n\nArandela apagada!");
luz_parede->setVisible(false);
cliente c;
c.run("LMP3");
c.~cliente();
z=1;w=2;}
} break;
default: return false;
}
printf("\r\nx= %d",bx);printf("
y= %d",by);printf("
z=
%d",bz);
} return false;
}
// Bloco de declarações das variáveis, funções e métodos da classe que cria o
AMBIENTE
#include <irrlicht.h>
using namespace irr;
class CAmbiente : public IEventReceiver
{
public:
54
CAmbiente();
~CAmbiente();
virtual bool OnEvent(SEvent evento);
int run(video::E_DRIVER_TYPE DriverType, bool fullscreen);
// nós que participam do evento de acionamento das lampadas
scene::ISceneNode* lampada;
scene::ISceneNode* arandela;
scene::ISceneNode* interruptor1;
scene::ISceneNode* interruptor2;
scene::IBillboardSceneNode* bill;
scene::ISceneNode* luz_central;
scene::ISceneNode* luz_parede;
// vetores e coordenadas da posicao do billboard e dos interruptores
core::vector3df v1,v2,v3;
int i1x,i1y,i1z,i2x,i2y,i2z,bx,by,bz,x,y,w,z;
// nós que vao ser carregados com as texturas da luz acesa ou apagada
video::ITexture* acesa1;
video::ITexture* apagada1;
video::ITexture* acesa2;
video::ITexture* apagada2;
scene::ISceneManager* cena;
};
// Classe que cria o MENU
#include "CMainMenu.h"
CMainMenu::CMainMenu()
: startButton(0), device(0), start(false), fullscreen(false), selected(0),
com1(true), transparent(true), com2(true)
{
}
55
/* Método que chama as funções responsáveis pela criação do MENU. Nele é passado
como parâmetro as variáveis declaradas no bloco principal.*/
bool CMainMenu::run(bool& outFullscreen, bool& outCom1, bool&
outCom2,video::E_DRIVER_TYPE& outDriver)
{
// Primeiramente, é necessário criar um dispositivo principal para a
aplicação.
// É a partir deste nó que tudo é criado.
device = createDevice( video::EDT_BURNINGSVIDEO,core::dimension2d<s32>(512,
384), 16, false, false, false, this);
// Agora deve ser criado um objeto responsável pelas funções que tratam a
parte gráfica da aplicação.
video::IVideoDriver* driver = device->getVideoDriver();
// Depois é necessário criar um objeto para gerenciar todos os nós
adicionados na cena.
scene::ISceneManager* smgr = device->getSceneManager();
// Como nesta classe será criado um MENU, é necessário criar um objeto
// que forneça uma relação gráfica para os usuários.
gui::IGUIEnvironment* guienv = device->getGUIEnvironment();
// Neste bloco, é setado o título da janela do programa. Junto ao título,
será exibido a versão
// da engine utilizada.
core::stringw str = "Irrlicht Engine";
str += device->getVersion();
device->setWindowCaption(str.c_str());
// Para a criaçã do MENU, será utilizado um elemento semelhante à uma
película transparente,
// dando uma estética mais agradável para o MENU. Esse elemento é chamado de
Skin.
56
gui::IGUISkin* newskin = guienv->createSkin( gui::EGST_BURNING_SKIN);
guienv->setSkin(newskin);
newskin->drop();
// Agora, será mudado a fonte dos textos inscritos no MENU. Deve-se ter um
arquivo contendo
// a fonte desejada. Depois é só indicá-lo pelo nome.
gui::IGUIFont* font =
guienv->getFont("../../media/fonthaettenschweiler.bmp");
if (font)
guienv->getSkin()->setFont(font);
const s32 leftX = 260;
/* O MENU será composto por 2 guias: uma fornecendo algumas opções da
aplicação para o usuário, e a outra que irá exibir um texto sobre o este
projeto. Dessa forma, é necessário criar um controlador de guias.
*/
gui::IGUITabControl* tabctrl =
guienv->addTabControl(core::rect<int>(leftX,10,512-10,384-10),0, true, true);
// Guia que fornece opções para o usuário. Essas opções são: tipo de
renderizador gráfico, opção
// de fullscreen e porta de comunicação.
gui::IGUITab* optTab = tabctrl->addTab(L"Menu");
// Guia que exibe um texto sobreo projeto.
gui::IGUITab* aboutTab = tabctrl->addTab(L"Sobre");
// A Engine IrrLicht disponibiliza alguns renderizadores gráficos. Esses
renderizadores são
// listados no MENU para que atenda aos diferenes usuários de acordo com suas
preferências.
gui::IGUIListBox* box = guienv->addListBox(core::rect<int>(10,10,220,120),
optTab, 1);
box->addItem(L"OpenGL 1.5");
box->addItem(L"Direct3D 8.1");
57
box->addItem(L"Direct3D 9.0c");
box->addItem(L"Burning's Video 0.38");
box->addItem(L"Irrlicht Software Renderer 1.0");
box->setSelected(selected);
// Agora vamos dar algumas outras opções ao usuário.
const s32 d = 50;
// opção de fullscreen
guienv->addCheckBox(fullscreen, core::rect<int>(20,85+d,130,110+d),
optTab, 3, L"Fullscreen");
// porta de comunicação serial COM1
guienv->addCheckBox(com1, core::rect<int>(20,160+d,230,185+d),
optTab, 6, L"IP: 192.168.0.90");
// porta de comunicação serial COM2
guienv->addCheckBox(com2, core::rect<int>(20,185+d,230,210+d),
optTab, 7, L"PORTA: 8000");
// Depois que o usuário esquelheu suas opções desejadas, agora ele pode
iniciar a interação
// com o ambiente pressionado o botão "START", que é criado da seguinte
maneira:
startButton = guienv->addButton(core::rect<int>(30,295,200,324), optTab, 2,
L"Start");
// Até agora foram criados os itens da primeira guia (guia "MENU"). Agora
vamos criar um texto falando
// sobreo projeto e colocá-lo na segunda guia (guia "SOBRE").
wchar_t* text2 = L"Para comecar, selecione um dispositivo que funcione
melhor"\
L"com seu hardware e pressione 'start'. "\
L"Trata-se de um programa em que o usuario navega pelo ambiente e, ao
clicar sobre "\
L"os interruptores instalados, lampadas referente a estes, serao
acionados, "\
58
L"no modo em que o usuario pode controlar os dispositivos reais atraves
do ambiente virtual via web. "\
L"Este programa foi desenvolvido pelos alunos do curso de Ciencia da
Computacao: "\
L"Frederico da Silva, Erica Roque, Alessandro Goncalves, orientado pelo
Professor "\
L"Marcelo Camponez. Para mais informacoes, por favor entre em contato:
[email protected]";
guienv->addStaticText(text2, core::rect<int>(10, 10, 230, 320),true, true,
aboutTab);
#if 1
#endif
// Para deixar a tela de apresentação mais agradável, vamos colocar a
logomarca da engine
// IrrLicht e uma imagem do ambiente de fundo.
bool oldMipMapState =
driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
guienv->addImage(driver->getTexture("../../media/irrlichtlogo2.png"),
core::position2d<s32>(5,5));
// criando a imagem de fundo.
video::ITexture* irrlichtBack =
driver->getTexture("../../media/imagem_menu.bmp");
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState);
// Estas funções são usadas para dar um detalhamento na estética do MENU.
// Função que extrai a cor original do Skin.
getOriginalSkinColor ();
// Função que seta transparência no MENU.
setTransparency();
59
/* Pronto, o MENU está criado. Agora o que devemos fazer é colcoar o
dispositivo para funcionar, chamando o método RUN. Este método vai colocar o
dispositivo em loop infinito até que o usuário termine a aplicação fechando a
janela ou pressionando ALT+F4.
*/
while(device->run())
{
// Esta função é opcional, mas sem ela, o dispositivo não garante que o
cursor do mouse
// seja iniciado no centro da janela.
if (device->isWindowActive())
{
driver->beginScene(false, true, video::SColor(0,0,0,0));
if ( irrlichtBack )
driver->draw2DImage(irrlichtBack,core::position2d<int>(0,0));
// Para desenhar realmente o MENU na tela, temos que extrair todos os
métodos e funções
// utilizados para este propósito. Para isso, utilizamos a função
DRAWALL.
smgr->drawAll();
guienv->drawAll();
driver->endScene();
}
}
device->drop();
outFullscreen = fullscreen;
outCom1 = com1;
// Neste bloco é selecionado o renderizador escolhido pelo usuário.
switch(selected)
{
case 0: outDriver = video::EDT_OPENGL; break;
60
case 1: outDriver = video::EDT_DIRECT3D8; break;
case 2: outDriver = video::EDT_DIRECT3D9; break;
case 3: outDriver = video::EDT_BURNINGSVIDEO; break;
case 4: outDriver = video::EDT_SOFTWARE; break;
}
return start;
}
/* O método ONEVENT geralmente é usado para tratar eventos vindos do clique do
mouse ou quando teclas do teclado são pressionadas. Neste caso, usaremos este
método para tratar os ítens selecionados no MENU.*/
bool CMainMenu::OnEvent(SEvent event)
{
if (event.EventType == EET_KEY_INPUT_EVENT &&
event.KeyInput.Key == KEY_F9 &&
event.KeyInput.PressedDown == false)
{
video::IImage* image = device->getVideoDriver()->createScreenShot();
if (image)
{
device->getVideoDriver()->writeImageToFile(image,
"screenshot_main.jpg");
image->drop();
}
}
else
if (event.EventType == irr::EET_MOUSE_INPUT_EVENT &&
event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP )
{
core::rect<s32> r(event.MouseInput.X, event.MouseInput.Y, 0, 0);
gui::IGUIContextMenu* menu =
device->getGUIEnvironment()->addContextMenu(r, 0, 45);
menu->addItem(L"transparent menus", 666, transparent == false);
menu->addItem(L"solid menus", 666, transparent == true);
menu->addSeparator();
61
menu->addItem(L"Cancel");
}
else
if (event.EventType == EET_GUI_EVENT)
{
s32 id = event.GUIEvent.Caller->getID();
switch(id)
{
case 45:
if (event.GUIEvent.EventType == gui::EGET_MENU_ITEM_SELECTED)
{
s32 s =
((gui::IGUIContextMenu*)event.GUIEvent.Caller)->getSelectedItem();
if (s == 0 || s == 1)
{
transparent = !transparent;
setTransparency();
}
}
break;
case 1:
if (event.GUIEvent.EventType == gui::EGET_LISTBOX_CHANGED ||
event.GUIEvent.EventType == gui::EGET_LISTBOX_SELECTED_AGAIN)
{
selected =
((gui::IGUIListBox*)event.GUIEvent.Caller)->getSelected();
//startButton->setEnabled(selected != 4);
startButton->setEnabled( true );
}
break;
case 2:
if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED )
{
device->closeDevice();
start = true;
62
}
case 3:
if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )
fullscreen =
((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();
break;
case 6:
if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )
com1 = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();
strcpy (pt,"com1");
break;
case 7:
//if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )
// com2 = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();
//strcpy (pt,"com2");
break;
}
}
return false;
}
void CMainMenu::getOriginalSkinColor()
{
irr::gui::IGUISkin * skin = device->getGUIEnvironment()->getSkin();
for (s32 i=0; i<gui::EGDC_COUNT ; ++i)
{
SkinColor [ i ] = skin->getColor ( (gui::EGUI_DEFAULT_COLOR)i );
}
}
void CMainMenu::setTransparency()
{
irr::gui::IGUISkin * skin = device->getGUIEnvironment()->getSkin();
u32 i;
for ( i=0; i<gui::EGDC_COUNT ; ++i)
63
{
video::SColor col = SkinColor [ i ];
if ( false == transparent )
col.setAlpha( 255);
skin->setColor((gui::EGUI_DEFAULT_COLOR)i, col);
}
}
// Bloco de declarações das variáveis, funções e métodos da classe que cria o
MENU
#ifndef __C_MAIN_MENU_H_INCLUDED__
#define __C_MAIN_MENU_H_INCLUDED__
#include <irrlicht.h>
using namespace irr;
class CMainMenu : public IEventReceiver
{
public:
CMainMenu();
bool run(bool& outFullscreen,bool& outCom1,bool&
outCom2,video::E_DRIVER_TYPE& outDriver);
virtual bool OnEvent(SEvent event);
private:
void setTransparency();
gui::IGUIButton* startButton;
IrrlichtDevice *device;
s32 selected;
bool start;
bool fullscreen;
64
bool com1;
bool transparent;
bool com2;
char pt[5];
scene::IAnimatedMesh* quakeLevel;
scene::ISceneNode* lightMapNode;
scene::ISceneNode* dynamicNode;
video::SColor SkinColor [ gui::EGDC_COUNT ];
void getOriginalSkinColor();
};
#endif
// Classe que faz a comunicação serial através do envio de um caracter.
#include "serial.h"
#include <cstdlib>
#include <iostream>
#include<windows.h>
#include<stdio.h>
#include<string>
using namespace std;
// Primeiramente, temos que ter um identificador para a porta serial. Este
identificador é do tipo
// HANDLE.
HANDLE hCom;
// Agora nós precisamos de uma estrutra pra definir todos os parametros da
comunicação. Essa
// estrutura é do tipo DCB.
DCB dcb;
// Para controlar o tempo de leitura e escrita na porta serial, é necessário
criar um timeout.
65
COMMTIMEOUTS CommTimeouts;
// Método construtor da classe serial
cliente::cliente(){}
// Depois que tudo está configurado, a palavra pode ser enviado para o servidor.
Para isto, utilizamos este
// método.
bool cliente::enviaCaracter(char *c){
// criar um socket
SOCKET ServidorSocket;
//struct que contém as configurações do socket: porta, host e famàlia
struct sockaddr_in ServidorAddr;
//variível auxiliar para inicializar o winsock
WSADATA wsad;
//utilizada para inicializar o winsock
WSAStartup( MAKEWORD(2,2),&wsad);
//criar um socket
ServidorSocket = socket( AF_INET, SOCK_STREAM,0);
//Configura socket
ServidorAddr.sin_family = AF_INET;
//transformar uma porta em network byte
ServidorAddr.sin_port = htons(8000);
//transformar um IP de string (xxx.xxx.xxx.xxx) para valor numérico
ServidorAddr.sin_addr.s_addr = inet_addr("192.168.0.90");
//conectar-se a um host
66
connect(ServidorSocket,(struct sockaddr
*)&ServidorAddr,sizeof(ServidorAddr));
//enviar dados para uma conexão ativa
send(ServidorSocket,c,255,0);
//fechar socket
closesocket(ServidorSocket);
//finalizar winsock
WSACleanup();
}
// Este é método principal da classe. É através dele que todos os outros métodos
desta classe são
// chamados.
bool cliente::run(char *s){
enviaCaracter(s);
}
cliente::~cliente()
{
}
// Bloco de declarações das variáveis, funções e métodos da classe que faz a
comunicação cliente servidor.
#pragma once
class cliente
{
public:
cliente();
bool enviaCaracter(char *c);
67
bool run(char *s);
~cliente();
};
68
ANEXO B -- Anexo B - Código desenvolvido
do Servidor
// Classe que faz a comunicação serial através do envio de um caracter.
#include "Serial.h"
#include <cstdlib>
#include <iostream>
#include<windows.h>
#include<stdio.h>
#include<string>
using namespace std;
// Primeiramente, temos que ter um identificador para a porta serial. Este
identificador é do tipo
// HANDLE.
HANDLE hCom;
// Agora nós precisamos de uma estrutra pra definir todos os parametros da
comunicação. Essa
// estrutura é do tipo DCB.
DCB dcb;
// Para controlar o tempo de leitura e escrita na porta serial, é necessário
criar um timeout.
COMMTIMEOUTS CommTimeouts;
// Méodo construtor da classe serial
serial::serial(){}
69
// Este método é rsponsável pela abertura da porta serial, na qual serão
enviados os caracteres
// para as placas de acionamento.
bool serial::abrirSerial(char *porta){
hCom = CreateFile(porta,GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
// condição de invalidade do handle
if (hCom == INVALID_HANDLE_VALUE) {
printf("erro");
return false;
}
printf("\r\n\nPorta serial: ok");
return true;
}
// Depois que a porta serial foi aberta, temos que configurá-la.
bool serial::configuraPorta(){
// condição de de erro na leitura da dcb
if( !GetCommState(hCom, &dcb)){
printf("\r\nProblemas na abertura da DCB!");
return false;
}
printf("\r\nAbertura da DCB: ok");
dcb.BaudRate = CBR_1200;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
// define novo estado
if( SetCommState(hCom, &dcb) == 0 ){
printf("\r\nProblemas na configuracao da serial");
return false;
}
printf("\r\nConfiguracao da serial: ok");
return true;
}
70
// Os timeouts são configurados de acordo com as necessidades da aplicação.
bool serial::configuraTimeouts(){
// condição de erro nos timeouts
if( GetCommTimeouts(hCom, &CommTimeouts) == 0 ){
printf("\r\nProblemas nos timeouts!");
return false;
}
CommTimeouts.ReadIntervalTimeout = 0;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0;
CommTimeouts.WriteTotalTimeoutMultiplier = 0;
CommTimeouts.WriteTotalTimeoutConstant = 0;
if( SetCommTimeouts(hCom, &CommTimeouts) == 0 )
return false;
printf("\r\nTimeouts: ok");
return true;
}
// Depois que tudo está configurado, o carater pode ser transmitido. Para isto,
utilizamos este
// método.
bool serial::enviaCaracter(char *c){
/*
MYSQL conexao;
mysql_init(&conexao);
if ( mysql_real_connect(&conexao, "127.0.0.1", "root", "1234", "BANCO", 0, NULL,
0) )
{
printf("conectado com sucesso!\n");
mysql_query(&conexao,"UPDATE estado set status = 'ligado' where posicao =
c");
71
mysql_close(&conexao);
}
else
{
printf("Falha de conexao\n");
printf("Erro %d : %s\n", mysql_errno(&conexao), mysql_error(&conexao));
}*/
DWORD BytesEscritos = 0;
int TamaString;
TamaString = strlen(c);
if(!WriteFile( hCom, c, TamaString, &BytesEscritos, NULL )){
printf("\r\nProblemas ao escrever na serial!");
return false;
}
printf("\r\nCaracter enviado com sucesso!");
return true;
}
// Depois que o caracter foi enviado, devemos fechar a porta serial para dar
acesso à outra
// solicitação.
void serial::fechaPorta(){
CloseHandle( hCom );
}
// Este é método principal da classe. É através dele que todos os outros métodos
desta classe são
// chamados.
bool serial::run(char *porta,char *s){
abrirSerial(porta);
configuraPorta();
configuraTimeouts();
enviaCaracter(s);
fechaPorta();
}
72
serial::~serial()
{
}
#include "Serial.h"
void Conexao(char Buffer[255]){
//declarando aonde deve ser feito a conexão
MYSQL conexao;
//iniciando a conexão
mysql_init(&conexao);
//depois de iniciada, enviado dados necessarios para entrar no MYSQL, e no
banco necessario
if ( mysql_real_connect(&conexao, "127.0.0.1", "root", "1234", "BANCO", 0,
NULL, 0) )
{
printf("\n \t conectado com sucesso!\n");
//Comparando a palavra para decidir aonde ela sera armazenada
if(Buffer[3]=='2')
//atualização na tabela, chamada da função de envio do caracter
{mysql_query(&conexao,"update lampada set status = 'ligado' where status =
'desligado' and idLampada = 123;");
serial s;
s.run("com1","FF");
s.run("com1","FF");
}
if(Buffer[3]=='1')
{mysql_query(&conexao,"update lampada set status = 'desligado' where status
= 'ligado' and idLampada = 123;");
serial s;
73
s.run("com1","AA");
s.run("com1","AA");
}if(Buffer[3]=='0')
{mysql_query(&conexao,"update lampada set status = 'ligado' where status =
'desligado' and idLampada = 124;");
serial s;
s.run("com1","FF");
s.run("com1","FF");
}if(Buffer[3]=='3')
{mysql_query(&conexao,"update lampada set status = 'desligado' where status
= 'ligado' and idLampada = 124;");
serial s;
s.run("com1","AA");
s.run("com1","AA");
}
//fechando conexão com o banco
mysql_close(&conexao);
}
else
{
printf("Falha de conexao\n");
printf("Erro %d : %s\n",
//mostrando qual o erro com a conexão com o banco de dados
mysql_errno(&conexao), mysql_error(&conexao));
}
}
// Bloco de declarações das variáveis, funções e métodos da classe que faz a
comunicação serial.
#pragma once
class serial
{
74
public:
serial();
bool abrirSerial(char *p);
bool configuraPorta();
bool configuraTimeouts();
bool enviaCaracter(char *c);
bool recebeCaracter();
bool run(char *porta,char *s);
void fechaPorta();
~serial();
};
Download

ACIONAMENTO 3D - ESTENDENDO PARA INTERNET