Estacionamento do Caminhão

Transcrição

Estacionamento do Caminhão
Sistemas Especialistas Difusos (Fuzzy Expert Systems) :
FuzzyClips
Exercício: Estacionamento do Caminhão
1
1. O programa Truck.exe da HyperLogic
• O programa TRUCK.EXE da Hyperlogic é um simulador de rotas de
estacionamento de um caminhão, em marcha-ré, com velocidade
constante, utilizando lógica fuzzy (lógica nebulosa).
Objetivo do programa Truck.exe
• Estacionar um caminhão:
Movendo-se em marcha-ré,
Com velocidade constante,
Num determinado local de um pátio de área 100 x 100 unidades (por
exemplo 100 x 100 m) onde se encontra.
• O local do estacionamento deve situar-se no ponto X = 50 com o
caminhão parado perpendicularmente ao eixo dos X (ou seja, ϕ = 90o)
Fig. 1 – Desenho esquemático do pátio de manobras do caminhão
2
Fig. 2 – Desenho esquemático da situação final desejada para o caminhão...
1.1 Como funciona a execução do programa ?
• Indicar, inicialmente
A posição (X,Y) do caminhão
ângulo ϕ do caminhão com o eixo dos X
A velocidade constante de marcha-ré do caminhão ( 1, 2, 3, 4 ou 5)
• No programa Truck.exe escolha a opção Run → Situation e configure as
opções
X position e Y position (posição (X,Y) do caminhão)
Azimuth angle (ângulo ϕ do caminhão com o eixo dos X)
Truck speed (velocidade constante de marcha-ré do caminhão)
3
Fig. 3 – Configurando a situação inicial através da opção Run → Situation do programa Truck.exe.
• Para executar o programa Truck.exe com as opções apresentadas na Figura 3 [ X
Position = 20, Y Position = 30, Azimuth angle (ϕ
ϕ) = 235o e Truck Speed (velocidade
constante de marcha-ré) = 2 ] escolha a opção Run → Situation.
Fig. 4 – Resultado da execução do programa Truck.exe (situação inicial: X = 20, Y = 30, ϕ = 235o e
velocidade = 2)
4
1.2 Execute o programa para algumas situações iniciais...
• Para maior familiaridade com o programa, execute-o algumas vezes.
Abaixo, uma tabela de situações iniciais para teste (e o resultado da
execução).
Teste No
1
2
3
4
5
6
7
8
9
10
11
12
13
X
20
20
70
70
70
10
10
90
90
22
22
22
22
Y
30
30
25
10
10
10
10
50
50
76
76
76
76
ϕ
0o
180o
90o
270o
350o
270o
270o
270o
270o
100o
100o
280o
280o
Velocidade
2
2
1
3
1
2
1
1
2
5
1
5
1
Resultado
Ok
Ok
Ok
Ok
Ok
?
Ok
Ok
?
Ok
Ok
Ok
Ok
1) Porquê os testes 6 e 9 não funcionaram ?
2) Porquê o teste 11 apresentou “melhor” resultado que o teste 10 ? Idem
para o teste 13 com relação ao teste 12.
3) Teste outras situações iniciais...
5
1.3 Entendendo o “controle difuso” do caminhão...
• Após executar o programa Truck.exe foi possível perceber que as
variáveis de entrada: (1) X, (2) Y, (3) ϕ e (4) velocidade constante de
marcha-ré do caminhão “iniciam” o processo de controle de
estacionamento do caminhão.
• Mas afinal, o que ocorre a cada “instante” do processo de estacionamento?
Vamos tentar entender...
O programa inicialmente analisa:
A coordenada X em que se encontra o caminhão
o ângulo ϕ do caminhão com o eixo dos X
e calcula
o ângulo θ da roda do caminhão com seu eixo
• Assim, o primeiro valor de saída a cada “instante” é o ângulo θ.
Fig. 5 – Variáveis de entrada (X e ϕ) e variável de saída (θ
θ)
6
1.3.1 – O processo básico de fuzificação
• O processo de fuzificação se baseia na avaliação da seguinte estrutura de
regra:
SE
Distância X = ... E
Ângulo ϕ = ...
ENTÃO
Ângulo θ = ...
• Foi proposto pelos autores do programa Truck.exe a seguinte fuzificação:
1.3.1.1 – Variável Distância (X)
Variável Linguística:
DISTÂNCIA (X)
Termo Linguístico
Significado
LE
Left
LC
Left-Center
CE
Center
RC
Right-Center
RI
Right
7
1.3.1.2 – Variável ângulo ϕ do caminhão com o eixo dos X
Variável Linguística:
Ângulo ϕ
Termo Linguístico
Significado
RB
Right-Below
RU
Right-Up
RV
Right-Vertical
VE
Vertical
LV
Left-Vertical
LU
Left-Up
LB
Left-Below
8
Fig. 6 – Orientação do ângulo ϕ do caminhão com o eixo dos X
1.3.1.3 – Variável ângulo θ da roda do caminhão com seu eixo
Variável Linguística:
Ângulo θ
Termo Linguístico
Significado
NB
Negative
NM
Negative-Medium
NS
Negative-Small
ZE
Zero
PS
Positive-Small
PM
Positive-Medium
PB
Positive
9
1.3.2 – As regras do Sistema Especialista
• O programa Truck.exe utiliza 35 regras para controlar o valor da variável
de saída (ângulo θ) a cada “instante”: como temos a variável X
apresentando 5 termos linguísticos e a variável ϕ apresentando 7 termos
linguísticos, teremos 35 combinações:
Fig. 7 – A “combinação” de 5 valores de distância X e 7 valores de ϕ “produz” 35 regras.
• O programa Truck.exe apresenta uma proposta de modelagem para as 35
regras, com a qual ele executa o processo de estacionamento:
Fig. 8 – As 35 regras de controle do programa Truck.exe
10
• Na Figura 8 podemos ver as 35 regras inicialmente propostas pelos
projetistas do programa Truck.exe. Por exemplo:
SE
Distância X = LE
Ângulo ϕ = RB
ENTÃO
Ângulo θ = PS
SE
Distância X = LC
Ângulo ϕ = RB
ENTÃO
Ângulo θ = PM
SE
Distância X = LC
Ângulo ϕ = RU
ENTÃO
Ângulo θ = PS
SE
Distância X = CE
Ângulo ϕ = VE
ENTÃO
Ângulo θ = ZE
SE
Distância X = RC
Ângulo ϕ = LU
ENTÃO
Ângulo θ = NS
E
E
E
E
E
• É possível alterar o resultado (a parte “ENTÃO”) de qualquer uma das 35
regras. Basta utilizar a opção Project → Rules e “navegar” com as setas
do teclado para apontar o resultante que se deseja alterar (na “janela”
Rules: X vs. Chi) e, ao teclar <enter> escolher o novo valor.
11
1.3.3 – O disparo de uma regra do Sistema Especialista
• O que acontece quando uma regra do sistema é disparada ?
Podemos dizer, neste caso, que os fatos referentes à distância X e ao
ângulo ϕ casaram com seus respectivos antecedentes na regra
disparada. Assim a regra disparada apresentou como resultado de saída
o ângulo θ.
Porém, θ não é o único resultado naquele “instante”. Uma vez
calculado não podemos esquecer que o propósito do sistema é
“movimentar” o caminhão para o local de estacionamento desejado.
Assim, com o ângulo θ recém calculado, é calculado o novo ângulo ϕ’
do caminhão com o eixo dos X.
Em seguida, com o ângulo ϕ’ recém calculado, a posição atual (X,Y)
do caminhão e a velocidade constante de marcha-ré do caminhão,
calcula-se a nova posição (X’,Y’) do caminhão.
• Vejamos a seguir como calcular ϕ’ e (X’,Y’).
1.3.3.1 – O cálculo de novo ângulo ϕ’ do caminhão com o eixo dos X.
• O valor de ϕ’ é assim calculado:
ϕ’ = ϕ + θ
• Para entender esta fórmula vejamos uma situação-exemplo:
O caminhão encontra-se, em determinado instante, na posição (X,Y) =
(60,30) e ϕ = 315o = - 45o (Ver Figura 9).
12
Fig. 9 – (A) O caminhão encontra-se, em determinado instante, na posição (X,Y) = (60,30)
com
ϕ = - 45º . (B) A orientação do ângulo ϕ.
Nestas condições temos que:
Considerando a definição dos conjuntos difusos para a variável
Distância X apresentada no item 1.3.1.1, X = 60 é considerado apenas
um valor RC (Right-Center) com grau de pertinência 1 (µRC(60) = 1).
Para os demais valores (LE, LC, CE, RI) X = 60 apresenta grau de
pertinência zero.
Considerando a definição dos conjuntos difusos para a variável Ângulo
ϕ do caminhão com o eixo dos X apresentada no item 1.3.1.2, ϕ = -45o
é considerado apenas uma valor RB (Right-Below). Como em 1.3.1.2 o
conjunto difuso RB não está definido numericamente (apenas sabemos
que –90 tem grau de pertinência zero), suponha que µRB(-45) = .7 !!!
Da Figura 8, que apresenta o conjunto de 35 regras de controle de cálculo
do ângulo θ temos que:
13
SE
Distância X = RC
Ângulo ϕ = RB
ENTÃO
Ângulo θ = PB
E
Como µRC(60) = 1 e µRB(-45) = .7, a regra acima será disparada com
potência de disparo min(1 , .7) = .7 !!!
Assim, o resultado é θ = PB com potência de disparo da regra de .7 !!!
O conjunto difuso resultante, que corresponde ao ângulo θ será o seguinte:
O valor de θ após a defuzificação pelo método do centróide é 26,44o ,
conforme pode ser observado na figura abaixo:
14
Foi dito que ϕ’ = ϕ + θ. Observe a Figura 10 abaixo para entender
porquê :
15
Fig. 10 – Novo ângulo ϕ’ é resultante da soma de ϕ com θ .
Assim o novo valor ϕ’ = ϕ + θ = -45o + 26.44o = -18.56o.
1.3.3.2 – O cálculo da nova posição (X’,Y’) do caminhão
•
Continuando a situação-exemplo da seção anterior, o que se deseja é
calcular a nova posição (X’,Y’) do caminhão.
• O deslocamento “instantâneo” ocorre a determinada velocidade constante
de marcha-ré do caminhão ( 1, 2, 3, 4 ou 5)
• Esta velocidade nada mais é do que a hipotenusa do triângulo retângulo
apresentado abaixo na Figura 11:
16
Fig. 11 – Cálculo da nova posição (X’ , Y’).
• Observe que na Figura 11 também é apresentado o cálculo de (X’ , Y’)
• Na situação-exemplo, supondo V = 2 temos então:
X’ = X + V cos(ϕ’) = 60 + 2 cos(-18,56 ) = 60 + (2 * 0,948) = 61,896
o
Y’ = Y + V sen(ϕ’) = 30 + 2 sen(-18,56 ) = 30 + (2 * -0,318) = 29,364
o
o
Obs.: Note que cos(-18,56 ) = -0,948 e não +0,948. Deve-se inverter o sinal
porquê o programa Truck.exe adotou como convenção 360o = 0o o semi-eixo
oposto ao que é normalmente apresentado quando se usa o círculo
trigonométrico em Matemática (ver Figuras 6, 9 e 10). Veja a Figura 12
abaixo
17
Fig. 12 – Orientação do ângulo
“convencional”
18
ϕ do caminhão com o eixo dos X e Círculo trigonométrico
1.3.3.3 – RESUMO: cálculo da nova posição (X’,Y’) do caminhão
1) Variáveis de entrada: X e ϕ
2) Avaliar, entre as 35 regras, quais serão acionadas e dispará-las.
3) O resultado das regras disparadas é a variável θ
4) Calcular:
4.1) ϕ’ = ϕ + θ
4.2) X’ = X + V cos(ϕ
ϕ’)
4.3) Y’ = Y + V sen(ϕ’)
1.3.4 – O funcionamento completo do sistema especialista para
estacionar o caminhão
• O programa TRUCK.exe se propõe a executar o estacionamento do
caminhão na parte “inferior” do pátio (veja na Figura 2)
• Um esqueleto básico para este algoritmo poderia ser o abaixo apresentado:
Y´ = - 999
Ler Variáveis de entrada: X e ϕ
Enquanto Y’ <> 100 faça:
1) avaliar, entre as 35 regras, quais serão acionadas e
dispará-las
2) defuzificar a variável θ
3) calcular ϕ’ = ϕ + θ
4) calcular X’ = X + V cos(ϕ
ϕ’)
5) calcular Y’ = Y + V sen(ϕ
ϕ’)
Fim-Enquanto
19
Questão 1
Objetivo: Apresentar a movimentação do caminhão em marcha à ré usando o código
javascript em anexo para cada uma das situações (testes) abaixo:
20
Teste No
X
Y
ϕ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
20
20
70
70
70
70
10
90
70
22
22
86
22
33
10
12
12
12
90
5
50
80
90
50
27
20
20
70
30
30
25
10
10
25
10
50
25
76
76
27
76
44
15
85
60
60
30
20
40
37
20
40
33
30
30
25
0o
180o
90o
270o
350o
300o
270o
270o
300o
100o
100o
220o
280o
220o
320o
210o
210o
277o
200o
300o
279o
230o
30o
333o
333o
0o
180o
90o
Velocidade
inicial
2
2
1
3
1
4
1
1
2
5
1
3
1
2
4
1
2
4
5
3
4
2
4
3
3
2
2
1
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
70
70
70
10
90
70
76
50
76
76
81
10
85
12
12
15
5
50
80
90
50
27
10
10
25
10
50
25
22
45
47
22
35
15
12
60
22
42
39
10
12
12
40
33
270o
350o
300o
270o
270o
300o
100o
233o
280o
280o
220o
320o
210o
210o
277o
260o
300o
279o
230o
30o
333o
333o
3
1
4
1
1
2
5
1
3
1
3
4
1
2
4
5
3
4
2
4
3
3
Material a ser elaborado e apresentado ao professor:
Código do fuzzy clips para cálculo de TETA pronto para ser executado
Planilha eletrónica mostrando localizações do caminhão (ver modelo de planilha
abaixo, no exemplo)
Execução do deslocamento do caminhão usando a página html e o código
javascript apresentados abaixo no ANEXO 1
21
Procedimento:
1) Codifique no FuzzyClips as variáveis linguísticas X, ϕ e θ conforme as
definições dadas acima para o programa Truck.exe
2) Codifique no FuzzyClips as regras de processamento conforme as definições
dadas acima para o programa Truck.exe
3) Faça o valor do fato referente à variável linguística ser um conjunto difuso triangular
centrado no valor da variável com grau de pertinência 1 com amplitude de 0,1 a mais
e a menos deste valor da variável.
3.1) Exemplo: Se X = 84 metros, então, supondo que DISTX seja a variável linguística
o
X no FuzzyClips e se ϕ = 133.7 , então, supondo que PHI seja a variável
linguística ϕ no FuzzyClips temos os fatos codificados conforme abaixo:
4) Para cada MOVIMENTAÇÃO do caminhão registre, em planilha,
(1)
(2)
(3)
(4)
(5)
a sua posição (X, Y),
o ângulo ϕ,
a velocidade V de marcha a ré,
o ângulo θ (que é resultante do movimento do caminhão) e
o novo valor (X’, Y’) da nova posição do caminhão
(6) Use obrigatoriamente para as 2 (duas) primeiras movimentações a
Velocidade inicial indicada no teste. Depois, escolha livremente a melhor
velocidade para movimentação
22
ACOMPANHE O EXEMPLO ABAIXO
♦ Suponha que, inicialmente, o caminhão está na posição X = 84 metros e Y = 30
o
metros, com ângulo ϕ = 133.7 e velocidade de marcha à ré V = 4
♦ Então na planilha fica assim:
♦ Vamos executar o FuzzyClips para calcular TETA, com as condições acima:
23
♦ Então o ângulo TETA defuzificado pelo processo do centroide vale
θ = 13,0485 ≈ 13,05
♦ Agora calculamos o novo valor de PHI:
ϕ’ = ϕ + θ
ϕ’ = 133.7 - 13,05 = 120.65o
(veja que aqui subtraiu ao invés de somar TETA. Porquê ?)
♦ Agora calculamos o novo ponto (X’;Y’) do caminhão:
X’ = X + V cos(ϕ’)
Y’ = Y + V sen(ϕ
ϕ’)
X’ = 84 + 4 * cos(120.65o)
Y’ = 30 + 4 * sen(120.65o)
X’ = 84 + 4 * -0.50979
Y’ = 30 + 4 * 0.860297
X’ = 81.96
Y’ = 33.44
♦ Pronto !!! Agora temos a segunda localização do caminhão. Registre na planilha e
repita a operação para achar a 3a, 4a, 5a, .... localização do caminhão...
♦ Então, para a 3a localização do caminhão temos que X = 81.96 e ϕ = 120.65o
♦ Codifique estes fatos no FuzzyClips assim:
24
♦ Aí execute o fuzzyclips com estes fatos para ver qual o ângulo TETA
♦ Então, para a 3a localização, o ângulo TETA defuzificado pelo processo do centroide
vale
θ = 16,40762 ≈ 16,41
25
♦ Agora calculamos o novo valor de PHI:
ϕ’ = ϕ + θ
ϕ’ = 120.65 - 16,41 = 104,24o
(veja que aqui subtraiu ao invés de somar TETA. Porquê ?)
♦ Agora calculamos o novo ponto (X’;Y’) do caminhão:
X’ = X + V cos(ϕ’)
Y’ = Y + V sen(ϕ
ϕ’)
X’ = 81.96 + 4 * cos(104,24o)
Y’ = 33.44 + 4 * sen(104,24o)
X’ = 81.96 + 4 * -0.24598
Y’ = 33.44 + 4 * 0.969274
X’ = 80.99
Y’ = 37.32
♦ Pronto !!! Agora temos a terceira localização do caminhão. Registre na planilha e
repita a operação para achar a 4a, 5a, .... localização do caminhão... até ele estacionar
ATENÇÃO !!! Após 2 (duas localizações) registradas na planilha, para
acelerar o trabalho de estacionamento do seu caminhão, se você quiser
começe a utilizar, A PARTIR DA 3a LOCALIZAÇÃO, a velocidade que
melhor convier
♦ Finalmente, após ter registrado na planilha todos os pontos (X,Y) mostre-os na
página html (com javascript) apresentada no anexo
26
♦ Suponha que a planilha abaixo seja o resultado final:
♦ Salve a planilha em formato .txt ou .csv. Veja o exemplo abaixo
♦ No exemplo acima, é importante criar, no arquivo .txt ou .csv um cabeçalho contendo
as seguintes colunas (separadas por ponto-e-vírgula):
LOCALIZACAO;X;Y;PHI;TETA;XLINHA;YLINHA
♦ E vai interessar apenas as colunas LOCALIZACAO, X e Y.
♦ Execute a página html (está em anexo) e abra o arquivo .txt (ou .csv) que você
salvou). O resultado será algo parecido com a seguinte imagem:
27
*** FIM DO EXERCÍCIO ***
28
ANEXO
Arquivo patio_caminhao.htm
<html>
<head>
<script language="JavaScript" type="text/JavaScript" src="jsPatioCaminhao.js">
</script>
</head>
<body onload="f_IniciarTela();">
<center><h2>Exercício do estacionamento do caminhão</h2></center>
<hr>
<div id='divMsg' style="display:block; position:relative; background-color:#eeeeee;">
</div>
<hr>
<div id='divArqTrilhaCaminhao' style="display:none; position:relative; background-color:#eeeeee;">
<Table align='Center' border>
<TR><TD>
<table border=1>
<tr>
<td align='center'>
<font color="#000000"><b>Arquivo com a trilha do caminhão</b></font>
</td>
</tr>
<tr>
<td align='center'>
Nome do arquivo com a trilha do caminhão:
<input type="file" id="vArqTrilhaCaminhao" name="vArqTrilhaCaminhao[]" multiple maxlength="100" />
</td>
</tr>
<tr>
<td align='center'>
Obs.: o arquivo DEVE estar em formato .txt ou .csv e a primeira linha será a linha contendo cabeçalho das
colunas
</td>
</tr>
</table>
</TD></TR>
</Table>
</div>
<div id='divArquivoLido' style="display:none; position:relative; background-color:#eeeeee;">
</div>
<hr>
</body>
</html>
29
Arquivo jsPatioCaminhao.js
//----- Variáveis globais -----------------------var gDados
= ""
var gNomeArq = "";
var gX_Ponto0_noCanvas = -1;
var gY_Ponto0_noCanvas = -1;
var g_X_ImgRect
= -1;
var g_Y_ImgRect
= -1;
var g_Width_ImgRect = -1;
var g_Height_ImgRect = -1;
var gRaio, gMoldura, gPixelsXporMetro, gPixelsYporMetro;
//-------------------------------------------------------------function f_IniciarTela() {
// Check for the various File API support.
// Obs.: é possível testar para apenas um tipo (File, FileREader, FileList, Blob)
if (window.File && window.FileReader && window.FileList && window.Blob) {
f_Prosseguir(); // Para poder carregar listener do objeto input type=file...
}
else {
alert("Este browser não permite ler arquivos da máquina local");
}
}
//-------------------------------------------------------------function f_Prosseguir() {
var vTexto, vDiv;
vDiv = document.getElementById('divMsg');
vTexto = "<A href='javascript: f_Prosseguir_2()'> (1) Clique aqui para iniciar...</A>";
vDiv.innerHTML = vTexto;
}
//-------------------------------------------------------------function f_Prosseguir_2() {
var vTexto, vDiv;
vDiv = document.getElementById('divMsg');
vTexto = "<A href='javascript: f_LerArquivoComTrilha()'> (2) Clique aqui para abrir o arquivo com a trilha do
caminhão...</A>";
vDiv.innerHTML = vTexto;
}
//-------------------------------------------------------------function f_LerArquivoComTrilha() {
f_AddListenerParaObjFile();
30
//-------------------------------------------------------------}function f_AddListenerParaObjFile() {
var vDiv
document.getElementById('vArqTrilhaCaminhao').addEventListener('change', f_ManipularArqTrilhaCaminhao, false);
vDiv = document.getElementById('divArqTrilhaCaminhao');
document.getElementById('divArquivoLido').style.display
= 'none';
document.getElementById('divArqTrilhaCaminhao').style.display = 'block';
}
//-------------------------------------------------------------function f_ManipularArqTrilhaCaminhao(evt) {
//Retrieve the first (and only!) File from the FileList object
var vFile, vFileReader, vTexto, vDiv, vAux;
var vConteudoArquivo, vLen, vProximaFuncao;
var vTipoArq;
vFile = evt.target.files[0];
if (vFile) {
gNomeArq = evt.target.files[0].name;
vTipoArq = evt.target.files[0].name;
if (vTipoArq.length >= 4) {
vTipoArq = vTipoArq.substring(vTipoArq.length-4,vTipoArq.length);
}
if ( (!vFile.type.match('text.*')) && (vTipoArq !== '.csv') && (vTipoArq !== '.CSV') ) {
alert("Arquivo não apresenta formato txt ou csv");
}
else {
gNomeArq = vFile.name;
vDiv = document.getElementById('divArquivoLido');
vTexto = "Nome do arquivo: <b>" + gNomeArq + "</b>";
vTexto += "<p>";
vDiv.innerHTML = vTexto;
document.getElementById('divArqTrilhaCaminhao').style.display = 'none';
document.getElementById('divArquivoLido').style.display
= 'block';
//--//------> Criar um objeto reader de arquivo...
vFileReader = new FileReader();
//------> Declara apenas a função que diz o que fazer ao terminar a leitura....
vFileReader.onload = function(e) {
vConteudoArquivo = e.target.result;
vLen
= parseInt(vConteudoArquivo.length,10);
gDados
= vConteudoArquivo.substring(0,vLen);
vProximaFuncao = 'f_ManipularArqTrilhaCaminhao_A()';
eval(vProximaFuncao);
}
//------> Aqui aciona efetivamente a leitura...
vFileReader.readAsText(vFile);
}
}
else {
gNomeArq = "";
vTexto = "<LI><img src='../ppmbimg/subitem01.gif' border=0> " + "Não conseguiu ler o arquivo" + "</LI>";
fpmb01_MensagensCliente(vTexto,'divMsg','f002_MostrarDiv','','');
}
31
//-------------------------------------------------------------}function f_ManipularArqTrilhaCaminhao_A() {
//---> Em gDados está o conteúdo do arquivo lido como texto
//---> Forçamos o modo síncrono...
var vTexto, vDiv;
vDiv = document.getElementById('divArquivoLido');
vTexto = "<table border=1 id='tbArqTrilha'>";
vTexto += "<tr id='row1'>";
vTexto += "<td valign='top'>";
vTexto += "Nome do arquivo: <b>" + gNomeArq + "</b>";
vTexto += "<br>";
vTexto += "<p>";
vTexto += "<textarea rows='4' cols='50'>";
vTexto += gDados;
vTexto += "</textarea>";
vTexto += "</td>"
vTexto += "<td width='5%'> </td>";
vTexto += "<td> </td>";
vTexto += "</tr>";
vTexto += "</table>";
vDiv.innerHTML = vTexto;
document.getElementById('divArqTrilhaCaminhao').style.display = 'none';
document.getElementById('divArquivoLido').style.display
= 'block';
//--clearTimeout();
setTimeout(f_ManipularArqTrilhaCaminhao_B(), 500); // dispara a função após 500 milisegundos
}
//-------------------------------------------------------------function f_ManipularArqTrilhaCaminhao_B() {
//---> Em gDados está o arquivo lido com a trilha do caminhao
var k, vLinha, vLen, vTexto, vDados;
var vRow, vCells;
vDados = gDados;
k = vDados.indexOf("\n"); // pegar primeira linha (deve ser X;Y) ...
if (k >= 0) {
vLinha = vDados.substring(0,k-1); // \n tem dois bytes... descontar um byte...
vLinha = f_TransformaLinhaEmCsv(vLinha);
vLen = vDados.length;
vDados = vDados.substring(k+1,vLen);
}
else {
vLinha = "???";
}
if (vLinha === "LOCALIZACAO;X;Y;PHI;TETA;XLINHA;YLINHA") {
f_ManipularArqTrilhaCaminhao_C();
}
else {
vTexto = "<p><b>A primeira linha do arquivo não contém o cabeçalho esperado</b>";
vTexto += "<p> O cabeçalho esperado é o seguinte:";
32
vRow = document.getElementById("row1");
vCells = vRow.getElementsByTagName("td");
vTexto
+= "<p><p><b>LOCALIZACAO;X;Y;PHI;TETA;XLINHA;YLINHA<b>";
vCells[2].innerHTML
= vTexto;
}
}
//-------------------------------------------------------------function f_ManipularArqTrilhaCaminhao_C() {
//---> Em gDados está o arquivo lido com a trilha do caminhao
var vTexto;
var vRow, vCells;
vTexto = "<canvas id='cCanvas_Patio' width='500' height='500' style='border:1px solid #000000;'>";
vTexto += "</canvas>";
vRow = document.getElementById("row1");
vCells = vRow.getElementsByTagName("td");
vCells[2].innerHTML = vTexto;
//--vTexto = "<p>";
vTexto += "<center>";
vTexto += "Temporizador de movimento: "
vTexto += "<input type='text' id='txtMilissegundos' size='4' maxlength='4' value='1000'> milissegundos";
vTexto += "<p>";
vTexto += "<A href='javascript: f_ManipularArqTrilhaCaminhao_D()'> MOSTRAR TRILHA DO CAMINHÃO</A>";
vTexto += "</center>";
vRow = document.getElementById("row1");
vCells = vRow.getElementsByTagName("td");
vCells[0].innerHTML = vCells[0].innerHTML + vTexto;
}
//-------------------------------------------------------------function f_ManipularArqTrilhaCaminhao_D() {
//---> Em gDados está o arquivo lido com a trilha do caminhao
var vDados, vLinha, vLen, k, vAux, vCanvas, vContexto;
var vLocalizacao, vX, vY, vPhi, vTeta, vXlinha, vYlinha;
//---> Limpar área do canvas...
vCanvas = document.getElementById("cCanvas_Patio");
vContexto = vCanvas.getContext("2d");
vContexto.clearRect(0,0,vCanvas.width,vCanvas.height); // limpar a área canvas...
//---> "zerar" última posição do caminhão
g_X_ImgRect
= -1;
g_Y_ImgRect
= -1;
g_Width_ImgRect = -1;
g_Height_ImgRect = -1;
//---> desenhar o pátio...
gRaio = 8;
gMoldura = 30;
gX_Ponto0_noCanvas = gMoldura;
gY_Ponto0_noCanvas = vCanvas.height - gMoldura;
gPixelsXporMetro = (vCanvas.width - (2*gMoldura)) / 100; // 100 m = comprimento do pátio
33
vContexto.beginPath();
gPixelsYporMetro
= (vCanvas.height - (2*gMoldura)) / 100; // 100 m = largura do pátio
vPosX = gX_Ponto0_noCanvas;
vPosY = gY_Ponto0_noCanvas;
vContexto.moveTo(vPosX,vPosY);
vPosX = gX_Ponto0_noCanvas;
vPosY = gMoldura;
vContexto.lineTo(vPosX,vPosY);
vContexto.stroke();
vPosX = gX_Ponto0_noCanvas;
vPosY = gY_Ponto0_noCanvas;
vContexto.moveTo(vPosX,vPosY);
vPosX = vCanvas.width - gX_Ponto0_noCanvas;
vPosY = gY_Ponto0_noCanvas;
vContexto.lineTo(vPosX,vPosY);
vContexto.stroke();
//---> Marcar ponto de estacionamento
vPosX = gX_Ponto0_noCanvas + ((vCanvas.width - gX_Ponto0_noCanvas) / 2);
vPosY = gY_Ponto0_noCanvas
vContexto.moveTo(vPosX,vPosY);
vPosX = gX_Ponto0_noCanvas + ((vCanvas.width - gX_Ponto0_noCanvas) / 2);
vPosY = gY_Ponto0_noCanvas + (gMoldura/2);
vContexto.lineTo(vPosX,vPosY);
vContexto.stroke();
vPosX = gX_Ponto0_noCanvas + ((vCanvas.width - gX_Ponto0_noCanvas) / 2);
vPosY = gY_Ponto0_noCanvas
vContexto.moveTo(vPosX,vPosY);
vPosX = gX_Ponto0_noCanvas + ((vCanvas.width - gX_Ponto0_noCanvas) / 2);
vPosY = gY_Ponto0_noCanvas - (gMoldura/2);
vContexto.lineTo(vPosX,vPosY);
vContexto.stroke();
//---> 0 mm...
vPosX = gX_Ponto0_noCanvas - 5;
vPosY = gY_Ponto0_noCanvas + (1.5* (gMoldura/2));
vTexto = "0 m";
vContexto.beginPath(); // começa outra configuração (cor, espessura, etc...)
vContexto.fillStyle = 'blue';
vContexto.fillText(vTexto, vPosX, vPosY);
//---> 50 mm...
vPosX = gX_Ponto0_noCanvas + ((vCanvas.width - gX_Ponto0_noCanvas) / 2) - 15;
vPosY = gY_Ponto0_noCanvas + (1.5* (gMoldura/2));
vTexto = "50 m";
vContexto.beginPath(); // começa outra configuração (cor, espessura, etc...)
vContexto.fillStyle = 'blue';
vContexto.fillText(vTexto, vPosX, vPosY);
//---> 100 mm...
vPosX = (vCanvas.width - gX_Ponto0_noCanvas) - 5;
vPosY = gY_Ponto0_noCanvas + (1.5* (gMoldura/2));
vTexto = "100 m";
vContexto.beginPath(); // começa outra configuração (cor, espessura, etc...)
vContexto.fillStyle = 'blue';
vContexto.fillText(vTexto, vPosX, vPosY);
//---> Desenhar aPosicao-ésima do caminhão...
f_DesenharCaminhaoNaLocalizacao(1);
}
34
//-------------------------------------------------------------function f_DesenharCaminhaoNaLocalizacao(aLocalizacao) {
//---> Em gDados está o arquivo lido com a trilha do caminhao
var vDados, vLinha, vLen, k, vAux, vCanvas, vContexto;
var vLocalizacao, vX, vY, vPhi, vTeta, vXlinha, vYlinha;
var vAchouLocalizacao, vProximaLocalizacao;
var vTemporizador = document.getElementById("txtMilissegundos").value;
//---> Acessar o canvas...
vCanvas = document.getElementById("cCanvas_Patio");
vContexto = vCanvas.getContext("2d");
//--vAchouLocalizacao = "N";
vDados = gDados;
k = vDados.indexOf("\n"); // pegar linha
while ( (k >= 0) && (vAchouLocalizacao === "N") ){
vLinha = vDados.substring(0,k-1); // \n tem dois bytes... descontar um byte...
vLinha = f_TransformaLinhaEmCsv(vLinha);
fg_TrimLeft(fg_TrimRight(vLinha));
vLen = vDados.length;
//---> Pegar coluna LOCALIZACAO...
m
= vLinha.indexOf(";");
vLocalizacao = vLinha.substring(0,m);
vLinha
= vLinha.substring(m+1,vLen);
vLen
= vLinha.length;
if (parseInt(vLocalizacao) === parseInt(aLocalizacao)) {
vAchouLocalizacao = "S";
}
//---> Pegar coluna X...
m = vLinha.indexOf(";");
vX = vLinha.substring(0,m);
vX = parseFloat(vX,10);
vLinha = vLinha.substring(m+1,vLen);
vLen = vLinha.length;
//---> Pegar coluna Y...
m = vLinha.indexOf(";");
vY = vLinha.substring(0,m);
vY = parseFloat(vY,10);
vLinha = vLinha.substring(m+1,vLen);
vLen = vLinha.length;
//---> Pegar coluna PHI...
m = vLinha.indexOf(";");
vPhi = vLinha.substring(0,m);
vLinha = vLinha.substring(m+1,vLen);
vLen = vLinha.length;
//---> Pegar coluna TETA...
m = vLinha.indexOf(";");
vTeta = vLinha.substring(0,m);
vLinha = vLinha.substring(m+1,vLen);
vLen = vLinha.length;
//---> Pegar coluna XLINHA...
m = vLinha.indexOf(";");
vXlinha = vLinha.substring(0,m);
vLinha = vLinha.substring(m+1,vLen);
vLen = vLinha.length;
35
vYlinha = vLinha;
//---> Próxima linha (proxima localizacao)...
//--->vLen
Pegar coluna=YLINHA...
vDados.length;
vDados = vDados.substring(k+1,vLen);
k
= vDados.indexOf("\n"); // pegar proxima linha
} // end-while
//--->
//---> Tem retângulo imagem anterior ? Então restaura...
if ( (g_X_ImgRect >= 0) && (g_Y_ImgRect >= 0) ) {
vContexto.clearRect(g_X_ImgRect,g_Y_ImgRect,g_Width_ImgRect,g_Height_ImgRect);
vContexto.putImageData(g_ImgRect,g_X_ImgRect,g_Y_ImgRect);
}
//---> Salvar área onde está o caminhão em vX, vY com vRaio...
g_X_ImgRect
= vX - gRaio - 1;
if (g_X_ImgRect < 0) { g_X_ImgRect = 0; }
g_Y_ImgRect
= vY - gRaio - 1;
if (g_Y_ImgRect < 0) { g_Y_ImgRect = 0; }
g_Width_ImgRect = (gRaio * 2) + 2;
g_Height_ImgRect = (gRaio * 2) + 2;
g_ImgRect = vContexto.getImageData(g_X_ImgRect, g_Y_ImgRect, g_Width_ImgRect, g_Height_ImgRect);
if (vAchouLocalizacao === "S") {
vContexto.beginPath(); // começa outra configuração (cor, espessura, etc...)
vX = (vX * gPixelsXporMetro) + gX_Ponto0_noCanvas;
vY = (vY * gPixelsYporMetro) + gMoldura;
vContexto.arc(vX, vY, gRaio, 0, 2 * Math.PI, false);
vContexto.fillStyle = 'green';
vContexto.fill();
vContexto.lineWidth = 1;
vContexto.strokeStyle = '#003300';
vContexto.stroke();
//---> Proxima localização...
vProximaLocalizacao = parseInt(aLocalizacao) + 1;
vAux = "f_DesenharCaminhaoNaLocalizacao(";
vAux += "'" + vProximaLocalizacao + "'";
vAux += ")";
setTimeout(vAux,vTemporizador); // daqui a vTemporizador milissegundos desenha no canvas...
}
else {
//---> Caso queira informar final do processo... faça aqui...
}
}
//-------------------------------------------------------------function f_TransformaLinhaEmCsv(aLinha) {
var vLinha, vLinhaAux, k, vTemPontoVirgula, vChar;
vTemPontoVirgula = "N";
vLinha
= "";
vLinhaAux
= aLinha;
vLinhaAux
= fg_TrimLeft(fg_TrimRight(vLinhaAux));
36
for (k = 0; k < vLinhaAux.length; k++) {
vChar = vLinhaAux.substring(k,k+1);
if (vChar === ";") {
vLinha = vLinha + vChar;
vTemPontoVirgula = "S";
}
else if (vChar === " ") {
if (vTemPontoVirgula === "N") {
vLinha
= vLinha + ";";
vTemPontoVirgula = "S";
}
}
//
else if (vChar === chr(9)) { codificar chr(9) tab 31/12/2012
//
if (vTemPontoVirgula === "N") {
//
vLinha
= vLinha + ";";
//
vTemPontoVirgula = "S";
//
}
//
}
else {
vLinha = vLinha + vChar;
}
}
//--return vLinha;
}
//-------------------------------------------------------------------------------function fg_TrimLeft( str ) {
var resultStr = "";
var i = len = 0;
// Return immediately if an invalid value was passed in
if (str+"" === "undefined" || str === null)
return null;
// Make sure the argument is a string
str += "";
if (str.length === 0)
resultStr = "";
else {
// Loop through string starting at the beginning as long as there
// are spaces.
// len = str.length - 1;
len = str.length;
while ((i <= len) && (str.charAt(i) === " "))
i++;
// When the loop is done, we're sitting at the first non-space char,
// so return that char plus the remaining chars of the string.
resultStr = str.substring(i, len);
}
return resultStr;
}
//-------------------------------------------------------------------------------function fg_TrimRight( str ) {
var resultStr = "";
var i = 0;
// Return immediately if an invalid value was passed in
37
return null;
// Make sure the argument is a string
if
str(str+""
+= ""; === "undefined" || str === null)
if (str.length === 0)
resultStr = "";
else {
// Loop through string starting at the end as long as there
// are spaces.
i = str.length - 1;
while ((i >= 0) && (str.charAt(i) === " "))
i--;
// When the loop is done, we're sitting at the last non-space char,
// so return that char plus all previous chars of the string.
resultStr = str.substring(0, i + 1);
}
return resultStr;
}
38

Documentos relacionados