Criação de um Dispositivo de Navegação em Mundos Virtuais
(Bicicleta Virtual)
Desenvolvido no âmbito do grupo de
realidade Virtual da PUCRS
(Financiado com recursos da FAPERGS e da PUCRS)
Leandro Luis Dias
(Bolsista)Este relatório está dividido em duas partes: a primeira, descreve resumidamente os resultados do projeto, a segunda detalha os aspectos técnicos do mesmo.
Descrição Resumida dos Resultados do Projeto
1. Resumo do Projeto
Uma das tarefas mais complicadas quando se trabalha com mundos virtuais tridimensionais é a navegação. Em geral, este processo envolve o uso de botões, teclas e outros artifícios, pouco naturais ao processo de "andar por algum lugar". Exemplos disto são os navegadores ou ambientes como Nestcape, Virtus, Internet Explorer, Worldtoolkit e outros.
Pensando nisto este projeto criou uma ferramenta de navegação mais natural. Em uma bicicleta, ligamos um conjunto de dispositivos elétricos e, pela interpretação das informações obtidas destes equipamentos, efetuamos o deslocamento dentro de um mundo virtual previamente criado.
A exibição do mundo virtual é feita utilizando a biblioteca de rendering tridimensional em tempo real OPENGL. As imagens geradas são exibidas em um óculos de realidade virtual que fornece informações à respeito da movimentação da cabeça do usuário, permitindo, assim, a exibição de uma imagem ainda mais realista, adaptável à movimentação da cabeça do usuário. A fim de deixar documentado o estudo realizado sobre OpenGL, criamos uma homepage(http://www.inf.pucrs.br/cg) que já está em uso desde maio de 1998.
A leitura dos dados da bicicleta é realizada pela captura dos movimentos dos pedais e da direção. No guidão da bicicleta instalamos um resistor variável(potenciômetro) que com os movimentos do guidão altera sua resistência. Este dado analógico, convertido para forma digital é então lido pelo computador e usado para atualizar a imagem que está sendo exibida ao usuário.
Para o deslocamento no mundo virtual é usada a informação proveniente do giro da roda ou dos pedais da bicicleta. Este dado é usado para dar a velocidade do descolamento no mundo virtual.
No esquema a seguir é apresentado um modelo da arquitetura desenvolvida. Cabe ressaltar que neste projeto ainda não tratamos aspectos relativos à movimentação física da bicicleta(inclinação, trepidação, levantamento).
2. Resultados Atingidos com o Projeto
2.1 Resultado Geral
Dando continuidade a implantação do Laboratório de Realidade Virtual da PUCRS, este projeto teve como objetivo criar um Dispositivo de Navegação em Mundos Virtuais através da captura dos movimentos de um bicicleta.
Para coroar o trabalho, o Museu de Ciências e Tecnologia da PUCRS, convidou para que o projeto seja apresentado, de forma permanente, em sua área de experimentos tecnológicos. Os procedimentos para tanto já estão sendo desenvolvidos.
2.2 Resultados Específicos
Com o desenvolvimento deste projeto foi possível:prosseguir a implantação do Laboratório de Realidade Virtual da PUCRS;
formar pessoal capacitado em realidade virtual;
criar um dispositivo que facilite a navegação em ambientes virtuais;
dominar a utilização de ferramentas de geração de imagens tridimensionais em tempo real;
dominar aspectos relativos à aquisição de dados analógicos em computador;
realizar seminários sobre realidade virtual e aquisição de dados;
levar o bolsista a participar de eventos de iniciação científica;
Incorporar assuntos deste projeto, nas disciplinas de Computação Gráfica do curso de Bacharelado em Informática da PUCRS.
Dentro desta perspectiva o bolsista desenvolveu ou auxiliou o prof. Orientador na nas seguintes tarefas:
Levantamento de material sobre aquisição de dados e conversão analógica/digital
Levantamento de material sobre bibliotecas de rendering tridimensional;
Levantamento de material sobre realidade virtual disponível na Internet e demais universidades brasileiras;
Manutenção de uma Home-Page sobre realidade virtual, que está disponível na Internet no endereço http://www.inf.pucrs.br/~grv;
Testes com o óculos de realidade Virtual I-glasses!;
Auxílio ao prof. Orientador na elaboração de palestra sobre Realidade Virtual e Computação Gráfica que foi ministrada pelo professor-orientador, em Porto Alegre, São Carlos(SP), Goiania(GO), Belo Horizonte(MG), Viçosa(MG) e Santa Maria(RS);
Publicação do Tutorial "Uma Introdução à Realidade Virtual" na Escola Reagional de Informática da Região Centro-Oeste.
3. Conclusão
O projeto obteve êxito em seu desenvolvimento.
A divulgação do trabalho, junto ao Museu de Ciências e Tecnologia da PUCSR está proporcioando uma grande divulgação do projeto.
Participamos da Feira de Iniciação Científica da UFRGS.
Considerando que o objetivo central do projeto é difundir o uso de Realidade Virtual considero que estamos conseguindo atingi-lo.
Para o ano 1999 estamos solicitando a renovação da bolsa de Iniciação Científica.
4. Perspectiva de Continuidade ou Desdobramento do Trabalho
Para o ano de 1999 pretendemos:
Continuar o projeto dando ênfase a utilização de equipamentos que foram adquiridos pela Universidade;
Desenvolver o projeto na área de Realidade Aumentada(já encaminhado à FAPERGS).
Detalhamento Técnico do Projeto
1. Introdução
A seguir são apresentados os aspectos técnicos envolvidos no desenvolvimento do projeto de criação de uma Bicicleta Virtual.
O projeto implementa um periférico para navegação em ambientes virtuais que consiste basicamente de uma bicicleta e um dispositivo de visualização (HMD - Head-Mounted Display) dotado de um rastreador. Estes equipamentos com o auxílio de outros dispositivos para leitura dos movimentos proporcionam ao usuário a sensação de imersão no ambiente virtual.
Os dados lidos pelo sistema podem ser resumidos em: direção de locomoção, velocidade de locomoção e alvo de visão.
Os dados relativos a locomoção do usuário dentro do sistema são informados através da bicicleta. Para a direção de locomoção, utiliza-se um potenciômetro e para a velocidade de locomoção utiliza-se um dínamo. Ambos geram saídas analógicas que devem ser convertidas para sinais digitais. Assim, estes dispositivos são ligados a uma placa de conversão analógica/digital, que é instalada ao barramento ISA do computador.
Na seção 2 descreveremos esta placa mais detalhadamente. Para tratamento dos dados fornecidos pela AX5210, foi adquirida uma biblioteca que realiza esta conversão.
O alvo de visão, ou seja, a direção para onde o usuário está olhando é fornecida por um dispositivo de rastreamento (tracker). Conforme os movimentos da cabeça do usuário, o tracker envia as coordenadas ao sistema para atualização da imagem a ser mostrada. O HMD que estamos utilizando (I-Glasses!), já possui acoplado um tracker próprio, como será descrito no capítulo 3. Uma biblioteca específica para a leitura do traker pode ser encontrada na página de projetos do GRV.
A navegação do usuário ocorre dentro de um mundo virtual. Para exibição deste, é utilizada uma biblioteca de Rendering 3D, chamada OpenGL. Uma descrição mais detalhada desta biblioteca é dada na página da Disciplina de Computação Gráfica da Faculdade de Informática da PUCRS.
A modelagem dos cenários onde se desenvolve a navegação é feito por um Editor de Cidades.
Apresentamos na figura a seguir uma esquematização abrangente dos periféricos e dispositivos envolvidos no sistema.
Figura 1.1 - Descrição Geral do Sistema
2. Aquisição dos Dados da Bicicleta
2.1 Placa Conversora Analógico/Digital AX5210
A função básica de um sistema de conversão analógica é converter um sinal de entrada analógico para um formato correspondente(digital) que o computador possa ler.
É uma característica normal ao processo de conversão o chamado erro de quantificação. Este erro se deve ao fato de que para realizar a conversão A/D é necessário definir faixas de entrada para a voltagem. Por exemplo, se tivermos uma resolução de (1 contagem)/(100mV), teremos a mesma saída digital num intervalo de 100mV, tendo um erro de quantificação de ± 50mV. Na prática, este erro pode ser um pouco maior, devido às imprecisões características das tensões de referência.
Todas as técnicas de conversão necessitam do emprego de comparadores lógicos. Estes comparadores funcionam como uma porta lógica, recebendo duas tensões analógicas como entrada (Va e Vb). É feito uma comparação entre elas de modo que se Va>Vb, a saída será 1, caso contrário será 0.
Dois dos métodos de conversão A/D são o de conversor controlado por contador e o de aproximações sucessivas. O primeiro é mais lento, sendo necessários 2N-1 períodos de relógio (15 para um conversor de 4 bits) para realizar a conversão. O método das aproximações sucessivas é mais rápido, exigindo, em geral, N comparações para uma comparação de N bits.
A AX5210 é uma placa interna para PC que permite a aquisição de dados analógicos externos. São exemplos de dados analógicos: pressão, temperatura, umidade, corrente, tensão, etc.
Esta placa, fabricada pela AXIOM Technology, possui um conversor A/D de 12 bits com 16 canais de entrada analógica e velocidade de comunicação com a memória de 30Khz. Para cada entrada é possível definir um valor particular de ganho, correspondente ao nível do sinal na entrada. Este processo, chamado de calibração, é que irá definir o valor da saída digital conforme uma tensão de entrada.
A rotina de leitura dos dados gerados por esta placa está descrita na seção 2.5.
Estamos desenvolvendo uma nova versão do proejto utilizando um outro dispositivo de conversão A/D chamado TNG3, fabricado pela MINDTEL.
2.2 Placa de Proteção
O intervalo de voltagem aceito pela placa AX5210 é de 20V a +20V. Valores fora deste intervalo poderão danificar a placa. Como uma das fontes de tensão é um dínamo, que gera uma quantidade de tensão proporcional à velocidade que seu eixo está sendo rotado, foi necessário construir uma Placa de Proteção para evitar que a corrente elétrica superasse o valor máximo suportado e queimasse a Placa de Conversão A/D ou outros acessórios do microcomputador.
Conforme pode ser notado nas Figuras 2.1 e 2.2 , vê-se que para cada uma das entradas dos canais da placa conversora existem circuitos que protegem o equipamento e o microcomputador de correntes elevadas e sobre-tensões. A finalidade dos diodos (D) é de garantir que não haverá uma tensão muito grande que não seria suportada pela placa conversora. O resistor R tem a finalidade de baixar a corrente do sinal de entrada no canal da placa conversora. Esta Placa de Proteção foi criada pelo bolsista Cícero Zanoni com o apoio técnico do IPCT.
Figura 2.1 - Esquema de Proteção para utilização do potenciômetro
Figura 2.2 - Esquema de Proteção para utilização do dínamo
2.3 Potenciômetro para Leitura da Direção
Para possibilitar a leitura da direção da bicicleta, ou seja, para que lado o usuário está girando o guidom, foi utilizado um potenciômetro comum. Os potenciômetros, também chamados de resistores variáveis, permitem variar a tensão que passará por eles. O desenho do circuito utilizado é mostrado na Figura 2.3.
Figura 2.3 - Esquema elétrico de conexão do potenciômetro
A tensão que passa pelo potenciômetro é gerada por uma fonte de corrente elétrica contínua. Conforme é mostrado na Figura 2.4, esse adaptador é conectado na Placa de Proteção, assim como o potenciômetro. Desse saem três fios e daquele apenas o seu conector. Um dos fios do potenciômetro é o que transporta a corrente elétrica de entrada(deve ser conectado à entrada 1). O segundo transporta a corrente elétrica de saída e deve ser conectado à entrada 6. O terceiro fio é o terra(deve ser conectado à entrada 11). Desta forma, quando o potenciômetro é girado a corrente elétrica que está saindo aumenta ou diminui de acordo com o lado em que se está girando.
Figura 2.4 - Esquema de conexão do Potenciômetro na Placa de Proteção
Para acoplar o potenciômetro à bicicleta foi necessário a construção de um pequeno suporte, como é mostrado na Figura 2.5. Esse suporte possui um furo por onde passa o cilindro rotatório do potenciômetro que é fixado com uma pequena porca. O suporte é preso no quadro da bicicleta com um parafuso e uma porca, ficando paralelo ao garfo da bicicleta e bem próximo do mesmo, como pode ser visualizado na Figura 2.6. Para que houvesse aderência entre o garfo e o cilindro rotatório do potenciômetro foi utilizada uma pequena roda de borracha. Desta forma, quando o guidom da bicicleta é girado, o cilindro do potenciômetro também é girado, mas em sentido contrário.
Figura 2.5 - Potenciômetro acoplado ao seu suporte
Figura 2.6 - Potenciômetro acoplado ao quadro da bicicleta
A corrente elétrica enviada pelo potenciômetro para a Placa de Proteção varia de acordo com a corrente de entrada, mas a Placa de Conversão A/D só emite dados entre [0; 5]. Como o intervalo é fixo foi feita uma escala para transformar os valores de corrente elétrica para as possíveis direções. O valor 2.5 corresponde ao centro, ou seja, o guidom não está girado para nenhum lado. Da mesma forma, o valor 0 corresponde ao lado esquerdo e o valor 5 ao lado direito. As direções intermediárias são calculadas usando o mesmo raciocínio.
2.4 Dínamo para Leitura da Velocidade
Para possibilitar a leitura da velocidade da bicicleta, ou seja, a rapidez que o usuário está pedalando, foi utilizado um dínamo próprio para bicicletas, como é mostrado na Figura 2.7. Quando o dínamo é rotacionado ele gera eletricidade. A corrente elétrica gerada é do tipo alternada e diretamente proporcional à velocidade imposta ao dínamo.
Figura 2.7 - Dínamo
O dínamo é preso na parte traseira do quadro da bicicleta. A parte posterior do cilindro rotatório que sai do dínamo fica firmemente apoiada na roda da bicicleta, como é mostrado na Figura 2.8. Desta forma, quando a roda da bicicleta gira faz com que o cilindro do dínamo também gire. A corrente elétrica gerada por essa rotação é levada à Placa de Proteção por dois fios.
Figura 2.8 - Dínamo acoplado à bicicleta
Para a conversão de corrente elétrica alternada para contínua foi usado um retificador AC/DC do tipo RS405L. Os dois fios que saem do dínamo são ligados no retificador. Deste saem outros dois fios conduzindo a corrente elétrica contínua e que são conectados à Placa de Proteção, no pinos 8 e 11, como é mostrado na Figura 2.9
Figura 2.9 - Esquema de conexão Dínamo / Retificador / Placa de Proteção
2.5 Rotinas para Leitura dos Dados
Para possibilitar a leitura dos dados emitidos pela Placa de Conversão A/D foi adquirido pela PUCRS um kit para programação da placa no ambiente Windows. Esse kit é composto por DLLs (Dinamic Link Library) e a documentação de suas funções. Toda a parte de programação direcionada para a Placa de Conversão A/D foi feita utilizando essa biblioteca.
As funções da biblioteca fazem uso de algumas estruturas que devem ser declaradas previamente. Como só foi utilizada a conversão analógica para digital, basta declarar a estrutura utilizada para este tipo de conversão, como mostra a Figura 2.10.
TypeAIPARM = Record
wChan: Integer ' Canal AD utilizado
wGainCode: Integer ' Código de ganho
wExpChan: Integer ' Canal da placa de expansão
wExpGainCode: Integer ' Código de ganho da placa de exp.
fData: Single ' Dado de saída
hWnd: Long ' Handle da janela
End
Figura 2.10 - Declaração do tipo AIPARM
A primeira coisa a ser feita para utilizar o kit é inicializar a biblioteca. Isso é feito basicamente pela chamada da função axInitialize que carrega alguns dados de configuração da Placa de Conversão A/D previamente gravados no arquivo INI passado por parâmetro para a função. Foi desenvolvida a função Inicializa_Placa_AD que além de inicializar a biblioteca, também inicializa as estruturas AIPARM utilizadas para capturar os valores enviados pela Placa A/D. Todo o código utilizado para inicialização da biblioteca é mostrado na Figura 2.11.
//Procedimento que Inicializa a Placa Analógica-Digital
procedure Inicializa;
begin
lpstrIniFile := 'axdrv.ini';
wErr := axInitialize(lpstrIniFile);
if wErr > 0 then
begin
axGetErrMsg(wErr,lpstrDes);
ShowMessage(lpstrDes);
end;
end;
Figura 2.11 - Função para inicialização da biblioteca
Feita a inicialização da biblioteca com sucesso já é possível ler dados. A leitura é feita pela função axADInput. Foi desenvolvida a função Le_Entrada que recebe um parâmetro que define o número do Canal a ser lido. A Figura 2.12 mostra o código utilizado para capturar os dados advindos da Placa A/D.
//==== Função que lê os dados que
estão sendo enviados para a placa ====// function Le_Entrada(Channel : integer): Single; Var Readlparm: AIPARM; begin Readlparm.wChan := Channel; wErr := axADInput(wDev, Readlparm); if wErr > 0 then begin wErr := axGetErrMsg(wErr, lpstrDes); ShowMessage(lpstrDes); Le_Entrada := -200; end else Le_Entrada := Readlparm.fData; end; |
Figura 2.12 - Função para leitura de dados da Placa Conversora A/D
A função Le_Entrada é chamada por uma função controlada por um timer. Nesta rotina, primeiramente, é lido o canal 1 para obter a velocidade. Esta velocidade é então usada para atualizar a posição da bicicleta no mundo virtual. A seguir é lido o canal 2 para a atualização da direção de locomoção(figura 2.13).
// Faz a leitura dos dados da placa através de um timer
procedure TFormCidade.TimerPlacaTimer(Sender: TObject);
Var
Guidao: Integer;
NovaVelocidade:GLDouble;
begin
Andou := false;
// Controla a velocidade
NovaVelocidade := Le_Entrada(1);
AtualizaPosicao(NovaVelocidade);
// Controla a Guidão
Guidao := Round(Le_Entrada(0)) ;
AtualizaDirecao(Guidao);
end;
Figura 2.13 - Função para tratamento dos dados
3. Aquisição dos Dados do Óculos
Para capturar os dados do óculos ele deve ser conectado em uma das portas seriais (RS-232) livres existente no computador. Esta conexão é feita através de um cabo de interface DB-9 que através de um adaptador pode ser ligado a interfaces DB-25. Também ligados ao computador, estão um cabo de saída de vídeo e outro de entrada ao qual é ligado o monitor (VGA), com isso, é permitido a visualização do cenário tanto no óculos como no próprio monitor.
Além da utilização do óculos para a visualização, ele é utilizado no rastreamento dos movimentos do usuário através do tracker acoplado na parte traseira do óculos. Este tracker emite dados (em forma de pacotes) através da porta serial.
3.1 HMD I-Glasses! VPC da Virtual I/O
O I-glasses é um óculos que permite visualizar imagens 3D em videotapes, jogos eletrônicos, jogos de PC ou qualquer outra fonte de vídeo NTSC. Possui capacidade de rastreamento (head-tracker acoplado), compatibilidade com imagens advindas de vídeo e de computador e pode ser usado com óculos de grau. Também é possível, através de seus dois alto-falantes, emitir estímulos sonoros ao usuário.
Uma outra vantagem do I-glasses! é que ele permite visão estereoscópica. Ela a responsável pela sensação de imersão no ambiente. Esta sensação é obtida gerando-se uma imagem diferente para cada olho. Na verdade é uma única cena vista de perspectivas diferentes, e exibidas simultaneamente uma para cada olho, como demonstrado na Figura 3.1.
Figura 3.1 - Visão Estereoscópica
Para rastreamento dos movimentos da cabeça do usuário, o I-glasses! Possui três sensores, sendo um para cada eixo: X, Y e Z. Estes movimentos, demonstrados nos itens 1, 2 e 3 da Figura 3.2, são chamados de:
Pitch: é o movimento da cabeça para cima e para baixo, como quando você diz "sim". Eixo de rotação: X;
Roll: é o movimento lateral da cabeça para a direita e esquerda, como que tentando encostar a orelha no ombro. Eixo de Rotação: Z;
Yaw: é o movimento de rotação lateral da cabeça, como quando você diz "não". Eixo de rotação: Y.
Figura 3.2 - Movimentos Rastreados pelo I-Glasses!
Também é possível, através destes movimentos, fazer com que o óculos emule um mouse ou um joystick.
Somente é aceito como entrada pelo I-glasses! um sinal NTSC. Vídeo cassetes e videogames utilizam este sinal como saída, mas a maioria dos PCs utilizam uma saída VGA. Para converter este sinal, usa-se o Virtual I-O PC Interface, mostrado na Figura 3.3. Este dispositivo possui uma entrada para VGA, uma saída para o head-tracker, um conector para áudio, uma saída para microfone, uma entrada para vídeo RCA e uma entrada de energia.
Figura 3.3 - Virtual I-O PC Interface
A leitura dos dados gerados pelo óculos é feita por algumas funções que são distribuídas junto com o mesmo. Estes dados são as variáveis P, R e Y (já descritas anteriormente) fornecidas pelo tracker.
Na Figura 3.4, mostramos exemplo de um programa em C que faz esta leitura dos dados gerados pelo óculos:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include "vstrack1.h"
void main(int argc,char ** argv)
{
TrackerData td;
TrackerStatus ts;
TrackerPort trackerPort;
printf("Inicializando o tracker.\n");
//Inicializa o tracker e determina em que porta serial
ts = initTrackerSearch(&td,&trackerPort,9600,timerSecs(2));
printf("%s.\n",trackerInfo(ts));
if (ts != TS_OK)
{
closeTracker(&td); //se der erro, fecha e sai do programa
exit(0);
}
//envia parâmetros para iniciar leitura de dados
ts = sendTrackerCMD(&td,"!M1,P,B\r",timerSecs(2));
if (ts != TS_OK)
{
printf("%s.\n",trackerInfo(ts)); //se der erro mostra o status
closeTracker(&td); //fecha
exit(0); //e sai do programa
}
requestTrackerData(&td); //requisita dados
//inicia um loop eterno (até pressionar 'q') de leitura de dados
while (1)
{
float y,p,p2,r;
if (kbhit() && getch() == 'q') break;
ts = readTracker(&td,timerSecs(1)); //checa tracker
if (ts != TS_OK) //se houver erro
{
printf("\n%s.\n",trackerInfo(ts)); //mostra status e
ts = resetTracker(&td,timerTSecs(1)); //reseta tracker
if (ts != TS_OK)
{ //se novo erro
printf("\n%s.\n",trackerInfo(ts)); //então mostra status
}
}
requestTrackerData(&td); //requisita dados
y = TOFLOAT(td.euler.y); //converte dados
p = TOFLOAT(td.euler.x);
r = TOFLOAT(td.euler.z);
//imprime dados lidos no monitor
printf("y %6.2f p %6.2f r %6.2f\n", y, p, r);
}
//encera leitura
closeTracker(&td);
}
Figura 3.4 - Exemplo de Leitura do Tracker do I-Glasses!
3.2 Protocolo de Comunicação do Óculos
Para a leitura dos dados foi utilizado o componente MSComm32 ActiveX Control Versão 5.0 [MIC-97], desenvolvido pela Microsoft Corp., a qual disponibiliza este em todas as máquinas que possuem o sistema operacional Windows95 instalado. Este componente esta disponível no formato de OCX o que facilita na sua programação.
Para o funcionamento do óculos é necessário que a porta serial do computador esteja configurada conforme a tabela da figura 3.5.
Parâmetro |
Valor |
Bits per second |
9600 |
Data bits |
8 |
Parity |
None |
Stop Bits |
1 |
Flow Control |
Xon/Xoff |
Figura 3.5 - Configurações da porta serial
No projeto foi utilizada a COMM=2 como porta de comunicação entre o computador e o tracker.
3.3 Inicialização
Para a inicialização da comunicação com o tracker do óculos, deve-se primeiro abrir a porta de comunicação. Na figura 3.6, a porta serial é configurada conforme os parâmetros citados anteirormente através da propriedade Settings, o número da porta COMM a ser utilizada é determinado pela propriedade CommPort, através da propriedade InputLen determina-se que o componente deve ler todo o buffer de entrada não importando o tamanho, e logo após, a propriedade PortOpen recebe True indicando que a porta deve ser aberta para dar início a comunicação.
MSComm1.Settings
= "9600,N,8,1" Configura porta serial |
Figura 3.6 - Inicialização da porta serial
Após a abertura da porta serial deve ser enviado um comando de reset (inicialização) para o tracker através do envio da string "!R" seguida do símbolo de carriage-return (ASCII=13). Logo após a inicialização deve ser enviada uma string de configuração que o tracker utilizará como padrão para a comunicação. Na figura 3.7, mostra-se um trecho de código para efetuar a inicialização. Note que é utilizada a propriedade output tanto para o envio da string de inicialização, como para o envio da string de configuração ("!M2,P,A,7,7"), que define que o modo de leitura é "pulled" e ASCII, ou seja, os dados serão enviados somente quando solicitados e no formato ASCII. Observa-se que entre os dois envios a um loop onde o sistema permanece lendo a COMM até que seja recebido a string "0" identificando que a operação ocorreu com sucesso.
Aux = " " 'Inicializa variável
auxiliar Do MSComm1.output = "!R" +Chr$(13) 'Envia comando de reset ao traker Do Loop Until MSComm1.InBufferCount > 0 'Loop até que buffer com algo Aux = MSComm1.Input 'Armazena entrada na variável Aux Loop Until Aux = "0" 'Permanece em loop até que receba "0" de OK Aux = " " Do MSComm1.output = "!M2,P,A,7,7" +Chr$(13) 'Envia string de configuração Do Loop Until MSComm1.InBufferCount > 0 Aux = MSComm1.Input Loop Until Aux = "0" |
Figura 3.7 - Inicialização do óculos
3.4 Formato dos Pacotes de Dados
Os pacotes de dados são enviados a partir de cada pedido, este realizado através do envio do caracter "S". Conforme a string de configuração enviada anteriormente, os pacotes de dados são enviados em formato ASCII. Este pacote para que tenha validade (possa ser aceito pelo sistema) deve vir com a string "FF" como header. Caso esta exigência seja cumprida o resto do pacote pode ser tratado. Os dados de Yaw, Pitch e Row vêm agrupados separados por espaços em branco, sendo que o seus valores reais são enviados em formato Hexadecimal. Na Figura 3.8, é mostrado um exemplo de pacote de dados válidos que representa os seguintes valores: Yaw=15400, Pitch=230 e Row=1040.
"FF 3C28 00E6 0410" |
Figura 3.8 - Exemplo de pacote de dados
3.5 Rotina de Leitura
A rotina de leitura consiste em:
solicitar um pacote de dados através do envio do caracter "S".
verificar a validade do pacote através do header.
no caso de um pacote válido, chamar a função Trata_Dados enviando o pacote de dados juntamente com as variáveis Yaw, Pitch e Row, para que estas possam receber os valores correspondentes a seus movimentos já convertidos de hexadecimal para o formato decimal.
Na figura 3.9 é mostrado um trecho que implementa a rotina de leitura. A função Trata_Dados é descrita na figura 3.10. Note que também foi incluído um trecho que serve para dar tempo para que o processador execute suas tarefas. Este trecho foi incluído para previnir, no caso de utilização em loops, que o sistema tranque por falha de processamento.
MSComm1.output
= "S" Solicita pacote de dados |
Figura 3.9 - Rotina de leitura dos dados
Private Sub Trata_Dados(linha, ByRef Y,
ByRef p, ByRef r) Dim Cont, i As Integer 'Declaração de variáveis Dim valor_dec As Integer Dim tamanho As Integer Dim valor_hex As String tamanho = Len(linha) 'Armazena tamanho do pacote valor_hex = " " 'Variável para armazenamento de valores capturados Cont = 1 'Inicia contador de movimentos For i = 4 To tamanho 'Loop até o fim do pacote If (Mid(linha, i, 1) = " ") Then 'Caso separador de movimento valor_dec = Val("&H" + valor_hex) 'Converte valor Hexadecimal valor_hex = " " 'Zera string auxiliar If Cont = 1 Then 'Caso seja primeiro movimento Y = valor_dec 'Carrega valor de Yaw End If If Cont = 2 Then 'Caso seja segundo movimento p = valor_dec 'Carrega valor do Pitch End If If Cont = 3 Then 'Caso seja terceiro movimento r = valor_dec 'Carrega valor do Row End If Cont = Cont + 1 'Incrementa contador de movimento Else valor_hex=valor_hex+Mid(linha, i, 1) 'Captura valor hexadecimal End If Next I End Sub |
Figura 3.10 - Função para tratamento dos dados
4. Utilização dos dados do Óculos
Para a perfeita exibição das imagens no óculos é necessário atualizá-las a cada vez que o usuário mover a cabeça.
A partir dos pacotes de dados que são lidos da porta serial e da utilização da função Trata_Dados (convertendo os valores hexadecimal para decimal dos movimentos da cabeça) é identificada a rotação necessária para atualizar a imagem visualizada.
Esta rotação foi implementada com base na análise da diferença do valor capturado e o valor anterior. No trabalho foi implementado apenas o movimento de yaw, podendo posteirmente ser acrescentados os movimentos de pitch e row.
Para desenvolver uma fórmula que retornasse como resultado o ângulo em graus de rotação (este no eixo Y, representando o movimento de yaw) foi necessário identificar o intervalo de valores que o tracker retornava para este movimento. Com testes específicos foi verificado que eles variavam de [-16384;+16384], totalizando 32768 para um giro completo. Como este movimento suporta 360º graus de rotação chegamos a seguinte fórmula mostrada na Figura 4.1. Note que a fórmula representa exatamente a regra de três (também mostrada na Figura 4.1.) que demonstra a relação dos ângulos com os valores de yaw.
Ângulo > valor de yaw (Ycapturado Yanterior) |
Figura 4.1 Fórmula do ângulo de rotação
A função Rotaciona_Y mostrada na Figura 4.2 utiliza a fórmula descrita para atualizar o cenário conforme a variação de yaw. Note que é feita uma consistência para verificar se os valores variaram positivamente ou negativamente, e conforme o caso, rotaciona-se o observador (câmera) no sentido horário ou anti-horário.
Private Sub
Rotaciona_Y(Y As Long) Angulo = (360 * Abs(Y - Yaw)) \ 32768 Obtem o
ângulo End Sub |
Figura 4.2 Função que rotaciona eixo Y
Na Figura 4.3. é mostrado o cenário do mundo virtual na sua posição inicial, e logo após na Figura 4.4 é demonstrado um pequeno giro da cabeça do usuário para a direita, correspondendo a uma rotação positiva no eixo Y.
Figura 4.3 Posição inicial do usuário no mundo virtual
Figura 4.4 Visão do usuário após movimento da cabeça
5. Utilização dos dados do Potenciômetro
Para definir a direção de deslocamento do usuário no mundo virtual é preciso ler a movimentação do guidom através do potenciômetro, e usar seus valores para rotacionar a câmera.
Com a utilização da função Le_Placa (parâmetro 0 para potenciômetro) descrita anteriormente, que retorna um valor de 0 a 180, correspondente ao ângulo de giro do guidom da bicicleta, consegue-se definir qual a direção na qual esta se movimenta.
Na figura 5.1. são mostrados os vetores principais de direção com os respectivos valores de intervalo retornados da função Le_Placa, comparados com os correspondentes valores de ângulo de rotação do guidom.
Para guardar a direção (atualizada) de movimentação do usuário foi criado o vetor direção, inicializado em (x=0,y=0 e z=1), indicando que até o usuário alterar a posição inicial do guidom (reto para a frente) a bicicleta andará ao longo do eixo Z do mundo virtual.
Figura 5.1 Relação dos valores do potenciômetro com os de rotação do guidom
Observando a figura 5.1, nota-se que a diferença entre os valores retornados do potenciômetro e os valores do ângulo de rotação do guidom é de exatamente 90 unidades. Com base nesta observação foi concluído que a partir dos valores coletados do potenciômetro deve-se diminuir de 90 unidades para ter o valores correspondentes do ângulo de rotação do guidom.
Para atualizarmos a direção de movimento do usuário (vetor de direção) foram utilizadas fórmulas de rotação em torno do eixo Y (figura 5.2.). Esta função recebe o ângulo de rotação do guidom e o emprega nas fórmulas para obter um novo vetor.
Private Sub
Seta_VetDirecao(ByVal angulo As Integer) |
Figura 5.2 Função que atualiza vetor de direção
Para simular a correta realização de uma curva é preciso garantir que, na retomada da mesma (quando o guidom retorna à posição normal) o vetor direção não seja alterado. Ou seja, após uma conversão para a direita o vetor direção deve ficar em (1,0,0) mesmo após o retorno do guidom. Isto foi resolvido considerando para rotações, apenas o aumento (em valores absolutos) do ângulo do guidom.
6. Utilização dos dados do Dínamo
A utilização da função Le_Placa (parâmetro 1 para dínamo) descrita anteriormente, retorna um valor de 0 até o limite de velocidade conseguido pelo usuário. Através desta função consegue-se definir o valor que será multiplicado ao vetor de direção. Na figura 6.1 é mostrado um trecho de código que demonstra a atualização das coordenadas do observador (câmera) em relação ao mundo virtual. Note que quanto maior a velocidade, maior será o valor de atualização, com isso, o usuário têm a sensação de que está andando mais rapidamente.
View.cameraX
= View.cameraX + (dirx * velocidade) |
Figura 6.1 Trecho de código que atualiza observador no mundo virtual